测试结果:

主要思路:选择一段多段线,使用封装的jig类进行实时拖动,其原理就是在拖动的时候,确定被拖动的边,我是选择离输入第一个点最近的边作为拖动边,有了这条边,就能确定需要实时更改的点了,然后当鼠标拖动的时候,限制拖动方向只能是X轴或者Y轴变换,详细我在代码里都写了注释的。不足之处就是选择之后,我是把原来的对象复制一份,在删除了原对象,不知道是不是这个原因,Polyline会在选择之后消失,再次点击又出现了。我试了如果直接以写的方式操作原对像,cad会报错,说NotOpenForWrite,我也不知道这是什么原因。下面贴出所有的代码。

Jig操作类:

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;
}
}

这个类在我的另一篇jig操作里做了点介绍的:

https://www.cnblogs.com/HelloQLQ/p/12000879.html
命令类:

public class MyDrag
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
Database db = Application.DocumentManager.MdiActiveDocument.Database;
Polyline pl = null;
bool IsDrag = false;
[CommandMethod("MyDrag")]
public void DragIt()
{
IsDrag = false;
PromptEntityOptions entOpts = new PromptEntityOptions("请选择Polyline"); entOpts.SetRejectMessage("请选择多段线");
entOpts.AddAllowedClass(typeof(Polyline), true); var pEntRes = ed.GetEntity(entOpts); if (pEntRes.Status != PromptStatus.OK)
return; Polyline plCo = null;
using (var trans = db.TransactionManager.StartTransaction())
{ pl = trans.GetObject(pEntRes.ObjectId, OpenMode.ForWrite) as Polyline; //这里如果不复制,直接操作pl,虽然是以写的方式打开的实体,但是会报错说NotOpenForWrite
plCo = pl.Clone() as Polyline; pl.Erase(); trans.Commit(); } List<LineSegment2d> listL2d = new List<LineSegment2d>();
for (int i = ; i < pl.NumberOfVertices - ; i++)
{
listL2d.Add(pl.GetLineSegment2dAt(i));
} var pointRes = ed.GetPoint(new PromptPointOptions("请输入一地个点:\n")); if (pointRes.Status != PromptStatus.OK) return; Vector2d v2d = new Vector2d(, ); JigPromptPointOptions jigOpts = new JigPromptPointOptions(); MyJig myJig = new MyJig(); myJig.PromptInput(jigOpts, "拖动鼠标");
myJig.JigEnts.Add(plCo); int dir = -; myJig.SetJigUpdate((jig) =>
{
if (jig.JigEnts == null || jig.JigEnts.Count == )
{
return;
} Polyline p = jig.JigEnts[] as Polyline; var pt1 = pointRes.Value; var pt2 = jig.Point; var vec = pt2 - pt1; /*获取鼠标拖动方向,主要思路
*当拖动的距离拖动前按下的那个点的
* 距离>1的时候,计算是X轴方向还是Y轴方向
* 因为第一次判断,如果距离过下方向不准确。
* 并且这个方向一确定,就不在更改。
*/
if (!IsDrag)
{
if (vec.Length > )
{
IsDrag = true; if (Math.Abs(vec.X) > Math.Abs(vec.Y))
{
dir = ; }
else
{
dir = ;
}
} }
//向右或者向左
if (dir == )
{ v2d = new Vector2d(vec.X, ); }
else//向上或者向下
{
v2d = new Vector2d(, vec.Y); } /*
* 确定要拖动的边是选择距离鼠标按下的那个点最近的边
*/
double minLength = double.MaxValue; int index = -; foreach (var i in Enumerable.Range(, listL2d.Count))
{
var l = listL2d[i];
double dis = l.GetDistanceTo(new Point2d(pointRes.Value.X, pointRes.Value.Y)); if (dis < minLength)
{ minLength = dis;
index = i;
} } var l2d = listL2d[index]; Matrix2d mtx2d = Matrix2d.Displacement(v2d); var ptGet1 = l2d.StartPoint;
var ptGet2 = l2d.EndPoint; //实时得到变化的点
var ptStart = ptGet1.TransformBy(mtx2d);
var ptEnd = ptGet2.TransformBy(mtx2d); var vecGet = ptGet2 - ptGet1; //判断鼠标移动的方向和被拖动的边是否是在大致的同一方向
//如果不是,就允许拖动
if (dir == && (Math.Abs(vecGet.X) < Math.Abs(vecGet.Y)) ||
dir == && (Math.Abs(vecGet.X) > Math.Abs(vecGet.Y)))
{
p.SetPointAt(index, ptStart);
p.SetPointAt(index + , ptEnd); //如果polyline是封闭的,要判断被拖动的点是否是闭合位置上的点,
//如果是,要一致更改起点和封闭点
if (p.Closed)
{
if (index == )
{
p.SetPointAt(p.NumberOfVertices - , ptStart);
}
if (index + == )
{
p.SetPointAt(p.NumberOfVertices - , ptEnd);
}
if (index == p.NumberOfVertices - )
{
p.SetPointAt(, ptStart);
}
if (index + == p.NumberOfVertices - )
{
p.SetPointAt(, ptEnd);
}
}
}
}); if (myJig.Drag() != PromptStatus.OK)
{ return;
} IsDrag = false; //加入到模型空间
myJig.JigEnts.ToSpace();
myJig.JigEnts.ForEach(a => a.Dispose());
} }

