ViewPort - Get entities from ViewPort

ViewPort - Get entities from ViewPort

sandeep_vaal
Enthusiast Enthusiast
3,791 Views
6 Replies
Message 1 of 7

ViewPort - Get entities from ViewPort

sandeep_vaal
Enthusiast
Enthusiast

Hello,

 

I having some questions on paper space records/layout's.

 

Can we read ViewPort geometry entities.? Is it possible to get whatever data present inside the ViewPort. ?

 

Can we get scale value for multiple viewports ?

 

I have written some sample code, to read all the layouts from dwg file. I am trying to read each layout, in that I am able to read other entities like Circle/polyline/Line etc but I am not able to read Viewport.

 

Can you please have a look on below sample code.

 

 

Thanks in advance ‼!

 

Regards,

Dinesh

dinesh.gavsane@vaal-triangle.com

 

      DBDictionary layoutListRecord = transaction.GetObject(this.database.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
            if (layoutListRecord != null)
            {
                // Step through and list each named layout and Model
                foreach (DBDictionaryEntry item in this.layoutListRecord)
                {
                    string layoutName = item.Key;
                    // Get the layout and block objects from the external drawing
                    Layout layEx = this.layoutListRecord.GetAt(layoutName).GetObject(OpenMode.ForRead) as Layout;
                    BlockTableRecord blkBlkRecEx = transaction.GetObject(layEx.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;

                    
                    foreach (ObjectId id in blkBlkRecEx)
                    {
                        var entity = transaction.GetObject(id, OpenMode.ForRead) as Entity;
                        if (null == entity)
                            continue;
                      

                        if (entity is Viewport)
                        {
                            // How to use this viewport
                            //I want to read the geometry entities from viewport
                            Viewport vPort = entity as Viewport;
                        }
                    }
                }
            }

0 Likes
Accepted solutions (1)
3,792 Views
6 Replies
Replies (6)
Message 2 of 7

SENL1362
Advisor
Advisor

I don't think there is a build in function to retrieve objects inside the viewport.
I'll use the following methode to find the InsideObjects:
- find the Viewport outline -- the Viewport might be clipped.
- Clone this outline and transform it to modelspace -- Viewport transformation involves Translation, Rotation and Scaling.
- Search for entities (partial or completely) inside the cloned outline.

 

0 Likes
Message 3 of 7

sandeep_vaal
Enthusiast
Enthusiast

Thanks for your reply.

 

I am having some customers dwg files, in that only paper space layouts are present and blank model space. Is this a valid case ?

 

Means is it acceptable ? Or its wrong case ?

 

If this is a valid case then as per you I have to find outline of viewport -- then get cloned transformation copy by applying translation, rotation and scaling of outlined viewport-- and then search for the entities inside.

 

Do you have any sample code for this ? or any reference links?

0 Likes
Message 4 of 7

SENL1362
Advisor
Advisor
Accepted solution

These are the steps involved -- not tested code.

 

        public static bool IsInside2D(Point3d[] polyPoints, Point3d entPoint)
        {
            bool oddNodes = false;


            int i, j = polyPoints.Length - 1;

            for (i = 0; i < polyPoints.Length; i++)
            {
                Point3d pp_i = polyPoints[i];
                Point3d pp_j = polyPoints[j];

                if ((pp_i.Y < entPoint.Y && pp_j.Y >= entPoint.Y || pp_j.Y < entPoint.Y && pp_i.Y >= entPoint.Y) &&
                    (pp_i.X <= entPoint.X || pp_j.X <= entPoint.X))
                    oddNodes ^= (pp_i.X + (entPoint.Y - pp_i.Y) / (pp_j.Y - pp_i.Y) * (pp_j.X - pp_i.X) < entPoint.X);

                j = i;
            }
            return oddNodes;
        }







        [CommandMethod("TestInsideViewport")]
        public void TestInsideViewport()
        {

            Document doc = null;
            Database db = null;
            Editor ed = null;



            try
            {
                doc = AcadApp.DocumentManager.MdiActiveDocument;
                db = doc.Database;
                ed = doc.Editor;
                LayoutManager layoutManager = LayoutManager.Current;


                string layoutName = layoutManager.CurrentLayout;
                ObjectId layoutId = layoutManager.GetLayoutId(layoutName);

                ObjectId vpId = ObjectId.Null;
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Layout layout = (Layout)tr.GetObject(layoutId, OpenMode.ForRead);
                    var vpIds = layout.GetViewports();
                    if (vpIds.Count > 0)
                        vpId = vpIds[1];        // First Viewport is Paperspace itself. Only one Viewport will be evaluated.
                    tr.Commit();
                }
                if (vpId.IsNull)
                    throw new System.Exception("No Viewport found in: " + layoutName);


                List<Point3d> vpOutlinePntsInMs = null;
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Viewport vp = (Viewport)tr.GetObject(vpId, OpenMode.ForRead);
                    //For now w'll assume the Viewport outline is a Polyline.
                    Polyline vpOutlineInMs = null;
                    if (vp.NonRectClipOn)
                    {
                        ObjectId vpClipId = vp.NonRectClipEntityId;
                        Entity vpBoundary = (Entity)tr.GetObject(vpClipId, OpenMode.ForRead);
                        vpOutlineInMs = (Polyline)vpBoundary.Clone();
                    }
                    else
                    {
                        Extents3d vpExt = vp.GeometricExtents;
                        vpOutlineInMs = new Polyline(4);
                        vpOutlineInMs.AddVertexAt(0, new Point2d(vpExt.MinPoint.X, vpExt.MinPoint.Y), 0, 0, 0);
                        vpOutlineInMs.AddVertexAt(1, new Point2d(vpExt.MaxPoint.X, vpExt.MinPoint.Y), 0, 0, 0);
                        vpOutlineInMs.AddVertexAt(2, new Point2d(vpExt.MaxPoint.X, vpExt.MaxPoint.Y), 0, 0, 0);
                        vpOutlineInMs.AddVertexAt(3, new Point2d(vpExt.MinPoint.X, vpExt.MaxPoint.Y), 0, 0, 0);
                        vpOutlineInMs.Closed = true;

                    }


                    // ViewportExtensionMethods.cs  (c) 2007-2012  Tony Tanzillo
                    Point3d center = new Point3d(vp.ViewCenter.X, vp.ViewCenter.Y, 0.0);
                    Matrix3d msToPs = Matrix3d.Displacement(new Vector3d(vp.CenterPoint.X - center.X, vp.CenterPoint.Y - center.Y, 0.0))
                                            * Matrix3d.Scaling(vp.CustomScale, center)
                                            * Matrix3d.Rotation(vp.TwistAngle, Vector3d.ZAxis, Point3d.Origin)
                                            * Matrix3d.WorldToPlane(new Plane(vp.ViewTarget, vp.ViewDirection));
                    vpOutlineInMs.TransformBy(msToPs.Inverse());

                    vpOutlinePntsInMs = new List<Point3d>();
                    for (int i = 0; i < vpOutlineInMs.NumberOfVertices; i++)
                        vpOutlinePntsInMs.Add(vpOutlineInMs.GetPoint3dAt(i));

                    tr.Commit();
                }


                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    var ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
                    foreach(ObjectId entId in ms)
                    {
                        Entity ent = (Entity)tr.GetObject(entId, OpenMode.ForRead);
                        var entExtents = ent.GeometricExtents;

                        //For now the entity is inside when all Extent points are.
                        var pt1 = ent.GeometricExtents.MinPoint;
                        var pt2 = new Point3d(ent.GeometricExtents.MaxPoint.X, ent.GeometricExtents.MinPoint.Y, 0);
                        var pt3 = ent.GeometricExtents.MaxPoint;
                        var pt4 = new Point3d(ent.GeometricExtents.MinPoint.X, ent.GeometricExtents.MaxPoint.Y, 0);

                        if (IsInside2D(vpOutlinePntsInMs.ToArray(), pt1) && IsInside2D(vpOutlinePntsInMs.ToArray(), pt2) &&
                            IsInside2D(vpOutlinePntsInMs.ToArray(), pt2) && IsInside2D(vpOutlinePntsInMs.ToArray(), pt4))
                        {
                            ed.WriteMessage("\n Entity in Viewport: {0} ({1))", entId.Handle, entId.ObjectClass.DxfName);
                        }
                    }
                    tr.Commit();
                }
            }
            catch (System.Exception ex)
            {
                if (ed != null)
                    ed.WriteMessage("\n Error: " + ex.Message);
                else
                    MessageBox.Show("Error: " + ex.Message, "TestInsideViewport", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
0 Likes
Message 5 of 7

sandeep_vaal
Enthusiast
Enthusiast

Thanks for your reply.

 

I am having one question by looking at code snippet provided by you.

 

Question:

When I try to compile the sample code it requires some of the AutoCAD references 

 

"acdbmgd.dll",

"acmgd.dll",

"accoremgd.dll",

"Autodeks.AutoCAD.Interop.dll",

"Autodesk.AutoCAD.Interop.Common.dll"

 

So my question is do we need to install AutoCAD on client machine ?

 

Because we are using RealDWG 2016 application toolkit.

 

Also before converting a paper space to model space, we have to traverse through the all layouts including model space and paper space layouts and then we have to use ConvertPaper2Model() Is it correct ??

0 Likes
Message 6 of 7

sandeep_vaal
Enthusiast
Enthusiast

Thank you very much Sir !!!

 

It's working for me. Only I have to check how to deal with ProxyEntity.

0 Likes
Message 7 of 7

Chuong.Ho
Advocate
Advocate

I just fix and tested full code, for any need to use in future : 

using System.Collections.Generic;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using Application = Autodesk.AutoCAD.ApplicationServices.Application;

namespace Test;

public class TestViewPort
{

    [CommandMethod("TestInsideViewport")]
    public void TestInsideViewport()
    {
        Document doc = null;
        Database db = null;
        Editor ed = null;

        try
        {
            doc = Application.DocumentManager.MdiActiveDocument;
            db = doc.Database;
            ed = doc.Editor;
            LayoutManager layoutManager = LayoutManager.Current;

            string layoutName = layoutManager.CurrentLayout;
            ed.WriteMessage($"\nLayout Name: {layoutName}");
            ObjectId layoutId = layoutManager.GetLayoutId(layoutName);

            ObjectId vpId = ObjectId.Null;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                Layout layout = (Layout)tr.GetObject(layoutId, OpenMode.ForRead);
                var vpIds = layout.GetViewports();
                if (vpIds.Count > 1)
                    vpId = vpIds[1]; // First Viewport is Paperspace itself
                tr.Commit();
            }

            if (vpId.IsNull)
                throw new Exception(ErrorStatus.Vetoed, "viewport have issue");

            List<Point3d> vpOutlinePntsInMs = null;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                Viewport vp = (Viewport)tr.GetObject(vpId, OpenMode.ForRead);
                Polyline vpOutlineInMs = null;

                if (vp.NonRectClipOn)
                {
                    ObjectId vpClipId = vp.NonRectClipEntityId;
                    Entity vpBoundary = (Entity)tr.GetObject(vpClipId, OpenMode.ForRead);
                    vpOutlineInMs = (Polyline)vpBoundary.Clone();
                }
                else
                {
                    Extents3d vpExt = vp.GeometricExtents;
                    vpOutlineInMs = new Polyline(4);
                    vpOutlineInMs.AddVertexAt(0, new Point2d(vpExt.MinPoint.X, vpExt.MinPoint.Y), 0, 0, 0);
                    vpOutlineInMs.AddVertexAt(1, new Point2d(vpExt.MaxPoint.X, vpExt.MinPoint.Y), 0, 0, 0);
                    vpOutlineInMs.AddVertexAt(2, new Point2d(vpExt.MaxPoint.X, vpExt.MaxPoint.Y), 0, 0, 0);
                    vpOutlineInMs.AddVertexAt(3, new Point2d(vpExt.MinPoint.X, vpExt.MaxPoint.Y), 0, 0, 0);
                    vpOutlineInMs.Closed = true;
                }

                Point3d center = new Point3d(vp.ViewCenter.X, vp.ViewCenter.Y, 0.0);
                Matrix3d msToPs =
                    Matrix3d.Displacement(new Vector3d(vp.CenterPoint.X - center.X, vp.CenterPoint.Y - center.Y, 0.0)) *
                    Matrix3d.Scaling(vp.CustomScale, center) *
                    Matrix3d.Rotation(vp.TwistAngle, Vector3d.ZAxis, Point3d.Origin) *
                    Matrix3d.WorldToPlane(new Plane(vp.ViewTarget, vp.ViewDirection));

                vpOutlineInMs.TransformBy(msToPs.Inverse());

                vpOutlinePntsInMs = new List<Point3d>();
                for (int i = 0; i < vpOutlineInMs.NumberOfVertices; i++)
                    vpOutlinePntsInMs.Add(vpOutlineInMs.GetPoint3dAt(i));

                // Draw polyline in model space
                Polyline transformedPoly = new Polyline();
                for (int i = 0; i < vpOutlinePntsInMs.Count; i++)
                    transformedPoly.AddVertexAt(i, new Point2d(vpOutlinePntsInMs[i].X, vpOutlinePntsInMs[i].Y), 0, 0,
                        0);
                transformedPoly.Closed = true;
                transformedPoly.ColorIndex = 1; // Red

                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                BlockTableRecord ms =
                    (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                ms.AppendEntity(transformedPoly);
                tr.AddNewlyCreatedDBObject(transformedPoly, true);

                tr.Commit();
            }

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord blockTableRecord = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db),
                    OpenMode.ForRead);
                foreach (ObjectId entId in blockTableRecord)
                {
                    Entity ent = (Entity)tr.GetObject(entId, OpenMode.ForRead);
                    if (ent is Polyline)
                        continue;

                    var pt1 = ent.GeometricExtents.MinPoint;
                    var pt2 = new Point3d(ent.GeometricExtents.MaxPoint.X, ent.GeometricExtents.MinPoint.Y, 0);
                    var pt3 = ent.GeometricExtents.MaxPoint;
                    var pt4 = new Point3d(ent.GeometricExtents.MinPoint.X, ent.GeometricExtents.MaxPoint.Y, 0);

                    if (IsInside2D(vpOutlinePntsInMs.ToArray(), pt1) &&
                        IsInside2D(vpOutlinePntsInMs.ToArray(), pt2) &&
                        IsInside2D(vpOutlinePntsInMs.ToArray(), pt3) &&
                        IsInside2D(vpOutlinePntsInMs.ToArray(), pt4))
                    {
                        if (ent is BlockReference block)
                        {
                            ed.WriteMessage($"\nEntity Block in Viewport: {entId.Handle} ({block.Name})");
                        }

                    }
                }

                tr.Commit();
            }
        }
        catch (Exception ex)
        {
            if (ed != null)
                ed.WriteMessage("\n Error: " + ex.ToString());
            else
                MessageBox.Show("Error: " + ex.Message, "TestInsideViewport", MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
        }
    }
    private static bool IsInside2D(Point3d[] polyPoints, Point3d entPoint)
    {
        bool oddNodes = false;


        int i, j = polyPoints.Length - 1;

        for (i = 0; i < polyPoints.Length; i++)
        {
            Point3d pp_i = polyPoints[i];
            Point3d pp_j = polyPoints[j];

            if ((pp_i.Y < entPoint.Y && pp_j.Y >= entPoint.Y || pp_j.Y < entPoint.Y && pp_i.Y >= entPoint.Y) &&
                (pp_i.X <= entPoint.X || pp_j.X <= entPoint.X))
                oddNodes ^= (pp_i.X + (entPoint.Y - pp_i.Y) / (pp_j.Y - pp_i.Y) * (pp_j.X - pp_i.X) < entPoint.X);

            j = i;
        }

        return oddNodes;
    }

}

 

Chuong Ho

EESignature

0 Likes