This question came in recently by email:
I have reached a snag when trying to find the boundaries of external references that have been "xclipped" by the user. Or, to be more precise, I can't even really find the data telling me whether or not the external reference has been "xclipped" at all. I'm wondering if you have any idea how or where I could find this data.
While I found this previous post showing how to perform an XCLIP, I couldn’t find anything showing how to query for XCLIP information.
Here’s some C# code that does just that for a selected block or external reference:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.DatabaseServices.Filters;
using System.Collections.Generic;
namespace SpatialFiltering
{
public class Commands
{
const string filterDictName = "ACAD_FILTER";
const string spatialName = "SPATIAL";
[CommandMethod("DXC")]
static public void DetectXClip()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var ed = doc.Editor;
// Ask for an xclipped xref to be selected
var peo =
new PromptEntityOptions(
"\nSelect xclipped block or xref"
);
peo.SetRejectMessage("Must be a block or xref.");
peo.AddAllowedClass(typeof(BlockReference), false);
var per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
return;
var tr = doc.TransactionManager.StartTransaction();
using (tr)
{
// Open the selected BlockReference
var br =
tr.GetObject(per.ObjectId, OpenMode.ForRead)
as BlockReference;
// To save multiple codepaths with the same message
// ("No clipping information found"), we'll use a flag to
// see whether we've found anything
bool found = false;
// It should always be a block reference, but it might
// not have an extension dictionary
if (
br != null && br.ExtensionDictionary != ObjectId.Null)
{
// The extension dictionary needs to contain a nested
// dictionary called ACAD_FILTER
var extdict =
tr.GetObject(br.ExtensionDictionary, OpenMode.ForRead)
as DBDictionary;
if (extdict != null && extdict.Contains(filterDictName))
{
var fildict =
tr.GetObject(
extdict.GetAt(filterDictName), OpenMode.ForRead
) as DBDictionary;
if (fildict != null)
{
// The nested dictionary should contain a
// SpatialFilter object called SPATIAL
if (fildict.Contains(spatialName))
{
var fil =
tr.GetObject(
fildict.GetAt(spatialName), OpenMode.ForRead
) as SpatialFilter;
if (fil != null)
{
// We have a SpatialFilter: print its bounds
var ext = fil.GetQueryBounds();
ed.WriteMessage(
"\nFound clip from {0} to {1}.",
ext.MinPoint, ext.MaxPoint
);
var pts = fil.Definition.GetPoints();
foreach (var pt in pts)
{
ed.WriteMessage(
"\nBoundary point at {0}", pt
);
}
found = true;
}
}
}
}
}
if (!found)
{
ed.WriteMessage("\nNo clipping information found.");
}
tr.Commit();
}
}
}
}
When we run the DXC command and selected an XCLIPped block or external reference, we see its clipping information printed to the command-line:
Command: DXC
Select xclipped block or xref:
Found clip from (4.05811894970383,5.24702344885421,-10000000000) to (6.37251127340078,8.93717310957857,10000000000).
Boundary point at (4.39197755714056,8.93717310957849)
Boundary point at (4.05811894970388,7.08011285053157)
Boundary point at (4.71314514170174,5.24702344885429)
Boundary point at (5.97105160306316,6.93165698166899)
Boundary point at (6.13163547119819,7.89430470599807)
Boundary point at (6.37251127340073,8.34888837222314)