You can define a region of an external reference for display and plotting by clipping the external reference. The clipping boundary must be a 2D polygon or rectangle with vertices constrained to lie within the boundaries of the external reference. Multiple instances of the same external reference can have different boundaries.
The SpatialFilter and SpatialFilterDefinition objects are used to define the properties of the clipping boundary for an external reference. Use the Enabled property of the SpatialFilterDefinition object show or hide the clipping boundary.
This example attaches an external reference and then clips the external reference so only part of it is displayed. This example uses the Exterior Elevations.dwg file found in the Sample directory. If you do not have this image, or if it is located in a different directory, insert a valid path and file name.
Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.Geometry <CommandMethod("ClippingExternalReference")> _ Public Sub ClippingExternalReference() ' Get the current database and start a transaction Dim acCurDb As Autodesk.AutoCAD.DatabaseServices.Database acCurDb = Application.DocumentManager.MdiActiveDocument.Database Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction() ' Create a reference to a DWG file Dim PathName As String = "C:\AutoCAD\Sample\Sheet Sets\Architectural\Res\Exterior Elevations.dwg" Dim acXrefId As ObjectId = acCurDb.AttachXref(PathName, "Exterior Elevations") ' If a valid reference is created then continue If Not acXrefId.IsNull Then ' Attach the DWG reference to the current space Dim insPt As New Point3d(1, 1, 0) Using acBlkRef As New BlockReference(insPt, acXrefId) Dim acBlkTblRec As BlockTableRecord acBlkTblRec = acTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForWrite) acBlkTblRec.AppendEntity(acBlkRef) acTrans.AddNewlyCreatedDBObject(acBlkRef, True) MsgBox("The external reference is attached.") Dim mat As Matrix3d = acBlkRef.BlockTransform mat.Inverse() Dim ptCol As New Point2dCollection ' Define the first corner of the clipping boundary Dim pt3d As New Point3d(-330, 400, 0) pt3d.TransformBy(mat) ptCol.Add(New Point2d(pt3d.X, pt3d.Y)) ' Define the second corner of the clipping boundary pt3d = New Point3d(1320, 1120, 0) pt3d.TransformBy(mat) ptCol.Add(New Point2d(pt3d.X, pt3d.Y)) ' Define the normal and elevation for the clipping boundary Dim normal As Vector3d Dim elev As Double = 0 If acCurDb.TileMode = True Then normal = acCurDb.Ucsxdir.CrossProduct(acCurDb.Ucsydir) elev = acCurDb.Elevation Else normal = acCurDb.Pucsxdir.CrossProduct(acCurDb.Pucsydir) elev = acCurDb.Pelevation End If ' Set the clipping boundary and enable it Using filter As New Filters.SpatialFilter Dim filterDef As New Filters.SpatialFilterDefinition(ptCol, normal, elev, 0, 0, True) filter.Definition = filterDef ' Define the name of the extension dictionary and entry name Dim dictName As String = "ACAD_FILTER" Dim spName As String = "SPATIAL" ' Check to see if the Extension Dictionary exists, if not create it If acBlkRef.ExtensionDictionary.IsNull Then acBlkRef.UpgradeOpen() acBlkRef.CreateExtensionDictionary() acBlkRef.DowngradeOpen() End If ' Open the Extension Dictionary for write Dim extDict As DBDictionary = acTrans.GetObject(acBlkRef.ExtensionDictionary, OpenMode.ForWrite) ' Check to see if the dictionary for clipped boundaries exists, ' and add the spatial filter to the dictionary If extDict.Contains(dictName) Then Dim filterDict As DBDictionary = acTrans.GetObject(extDict.GetAt(dictName), OpenMode.ForWrite) If (filterDict.Contains(spName)) Then filterDict.Remove(spName) filterDict.SetAt(spName, filter) Else Using filterDict As New DBDictionary extDict.SetAt(dictName, filterDict) acTrans.AddNewlyCreatedDBObject(filterDict, True) filterDict.SetAt(spName, filter) End Using End If ' Append the spatial filter to the drawing acTrans.AddNewlyCreatedDBObject(filter, True) End Using End Using MsgBox("The external reference is clipped.") End If ' Save the new objects to the database acTrans.Commit() ' Dispose of the transaction End Using End Sub
using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; [CommandMethod("ClippingExternalReference")] public void ClippingExternalReference() { // Get the current database and start a transaction Database acCurDb; acCurDb = Application.DocumentManager.MdiActiveDocument.Database; using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // Create a reference to a DWG file string PathName = "C:\\AutoCAD\\Sample\\Sheet Sets\\Architectural\\Res\\Exterior Elevations.dwg"; ObjectId acXrefId = acCurDb.AttachXref(PathName, "Exterior Elevations"); // If a valid reference is created then continue if (!acXrefId.IsNull) { // Attach the DWG reference to the current space Point3d insPt = new Point3d(1, 1, 0); using (BlockReference acBlkRef = new BlockReference(insPt, acXrefId)) { BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord; acBlkTblRec.AppendEntity(acBlkRef); acTrans.AddNewlyCreatedDBObject(acBlkRef, true); Application.ShowAlertDialog("The external reference is attached."); Matrix3d mat = acBlkRef.BlockTransform; mat.Inverse(); Point2dCollection ptCol = new Point2dCollection(); // Define the first corner of the clipping boundary Point3d pt3d = new Point3d(-330, 400, 0); pt3d.TransformBy(mat); ptCol.Add(new Point2d(pt3d.X, pt3d.Y)); // Define the second corner of the clipping boundary pt3d = new Point3d(1320, 1120, 0); pt3d.TransformBy(mat); ptCol.Add(new Point2d(pt3d.X, pt3d.Y)); // Define the normal and elevation for the clipping boundary Vector3d normal; double elev = 0; if (acCurDb.TileMode == true) { normal = acCurDb.Ucsxdir.CrossProduct(acCurDb.Ucsydir); elev = acCurDb.Elevation; } else { normal = acCurDb.Pucsxdir.CrossProduct(acCurDb.Pucsydir); elev = acCurDb.Pelevation; } // Set the clipping boundary and enable it using (Autodesk.AutoCAD.DatabaseServices.Filters.SpatialFilter filter = new Autodesk.AutoCAD.DatabaseServices.Filters.SpatialFilter()) { Autodesk.AutoCAD.DatabaseServices.Filters.SpatialFilterDefinition filterDef = new Autodesk.AutoCAD.DatabaseServices.Filters.SpatialFilterDefinition(ptCol, normal, elev, 0, 0, true); filter.Definition = filterDef; // Define the name of the extension dictionary and entry name string dictName = "ACAD_FILTER"; string spName = "SPATIAL"; // Check to see if the Extension Dictionary exists, if not create it if (acBlkRef.ExtensionDictionary.IsNull) { acBlkRef.UpgradeOpen(); acBlkRef.CreateExtensionDictionary(); acBlkRef.DowngradeOpen(); } // Open the Extension Dictionary for write DBDictionary extDict = acTrans.GetObject(acBlkRef.ExtensionDictionary, OpenMode.ForWrite) as DBDictionary; // Check to see if the dictionary for clipped boundaries exists, // and add the spatial filter to the dictionary if (extDict.Contains(dictName)) { DBDictionary filterDict = acTrans.GetObject(extDict.GetAt(dictName), OpenMode.ForWrite) as DBDictionary; if (filterDict.Contains(spName)) { filterDict.Remove(spName); } filterDict.SetAt(spName, filter); } else { using (DBDictionary filterDict = new DBDictionary()) { extDict.SetAt(dictName, filterDict); acTrans.AddNewlyCreatedDBObject(filterDict, true); filterDict.SetAt(spName, filter); } } // Append the spatial filter to the drawing acTrans.AddNewlyCreatedDBObject(filter, true); } } Application.ShowAlertDialog("The external reference is clipped."); } // Save the new objects to the database acTrans.Commit(); // Dispose of the transaction } }