GET THE DISPLAYING COORDINATES OF A VIEWPORT OBJECT

GET THE DISPLAYING COORDINATES OF A VIEWPORT OBJECT

inversiones_edgar_itriago
Enthusiast Enthusiast
4,521 Views
5 Replies
Message 1 of 6

GET THE DISPLAYING COORDINATES OF A VIEWPORT OBJECT

inversiones_edgar_itriago
Enthusiast
Enthusiast

Please I need Help!!! I hope that you may Help me..I have a Viewport rectangular object located in any paper space (layout1 for example) , which is displaying a certain area of the model space, I want to get the lower left and upper right coordinates (x,y) of that area I'm visualizing with the viewport object.

 

Thanks in advance

0 Likes
Accepted solutions (1)
4,522 Views
5 Replies
Replies (5)
Message 2 of 6

_gile
Consultant
Consultant
Accepted solution

Hi

 

You can use these extension methods (from GeometryExtensions).

 

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;

namespace GeometryExtensions
{
    /// <summary>
    /// Provides extension methods for the Viewport type.
    /// </summary>
    public static class ViewportExtensions
    {
        /// <summary>
        /// Gets the transformation matrix from the specified model space viewport Display Coordinate System (DCS)
        /// to the World Coordinate System (WCS).
        /// </summary>
        /// <param name="vp">The instance to which this method applies.</param>
        /// <returns>The DCS to WDCS transformation matrix.</returns>
        public static Matrix3d DCS2WCS(this Viewport vp)
        {
            return
                Matrix3d.Rotation(-vp.TwistAngle, vp.ViewDirection, vp.ViewTarget) *
                Matrix3d.Displacement(vp.ViewTarget - Point3d.Origin) *
                Matrix3d.PlaneToWorld(vp.ViewDirection);
        }

        /// <summary>
        /// Gets the transformation matrix from the World Coordinate System (WCS)
        /// to the specified model space viewport Display Coordinate System (DCS).
        /// </summary>
        /// <param name="vp">The instance to which this method applies.</param>
        /// <returns>The WCS to DCS transformation matrix.</returns>
        public static Matrix3d WCS2DCS(this Viewport vp)
        {
            return vp.DCS2WCS().Inverse();
        }

        /// <summary>
        /// Gets the transformation matrix from the specified paper space viewport Display Coordinate System (DCS)
        /// to the paper space Display Coordinate System (PSDCS).
        /// </summary>
        /// <param name="vp">The instance to which this method applies.</param>
        /// <returns>The DCS to PSDCS transformation matrix.</returns>
        public static Matrix3d DCS2PSDCS(this Viewport vp)
        {
            return
                Matrix3d.Scaling(vp.CustomScale, vp.CenterPoint) *
                Matrix3d.Displacement(vp.CenterPoint.GetAsVector()) *
                Matrix3d.Displacement(new Vector3d(-vp.ViewCenter.X, -vp.ViewCenter.Y, 0.0));
        }

        /// <summary>
        /// Gets the transformation matrix from the Paper Space Display Coordinate System (PSDCS)
        /// to the specified paper space viewport Display Coordinate System (DCS). 
        /// </summary>
        /// <param name="vp">The instance to which this method applies.</param>
        /// <returns>The PSDCS to DCS transformation matrix.</returns>
        public static Matrix3d PSDCS2DCS(this Viewport vp)
        {
            return vp.DCS2PSDCS().Inverse();
        }
    }
}

Here's a testing command which draws a Polyline3d in the model space figuring the selected viewport extents.

 

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using GeometryExtensions;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(ViewportToWorldCoordinates.Commands))]

namespace ViewportToWorldCoordinates
{
    public class Commands
    {
        [CommandMethod("Test", CommandFlags.NoTileMode)]
        public void Test()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var options = new PromptSelectionOptions();
            options.MessageForAdding = "\nSelect a viewport: ";
            options.SelectEverythingInAperture = true;
            options.SingleOnly = true;

            var filter = new SelectionFilter(new[] { new TypedValue(0, "VIEWPORT") });

            var selection = ed.GetSelection(options, filter);
            if (selection.Status != PromptStatus.OK)
                return;

