using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices.Filters;
using Autodesk.AutoCAD.Runtime;
using System;
namespace SpatialFiltering
{
public class ClipBlock
{
const string filterDictName = "ACAD_FILTER";
const string spatialName = "SPATIAL";
[CommandMethod("XCLIPBREF")]
public static void clipBlockTest()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// Выбираем блок для подрезки
PromptEntityOptions peo =
new PromptEntityOptions("\nВыберите вставку блока:");
peo.AllowNone = false;
peo.SetRejectMessage("\nЭто не вставка блока.");
peo.AddAllowedClass(typeof(BlockReference), false);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
return;
Point3dCollection pts3d = new Point3dCollection();
// Выбираем точки для подрезки
while (true)
{
PromptPointOptions ppo;
if (pts3d.Count < 3) {
ppo = new PromptPointOptions("\nУкажите " + (pts3d.Count + 1).ToString() + "-ую точку контура");
ppo.AllowNone = false;
} else {
ppo = new PromptPointOptions("\nУкажите " + (pts3d.Count + 1).ToString() + "-ую точку контура (ENTER - завершение)");
ppo.AllowNone = true;
}
if (pts3d.Count > 0)
{
ppo.BasePoint = pts3d[pts3d.Count-1];
ppo.UseBasePoint = true;
}
PromptPointResult ppr = ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK)
break;
if (pts3d.Count > 0)
ed.DrawVector(pts3d[pts3d.Count - 1], ppr.Value, 1, true);
pts3d.Add(ppr.Value);
}
Transaction tr = db.TransactionManager.StartTransaction();
using (tr)
{
// Преобразуем точки в систему координат блока!!!
BlockReference br = (BlockReference)tr.GetObject(per.ObjectId, OpenMode.ForRead);
Point2dCollection pts = new Point2dCollection(pts3d.Count);
Matrix3d mat = br.BlockTransform.Inverse();
foreach (Point3d p in pts3d)
{
Point3d pBlk = p.TransformBy(mat);
pts.Add(new Point2d(pBlk.X, pBlk.Y));
}
// Создаем фильтр
SpatialFilterDefinition sfd =
new SpatialFilterDefinition(
pts, Vector3d.ZAxis, 0.0, 0.0, 0.0, true
);
SpatialFilter sf = new SpatialFilter();
sf.Definition = sfd;
// Создаем ExtDict если его еще не было
if (br.ExtensionDictionary == ObjectId.Null)
{
br.UpgradeOpen();
br.CreateExtensionDictionary();
br.DowngradeOpen();
}
// Добавляем фильтр
DBDictionary xDict = (DBDictionary)tr.GetObject(br.ExtensionDictionary, OpenMode.ForWrite);
if (xDict.Contains(filterDictName))
{
DBDictionary fDict =
(DBDictionary)tr.GetObject(
xDict.GetAt(filterDictName), OpenMode.ForWrite
);
if (fDict.Contains(spatialName))
fDict.Remove(spatialName);
fDict.SetAt(spatialName, sf);
}
else
{
DBDictionary fDict = new DBDictionary();
xDict.SetAt(filterDictName, fDict);
tr.AddNewlyCreatedDBObject(fDict, true);
fDict.SetAt(spatialName, sf);
}
tr.AddNewlyCreatedDBObject(sf, true);
tr.Commit();
}
ed.Regen();
}
}
}