AutoCad 二次开发 Jig操作之墙块的拖动的更多相关文章

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

    AutoCad 二次开发 jig操作之标注跟随线移动 在autocad当中,我认为的jig操作的意思就是即时绘图的意思,它能够实时的显示出当前的操作,以便我们直观的感受到当前的绘图操作是什么样子会有什 ...

  2. AutoCad 二次开发 文字镜像

    AutoCad 二次开发 文字镜像 参考:https://adndevblog.typepad.com/autocad/2013/10/mirroring-a-dbtext-entity.html 在 ...

  3. AutoCAD二次开发——AutoCAD.NET API开发环境搭建

    AutoCAD二次开发工具:1986年AutoLisp,1989年ADS,1990年DCL,1993年ADS-RX,1995年ObjectARX,1996年Active X Automation(CO ...

  4. AutoCad 二次开发 .net 之层表的增加 删除 修改图层颜色 遍历 设置当前层

    AutoCad 二次开发 .net 之层表的增加 删除 修改图层颜色 遍历 设置当前层 AutoCad 二次开发 .net 之层表的增加 删除 修改图层颜色 遍历 设置当前层我理解的图层的作用大概是把 ...

  5. 1,下载和部署开发环境--AutoCAD二次开发

    环境需求为: AutoCAD 2020版 ObjectARX SDK 下载地址:https://www.autodesk.com/developer-network/platform-technolo ...

  6. AutoCAD二次开发-使用ObjectARX向导创建应用程序(HelloWorld例子)

    AutoCAD2007+vs2005 首先自己去网上搜索下载AutoCAD2007的ARX开发包. 解压后如下 打开后如下 classmap文件夹为C++类和.net类的框架图,是一个DWG文件. d ...

  7. 我的AutoCAD二次开发之路 (一)

    原帖地址 http://379910987.blog.163.com/blog/static/33523797201011184552167/ 今天在改代码的时候,遇到了AddVertexAt方法的用 ...

  8. Autocad中使用命令来调用python对Autocad二次开发打包后的exe程序

    在Autocad中直接调用Python二次开发程序是有必要的,下面介绍一种方法来实现这个功能: 其基本思路是:先将二次开发的程序打包为可执行程序exe,然后编写lsp文件,该文件写入调用exe程序的语 ...

  9. 承接 AutoCAD 二次开发 项目

    本人有多年的CAD开发经验,独立完成多个CAD二次开发项目.熟悉.net及Asp.net开发技术,和Lisp开发技术. 现在成立了工作室,独立承接CAD二次开发项目.结项后提供源码及开发文档,有需要的 ...

随机推荐

  1. 20-1 django上传文件和项目里上传头像如何查看

    一 普通上传方式 1 views def upload(request): if request.method == "POST": # print(request.POST) # ...

  2. @bzoj - 3836@ [Poi2014]Tourism

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个n个点,m条边的无向图,其中你在第i个点建立旅游站点的费 ...

  3. 模板—中国剩余定理+拓展GCD

    int exgcd(int a,int b,int &x,int &y) { ) { x=,y=; return a; } int gcd=exgcd(b,a%b,x,y); int ...

  4. 认识web前端开发

    web前端开发 1.web即web系统,是以网站的形式呈现,通过浏览器的访问来实现一定的功能的系统. 2.什么是前端开发? 前端开发是创建web页面或app等前端界面呈现给用户的过程.通过html.c ...

  5. 20190528-JavaScriptの打怪升级旅行 { 语句 [ 赋值 ,数据 ] }

    写在前面的乱七八糟:今天考了试,emmm很基础的题,还是Mrs房的面试题让人绝望啊┓( ´∀` )┏,补了很多知识,很综合的题,坑也很多,总的来说,查漏补缺,其实是啥都缺~ 今天打的小BOSS主要是数 ...

  6. 怎么查看mysql 的binlog日志存放的位置

    image.png 这个你可以看配置文件 启用了才有这样的记录默认是没有的 linux系统中的/etc/my.cnf my.cnf内容: log-bin = mysqlbin # 默认配置 一般放在/ ...

  7. Codeforces Round #186 (Div. 2)

    A. Ilya and Bank Account 模拟. B. Ilya and Queries 前缀和. C. Ilya and Matrix 考虑每个元素的贡献. 边长为\(2^n\)时,贡献为最 ...

  8. Spring Data Jpa 简单使用事务

    对于两张表,需要顺序操作,必须全部表均操作成功才可,否则两张表不操作. 例如,现在有device,collectionpoint两张表,向两张表顺序执行insert操作 SQL如下 INSERT IN ...

  9. CSS 伸缩布局

    转载于:https://blog.csdn.net/weixin_41342585/article/details/80140513 1. flex-direction:设置伸缩容器中成员的排列方式 ...

  10. linux 分配和释放设备编号

    在建立一个字符驱动时你的驱动需要做的第一件事是获取一个或多个设备编号来使用. 为 此目的的必要的函数是 register_chrdev_region, 在 <linux/fs.h>中声明: ...