            using (var tr = db.TransactionManager.StartTransaction())
            {
                var vp = (Viewport)tr.GetObject(selection.Value[0].ObjectId, OpenMode.ForRead);
                var extents = vp.GeometricExtents;
                var xform = vp.DCS2WCS() * vp.PSDCS2DCS();
                var vertices = new Point3dCollection();
                vertices.Add(extents.MinPoint.TransformBy(xform));
                vertices.Add(new Point3d(extents.MaxPoint.X, extents.MinPoint.Y, 0.0).TransformBy(xform));
                vertices.Add(extents.MaxPoint.TransformBy(xform));
                vertices.Add(new Point3d(extents.MinPoint.X, extents.MaxPoint.Y, 0.0).TransformBy(xform));
                Polyline3d pline = new Polyline3d(Poly3dType.SimplePoly, vertices, true);
                var modelSpace = (BlockTableRecord)tr.GetObject(
                    SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite);
                modelSpace.AppendEntity(pline);
                tr.AddNewlyCreatedDBObject(pline, true);
                tr.Commit();
            }
        }
    }
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 6

_gile
Consultant
Consultant

Hi,

 

Here's another testing command which draws a point (nodal) in paper space on the center of each circle entirely visible in the (rectangular) viewport.

the command works whatever the model space current UCS and whatever the view in the viewport.

 

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using GeometryExtensions;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(TransSpacialTranformations.Commands))]

namespace TransSpacialTranformations
{
    public class Commands
    {
        [CommandMethod("CENTERMARK", CommandFlags.NoTileMode)]
        public void CenterMark()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            // switch to paper space if a viewport is activated
            if ((short)AcAp.GetSystemVariable("CVPORT") != 1)
                ed.SwitchToPaperSpace();

            // select a viewport
            var options = new PromptSelectionOptions();
            options.MessageForAdding = "\nSelect a rectangular viewport: ";
            options.SelectEverythingInAperture = true;
            options.SingleOnly = true;
            var filter = new SelectionFilter(new[] { new TypedValue(0, "VIEWPORT") });
            var selection = ed.GetSelection(options, filter);
            if (selection.Status != PromptStatus.OK)
                return;

            using (var tr = db.TransactionManager.StartTransaction())
            {
                // get the viewport extents (paper space coordinates)
                var vp = (Viewport)tr.GetObject(selection.Value[0].ObjectId, OpenMode.ForRead);
                var extents = vp.GeometricExtents;
                double x1 = extents.MinPoint.X, y1 = extents.MinPoint.Y;
                double x2 = extents.MaxPoint.X, y2 = extents.MaxPoint.Y;

                // activate the selected viewport
                ed.SwitchToModelSpace();
                AcAp.SetSystemVariable("CVPORT", vp.Number);

                // compute the transformation matrix from paper space coordinates to model space current UCS
                var wcs2ucs = ed.CurrentUserCoordinateSystem.Inverse();
                var psdcs2ucs = wcs2ucs * vp.DCS2WCS() * vp.PSDCS2DCS();

                // compute the model space UCS polygon vertices corresponding to the viewport extents
                var polygon = new Point3dCollection();
                polygon.Add(new Point3d(x1, y1, 0.0).TransformBy(psdcs2ucs));
                polygon.Add(new Point3d(x2, y1, 0.0).TransformBy(psdcs2ucs));
                polygon.Add(new Point3d(x2, y2, 0.0).TransformBy(psdcs2ucs));
                polygon.Add(new Point3d(x1, y2, 0.0).TransformBy(psdcs2ucs));

                // select circles within the polygon
                filter = new SelectionFilter(new[] { new TypedValue(0, "CIRCLE") });
                selection = ed.SelectWindowPolygon(polygon, filter);
                if (selection.Status != PromptStatus.OK)
                    return;

                // collect the selected circles centers transformed into paper space coordinates
                var centers = new Point3dCollection();
                var wcs2psdcs = vp.DCS2PSDCS() * vp.WCS2DCS();
                foreach (SelectedObject so in selection.Value)
                {
                    var circle = (Circle)tr.GetObject(so.ObjectId, OpenMode.ForRead);
                    centers.Add(circle.Center.TransformBy(wcs2psdcs));
                }

                // switch back to paper space
                ed.SwitchToPaperSpace();

                // add a point (nodal) in paper space on the center of the selected circles
                var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                foreach (Point3d pt in centers)
                {
                    DBPoint point = new DBPoint(pt);
                    curSpace.AppendEntity(point);
                    tr.AddNewlyCreatedDBObject(point, true);
                }

                tr.Commit();
            }
        }
    }
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 4 of 6

inversiones_edgar_itriago
Enthusiast
Enthusiast

Hi Guilles, thanks for the answers, it looks interesting, I look forward to reviewing... but have another problem, I could not test it because I have my installation of AutoCAD 2016 was a trial version and expired two days ago,  :'-(   Help!

 

0 Likes
Message 5 of 6

_gile
Consultant
Consultant

Sorry but I can't help you for your license problem.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 6 of 6

inversiones_edgar_itriago
Enthusiast
Enthusiast

hello, I could test the code you suggested, it's perfect, thank you!

0 Likes