出處
https://www.theswamp.org/index.php?topic=59354.msg619875#msg619875
問題描述
用以下程式碼建立了一個Hatch,這Hatch周圍沒有建立Polyline,如何選擇這個無邊界Hatch的邊界上的點。
比如用line命令時如何捕捉Hatch邊界上的點?
希望有一個簡潔的方案。
var pts = new Point2d[]
{
new Point2d(10, 0),
new Point2d(10, 10),
new Point2d(20, 10),
new Point2d(20, 0),
new Point2d(10, 0),
};
var ptCol = new Point2dCollection(pts);
var doubleCol = new DoubleCollection();
var doc = Acap.DocumentManager.MdiActiveDocument;
using (var tran = doc.Database.TransactionManager.StartTransaction())
{
var table = tran.GetObject(doc.Database.BlockTableId, OpenMode.ForRead) as BlockTable;
var record = tran.GetObject(table[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
var hatch = new Hatch();
record.AppendEntity(hatch);
hatch.AppendLoop(HatchLoopTypes.Default, ptCol, doubleCol);
hatch.EvaluateHatch(true);
tran.AddNewlyCreatedDBObject(hatch, true);
tran.Commit();
}
回答
可以為圖案填充邊界頂點建立自定義物件捕捉。
系統變數OSPTIONS的值不得包括1(即0、2、4或6)。
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
namespace HatchBoundaryOsnap
{
internal class HatchBoundOsnap
{
public static void Create()
{
var hatchBoundGlyph = new HatchBoundGlyph();
var hatchBoundSnapMode = new CustomObjectSnapMode("HBV", "HBV", "Hatch boundary vertex", hatchBoundGlyph);
var hatchBoundInfo = new HatchBoundInfo();
hatchBoundSnapMode.ApplyToEntityType(RXObject.GetClass(typeof(Hatch)), new AddObjectSnapInfo(HatchBoundInfo.VertexInfo));
}
class HatchBoundGlyph : Glyph
{
private Point3d point;
public override void SetLocation(Point3d point)
{
this.point = point;
}
protected override void SubViewportDraw(ViewportDraw vd)
{
int glyphPixels = CustomObjectSnapMode.GlyphSize;
Point2d glyphSize = vd.Viewport.GetNumPixelsInUnitSquare(point);
double offset = (glyphPixels / glyphSize.Y) * 0.8;
var points = new Point3dCollection
{
new Point3d(point.X, point.Y - offset, point.Z),
new Point3d(point.X + offset, point.Y, point.Z),
new Point3d(point.X, point.Y + offset, point.Z),
new Point3d(point.X - offset, point.Y, point.Z),
new Point3d(point.X, point.Y - offset, point.Z),
};
vd.Geometry.DeviceContextPolygon(points);
}
}
class HatchBoundInfo
{
public static void VertexInfo(ObjectSnapContext context, ObjectSnapInfo result)
{
if (context.PickedObject is Hatch hatch)
{
var xform = Matrix3d.PlaneToWorld(new Plane(Point3d.Origin, hatch.Normal));
double elevation = hatch.Elevation;
Point3d convert3d(Point2d pt) =>
new Point3d(pt.X, pt.Y, elevation).TransformBy(xform);
for (int i = 0; i < hatch.NumberOfLoops; i++)
{
var loop = hatch.GetLoopAt(i);
if (loop.IsPolyline)
{
foreach (BulgeVertex vertex in loop.Polyline)
{
result.SnapPoints.Add(convert3d(vertex.Vertex));
}
}
else
{
foreach (Curve2d curve in loop.Curves)
{
result.SnapPoints.Add(convert3d(curve.StartPoint));
}
}
}
}
}
}
}
}
若要使此物件捕捉可用,只需在實現IExtensionApplication的類的Initialize方法中,呼叫HatchBoundOsnap.Create()方法。
using Autodesk.AutoCAD.ApplicationServices.Core;
using Autodesk.AutoCAD.Runtime;
using System;
namespace HatchBoundaryOsnap
{
public class Initialization : IExtensionApplication
{
public void Initialize()
{
HatchBoundOsnap.Create();
}
public void Terminate()
{ }
}
}