找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2102|回复: 0

[分享] DCS vs. WCS (pt. 9) – Transform Entity from Viewport (MS) WCS/UCS to PS (PSDCS)

[复制链接]

已领礼包: 859个

财富等级: 财运亨通

发表于 2014-5-28 22:08:46 来自手机 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 csharp 于 2014-5-29 07:59 编辑

http://spiderinnet1.typepad.com/blog/2014/05/autocad-net-matrix-transformations-dcs-vs-wcs-pt-9-transform-entity-from-viewport-model-space-wcsucs-to-pa.html

We presented various ways before to draw a rectangle with the view size regardless of Model space or Layout (Viewport or Space) in WCS or UCS, in a plan view or isometric, twisted or not. We also used the type ViewTableRecord, the handy method Editor.GetCurrentView(), and pretty the same logic and code as introduced before to fulfill the same task.
Last time, we created a rectangle onto the Paper Space (PSDCS) from a Layout Viewport (Layout Model Space), with the Layout Viewport size. This time, let’s transform an entity picked in a Layout Viewport from the WCS/UCS of the Layout Viewport to the current Layout Paper Space (PSDCS or PDCS).

[CommandMethod("DrawOnDCS9", CommandFlags.NoTileMode)]
public static void DrawOnDCS9_Method()
{
    Database db = MgdAcApplication.DocumentManager.MdiActiveDocument.Database;
    Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;

    if (!IsInLayoutViewport())
    {
        ed.WriteMessage("Only works in Layout Viewport.");
        return;
    }

    try
    {
        PromptEntityResult prEntRes1 = ed.GetEntity("Select an entity: ");
        if (prEntRes1.Status == PromptStatus.OK)
        {
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                Viewport vp = tr.GetObject(ed.ActiveViewportId, OpenMode.ForRead) as Viewport;
                Point3d cp = vp.CenterPoint;
                Vector3d viewDirection = vp.ViewDirection;
                Point2d viewCenter = vp.ViewCenter;
                Point3d viewTarget = vp.ViewTarget;
                double viewTwist = vp.TwistAngle;
                double viewHeight = vp.ViewHeight;
                double viewWidth = vp.ViewHeight * vp.Width / vp.Height;

                Matrix3d matDcsToWcs = Matrix3d.PlaneToWorld(viewDirection)
                                                .PreMultiplyBy(Matrix3d.Displacement(viewTarget - Point3d.Origin))
                                                .PreMultiplyBy(Matrix3d.Rotation(-viewTwist, viewDirection, viewTarget));

                Matrix3d matDcsToPSDcs = Matrix3d.Displacement(cp - (new Point3d(viewCenter.X, viewCenter.Y, 0)))
                                                .PreMultiplyBy(Matrix3d.Scaling(vp.Height / vp.ViewHeight, cp));

                Matrix3d matWcsToPSDcs = matDcsToWcs.Inverse().PreMultiplyBy(matDcsToPSDcs);

                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockPaperSpaceId(db), OpenMode.ForWrite);
                Entity ent = (Entity)tr.GetObject(prEntRes1.ObjectId, OpenMode.ForRead);
                using (Entity pl = (Entity)ent.Clone())
                {
                    pl.ColorIndex = 3;

                    pl.TransformBy(matWcsToPSDcs);

                    //Move the clone a bit so that we can see it in PSDCS clearly along with the original in WCS/UCS of a Layout Viewport.
                    Matrix3d matMovement = Matrix3d.Displacement(new Vector3d(1, 1, 0));
                    pl.TransformBy(matMovement);

                    btr.AppendEntity(pl);
                    tr.AddNewlyCreatedDBObject(pl, true);
                }
                           
                tr.Commit();
            }
        }
    }
    catch (System.Exception ex)
    {
        ed.WriteMessage(ex.ToString());
    }
}

If we run the command in a Viewport of Layout, and pick an entity such as a closed polyline here, we will see it will be cloned to the Paper Space of the same Layout, with the color being changed to GREEN and offset a bit up right. As can be seen, the new green copy is clearly in the PSDCS and the original is in the WCS/UCS of the Layout Viewport. We also tried to select the new entity in the Viewport a few times but failed as expected.
   0.jpg

A few points may be worth of mentioning to help understand the code and some implications.
•    The Viewport class is used again in the code to represent the Layout Viewport since it has some benefits.
•    One of the benefits is that it has both view center (Viewport.ViewCenter) in WCS and center point (Viewport.CenterPoint) of the viewport object in paper space, so that we can easily build up the transformation matrix from the Layout Viewport DCS to the Paper DCS.
•    As mentioned before, though the Viewport.ViewCenter and the Viewport.CenterPoint on make sense in 2D, the former returns a Point3d. It’s not a big deal as we need to turn them all into 3D so as to calculate the 3d vector placement.
•    No need to consider the view target, view twist, or view direction as they are all the same for the Viewport DCS and the PSDCS for the matrix from the Viewport DCS to the Paper DCS.
•    We do need to think about the scaling factors though in the transformation as the Viewport DCS and the PSDCS use different units.
•    The polyline is created into the paper space this time instead of the current space, which is the model space actually from the perspective of a Layout Viewport.
•    The Database.TileMode property can be used to detect whether the viewport belongs to model space or paper space.
•    The code is supposed in a Layout Viewport only as the first few lines of code indicates.
•    We don’t have to transform the view direction (Viewport.ViewDirection), view center (Viewport.ViewCenter), view target (Viewport.ViewTarget) from UCS or DCS to WCS since these properties of the Viewport object are already expressed in WCS.
•    The view target (represented by the Viewport.ViewTarget property) instead of the view center is used to take part in the transformation matrix creation.
•    The Viewport.CenterPoint here indicates the center of the viewport entity in the paper space and it is expressed in the paper space coordinate system (PSCS, or PSDCS) which is 2D.
•    By the way, somewhere states that the Viewport.CenterPoint indicates screen pixels instead of paper space unit. It is wrong!
•    We should not assume the view center is always at the origin point. That explains why we offset the Viewport.ViewCenter to get the corners of the window on the DCS.
•    The Editor.ActiveViewportId returns the current/active viewport in either model space or paper space, but its object type will be different, Viewport in paper space but ViewportTableRecord in model space as demonstrated.
•    The Viewport.ViewHeight indicates the height of the view, expressed in the model space unit; however, the Viewport.Height is the height of the viewport entity in the paper space, thus expressed in the paper space unit.
•    There lacks of the Viewport.ViewWidth property, so we have to calculate it out from the Viewport.ViewHeight and the height to width ratio which can be got from the Viewport.Height and Viewport.Width.
•    Last but not least, the MgdAcApplication.DocumentManager.MdiActiveDocument.Database here is used instead of the HostApplicationServices.WorkingDatabase as is generally used to represent the current working database. Otherwise, a weird exception eNotFromThisDocument would occur!
Enjoy it!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-17 22:43 , Processed in 0.271263 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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