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

sorting through a DBObjectCollection

4 REPLIES 4
Reply
Message 1 of 5
Anonymous
582 Views, 4 Replies

sorting through a DBObjectCollection

hi ,


I'm working on a program that calculates an oriented bounding box for cubiod solids. I've got it working, but it seems to work slowly. That may or may not have to do with my solution. What I do Is explode the solid into regions, the regions into lines, then I orient (tranform) the solid to everyline on every plane(region) using a transformation matrix and get the min and max bounds of the solid. I suspect that this makes for a resource heavy method, so I want to try limiting the regions and lines that are analyzed. I can't seem to figure out how to reduce the DBObjectionCollection for my regions to only the 6 largest regions.

Here's the pertinent part of my code....I am a newbie.

Matt Araujo

DBObjectCollection regions = new DBObjectCollection();
DBObjectCollection lines = new DBObjectCollection();

s.Explode(regions);

//here's where I'd try and remove all but the largest six regions.

foreach (Region r in regions)
{
r.Explode(lines);
foreach (Line l in lines)
{ ....
4 REPLIES 4
Message 2 of 5
SEANT61
in reply to: Anonymous

Could the quality of “largest regions” be determined by either Region.Area or Region.Perimeter properties? That may minimize the number of regions requiring an explode, and subsequent analysis of the additional constituent elements.

************************************************************
May your cursor always snap to the location intended.
Message 3 of 5
BKSpurgeon
in reply to: Anonymous

i do not completely understand the problem, but might i suggest using a selection filter, and then filtering out all the things that you don't want so that you are left with what you do want - you can then perform the operation then.

 

i am a noob myself, but perhaps the above is helpful?

Message 4 of 5
SENL1362
in reply to: Anonymous

Might this be of any help:

 

SelectionFilter regionFilter=new SelectionFilter(new TypedValue[]{new TypedValue((int)DxfCode.Start, "REGION")});
var selRegResult=ed.SelectAll(regionFilter);
if (selRegResult.Status != PromptStatus.OK)
return;
var regionIds = selRegResult.Value.GetObjectIds();
//DBObjectCollection regions = new DBObjectCollection();

//Order by Area, largest first. MUST be all Region ObjectIds
var largestRegionIds = selRegResult.Value.GetObjectIds().Cast<dynamic>().OrderByDescending(r => r.Area);
//var largestRegions=regions.Cast<Autodesk.AutoCAD.DatabaseServices.Region>().OrderByDescending(r => r.Area);

//Take the first 6 only (or less)
var largest6RegionIds = selRegResult.Value.GetObjectIds().Cast<dynamic>().OrderByDescending(r => r.Area).Take(6);
//var largest6Regions = regions.Cast<Autodesk.AutoCAD.DatabaseServices.Region>().OrderByDescending(r => r.Area).Take(6);

largest6RegionIds.ToList().ForEach(r => ed.WriteMessage("\n Area={0}, Handle={1}", r.Area, r.Handle));
//largest6Regions.ToList().ForEach(r => ed.WriteMessage("\n Area={0}, Handle={1}", r.Area, r.Handle));

Message 5 of 5
SENL1362
in reply to: SENL1362

And if you still want to have access to the Region objects without the Explode, then this modified version of: Philippe Leefsma

(http://adndevblog.typepad.com/autocad/2012/07/accessing-sub-entities-using-assocperssubentityidpe-in... might help as well

 

                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    var largestRegion = (Autodesk.AutoCAD.DatabaseServices.Region)tr.GetObject(largest6RegionIds.First(), OpenMode.ForRead);
                    IntPtr pSubentityIdPE = largestRegion.QueryX(AssocPersSubentityIdPE.GetClass(typeof(AssocPersSubentityIdPE)));
                    if (pSubentityIdPE == IntPtr.Zero)
                        return;
                    AssocPersSubentityIdPE subentityIdPE = AssocPersSubentityIdPE.Create(pSubentityIdPE, false) as AssocPersSubentityIdPE;

                    ObjectId[] regionIdAsArray = new ObjectId[] { largestRegion.ObjectId };
                    SubentityId[] edgeIds = subentityIdPE.GetAllSubentities(largestRegion, SubentityType.Edge);
                    ed.WriteMessage("\n Largest Region: Area={0}, Handle={1} Edges: ", largestRegion.Area, largestRegion.Handle);
                    foreach (SubentityId subentId in edgeIds)
                    {
                        FullSubentityPath sePath = new FullSubentityPath(regionIdAsArray, subentId);
                        using (Entity edgeEntity = largestRegion.GetSubentity(sePath))
                        {
                            //SubEntity.Objectid==0  ed.WriteMessage("\n\t\t Type={0}, Handle={1}", edgeEntity.ObjectId.ObjectClass.DxfName, edgeEntity.Handle);
                            var edge=edgeEntity as Curve;
                            if (edge !=null)
                                ed.WriteMessage("\n\t Edge Type={0}: ({1},{2})..({3},{4})[OCS==WCS]",edge.GetRXClass().DxfName, (int)edge.StartPoint.X, (int)edge.StartPoint.Y, (int)edge.EndPoint.X, (int)edge.EndPoint.Y);

                            //Line line = edge as Line;
                            //if (line != null)
                            //    ...
                        }
                    }
                    tr.Commit();
                }

 

 

Sample results:

Command: TESTREGIONS

Area=7761017.86352489, Handle=28A
Area=4721276.38892092, Handle=28C
Area=2858533.41794501, Handle=28B
Area=1053332.21028311, Handle=239
Area=822640.105885869, Handle=236
Area=412343.241778572, Handle=235
Largest Region: Area=7761017.86352489, Handle=28A Edges:
Edge Type=LINE: (7682,2672)..(11590,2672)[OCS==WCS]
Edge Type=LINE: (7682,686)..(7682,2672)[OCS==WCS]
Edge Type=LINE: (11590,686)..(7682,686)[OCS==WCS]
Edge Type=LINE: (11590,2672)..(11590,686)[OCS==WCS]

 

 

 

 

 

 

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