Подрезка внешней ссылки
Вы можете определить границы показа для внешней ссылки, задав прямоугольник подрезки. Несколько экземпляров одной и той же внешней ссылки могут иметь разные границы.
Для определения свойств границы обрезки для внешней ссылки используются вспомогательные структуры SpatialFilter и SpatialFilterDefinition из пространства имён Autodesk.AutoCAD.DatabaseServices.Filters. Используйте свойство Enabled объекта SpatialFilterDefinition для отображения или скрытия границы обрезки.
В примере ниже формируется демонстрационный чертеж, содержащий множество окружностей переменного диаметра между точками (0,0) и (2000, 2000), в данном чертеже на него создается внешняя ссылка, создается её экземпляр в чертеже и для него задается граница подрезки в виде прямоугольника с крайними точками (200, 300) и (1200, 1100).
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.DatabaseServices.Filters;
[CommandMethod("ClippingExternalReference")]
public void ClippingExternalReference()
{
string tmpDwg = @"C:\Temp\test.dwg";
using (Database dbTmp = new Database())
{
using (Transaction acTrans = dbTmp.TransactionManager.StartTransaction())
{
// Open the Block table record for read
BlockTable acBlkTbl;
acBlkTbl = acTrans.GetObject(dbTmp.BlockTableId,
OpenMode.ForRead) as BlockTable;
// Open the Block table record Model space for write
BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
OpenMode.ForWrite) as BlockTableRecord;
System.Random r = new System.Random();
for (int i = 0; i < 2000; i += 20)
{
for (int j = 0; j < 2000; j += 20)
{
using (Circle acCirc = new Circle(new Point3d(i, j, 0), Vector3d.ZAxis, r.Next(1, 12)))
{
acBlkTblRec.AppendEntity(acCirc);
acTrans.AddNewlyCreatedDBObject(acCirc, true);
}
}
}
acTrans.Commit();
}
dbTmp.SaveAs(tmpDwg, DwgVersion.Current);
}
// 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
ObjectId acXrefId = acCurDb.AttachXref(tmpDwg, "Test 2");
// 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(200, 300, 0);
pt3d.TransformBy(mat);
ptCol.Add(new Point2d(pt3d.X, pt3d.Y));
// Define the second corner of the clipping boundary
pt3d = new Point3d(1200, 1100, 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 (SpatialFilter filter = new SpatialFilter())
{
SpatialFilterDefinition filterDef = new 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.CreateExtensionDictionary();
}
// 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
}
}