AutoCad 二次开发 jig操作之标注跟随线移动

在autocad当中,我认为的jig操作的意思就是即时绘图的意思,它能够实时的显示出当前的操作,以便我们直观的感受到当前的绘图操作是什么样子会有什么样的结果。比如我们自己写命令话一条直线,不用jig操作,只提示输入两个端点,我们在绘制过程中无法预先的感受到这条直线是在哪个位置,有多长,与x轴成什么角度,而是直接输入两点后就得到一条直线的结果了。还有当有了jig操作后,我们确定了一个端点后,在未输入第二个端点的时候,可以拖动鼠标拉长或缩短这条直线,也可以任意的绕第一个端点旋转这条直线。

我写了一个例子,是输入一条直线,并且在这条直线上建立一个对齐标注,拖动直线的同时,标注也跟随直线变化。我就以这个例子来具体的说说怎样实现一个jig操作。

首先要实现jig操作需要继承抽象类DrawJig, 它就是用来实现自定义的jig操作的,它的继承关系如图:

可以看到 DrawJig是继承自Jig的,有关jig的介绍:

  • Gets a user drag movement
  • Interprets this as a distance, angle, or point
  • Uses this value to update the entity's data
  • Calls the entity's WorldDraw method to redraw it on screen

这也是实现jig操作的步骤,大概意思就是用实时输入的距离、角度、点的数据去更新实体数据在屏幕上。要实现这个得在自定义的jig操作类中实现两个方法:

protected override SamplerStatus Sampler(JigPrompts prompts)

  这个方法主要作用就是获取提供实时的数据输入的,这个JigPrompts和我们常见的那些输入数据的方法类似。这是它的继承结构:

Autodesk.AutoCAD.EditorInput.PromptOptions
Autodesk.AutoCAD.EditorInput.JigPromptOptions
Autodesk.AutoCAD.EditorInput.JigPromptGeometryOptions
Autodesk.AutoCAD.EditorInput.JigPromptAngleOptions
Autodesk.AutoCAD.EditorInput.JigPromptDistanceOptions
Autodesk.AutoCAD.EditorInput.JigPromptPointOptions

我们可以看到,我们能输入4种数据,这里我是选的JigPromptPointOptions,我们就用这里输入的数据来实时的更新直线的EndPoint,和对齐标注的xLine2Point。代码:

InputFunc = (prmpts) =>
{ pointOpts.Message = msg; var res = prmpts.AcquirePoint(pointOpts);
//Point就是我们要更新实体数据的点
if (res.Value == Point)
{
return SamplerStatus.NoChange;
}
else if (res.Value != Point)
{
Point = res.Value;
return SamplerStatus.OK;
}
else
{
return SamplerStatus.Cancel;
} };
protected override bool WorldDraw(WorldDraw draw)

这个方法就是把更新数据后的实体实时的绘制到屏幕上去。代码:

if (JigEnts.Count > )
{
//这是个委托,主要实现你要如何去更新你的实体
JigUpdateAction(this);
foreach (var ent in JigEnts)
{
ent.WorldDraw(draw);
}
}
return true;

JigUpdateAction代码:

(jig) =>
{
line.EndPoint = jig.Point;
dim.XLine2Point = jig.Point;
dim.DimensionText = line.Length.ToString() ; var centerPt = new Point3d((line.StartPoint.X + jig.Point.X) / , (line.StartPoint.Y + jig.Point.Y) / , (line.StartPoint.Z + jig.Point.Z) / ); dim.DimLinePoint = centerPt+ (jig.Point-line.StartPoint).GetNormal().RotateBy(Math.PI / , Vector3d.ZAxis) * ; });

实现了以上两个方法基本上就可以了,最后你需要把实体加入到空间里面去。

完整代码:

using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime; namespace JigDimension
{
public class JigDim
{
[CommandMethod("myjig")]
public void MyJigDimension()
{
var Doc = Application.DocumentManager.MdiActiveDocument;
var Ed = Doc.Editor; var pointRes = Ed.GetPoint(new PromptPointOptions("请输入一地个点:\n")); if (pointRes.Status != PromptStatus.OK) return; Line line = new Line() { StartPoint = pointRes.Value };
AlignedDimension dim = new AlignedDimension() { XLine1Point = line.StartPoint, DimensionStyle = ObjectId.Null }; JigPromptPointOptions jigOpts = new JigPromptPointOptions(); jigOpts.BasePoint = pointRes.Value;
jigOpts.UseBasePoint = true; MyJig myJig = new MyJig(); myJig.PromptInput(jigOpts, "输入第二个点");
myJig.JigEnts.Add(line);
myJig.JigEnts.Add(dim);
myJig.SetJigUpdate((jig) =>
{
line.EndPoint = jig.Point;
dim.XLine2Point = jig.Point;
dim.DimensionText = line.Length.ToString() ; var centerPt = new Point3d((line.StartPoint.X + jig.Point.X) / , (line.StartPoint.Y + jig.Point.Y) / , (line.StartPoint.Z + jig.Point.Z) / ); dim.DimLinePoint = centerPt+ (jig.Point-line.StartPoint).GetNormal().RotateBy(Math.PI / , Vector3d.ZAxis) * ; }); if (myJig.Drag() != PromptStatus.OK)
{
return;
} myJig.JigEnts.ToSpace(); } }
public class MyJig : DrawJig
{ public Point3d Point = Point3d.Origin; Func<JigPrompts, SamplerStatus> InputFunc; public List<Entity> JigEnts = new List<Entity>();
Action<MyJig> JigUpdateAction; public MyJig()
{
JigEnts.Clear();
InputFunc = null;
} public void SetJigUpdate(Action<MyJig> action)
{
JigUpdateAction = action;
} public void PromptInput(JigPromptPointOptions pointOpts,string msg)
{
InputFunc = (prmpts) =>
{ pointOpts.Message = msg; var res = prmpts.AcquirePoint(pointOpts);
//Point就是我们要更新实体数据的点
if (res.Value == Point)
{
return SamplerStatus.NoChange;
}
else if (res.Value != Point)
{
Point = res.Value;
return SamplerStatus.OK;
}
else
{
return SamplerStatus.Cancel;
} }; } protected override SamplerStatus Sampler(JigPrompts prompts)
{
if (InputFunc == null)
{
return SamplerStatus.NoChange;
} return InputFunc.Invoke(prompts);
} protected override bool WorldDraw(WorldDraw draw)
{
if (JigEnts.Count > )
{
//这是个委托,主要实现你要如何去更新你的实体
JigUpdateAction(this);
foreach (var ent in JigEnts)
{
ent.WorldDraw(draw);
}
}
return true;
}
public PromptStatus Drag()
{
return Application.DocumentManager.MdiActiveDocument.Editor
.Drag(this).Status;
}
}
}

最新文章

  1. Atitit.架构设计趋势 设计模式 ---微服务架构&#160;&#160;soa
  2. web.config
  3. Java开源框架推荐(全)
  4. cf455a(简单dp)
  5. oracle 回车、换行符
  6. window对象的属性方法名造成的命名冲突
  7. IOS 给图片添加水印 打印文字
  8. Microsoft.AspNet.FriendlyUrls发布到IIS后404报错的解决方案
  9. startActivity与startActivityForResult的使用小结
  10. 详解python2 和 python3的区别
  11. Python IDLE 运行错误:IDLE&#39;s subprocess didn&#39;t make connection. --已解决(原创)!
  12. asyncio
  13. maridb安装审计audit插件
  14. JavaScript中Object的总结
  15. vue 的准备项目架构环境配置
  16. [Swift]LeetCode304. 二维区域和检索 - 矩阵不可变 | Range Sum Query 2D - Immutable
  17. C. Multi-Subject Competition 思维+前缀和+填表加减复杂度(复杂度计算错误)
  18. Java中有哪些语法糖?
  19. Repeater控件添加序号列
  20. informix数据库知识积累

热门文章

  1. XSS与CSRF详解
  2. Numpy 排序和使用索引
  3. 「刷题」可怜与STS
  4. Topshelf+Quatz.Net的简单使用
  5. 什么是&quot;双活&quot;
  6. 如何在双向绑定的Image控件上绘制自定义标记(wpf)
  7. Deepin 下 使用 Rider 开发 .NET Core
  8. 重写equals方法,也应该重写hashcode方法,反之亦然
  9. 使用Jquery获取指定属性的值
  10. pat 1132 Cut Integer(20 分)