.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Regions subtract problem.

3 REPLIES 3
Reply
Message 1 of 4
GrzesiekGP
1090 Views, 3 Replies

Regions subtract problem.

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);
                }
            }
        }

 

Tags (2)
3 REPLIES 3
Message 2 of 4
GrzesiekGP
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.

Message 3 of 4
Balaji_Ram
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

Message 4 of 4
Hallex
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

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost