Message 1 of 2
AutoCAD API c# - Get Viewport Objects - location not accurate
Not applicable
05-14-2017
02:54 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Following is what I am trying to achieve,
- User picking a viewport
- Code get the modespace coordinate of the selected viewport
- Gets the objects within the selected polygon
Now the issue is, the coordinate conversion from viewport to model space is working fine for the first attempt. In the second attempt it gets the model space coordinates incorrectly.
This is from a button click event from a wpf user control tool palette
That is,
- When i select the viewport first it works fine.
- When i select the viewport second time its not working correctly.
- When i go to model space and then come and pick the viewport second time it is working fine.
If I create the same code as a separate command it is working fine.
The seem to be in the following line of code,
cenPnt = (Point3d)AcAp.GetSystemVariable("VIEWCTR");
Here is rest of my code,
// switch to paper space if a viewport is activated
if ((short)AcAp.GetSystemVariable("CVPORT") != 1)
{
GV.processStatus = false;
GV.ed.SwitchToPaperSpace();
}
PromptEntityOptions eo = new PromptEntityOptions("\nSelect a viewport: ");
eo.AllowNone = false;
eo.SetRejectMessage("\nNeed to select a viewport!");
eo.AddAllowedClass(typeof(CadDb.Viewport), true);
//next lines are to allow for non-rectangular viewport selection
eo.AddAllowedClass(typeof(Circle), true);
eo.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline), true);
eo.AddAllowedClass(typeof(Polyline2d), true);
eo.AddAllowedClass(typeof(Polyline3d), true);
eo.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Ellipse), true);
eo.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Region), true);
eo.AddAllowedClass(typeof(Spline), true);
eo.AddAllowedClass(typeof(Face), true);
PromptEntityResult er = GV.ed.GetEntity(eo);
#endregion
if (er.Status != PromptStatus.OK)
return;
else
{
using (var tr = GV.Db.TransactionManager.StartTransaction())
{
DS.Entity newEnt = null;
CadDb.Viewport vpEnt = null;
#region Clasify Viewport shape
DS.Entity selEnt = (DS.Entity)er.ObjectId.GetObject(OpenMode.ForRead);
if (selEnt.GetType() == typeof(CadDb.Viewport))
{
//Viewport is rectangular
vpEnt = (CadDb.Viewport)selEnt;
Extents3d vpExt = vpEnt.GeometricExtents;
double w = vpExt.MaxPoint.X - vpExt.MinPoint.X;
double h = vpExt.MaxPoint.Y - vpExt.MinPoint.Y;
DS.Polyline poly = new DS.Polyline(4);
poly.AddVertexAt(0, new Point2d(0, 0), 0, -1, -1);
poly.AddVertexAt(1, new Point2d(w, 0), 0, -1, -1);
poly.AddVertexAt(2, new Point2d(w, h), 0, -1, -1);
poly.AddVertexAt(3, new Point2d(0, h), 0, -1, -1);
poly.Closed = true;
newEnt = poly;
}
else
{
//Viewport is non-rectangular, attempt to get it from the selected clip entity
ObjectId vpId = LayoutManager.Current.GetNonRectangularViewportIdFromClipId(selEnt.Id);
if (vpId == ObjectId.Null)
vpEnt = null;
else
{
vpEnt = (CadDb.Viewport)vpId.GetObject(OpenMode.ForRead);
newEnt = (DS.Entity)selEnt.Clone();
}
}
if (vpEnt == null)
{
GV.ed.WriteMessage("\nSelected object is not a viewport!");
tr.Commit();
return;
}
// Turn viewport on if needed
if (!vpEnt.On)
{
vpEnt.UpgradeOpen();
vpEnt.On = true;
}
#endregion
#region Coordinate Conversion
//Activate a vport, set CVPORT to the selected vport, and get VIEWCTR of vport
GV.ed.SwitchToModelSpace();
AcAp.SetSystemVariable("CVPORT", vpEnt.Number);
cenPnt = (Point3d)AcAp.GetSystemVariable("VIEWCTR");
Extents3d entExt = newEnt.GeometricExtents;
Point3d p1 = entExt.MinPoint;
Point3d p2 = entExt.MaxPoint;
Point3d extMid = new Point3d((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2, (p1.Z + p2.Z) / 2);
double entHeight = p2.Y - p1.Y;
Vector3d zAxis = vpEnt.ViewDirection;
Vector3d xAxis = zAxis.GetPerpendicularVector().GetNormal();
Vector3d yAxis = zAxis.CrossProduct(xAxis).GetNormal();
zAxis = zAxis.GetNormal();
Matrix3d transMat;
transMat = Matrix3d.AlignCoordinateSystem(extMid, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis,
cenPnt, xAxis, yAxis, zAxis);
newEnt.TransformBy(transMat);
transMat = Matrix3d.Scaling(vpEnt.ViewHeight / entHeight, cenPnt);
newEnt.TransformBy(transMat);
transMat = Matrix3d.Rotation(-vpEnt.TwistAngle, zAxis, cenPnt);
newEnt.TransformBy(transMat);
#endregion