lzx838 发表于 2009-9-21 11:45:00

[原创]翔麟专集——使用"Overrule“实现线中加文本

本帖最后由 作者 于 2009-9-21 13:56:49 编辑

在lzh741206的帮助下(其实可以说是他写的),实现了在直线中加居中文本,并销除文本后面的线段。
具体效果如下图:

具体实现代码如下:using System;
using Autodesk.AutoCAD.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);
            }
      }
    }
}

nslove44202489 发表于 2019-3-19 20:11:13

毛线用,保存后再打开就没了,体验不如属性块

lzx838 发表于 2009-9-21 11:52:00

<p>本贴最大的特色是:</p><p>1.实现了文本文字不管在什么角度,都正向朝北。</p><p>2.实现了文本文字背后我的线段被销除。</p><p>3.能动态显示直线的长度。</p><p>4.根据直线的长度是否在某个值的范围内,更换文本内容及文本颜色,从而实现了直线与文本两者的颜色不同而存。</p>

asdfxx 发表于 2009-9-21 16:49:00

xinzhi 发表于 2009-9-23 22:15:00

<strong>翔麟牛</strong>

gsteven 发表于 2009-9-23 23:46:00

本帖最后由 作者 于 2009-9-24 0:10:59 编辑 <br /><br /> <p><br/></p><p>为什么用两种不同的方式呢?一个是CommandClass,一个是ExtensionApplication?有什么区别吗?</p><p>还有下面这一句出错,找不到类型或命名空间名称DrawableOverrule(是否缺少using指令或程序集引用?)</p><p>//显示重定义<br/>&nbsp;&nbsp;&nbsp; public class LArrowDrawOverrule : DrawableOverrule</p>

lzx838 发表于 2009-9-24 12:35:00

楼上,你用的CAD是什么版本,这个Overrule目前只能在AutoCAD2010上运行!

gsteven 发表于 2009-9-24 12:55:00

<p>我用的是2009啊!</p><p>请问2010哪里有下载啊?</p>

雪山飞狐_lzh 发表于 2009-9-24 13:37:00

<p>应用版的置顶贴</p><p><a href="http://bbs.mjtd.com/forum.php?mod=forumdisplay&fid=41">http://bbs.mjtd.com/forum.php?mod=forumdisplay&fid=41</a></p>

游天居士 发表于 2009-9-24 22:58:00

<p>确实不一般.看来我要转到CAD2010上开发了.</p><p>游天居士到此一游.</p>
页: [1]
查看完整版本: [原创]翔麟专集——使用"Overrule“实现线中加文本