close polygons

close polygons

Anonymous
Not applicable
942 Views
4 Replies
Message 1 of 5

close polygons

Anonymous
Not applicable

I want to write a routine to check if then first point of a polyline en the last point is the same. If yes and polyline is not closed:  delete last vertice and close polyline. My code crashes at

Dim obj As Object = myObjID.GetObject(OpenMode.ForRead, False)

when there are more than one polygons.

What is wrong.

In the next step I want to expand my code to all polylines (polyline3d, polyline2d, polyline and lwpolyline) : the code crashes also when I add this to the typed value

 

 <CommandMethod("Closepolygons")>
        Public Shared Sub Closepolygons()
            
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            Dim filterlist As TypedValue() = New TypedValue(1) {}
            filterlist(0) = New TypedValue(0, "LWPOLYLINE")
            filterlist(1) = New TypedValue(8, "*")
            Dim filter As SelectionFilter = New SelectionFilter(filterlist)
            Dim selRes As PromptSelectionResult = ed.SelectAll(filter)
            Dim myObjIDs As ObjectIdCollection

            If selRes.Status = PromptStatus.OK Then
                ' If per.Status = PromptStatus.OK Then
                myObjIDs = New ObjectIdCollection(selRes.Value.GetObjectIds)
                Dim tr As Transaction = db.TransactionManager.StartTransaction()
                For Each myObjID In myObjIDs
                    Using tr
                        Dim obj As Object = myObjID.GetObject(OpenMode.ForRead, False)
                        Dim lwp As Polyline = TryCast(obj, Polyline)
                        If lwp IsNot Nothing Then
                            Dim vn As Integer = lwp.NumberOfVertices
                            Dim point1, point2 As Point2d
                            point1 = lwp.GetPoint2dAt(0)
                            point2 = lwp.GetPoint2dAt(vn - 1)
                            If point1 = point2 Then
                                'delete last vertex
                                Dim obj2 As Object = myObjID.GetObject(OpenMode.ForWrite, False)
                                lwp.RemoveVertexAt(vn - 1)
                                If Not lwp.Closed Then
                                    lwp.Closed = True
                                End If
                                lwp.UpgradeOpen()
                                lwp.RecordGraphicsModified(True)
                            End If
                        End If
                        tr.Commit()
                    End Using
                Next
            End If
        End Sub
0 Likes
Accepted solutions (2)
943 Views
4 Replies
Replies (4)
Message 2 of 5

_gile
Consultant
Consultant
Accepted solution

Hi,

 

You have to make the For Each loop within the Using Transaction statement because the way you do it, the Transaction is Disposed at the first iteration when you do End Using.

 

Also, I'm not very cumfortable with VB but why do you do:

Dim obj As Object = myObjID.GetObject(OpenMode.ForRead, False)

knowing that GetObject returns a DBObject instant and, in this case, the DBObject is always a Polyline due to the selection filter ?

You could directly do:

Dim lwp As Polyline = DirectCast(myObjID.GetObject(OpenMode.ForRead, False), Polyline)

You should be able to get some inspiration from this working code.

        [CommandMethod("CLOSEPOLYGONS")]
        public static void Closepolygons()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var filter = new SelectionFilter(new[] { new TypedValue(0, "LWPOLYLINE") });
            var selection = ed.SelectAll(filter);
            if (selection.Status != PromptStatus.OK)
                return;

            using (var tr = db.TransactionManager.StartTransaction())
            {
                foreach (SelectedObject obj in selection.Value)
                {
                    var pline = (Polyline)tr.GetObject(obj.ObjectId, OpenMode.ForRead);
                    int lastIndex = pline.NumberOfVertices - 1;
                    if (pline.GetPoint2dAt(0).IsEqualTo(pline.GetPoint2dAt(lastIndex)))
                    {
                        tr.GetObject(obj.ObjectId, OpenMode.ForWrite);
                        pline.RemoveVertexAt(lastIndex);
                        pline.Closed = true;
                    }
                }
                tr.Commit();
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 5

Anonymous
Not applicable

thanks, this codes works perfect and how can I make it work for a polyline3D ?

 

0 Likes
Message 4 of 5

_gile
Consultant
Consultant
Accepted solution

Here's an example with Polyline3d.

 

        [CommandMethod("CLOSEPOLYGONS3D")]
        public static void Closepolygons3d()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var filter = new SelectionFilter(new[] {
                new TypedValue(0, "POLYLINE"),
                new TypedValue(-4, "&"),
                new TypedValue(70, 8)});
            var selection = ed.SelectAll(filter);
            if (selection.Status != PromptStatus.OK)
                return;

            using (var tr = db.TransactionManager.StartTransaction())
            {
                foreach (SelectedObject obj in selection.Value)
                {
                    var pline = (Polyline3d)tr.GetObject(obj.ObjectId, OpenMode.ForRead);
                    if (pline.PolyType != Poly3dType.SimplePoly) 
                        continue;
                    
                    ObjectId vertexId = ObjectId.Null;
                    foreach (ObjectId id in pline)
                    {
                        vertexId = id;
                    }
                    var vertex = (PolylineVertex3d)tr.GetObject(vertexId, OpenMode.ForRead);
                    if (vertex.Position.IsEqualTo(pline.StartPoint))
                    {
                        tr.GetObject(vertexId, OpenMode.ForWrite);
                        vertex.Erase();
                        tr.GetObject(pline.ObjectId, OpenMode.ForWrite);
                        pline.Closed = true;
                    }
                }
                tr.Commit();
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 5 of 5

Anonymous
Not applicable

Thanks !  Works great !

0 Likes