Hi all,
So I'm working with a Dynamic block that has a few visibility states, each one gives it a different shape and size. My problem is that when trying to calculate the geometric extents of these blocks, it examines every single visibility state when calculating the min/max geometric extents, so the shape is wildly out of step with the reality of the current visibility state.
This brings me to where I'm getting stuck. So I figured my best approach was to make a copy of the selected block, exploding it, then calculating the extents based on the min/max extents, but the problem is after exploding it still reads that tons of visibility state objects are still being accounted for, it's not until after the transaction is executed that schroedingers block finally collapses into its visibility state but by then it's too late to be of use. Any advice?
<CommandMethod("GetDynamicExtents")>
Public Sub CloneAndExplodeDynamicBlock()
Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Dim peo As PromptEntityOptions = New PromptEntityOptions(vbLf & "Select a dynamic block to clone and explode:")
Dim per As PromptEntityResult = ed.GetEntity(peo)
If per.Status <> PromptStatus.OK Then
Return
End If
Using tr As Transaction = db.TransactionManager.StartTransaction()
Dim bd As BlockReference = tr.GetObject(per.ObjectId, OpenMode.ForRead)
If Not bd.IsDynamicBlock Then
ed.WriteMessage(vbLf & "Selected entity is not a dynamic block.")
Return
End If
' Create a copy of the block
Dim bdClone As BlockReference = CType(bd.Clone(), BlockReference)
Dim currentSpace As BlockTableRecord = CType(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
' Add the clone to the current space
currentSpace.AppendEntity(bdClone)
tr.AddNewlyCreatedDBObject(bdClone, True)
' Explode the clone
Dim objCol As New DBObjectCollection
bdClone.Explode(objCol)
For Each dbObj As DBObject In objCol
currentSpace.AppendEntity(dbObj)
tr.AddNewlyCreatedDBObject(dbObj, True)
Next
' Remove the clone
bdClone.Erase(True)
tr.Commit()
End Using
End Sub
Solved! Go to Solution.
Solved by _gile. Go to Solution.
Hi,
You do not need to clone the block reference before exploding it but you have to explicitly dispose of the generated entities.
To get the geometric extents of the currznt visibility state, you need to check for the Visibility property of each entity.
private static Extents3d GetGeometricExtents(BlockReference br)
{
var extents = new Extents3d();
using (var entitySet = new DBObjectCollection())
{
br.Explode(entitySet);
foreach (Entity entity in entitySet)
{
if (entity.Visible)
{
var bounds = entity.Bounds;
if (bounds.HasValue)
{
extents.AddExtents(bounds.Value);
}
}
entity.Dispose();
}
}
return extents;
}
Can't find what you're looking for? Ask the community or share your knowledge.