admin 发表于 2024-3-9 11:07:29

[原创] 使用"Overrule“实现线中加文本

using System;
using Autodesk.<a href="http://bbs.mjtd.com/forum-41-1.html" target="_blank" class="relatedlink">AutoCAD</a>.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;


namespace ArrowOverrule
{
    //管理重定义
    class TlsApplication : IExtensionApplication
    {
      //初始化例程,重定义生效
      void IExtensionApplication.Initialize()
      {
            Helper.OverruleStart();
            Overrule.Overruling = true;
      }
      //
      void IExtensionApplication.Terminate()
      {
            Helper.OverruleEnd();
            Overrule.Overruling = false;
      }
    }
    //静态类,存放常用的参数
    static class Helper
    {
      //XData的应用程序注册名
      public readonly static string RegAppName = "TlsCad.Arrow";
      //箭头长度,暂时无法更改,可扩展功能
      public static double ArrowLen = 5;
      //重定义生效
      public static void OverruleStart()
      {
            Overrule.AddOverrule(RXObject.GetClass(typeof(Line)), LArrowDrawOverrule.TheOverrule, false);
      }
      //重定义失效
      public static void OverruleEnd()
      {
            Overrule.RemoveOverrule(RXObject.GetClass(typeof(Line)), LArrowDrawOverrule.TheOverrule);
      }
      //让特定的实体附着XData,以便重定义重载可以过滤到该实体
      public static void SetTo(Line line)
      {
            ResultBuffer rb =
                new ResultBuffer(
                  new TypedValue[] {
                         new TypedValue((int)DxfCode.ExtendedDataRegAppName, RegAppName),
                         new TypedValue((int)DxfCode.ExtendedDataReal, ArrowLen) });
            line.XData = rb;
      }
      
      public static void LArrow()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            PromptPointResult res1 = ed.GetPoint("\n请输入起点:");
            if (res1.Status == PromptStatus.OK)
            {
                PromptPointOptions opts = new PromptPointOptions("\n请输入终点:");
                opts.BasePoint = res1.Value;
                opts.UseBasePoint = true;
                PromptPointResult res2 = ed.GetPoint(opts);
                if (res2.Status == PromptStatus.OK)
                {
                  Database db = doc.Database;
                  using (Transaction tr = db.TransactionManager.StartTransaction())
                  {
                        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, false);
                        Line line = new Line(res1.Value, res2.Value);
                        btr.AppendEntity(line);
                        tr.AddNewlyCreatedDBObject(line, true);
                        RegAppTable rat = (RegAppTable)tr.GetObject(db.RegAppTableId, OpenMode.ForRead, false);
                        if (!rat.Has(RegAppName))
                        {
                            rat.UpgradeOpen();
                            RegAppTableRecord regapp = new RegAppTableRecord();
                            regapp.Name = RegAppName;
                            rat.Add(regapp);
                            tr.AddNewlyCreatedDBObject(regapp, true);
                        }
                        SetTo(line);
                        tr.Commit();
                  }
                }
            }
      }
    }
    //显示重定义
    public class LArrowDrawOverrule : DrawableOverrule
    {
      public static LArrowDrawOverrule TheOverrule = new LArrowDrawOverrule();
      //设置重定义的过滤条件
      public LArrowDrawOverrule()
      {
            SetXDataFilter(Helper.RegAppName);
      }
      //显示重载
      public override bool WorldDraw(Drawable drawable, WorldDraw wd)
      {
            Line line = (Line)drawable;
            if (line.Length == 0)
            {
                return base.WorldDraw(drawable, wd);
            }
            else
            {
                double cenpar = (line.StartParam + line.EndParam) / 2;
                Point3d cenpnt = line.GetPointAtParameter(cenpar);
                Vector3d vec = (line.EndPoint - line.StartPoint).GetNormal();
                double douAngle = vec.AngleOnPlane(line.GetPlane());
                //让文本朝北
                if (douAngle > Math.PI / 2 && douAngle < 3 * Math.PI / 2)
                {
                  douAngle -= Math.PI;
                }
                MText mtxt = new MText();
                mtxt.Attachment = AttachmentPoint.MiddleCenter;
                mtxt.Location = cenpnt;
                mtxt.Height = 0.5;
                if (line.Length > 30)
                {
                  mtxt.Contents = "直线超长:" + line.Length.ToString("0.00");
                  mtxt.ColorIndex = 1;
                }
                else
                {
                  mtxt.Contents = "直线长度:" + line.Length.ToString("0.00");
                  mtxt.ColorIndex = 3;
                }
                Extents3d ext = mtxt.GeometricExtents;
                mtxt.Rotation = douAngle;
                double width = (ext.MaxPoint - ext.MinPoint).Length;
                Point3d p1 = line.StartPoint + vec * (line.Length - width) / 2;
                Point3d p2 = p1 + vec * width;
                Line lineLeft = new Line(line.StartPoint, p1);
                Line lineRight = new Line(p2, line.EndPoint);
                wd.Geometry.Draw(lineLeft);
                wd.Geometry.Draw(lineRight);
                return base.WorldDraw(mtxt, wd);
            }
      }
    }
}
页: [1]
查看完整版本: [原创] 使用"Overrule“实现线中加文本