AutoCAD API c# - Get Viewport Objects - location not accurate

AutoCAD API c# - Get Viewport Objects - location not accurate

Anonymous
Not applicable
3,781 Views
1 Reply
Message 1 of 2

AutoCAD API c# - Get Viewport Objects - location not accurate

Anonymous
Not applicable

Following is what I am trying to achieve,

 

  1. User picking a viewport
  2. Code get the modespace coordinate of the selected viewport
  3. 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

 

3,782 Views
1 Reply
Reply (1)
Message 2 of 2

Anonymous
Not applicable

Update:

 

The issue happens when the usc is rotated with the vewport. Only then the viewport is rotated I am not able to get the right model space coordinates.

0 Likes