TheSwamp

Code Red => .NET => Topic started by: MexicanCustard on August 01, 2011, 04:38:39 PM

Title: Entities within a closed polyline
Post by: MexicanCustard on August 01, 2011, 04:38:39 PM
I know this has to have been covered but I cant find anything on The Swamp or the interwebs via Google when I type the title to this post, except some LISP routines. I keep trying but from someone who comes from the OOP world, LISP is a garbled mess. So I'm looking for help in the form of .NET or even C++.

So what I want to do is find all the entities within a closed polyline from WCS. Any pointing in the right direction would be much appreciated.
Title: Re: Entities within a closed polyline
Post by: Jeff H on August 01, 2011, 05:30:44 PM
Have you tried Editor.SelectWindow using the extents for a rectangular polyline
or Editor.SelectWindowPolygon using the vertices for a irregular shaped polyline
 or does the polyline use arcs?
Title: Re: Entities within a closed polyline
Post by: MexicanCustard on August 02, 2011, 07:25:13 AM
Thanks Jeff, and no I haven't tried using a selection window. Thought about that on my way in this morning.
Title: Re: Entities within a closed polyline
Post by: n.yuan on August 02, 2011, 09:55:11 AM
Make sure the selectcing polygon, rectangular or not, is entirely visible on the current view before calling Editor.SelectWindowPolygon, or the returned SelectionSet may not be accurate. This is a known issue when using this method in code.
Title: Re: Entities within a closed polyline
Post by: MexicanCustard on August 02, 2011, 05:25:46 PM
Thanks for the heads up.
Title: Re: Entities within a closed polyline
Post by: kaefer on August 03, 2011, 07:54:34 AM
Thanks for the heads up.

Are you still with us? Have a look at this. Most of it comes from the AutoCAD .NET Developer's Guide, for doing what n.yuan said.

Code: [Select]
    public class Commands
    {
        Database db;
        Editor ed;
        public Commands()
        {
            Document doc = acApp.DocumentManager.MdiActiveDocument;
            db = doc.Database;
            ed = doc.Editor;
        }
        [CommandMethod("SelectInPolyline")]
        public void SelectInPolylineCmd()
        {
            PromptEntityOptions peo = new PromptEntityOptions("\nSelect a polyline: ");
            peo.SetRejectMessage("Only polylines accepted");
            peo.AddAllowedClass(typeof(Polyline), false);
            PromptEntityResult per = ed.GetEntity(peo);
            if(per.Status != PromptStatus.OK) return;
            ObjectId plId = per.ObjectId;
           
            using(Transaction tr = db.TransactionManager.StartTransaction())
            using(Point3dCollection vtcs = new Point3dCollection())
            {
                Polyline pl = (Polyline)tr.GetObject(plId, OpenMode.ForRead);
                ZoomExtents(pl.GeometricExtents);
                for(int i = 0; i < pl.NumberOfVertices; i++)
                    vtcs.Add(pl.GetPoint3dAt(i));
                tr.Commit();
                PromptSelectionResult psr = ed.SelectCrossingPolygon(vtcs);
                if(psr.Status != PromptStatus.OK) return;
                ObjectId[] ids = psr.Value.GetObjectIds();
                ed.SetImpliedSelection(ids.Where(id => id != plId).ToArray());                       
            }
        }
        // Lifted from
        // http://docs.autodesk.com/ACD/2010/ENU/AutoCAD%20.NET%20Developer%27s%20Guide/files/WS1a9193826455f5ff2566ffd511ff6f8c7ca-4363.htm
        private void ZoomExtents(Extents3d extents)
        {
            // Get the current view
            using(ViewTableRecord acView = ed.GetCurrentView())
            {
                // Translate WCS coordinates to DCS
                Matrix3d matWCS2DCS =
                    Matrix3d.Rotation(
                        -acView.ViewTwist, acView.ViewDirection, acView.Target ) *
                    Matrix3d.Displacement(acView.Target - Point3d.Origin) *
                    Matrix3d.PlaneToWorld(acView.ViewDirection);
 
                // Calculate the ratio between the width and height of the current view
                double dViewRatio = (acView.Width / acView.Height);
 
                // Tranform the extents of the view
                extents.TransformBy(matWCS2DCS.Inverse());

                // Calculate the new width and height of the current view
                double dWidth = extents.MaxPoint.X - extents.MinPoint.X;
                double dHeight = extents.MaxPoint.Y - extents.MinPoint.Y;

                // Check to see if the new width fits in current window
                if(dWidth > dHeight * dViewRatio)
                    dHeight = dWidth / dViewRatio;
           

                // Get the center of the view
                Point2d pNewCentPt =
                    new Point2d(
                        (extents.MaxPoint.X + extents.MinPoint.X) * 0.5,
                        (extents.MaxPoint.Y + extents.MinPoint.Y) * 0.5 );

                // Resize the view
                acView.Height = dHeight;
                acView.Width = dWidth;

                // Set the center of the view
                acView.CenterPoint = pNewCentPt;
 
                // Set the current view
                ed.SetCurrentView(acView);
            }
        }
    }
Title: Re: Entities within a closed polyline
Post by: dgorsman on August 03, 2011, 12:23:10 PM
No code, but "Point in boundary" seems to return a number of promising algorithms.  You could start with a simple min/max box filter on the extents of the enclosing boundary PLINE, then iterate the point(s) of any passing entities through the algorithm.
Title: Re: Entities within a closed polyline
Post by: MexicanCustard on August 04, 2011, 01:04:07 PM
kaefer, thanks for the code that looks promising.

Working on a Jig for the polyline. Everything with the jig was working great until I decide to give the user the option to make a rectangle. The rectangle isn't updated correctly in the Update method. Got a couple more things to try before posting my failure and asking for help.