本帖最后由 你有种再说一遍 于 2026-2-21 00:21 编辑
# 自制在位编辑器
终于写了一个自己的"在位编辑器"功能了.
RefEdit.cs
故事是:
这个东西koz告诉我怎么找到瞬间的workset以来,就晾着了,毕竟以后我的更懂它...
然后我处理拉伸填充的时候,发现我需要处理在位编辑,毕竟不能点击到外部填充产生意外边界.
然后我发现了原生的: "在位编辑-添加-撤回"
这个撤回ctrl+z是没有任何数据库事件响应的,因为它采用了"局部撤回"的技术.
造成我需要用一套undoLog日志系统来实现撤回.
日志是用正向过程模拟undo,通过发送命令再次执行在位编辑器实现的,
而两次在位编辑的workset临时图元是不一样的,
就又有一个跟踪临时图元的困难...
```
解决方案:
利用refedit命令触发前打开块表记录,
在每个ent.xdata进行记录一个虚拟句柄,在位编辑拷贝出临时图元会带有xdata,自然可以追踪了,
日志记录的是虚拟句柄,而不是id,就可以撤回时候识别.
```
虽然有解决方案,但是这个方案会污染数据库,实在不喜欢...
况且还有其它命令的undo问题(BEdit).
这说明了得到瞬间的workset容易,但是难以跟踪原生的在位编辑器内图元.
思前想后,不如自己造一个在位编辑器,然后替换进去,没想到还挺简单的.
基本功告诉我,在位编辑器本质上就是hashset的封装,只是褪色问题一直没有想通.
突发奇想,想起了原本图层有个褪色问题:
图层锁定会褪色,解锁不还原褪色,需要一个move0+内置刷新还原,
原本是一个难题,没想到却是特性,具体看代码就知道为什么了.
模拟了原生的几个命令: refedit/refset/refclose.
1,利用了"图层锁定-刷新图层显示-图层解锁"来处理褪色问题.
`刷新图层显示`函数: `IFoxUtils.RegenLayers(lockedLayers);`
2,处理官方命令的先执行再选择,
需要图层锁定触发过滤选择.
是要遍历当前空间图元置换到refEditor0图层锁定,所以量大就会卡.不过十万图元不也才1s.
由于无法并行修改图元图层,造成渐进式修改也是无法实现,只能忍忍?
感觉可以只刷新局部...例如选择块的包围盒扩展2倍.
3,如果有块编辑器的"参数/动作"是可以实现在在位编辑器实现这些功能的...
4,如果能强行设置系统变量refeditname = "xx"就好了,
似乎要读PE得到接口?内部指针操作?
5,undo/redo恢复workset的机制
a,纯内存的历史链表.
b,每个添加/删除对象事件,用了可撤事务写了一个DBDictionary.XData来追踪官方的undo位置.
6,命令后事件
undo命令后,如果使用`刷新图层显示`函数,会导致无法redo...无解.
这样造成undo之后显示不正常,
任意命令(例如M)才就能立即显示正常了,毕竟我不想破坏redo.
7,发现了历史记录适合用不可变类型.
还发现了C#并没有一次性构建不可变类型的功能,用户可能持有可变的指针,
总是要可变转不可变,然后得发生拷贝.
Rust是通过生命周期计算来实现编译报错实现阻止这种行为.
8,添加了一个标题栏修改,红色边框.
修复了ref_add和ref_remove的闪回历史.
撤回上面刷新还是有问题,不知道怎么修复,用了一个#if DEBUG来处理.网友答: 没事做啥undolog呢,头不好用就换头...结果一地鸡毛网友答: 支持下,cad的在位编辑确实不方便网友答: 自己也给锁了吧,全锁定了网友答:
锁了啊,都锁了网友答: 新年快乐,大佬,新手小白看了您的帖子,久仰大名,听您的推荐c#好,想学c#用来二次开发AutoCAD,请问有推荐的教程吗,视频或者文档都可以,望大佬指点指点迷津,跪谢大佬!!!
# 自制在位编辑器
终于写了一个自己的"在位编辑器"功能了.
RefEdit.cs
故事是:
这个东西koz告诉我怎么找到瞬间的workset以来,就晾着了,毕竟以后我的更懂它...
然后我处理拉伸填充的时候,发现我需要处理在位编辑,毕竟不能点击到外部填充产生意外边界.
然后我发现了原生的: "在位编辑-添加-撤回"
这个撤回ctrl+z是没有任何数据库事件响应的,因为它采用了"局部撤回"的技术.
造成我需要用一套undoLog日志系统来实现撤回.
日志是用正向过程模拟undo,通过发送命令再次执行在位编辑器实现的,
而两次在位编辑的workset临时图元是不一样的,
就又有一个跟踪临时图元的困难...
```
解决方案:
利用refedit命令触发前打开块表记录,
在每个ent.xdata进行记录一个虚拟句柄,在位编辑拷贝出临时图元会带有xdata,自然可以追踪了,
日志记录的是虚拟句柄,而不是id,就可以撤回时候识别.
```
虽然有解决方案,但是这个方案会污染数据库,实在不喜欢...
况且还有其它命令的undo问题(BEdit).
这说明了得到瞬间的workset容易,但是难以跟踪原生的在位编辑器内图元.
思前想后,不如自己造一个在位编辑器,然后替换进去,没想到还挺简单的.
基本功告诉我,在位编辑器本质上就是hashset的封装,只是褪色问题一直没有想通.
突发奇想,想起了原本图层有个褪色问题:
图层锁定会褪色,解锁不还原褪色,需要一个move0+内置刷新还原,
原本是一个难题,没想到却是特性,具体看代码就知道为什么了.
模拟了原生的几个命令: refedit/refset/refclose.
1,利用了"图层锁定-刷新图层显示-图层解锁"来处理褪色问题.
`刷新图层显示`函数: `IFoxUtils.RegenLayers(lockedLayers);`
2,处理官方命令的先执行再选择,
需要图层锁定触发过滤选择.
是要遍历当前空间图元置换到refEditor0图层锁定,所以量大就会卡.不过十万图元不也才1s.
由于无法并行修改图元图层,造成渐进式修改也是无法实现,只能忍忍?
感觉可以只刷新局部...例如选择块的包围盒扩展2倍.
3,如果有块编辑器的"参数/动作"是可以实现在在位编辑器实现这些功能的...
4,如果能强行设置系统变量refeditname = "xx"就好了,
似乎要读PE得到接口?内部指针操作?
5,undo/redo恢复workset的机制
a,纯内存的历史链表.
b,每个添加/删除对象事件,用了可撤事务写了一个DBDictionary.XData来追踪官方的undo位置.
6,命令后事件
undo命令后,如果使用`刷新图层显示`函数,会导致无法redo...无解.
这样造成undo之后显示不正常,
任意命令(例如M)才就能立即显示正常了,毕竟我不想破坏redo.
7,发现了历史记录适合用不可变类型.
还发现了C#并没有一次性构建不可变类型的功能,用户可能持有可变的指针,
总是要可变转不可变,然后得发生拷贝.
Rust是通过生命周期计算来实现编译报错实现阻止这种行为.
8,添加了一个标题栏修改,红色边框.
修复了ref_add和ref_remove的闪回历史.
撤回上面刷新还是有问题,不知道怎么修复,用了一个#if DEBUG来处理.网友答: 没事做啥undolog呢,头不好用就换头...结果一地鸡毛网友答: 支持下,cad的在位编辑确实不方便网友答: 自己也给锁了吧,全锁定了网友答:
forestgxc 发表于 2026-2-12 14:43
自己也给锁了吧,全锁定了
锁了啊,都锁了网友答: 新年快乐,大佬,新手小白看了您的帖子,久仰大名,听您的推荐c#好,想学c#用来二次开发AutoCAD,请问有推荐的教程吗,视频或者文档都可以,望大佬指点指点迷津,跪谢大佬!!!