Author Topic: Get Extents of objects in Xrefs  (Read 1773 times)

0 Members and 1 Guest are viewing this topic.

Keith Brown

  • Swamp Rat
  • Posts: 601
Get Extents of objects in Xrefs
« on: July 02, 2015, 05:22:35 PM »
Using the code shown in this post by MexicanCustard I am selecting entities in an xref and then getting the extents of the entities.  The code works great for xrefs that have not been moved or rotated in any way.  Once it has been moved or rotated the resulting box defined by the extents will still remain in the original position.  Here is the code that I am using to define the box (currently only as transient graphics).  I think that I will have to get the PromptEntityResult instead of the FullSubEntityPath and get its nested containers and then do a transform on them.  But I am not really sure how to do that.

Code - Visual Basic: [Select]
  1. Private Sub InsertSingle(sender As Object, e As EventArgs) Handles SemiAutoInsertButton.Click
  2.  
  3.         Dim document = Active.Document
  4.         Dim paths As List(Of FullSubentityPath)
  5.         Using document.LockDocument()
  6.  
  7.                 Using transaction As Transaction = Active.Database.TransactionManager.StartTransaction()
  8.  
  9.                         If Extensions.EditorExtensions.SelectNestedEntities(Active.Editor, paths, "Select an entity to add to extents:") Then
  10.                                
  11.                                 ' This for each loop is where I am going wrong.
  12.                                Dim extents = New Extents3d()
  13.                                 For Each fsp As FullSubentityPath In paths
  14.                                         Dim oIds = New List(Of ObjectId)(fsp.GetObjectIds())
  15.  
  16.                                         oIds.Reverse()
  17.                                         Dim entity = DirectCast(oIds(0).GetObject(OpenMode.ForWrite), Entity)
  18.                                         extents.AddExtents(entity.GeometricExtents)
  19.                                 Next
  20.  
  21.                                 Dim drawables = New List(Of Drawable)
  22.                                 Dim col As New IntegerCollection
  23.                                 Dim box = New Box(extents)
  24.  
  25.                                 drawables.AddRange(box.GetBoxAsLineCollection())
  26.                                 For Each drawable In drawables
  27.                                         TransientManager.CurrentTransientManager.AddTransient(drawable, TransientDrawingMode.Highlight, 128, col)
  28.                                 Next
  29.  
  30.                                 Extensions.EditorExtensions.UnhighlightSubEntities(paths)
  31.  
  32.                         End If
  33.  
  34.                         transaction.Commit()
  35.  
  36.                 End Using
  37.  
  38.         End Using
  39.  
  40. End Sub

And here is the backing code from the post above that I am using to get the entities.

Code - C#: [Select]
  1. public static bool SelectNestedEntities(Editor ed, out List<FullSubentityPath> paths, string prompt)
  2. {
  3.         paths = new List<FullSubentityPath>();
  4.         PromptNestedEntityResult promptNestedEntityResult;
  5.         var promptNestedEntityOptions = new PromptNestedEntityOptions(prompt) { AllowNone = true };
  6.  
  7.         do
  8.         {
  9.                 promptNestedEntityResult = ed.GetNestedEntity(promptNestedEntityOptions);
  10.  
  11.                 if (promptNestedEntityResult.Status != PromptStatus.OK)
  12.                 {
  13.                         continue;
  14.                 }
  15.  
  16.                 var path = HighlightSubEntity(promptNestedEntityResult);
  17.                 if (path != FullSubentityPath.Null)
  18.                 {
  19.                         paths.Add(path);
  20.                 }
  21.         }
  22.         while (promptNestedEntityResult.Status == PromptStatus.OK);
  23.  
  24.         return promptNestedEntityResult.Status != PromptStatus.Cancel;
  25. }
  26.  
  27. public static void UnhighlightSubEntities(List<FullSubentityPath> paths)
  28. {
  29.         for (int i = 0; i < paths.Count; i++)
  30.         {
  31.                 var objectIds = paths[i].GetObjectIds();
  32.                 var entity = objectIds[0].GetObject(OpenMode.ForRead) as Entity;
  33.                 if (entity != null)
  34.                 {
  35.                         entity.Unhighlight(paths[i], false);
  36.                 }
  37.         }
  38. }
  39.  
  40. public static FullSubentityPath HighlightSubEntity(PromptNestedEntityResult promptNestedEntityResult)
  41. {
  42.         var objIds = new List<ObjectId>(promptNestedEntityResult.GetContainers());
  43.         objIds.Reverse();
  44.         objIds.Add(promptNestedEntityResult.ObjectId);
  45.  
  46.         var subEnt = new SubentityId(SubentityType.Null, IntPtr.Zero);
  47.         var path = new FullSubentityPath(objIds.ToArray(), subEnt);
  48.  
  49.         var ent = objIds[0].GetObject(OpenMode.ForRead) as Entity;
  50.  
  51.         if (ent == null)
  52.         {
  53.                 return FullSubentityPath.Null;
  54.         }
  55.  
  56.         ent.Highlight(path, false);
  57.  
  58.         return path;
  59. }
  60.  
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: Get Extents of objects in Xrefs
« Reply #1 on: July 04, 2015, 11:24:12 AM »
After spending many hours trying to transform the entity from its containers I found something that made it really easy.


Apparently the PromptNestedEntityResult returns a transform that will get you exactly what you want.  So I changed the SelectNestedEntities routine to also return the PromptNestedEntityResults and then just used the transform of the result to transform the extents and everything worked great.

Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

MexicanCustard

  • Swamp Rat
  • Posts: 705
Re: Get Extents of objects in Xrefs
« Reply #2 on: July 06, 2015, 07:49:32 AM »
After spending many hours trying to transform the entity from its containers I found something that made it really easy.


Apparently the PromptNestedEntityResult returns a transform that will get you exactly what you want.  So I changed the SelectNestedEntities routine to also return the PromptNestedEntityResults and then just used the transform of the result to transform the extents and everything worked great.



Thanks Keith, didn't know about the returned transform.

Just for the record, I think I got that code from Kean.  It's been so long I can't remember.
Revit 2019, AMEP 2019 64bit Win 10

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: Get Extents of objects in Xrefs
« Reply #3 on: July 06, 2015, 08:19:13 AM »
The original code came from Kean but you can tell that you tweaked it.


Finding out that the result also has a transform made things so much easier for me.  I was trying to get the containers and do a bunch of calculations and wasnt having much success.  The result transform places the geometry exactly where it needs to be no matter how many xrefs I am going through.  Well... I have tested up to 4 so far which is close to the maximum that the user will need.
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013