- UID
- 658062
- 积分
- 2147
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2008-10-22
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
本帖最后由 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.
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!
|
|