找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1362|回复: 0

[分享] From Model Space to Paper Space

[复制链接]

已领礼包: 859个

财富等级: 财运亨通

发表于 2015-1-13 20:48:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
From Model Space to Paper Space                         By Augusto Goncalves
Convert a coordinate from a Paper Space Viewport to the respective Model Space is possible using acedTrans and it’s already described at this blog post. Note that a point on a Viewport will point to a single point on model space, meaning this is a 1 to 1 relationship.
The opposite way is not 1 to 1, but in fact 1 to many. A point on the model space can be on several paper space viewport. To make such a conversion, we need to have a viewport, then do some math to convert the coordinate. With that, the basic idea is calculate a scale factor using two points on both paper and model space. Then using those points again calculate how much the need to move.
With that in mind, the code below is the same from this post with a few new pieces in bold. To test the idea, the code is also adding DBPoints on Paper Space for each entity’s grip point (from model space).
Note this is assuming a 2D drawing on model space, showing as a 2D drawing on paper space, with a simple view (no perspective). To make it work on every possible scenario, we may need to adjust the math…
0.jpg
[CommandMethod("testAcadMS2PS")]
public void CmdTestAcadMS2PS()
{
  Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  // pick a PS Viewport
  PromptEntityOptions opts = new PromptEntityOptions("Pick PS Viewport");
  opts.SetRejectMessage("Must select PS Viewport objects only");
  opts.AddAllowedClass(typeof(Viewport), false);
  PromptEntityResult res = ed.GetEntity(opts);
  if (res.Status == PromptStatus.OK)
  {
    int vpNumber = 0;
    // extract the viewport points
    Point3dCollection psVpPnts = new Point3dCollection();
    using (Viewport psVp =
      res.ObjectId.Open(OpenMode.ForRead) as Viewport)
    {
      // get the vp number
      vpNumber = psVp.Number;
      // now extract the viewport geometry
      psVp.GetGripPoints(psVpPnts, new IntegerCollection(),
        new IntegerCollection());
    }

    // let's assume a rectangular vport for now,
    // make the cross-direction grips square
    Point3d tmp = psVpPnts[2];
    psVpPnts[2] = psVpPnts[1];
    psVpPnts[1] = tmp;

    // Transform the PS points to MS points
    ResultBuffer rbFrom = new ResultBuffer(new TypedValue(5003, 3));
    ResultBuffer rbTo = new ResultBuffer(new TypedValue(5003, 2));
    double[] retPointDouble = new double[] { 0, 0, 0 };
    // loop the ps points
    Point3dCollection msVpPnts = new Point3dCollection();
    foreach (Point3d pnt in psVpPnts)
    {
      // translate from from the DCS of Paper Space (PSDCS) RTSHORT=3 and
      // the DCS of the current model space viewport RTSHORT=2
      acedTrans(pnt.ToArray(), rbFrom.UnmanagedObject,
        rbTo.UnmanagedObject, 0, retPointDouble);
      // add the resulting point to the ms pnt array
      Point3d retPoint = new Point3d(retPointDouble);
      msVpPnts.Add(retPoint);
    }

    // *******
    // now we assume both list of points (on MS and PS) have
    // at least 2 points, which is correct as a Viewport needs
    // 3 points for create a closed area
    //
    // find the scale fator based on points from PS and MS
    double transformScale =
      psVpPnts[1].DistanceTo(psVpPnts[0]) /
      msVpPnts[1].DistanceTo(msVpPnts[0]);
    // and find the transformation vector (displacement)
    Vector3d transformVector = msVpPnts[0].TransformBy(
      Matrix3d.Scaling(transformScale, Point3d.Origin))
      .GetVectorTo(psVpPnts[0]);
    // *******


    // now switch to MS
    ed.SwitchToModelSpace();
    // set the CVPort
    Application.SetSystemVariable("CVPORT", vpNumber);
    // once switched, we can use the normal selection mode to select
    PromptSelectionResult selectionresult =
      ed.SelectCrossingPolygon(msVpPnts);
    // now switch back to PS
    ed.SwitchToPaperSpace();

    // *******
    Database db = Application.DocumentManager.MdiActiveDocument.Database;
    using (Transaction trans = db.TransactionManager.StartTransaction())
    {
      BlockTableRecord paperSpace = trans.GetObject(db.CurrentSpaceId,
        OpenMode.ForWrite) as BlockTableRecord;
      foreach (SelectedObject obj in selectionresult.Value)
      {
        Entity ent = trans.GetObject(obj.ObjectId, OpenMode.ForRead) as Entity;
        Point3dCollection grips = new Point3dCollection();
        ent.GetGripPoints(grips, new IntegerCollection(), new IntegerCollection());
        foreach (Point3d pt in grips)
        {
          // for each grip point on MS, add a DBPoint
          // apply first the scaling fator
          // then the displacement vector
          DBPoint point = new DBPoint(pt
            .TransformBy(Matrix3d.Scaling(transformScale, Point3d.Origin))
            .TransformBy(Matrix3d.Displacement(transformVector))
            );
          paperSpace.AppendEntity(point);
          trans.AddNewlyCreatedDBObject(point, true);
        }
      }
      trans.Commit();
    }
    // *******

  }
}

[DllImport("accore.dll",
  CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedTrans")]
private static extern int acedTrans(double[] point, IntPtr fromRb,
  IntPtr toRb, int disp, double[] result);

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-17 22:41 , Processed in 0.211496 second(s), 32 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表