.NET

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

Regions subtract problem.

429 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 (390 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: 609
Registered: ‎03-21-2011
Message 3 of 4 (366 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,554
Registered: ‎10-08-2008
Message 4 of 4 (347 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

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Welcome to the new Autodesk Community!
If this is your first visit, click here to get started and make the most of the Community. Let us know what you think of the new experience in the Community Feedback Forum.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community