.NET

Reply
Valued Contributor
GrzesiekGP
Posts: 67
Registered: ‎02-03-2012
Message 1 of 4 (493 Views)

Regions subtract problem.

493 Views, 3 Replies
09-10-2012 01:32 PM

I have closed polylines - few rectangles, some of them are inside another (picture).

 

Now I would like to:

1. Calculate areas of each closed polyline.

2. Calculate areas of each closed polyline subtract area of inside polyline.

 

Everything seems to work if I have only 1 polyline or 2 (first inside second). If I have more, I'm always getting zero.

 

Here is my code (ClipLines is a list of closed polylines):

 

      private static void CalculateClips(List<ClipsLines> cls)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            DBObjectCollection dbCl = new DBObjectCollection();
            DBObjectCollection myRegionColl = new DBObjectCollection();

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                try
                {
                    foreach (ClipsLines cl in cls)
                    {
                        DBObject obj = tr.GetObject(cl.id, OpenMode.ForRead);
                        dbCl.Add(obj);
                    }

                    myRegionColl = Region.CreateFromCurves(dbCl);


                    for (int i = 0; i < myRegionColl.Count; i++)
                    {
                        Region r1 = myRegionColl[i] as Region;
                        double mainRegArea = r1.Area;
                        
                        for (int j = 0; j < myRegionColl.Count; j++)
                        {
                            if (i != j)
                            {
                                Region r2 = myRegionColl[j] as Region;
                                r1.BooleanOperation(BooleanOperationType.BoolSubtract, r2);
                                if (r1.Area > 0)
                                    mainRegArea -= r1.Area;
                            }
                        }
                        doc.Editor.WriteMessage("\nReg1: " + mainRegArea);
                    }

                    tr.Commit();
                }
                catch (Autodesk.AutoCAD.Runtime.Exception ex)
                {
                    tr.Abort();
                    utilities.ErrorMessage("\nClips calculating exception!\n" + ex.Message);
                }
            }
        }

 

Valued Contributor
GrzesiekGP
Posts: 67
Registered: ‎02-03-2012
Message 2 of 4 (454 Views)

Re: Regions subtract problem.

09-13-2012 05:10 AM in reply to: GrzesiekGP

I've written this code:

 

