I have re-written the remainder of my code to completely abandon the concept of selection sets and I am relying solely on stepping through the BTRs. I have also adopted the idea of passing along the transaction to use only one per command - very efficient. I have considered trying this in the past, but your example showed me it is possible. Lastly, I am using bounds of blockrefs to establich location - giving me the ability to concentrate on a particular area defined like a window.
It is going well, with one exception. It ignores xrefs. No errors, just seems to disregard them. Here is where I am at:
VB.NET
Sub DeepDive(ByVal TransIn As Transaction, ByVal BTRin As BlockTableRecord, Optional ByVal windowPt1 As Point3d = Nothing, Optional ByVal windowPt2 As Point3d = Nothing)
For Each thisOID As ObjectId In BTRin
Dim thisEnt As Entity = thisOID.GetObject(OpenMode.ForRead)
If TypeOf thisEnt Is BlockReference Then
Dim thisBlockRef As BlockReference = DirectCast(TransIn.GetObject(thisOID, OpenMode.ForRead), BlockReference)
Dim thisBTR As BlockTableRecord = DirectCast(TransIn.GetObject(thisBlockRef.BlockTableRecord, OpenMode.ForRead), BlockTableRecord)
'If a window is provided make sure the block is within it...
If windowPt1 <> Nothing And windowPt2 <> Nothing Then
If Tools.IsWithin(thisBlockRef.Bounds.Value.MinPoint, windowPt1, windowPt2) And Tools.IsWithin(thisBlockRef.Bounds.Value.MaxPoint, windowPt1, windowPt2) Then
'Check for KN data
gatherKNdata(thisBlockRef, thisBTR)
'Then dive inside to look for more blockrefs
DeepDive(TransIn, thisBTR)
End If
Else
'If no window is provided everything is allowed...
'Check for KN data
gatherKNdata(thisBlockRef, thisBTR)
'Then dive inside to look for more blockrefs
DeepDive(TransIn, thisBTR)
End If
ElseIf TypeOf thisEnt Is Viewport Then
Dim myVP As Viewport = DirectCast(TransIn.GetObject(thisOID, OpenMode.ForRead), Viewport)
'If a window is provided make sure the block is within it...
If windowPt1 <> Nothing And windowPt2 <> Nothing Then
'If any of the viewports four corners are within the drawing area, include it
If Tools.IsWithin(myVP.Bounds.Value.MinPoint, windowPt1, windowPt2) Or _
Tools.IsWithin(myVP.Bounds.Value.MaxPoint, windowPt1, windowPt2) Or _
Tools.IsWithin(New Point3d(myVP.Bounds.Value.MinPoint.X, myVP.Bounds.Value.MaxPoint.Y, 0), windowPt1, windowPt2) Or _
Tools.IsWithin(New Point3d(myVP.Bounds.Value.MaxPoint.X, myVP.Bounds.Value.MinPoint.Y, 0), windowPt1, windowPt2) Then
Dim scaleFactor As Double = myVP.ViewHeight / myVP.Height
Dim myVPviewLL As New Point3d(myVP.ViewCenter.X - ((myVP.Width * scaleFactor) / 2), myVP.ViewCenter.Y - (myVP.ViewHeight / 2), 0)
Dim myVPviewUR As New Point3d(myVP.ViewCenter.X + ((myVP.Width * scaleFactor) / 2), myVP.ViewCenter.Y + (myVP.ViewHeight / 2), 0)
Dim myVPviewUL As New Point3d(myVP.ViewCenter.X - ((myVP.Width * scaleFactor) / 2), myVP.ViewCenter.Y + (myVP.ViewHeight / 2), 0)
Dim myVPviewLR As New Point3d(myVP.ViewCenter.X + ((myVP.Width * scaleFactor) / 2), myVP.ViewCenter.Y - (myVP.ViewHeight / 2), 0)
Dim myBT As BlockTable = DirectCast(TransIn.GetObject(HostApplicationServices.WorkingDatabase.BlockTableId, OpenMode.ForRead), BlockTable)
Dim msBTR As BlockTableRecord = DirectCast(TransIn.GetObject(myBT(BlockTableRecord.ModelSpace), OpenMode.ForRead), BlockTableRecord)
DeepDive(TransIn, msBTR, myVPviewLL, myVPviewUR)
End If
End If
End If
Next
End Sub
C#
private void DeepDive(Transaction TransIn, BlockTableRecord BTRin, Point3d windowPt1 = null, Point3d windowPt2 = null)
{
foreach (ObjectId thisOID in BTRin) {
Entity thisEnt = thisOID.GetObject(OpenMode.ForRead);
if (thisEnt is BlockReference) {
BlockReference thisBlockRef = (BlockReference)TransIn.GetObject(thisOID, OpenMode.ForRead);
BlockTableRecord thisBTR = (BlockTableRecord)TransIn.GetObject(thisBlockRef.BlockTableRecord, OpenMode.ForRead);
//If a window is provided make sure the block is within it...
if (windowPt1 != null & windowPt2 != null) {
if (Tools.IsWithin(thisBlockRef.Bounds.Value.MinPoint, windowPt1, windowPt2) & Tools.IsWithin(thisBlockRef.Bounds.Value.MaxPoint, windowPt1, windowPt2)) {
//Check for KN data
gatherKNdata(thisBlockRef, thisBTR);
//Then dive inside to look for more blockrefs
DeepDive(TransIn, thisBTR);
}
} else {
//If no window is provided everything is allowed...
//Check for KN data
gatherKNdata(thisBlockRef, thisBTR);
//Then dive inside to look for more blockrefs
DeepDive(TransIn, thisBTR);
}
} else if (thisEnt is Viewport) {
Viewport myVP = (Viewport)TransIn.GetObject(thisOID, OpenMode.ForRead);
//If a window is provided make sure the block is within it...
if (windowPt1 != null & windowPt2 != null) {
//If any of the viewports four corners are within the drawing area, include it
if (Tools.IsWithin(myVP.Bounds.Value.MinPoint, windowPt1, windowPt2) | Tools.IsWithin(myVP.Bounds.Value.MaxPoint, windowPt1, windowPt2) | Tools.IsWithin(new Point3d(myVP.Bounds.Value.MinPoint.X, myVP.Bounds.Value.MaxPoint.Y, 0), windowPt1, windowPt2) | Tools.IsWithin(new Point3d(myVP.Bounds.Value.MaxPoint.X, myVP.Bounds.Value.MinPoint.Y, 0), windowPt1, windowPt2)) {
double scaleFactor = myVP.ViewHeight / myVP.Height;
Point3d myVPviewLL = new Point3d(myVP.ViewCenter.X - ((myVP.Width * scaleFactor) / 2), myVP.ViewCenter.Y - (myVP.ViewHeight / 2), 0);
Point3d myVPviewUR = new Point3d(myVP.ViewCenter.X + ((myVP.Width * scaleFactor) / 2), myVP.ViewCenter.Y + (myVP.ViewHeight / 2), 0);
Point3d myVPviewUL = new Point3d(myVP.ViewCenter.X - ((myVP.Width * scaleFactor) / 2), myVP.ViewCenter.Y + (myVP.ViewHeight / 2), 0);
Point3d myVPviewLR = new Point3d(myVP.ViewCenter.X + ((myVP.Width * scaleFactor) / 2), myVP.ViewCenter.Y - (myVP.ViewHeight / 2), 0);
BlockTable myBT = (BlockTable)TransIn.GetObject(HostApplicationServices.WorkingDatabase.BlockTableId, OpenMode.ForRead);
BlockTableRecord msBTR = (BlockTableRecord)TransIn.GetObject(myBT(BlockTableRecord.ModelSpace), OpenMode.ForRead);
DeepDive(TransIn, msBTR, myVPviewLL, myVPviewUR);
}
}
}
}
}
Your example leads me to believe that you can step into an xref just like a block - even though it is technically another DB. Am I approaching this incorrectly?
Thanks,
Jeff