[原创]翔麟专集——使用"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);
}
}
}
}
毛线用,保存后再打开就没了,体验不如属性块 <p>本贴最大的特色是:</p><p>1.实现了文本文字不管在什么角度,都正向朝北。</p><p>2.实现了文本文字背后我的线段被销除。</p><p>3.能动态显示直线的长度。</p><p>4.根据直线的长度是否在某个值的范围内,更换文本内容及文本颜色,从而实现了直线与文本两者的颜色不同而存。</p> <strong>翔麟牛</strong> 本帖最后由 作者 于 2009-9-24 0:10:59 编辑 <br /><br /> <p><br/></p><p>为什么用两种不同的方式呢?一个是CommandClass,一个是ExtensionApplication?有什么区别吗?</p><p>还有下面这一句出错,找不到类型或命名空间名称DrawableOverrule(是否缺少using指令或程序集引用?)</p><p>//显示重定义<br/> public class LArrowDrawOverrule : DrawableOverrule</p> 楼上,你用的CAD是什么版本,这个Overrule目前只能在AutoCAD2010上运行! <p>我用的是2009啊!</p><p>请问2010哪里有下载啊?</p> <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> <p>确实不一般.看来我要转到CAD2010上开发了.</p><p>游天居士到此一游.</p>
页:
[1]