double[] areas = new double[clipsLines.Count];

                             for (int i = 0; i < clipsLines.Count; i++)
                             {
                                 DBObject obj1 = tr.GetObject(clipsLines[i].id, OpenMode.ForRead);
                                 Polyline l = (Polyline)obj1 as Polyline;
                                 double correctionArea = 0.0;

                                 for (int j = 0; j < clipsLines.Count; j++)
                                 {
                                     if (i != j)
                                     {
                                         DBObjectCollection dbCl = new DBObjectCollection();
                                         DBObject obj2 = tr.GetObject(clipsLines[j].id, OpenMode.ForRead);
                                         dbCl.Add(obj1);
                                         dbCl.Add(obj2);

                                         DBObjectCollection myRegionColl = new DBObjectCollection();
                                         myRegionColl = Region.CreateFromCurves(dbCl);

                                         Region r1 = myRegionColl[0] as Region;
                                         Region r2 = myRegionColl[1] as Region;
                                         double firstArea = r1.Area;
                                         r1.BooleanOperation(BooleanOperationType.BoolIntersect, r2);

                                         if (r1.Area - firstArea == 0)
                                             correctionArea += (r1.Area);
                                     }
                                 }

                                 areas[i] = l.Area - correctionArea;

For few polylines it works pretty good, but if I have more, AutoCAD is crashing down.

ADN Support Specialist
Balaji_Ram
Posts: 693
Registered: ‎03-21-2011
Message 3 of 4 (430 Views)

Re: Regions subtract problem.

09-17-2012 09:46 AM in reply to: GrzesiekGP

Hello,

 

Try disposing those regions explicitly.

 

The crash could be related the topics discussed in these posts :

http://through-the-interface.typepad.com/through_the_interface/2012/08/calling-dispose-on-autocad-ob...

 

http://adndevblog.typepad.com/autocad/2012/07/solids-created-with-booleanoper-may-crash-autocad-on-s...



Balaji
Developer Technical Services
Autodesk Developer Network

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 4 of 4 (411 Views)

Re: Regions subtract problem.

09-17-2012 11:45 PM in reply to: GrzesiekGP

Try this code, tested on A2010,

see comments within

 

        [CommandMethod("Rea")]
        public static void testUnionContours()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            // Argument to choose operation mode
            bool doUnion = false;// to subtract regions if many regions inside the biggest one, otherwise set to true
            List<Region> regLst = new List<Region>();
            List<Polyline> delPline = new List<Polyline>();
            //start a transaction
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {

                TypedValue[] tvs = new TypedValue[]
            {new TypedValue(0, "lwpolyline"),
                new TypedValue(70, 1)

            };
                SelectionFilter filter = new SelectionFilter(tvs);
                PromptSelectionOptions pso = new PromptSelectionOptions();
                pso.MessageForRemoval = "\nSelect closed polylines only: ";
                pso.MessageForAdding = "\nSelect closed polylines: ";
                PromptSelectionResult result = ed.GetSelection(filter);
                if (result.Status != PromptStatus.OK) return;
                // if (result.Value.Count != 2) return;
                try
                {
                    SelectionSet sset = result.Value;
                    ObjectId[] ids = sset.GetObjectIds();
                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, false);
                    Region objreg1 = new Region();
                   // Region objreg2 = new Region();
                    for (int n = 0; n < ids.Count(); n++)
                    {
                        
                        DBObject obj = tr.GetObject(ids[n], OpenMode.ForRead) as DBObject;
                        Polyline pline1 = obj as Polyline;
                        if (pline1 == null) return;
                        // Add the polyline to the List to rerase them all at the end of execution
                        delPline.Add(pline1);
                        // Add the polyline to the array
                        DBObjectCollection objArray1 = new DBObjectCollection();
                        objArray1.Add(pline1);
                        // create the 1 st region
                        DBObjectCollection objRegions1 = new DBObjectCollection();
                        objRegions1 = Region.CreateFromCurves(objArray1);
                        objreg1 = objRegions1[0] as Region;
                        btr.AppendEntity(objreg1);

                        tr.AddNewlyCreatedDBObject(objreg1, true);

                        objreg1.ColorIndex = 1;//optional
                        // Add the region to the List for the future work
                        regLst.Add(objreg1);                     
                    }
                    ed.WriteMessage("\nCount regions:\t{0}\n", regLst.Count);

                    //________________________________________________________//

                    // Sort regions by areas
                    Region[] items = regLst.ToArray();
                    Array.Sort(items, (Region x, Region y) => y.Area.CompareTo(x.Area));
                  // Get the biggest region first
                    Region mainReg = items[0];
                    ed.WriteMessage("\nMain region area:\t{0:f3}\n", items[0].Area);
                    if (!mainReg.IsWriteEnabled) mainReg.UpgradeOpen();
                    // Start iteration from the second region
                    int i = 1;
                    do
                    {
                        Region reg1 = items[i]; Region reg2 = items[i + 1];

                        if ((reg1 == null) || (reg2 == null))
                        {
                            break;
                        }

                        else
                        {
                            // Subtract region 1 from region 2
                            if (reg1.Area > reg2.Area)
                            {
                            // Subtract the smaller region from the larger one
                            // 
                            reg1.BooleanOperation(BooleanOperationType.BoolUnite, reg2);
                            if (!doUnion)
                            {
                                mainReg.BooleanOperation(BooleanOperationType.BoolSubtract, reg1);
                            }
                            else
                            {
                                mainReg.BooleanOperation(BooleanOperationType.BoolUnite, reg1);
                            }
                            
                            }

                            else
                            {

                            // Subtract the smaller region from the larger one
                            
                            reg2.BooleanOperation(BooleanOperationType.BoolUnite, reg1);
                            if (!doUnion)
                            {
                                mainReg.BooleanOperation(BooleanOperationType.BoolSubtract, reg2);
                            }
                            else
                            {
                                mainReg.BooleanOperation(BooleanOperationType.BoolUnite, reg2);
                            }
                            }

                        }
                        // Increment counter
                        i++;
                    } while (i < items.Length - 1);

                    mainReg.ColorIndex = 121;
                  
                    //__________________________________________________________//

                    //Erase polylines , optional
                    foreach (Polyline poly in delPline)
                    {
                        if (poly != null)
                        {
                            if (!poly.IsWriteEnabled) poly.UpgradeOpen();
                            poly.Erase();
                            if (!poly.IsDisposed) poly.Dispose();
                        }
                    }
                    tr.Commit();
                }

                catch (Autodesk.AutoCAD.Runtime.Exception ex)
                {

                    ed.WriteMessage("\nBoolean operation exception!\n" + ex.Message + "n" + ex.StackTrace);
                }
                finally
                {
                    ed.WriteMessage(new Autodesk.AutoCAD.Runtime.ErrorStatus().ToString());//optional, might be removed
                }
            }
        }

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.