Author Topic: Exploding the Polyline  (Read 2039 times)

0 Members and 1 Guest are viewing this topic.

tik

  • Guest
Exploding the Polyline
« on: September 04, 2012, 03:23:38 PM »

I am trying to do the following

Step 1:- Get all the entities in the drawing

Step 2: Loop through all the entities and if any entity is polyline explode that to individual line segments

             2.1 Erase the original polyline
             2.2 For each line segment from polyline set it to layer 0;

I am able to do most of it except when i am adding line segments to the drawing i am getting alreadyinthedrawing exception.

Any suggestions will be really appreciated and thanks in advance.

Code: [Select]
PromptSelectionResult allEntities = ActiveDocument.Editor.SelectAll();
            DBObjectCollection lineCollection = new DBObjectCollection();

             if (allEntities.Value.GetObjectIds().GetLength(0) > 0)
             {
                 ObjectIdCollection allEntitiesIds = new ObjectIdCollection(allEntities.Value.GetObjectIds());

                 using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                 {
                     using (DocumentLock dl = ActiveDocument.LockDocument())
                     {
                         foreach (ObjectId curID in allEntitiesIds)
                         {
                             DBObject curObj = acTrans.GetObject(curID, OpenMode.ForWrite);
                             if (curObj != null)
                             {
                                 Polyline curPolyLine = curObj as Polyline;
                                 if (curPolyLine != null)
                                 {
                                     curPolyLine.Explode(lineCollection);
                                     curPolyLine.Erase(true);
                                     if (lineCollection.Count > 0)
                                     {
                                         BlockTableRecord btr = (BlockTableRecord)acTrans.GetObject(ActiveDocument.Database.CurrentSpaceId, OpenMode.ForWrite);
                                         foreach (DBObject line in lineCollection)
                                         {
                                             try
                                             {
                                                 Entity lineEnt = line as Entity;
                                                 btr.AppendEntity(lineEnt);
                                                 acTrans.AddNewlyCreatedDBObject(lineEnt, true);
                                                 lineEnt.Layer = "0";
                                             }
                                             catch (System.Exception Ex)
                                             {
                                                 string exception = Ex.Message;
                                             }
                                         }
                                     }
                                 }
                                 else
                                 {
                                     Entity ent = curObj as Entity;
                                     ent.Layer = "0";
                                 }
                             }
                         }
                         acTrans.Commit();
                     }
                 }
             }

TheMaster

  • Guest
Re: Exploding the Polyline
« Reply #1 on: September 04, 2012, 03:36:28 PM »

I am trying to do the following

Step 1:- Get all the entities in the drawing

Step 2: Loop through all the entities and if any entity is polyline explode that to individual line segments

             2.1 Erase the original polyline
             2.2 For each line segment from polyline set it to layer 0;

I am able to do most of it except when i am adding line segments to the drawing i am getting alreadyinthedrawing exception.

Any suggestions will be really appreciated and thanks in advance.

Code: [Select]
PromptSelectionResult allEntities = ActiveDocument.Editor.SelectAll();
            DBObjectCollection lineCollection = new DBObjectCollection();

             if (allEntities.Value.GetObjectIds().GetLength(0) > 0)
             {
                 ObjectIdCollection allEntitiesIds = new ObjectIdCollection(allEntities.Value.GetObjectIds());

                 using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                 {
                     using (DocumentLock dl = ActiveDocument.LockDocument())
                     {
                         foreach (ObjectId curID in allEntitiesIds)
                         {
                             DBObject curObj = acTrans.GetObject(curID, OpenMode.ForWrite);
                             if (curObj != null)
                             {
                                 Polyline curPolyLine = curObj as Polyline;
                                 if (curPolyLine != null)
                                 {
                                     curPolyLine.Explode(lineCollection);
                                     curPolyLine.Erase(true);
                                     if (lineCollection.Count > 0)
                                     {
                                         BlockTableRecord btr = (BlockTableRecord)acTrans.GetObject(ActiveDocument.Database.CurrentSpaceId, OpenMode.ForWrite);
                                         foreach (DBObject line in lineCollection)
                                         {
                                             try
                                             {
                                                 Entity lineEnt = line as Entity;
                                                 btr.AppendEntity(lineEnt);
                                                 acTrans.AddNewlyCreatedDBObject(lineEnt, true);
                                                 lineEnt.Layer = "0";
                                             }
                                             catch (System.Exception Ex)
                                             {
                                                 string exception = Ex.Message;
                                             }
                                         }
                                     }
                                 }
                                 else
                                 {
                                     Entity ent = curObj as Entity;
                                     ent.Layer = "0";
                                 }
                             }
                         }
                         acTrans.Commit();
                     }
                 }
             }

Aside from the fact that ExplodeToOwnerSpace() does a lot of that work for you, it looks like the problem is that you're not clearing the DBObjectCollection after you pass it to Explode() and add the resulting entities to the database. So, those entities are still in it when you pass it to the next call to Explode(), which will just append the entities it creates to the collection.


« Last Edit: September 04, 2012, 03:40:25 PM by TT »

tik

  • Guest
Re: Exploding the Polyline
« Reply #2 on: September 04, 2012, 04:36:11 PM »
TT Thanks for the response.  I am familiar with the ExplodeToOwnerSpace related to a block reference but I didn't see that option for an Entity like polyline unless I am doing something wrong.

TheMaster

  • Guest
Re: Exploding the Polyline
« Reply #3 on: September 05, 2012, 08:41:45 AM »
TT Thanks for the response.  I am familiar with the ExplodeToOwnerSpace related to a block reference but I didn't see that option for an Entity like polyline unless I am doing something wrong.

Sorry, you're right. I never noticed that it was only implemented for BlockReference (it should be implemented for anything that can be exploded, as it's just a simple automation of what you're doing with Expode() - an incorrect assumption on my part).

In any case, I trust that the problem was not clearing the DBObjectCollection after each iteration.

You can handle it in two ways. One is to just call Explode() on as many polylines as you like, passing the same DBObjectCollection into each call, and let the new entities accumulate there, and once you're done exploding, you can just add everything in the DBObjectCollection to the database.

However, one dangerous aspect of your code is that it doesn't ensure the DBObjectCollection is disposed (including if the code fails before all the objects have been added to the drawing), which could lead to crashing AutoCAD. You should put the DBObjectCollection under control of using() to be sure it gets disposed.
« Last Edit: September 05, 2012, 08:48:30 AM by TT »

tik

  • Guest
Re: Exploding the Polyline
« Reply #4 on: September 05, 2012, 08:48:48 AM »
TT no problem and you are right regarding not clearing the dbobjectcollection and once I fixed that, it worked like magic. Thanks again.