using System;
using System.Collections.Generic;
using App = Autodesk.AutoCAD.ApplicationServices;
using Db = Autodesk.AutoCAD.DatabaseServices;
using Ed = Autodesk.AutoCAD.EditorInput;
using Gem = Autodesk.AutoCAD.Geometry;
using Rtm = Autodesk.AutoCAD.Runtime;
[assembly: Rtm.CommandClass(typeof(ClipedXref.Test))]
namespace ClipedXref
{
class Test
{
private static double XRefWidth { get; set; } = 10;
const string filterDictName = "ACAD_FILTER";
const string spatialName = "SPATIAL";
[Rtm.CommandMethod("zz")]
public static void ClipedXref()
{
App.Document acDoc = App.Application.DocumentManager.MdiActiveDocument;
if (acDoc == null) return;
Db.Database acCurDb = acDoc.Database;
Ed.Editor acEd = acDoc.Editor;
Db.BlockReference cloneXref = null;
List<Gem.Point3d> ptsIn = new List<Gem.Point3d>();
Ed.PromptEntityOptions opt = new Ed.PromptEntityOptions($"\n\nSelect line in XRef:");
opt.AllowNone = false;
opt.AllowObjectOnLockedLayer = true;
opt.SetRejectMessage("\nYou must select XRef!");
opt.AddAllowedClass(typeof(Db.BlockReference), true);
Ed.PromptEntityResult res = acEd.GetEntity(opt);
if (res.Status != Ed.PromptStatus.OK) return;
if (res.ObjectId.ObjectClass.IsDerivedFrom(Rtm.RXClass.GetClass(typeof(Db.BlockReference))))
{
using (Db.BlockReference br = res.ObjectId.Open(Db.OpenMode.ForRead) as Db.BlockReference)
{
Db.ObjectId btrId = br.BlockTableRecord;
using (Db.BlockTableRecord btr = btrId.Open(Db.OpenMode.ForRead) as Db.BlockTableRecord)
{
if (btr.IsFromExternalReference)
{
Ed.PromptNestedEntityOptions pneo = new Ed.PromptNestedEntityOptions("");
pneo.NonInteractivePickPoint = res.PickedPoint;
pneo.UseNonInteractivePickPoint = true;
Ed.PromptNestedEntityResult pner = acEd.GetNestedEntity(pneo);
if (pner.Status == Ed.PromptStatus.OK)
{
Db.ObjectId selId = pner.ObjectId;
if (selId.ObjectClass.IsDerivedFrom(Rtm.RXClass.GetClass(typeof(Db.Line))))
{
cloneXref = br.Clone() as Db.BlockReference;
using (Db.Line line = selId.Open(Db.OpenMode.ForRead) as Db.Line)
{
ptsIn.Add(line.StartPoint);
ptsIn.Add(line.EndPoint);
}
}
}
}
}
}
}
if (cloneXref != null && ptsIn.Count > 0)
{
Ed.PromptPointOptions optPnt = new Ed.PromptPointOptions("\nPick a point to insert XRef: ");
optPnt.AllowNone = false;
Ed.PromptPointResult resPnt = acEd.GetPoint(optPnt);
if (resPnt.Status == Ed.PromptStatus.OK)
{
Gem.Matrix3d mat = cloneXref.BlockTransform;
Gem.Vector3d v1 = ptsIn[0].TransformBy(mat).GetVectorTo(resPnt.Value);
for (int i = 0; i < ptsIn.Count; i++)
ptsIn[i] = ptsIn[i].TransformBy(mat) + v1;
CreateEXref(acCurDb.CurrentSpaceId, cloneXref, ptsIn, XRefWidth, v1);
}
}
acEd.Regen();
}
private static void CreateEXref(Db.ObjectId CurrentSpaceId, Db.BlockReference cloneXref1, List<Gem.Point3d> ptsIn, double dist, Gem.Vector3d v1)
{
App.Document acDoc = App.Application.DocumentManager.MdiActiveDocument;
Db.Database acCurDb = acDoc.Database;
for (int i = 0; i < ptsIn.Count - 1; i++)
{
Db.ObjectId id = Db.ObjectId.Null;
using (Db.Transaction tr = acCurDb.TransactionManager.StartTransaction())
{
Db.BlockTableRecord acBlkTblRec = tr.GetObject(CurrentSpaceId, Db.OpenMode.ForWrite) as Db.BlockTableRecord;
cloneXref1.TransformBy(Gem.Matrix3d.Displacement(v1));
id = acBlkTblRec.AppendEntity(cloneXref1);
tr.AddNewlyCreatedDBObject(cloneXref1, true);
tr.Commit();
}
using (Db.Transaction tr = acCurDb.TransactionManager.StartOpenCloseTransaction())
{
Db.BlockReference cloneXref = (Db.BlockReference)tr.GetObject(id, Db.OpenMode.ForRead);
Gem.Point3dCollection pts3d = new Gem.Point3dCollection();
Gem.Vector3d vG = ptsIn[i].GetVectorTo(ptsIn[i + 1]);
Gem.Vector3d vV = vG.GetPerpendicularVector().GetNormal() * dist / 2;
pts3d.Add(ptsIn[i] - vV);
pts3d.Add(ptsIn[i] + vG + vV);
Gem.Point2dCollection pts = new Gem.Point2dCollection(pts3d.Count);
Gem.Matrix3d mat = cloneXref.BlockTransform.Inverse();
foreach (Gem.Point3d p in pts3d)
{
Gem.Point3d pBlk = p.TransformBy(mat);
pts.Add(new Gem.Point2d(pBlk.X, pBlk.Y));
}
Gem.Point2d rectMin = new Gem.Point2d(
Math.Min(pts3d[0].X, pts3d[1].X),
Math.Min(pts3d[0].Y, pts3d[1].Y)
);
Gem.Point2d rectMax = new Gem.Point2d(
Math.Max(pts3d[0].X, pts3d[1].X),
Math.Max(pts3d[0].Y, pts3d[1].Y)
);
Gem.Point2dCollection pts1 = new Gem.Point2dCollection(2) { rectMin, rectMax };
Db.Filters.SpatialFilterDefinition sfd =
new Db.Filters.SpatialFilterDefinition(
pts1, Gem.Vector3d.ZAxis, 0.0, 0.0, 0.0, true
);
Db.Filters.SpatialFilter sf = new Db.Filters.SpatialFilter();
// Создаём ExtDict если её нет
Db.ObjectId idbrExt = cloneXref.ExtensionDictionary;
if (idbrExt == Db.ObjectId.Null)
{
cloneXref.UpgradeOpen();
cloneXref.CreateExtensionDictionary();
idbrExt = cloneXref.ExtensionDictionary;
cloneXref.DowngradeOpen();
}
// Добавляем фильтр в ExtDict
Db.DBDictionary xDict =
(Db.DBDictionary)tr.GetObject(
idbrExt, Db.OpenMode.ForWrite
);
if (xDict.Contains(filterDictName))
{
Db.DBDictionary fDict =
(Db.DBDictionary)tr.GetObject(
xDict.GetAt(filterDictName), Db.OpenMode.ForWrite
);
if (fDict.Contains(spatialName))
fDict.Remove(spatialName);
fDict.SetAt(spatialName, sf);
}
else
{
Db.DBDictionary fDict = new Db.DBDictionary();
xDict.SetAt(filterDictName, fDict);
tr.AddNewlyCreatedDBObject(fDict, true);
fDict.SetAt(spatialName, sf);
}
sf.Definition = sfd;
tr.AddNewlyCreatedDBObject(sf, true);
cloneXref.RecordGraphicsModified(true);
tr.Commit();
}
}
}
}
}