【AutoCAD .NET】如何在無邊界Hatch上選擇邊界點?

greencode發表於2024-03-16

出處

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()
        { }
    }
}
 

相關文章