魔改系列-2循环选择
本帖最后由 你有种再说一遍 于 2024-10-20 16:20 编辑# 循环选择
1,选择状态有夹点显示,此时缓冲区有id集合且不为0.
2,亮显没有夹点显示.
在Acad.net提供的手选函数,无法在缓冲区不为0时再选择,如果此时循环再手选,不会发生阻塞,而是直接就是ok的...
问题代码展示:
```csharp
public void LoopBug() {
Document doc = Acap.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
for (int i = 0; i < 5; i++) {
// 第一次会阻塞后执行手选,第二次就不会了.
var opts = new PromptSelectionOptions() { MessageForAdding = "\n请选择图元:" };
var ss = ed.GetSelection(opts);
if (ss.Status != PromptStatus.OK) {
ed.WriteMessage("\n未选择任何图元.");
continue;
}
var ids = ss.Value.GetObjectIds();
ed.WriteMessage("\n选择了图元数:" + ids.Length);
ed.SetImpliedSelection(ids);
}
}
```
我们很容易想到一个解决方案,
如果不设置缓冲区,那么是不是只能亮显了?
但是亮显图元无法用shift剔除.
重点:
此时需要通过键盘钩子进行拦截shift键入,然后发送消息结束ssget.把全部图元亮显,求出鼠标矩形在哪些图元上面,暗显并ids也减去.
shift抬起时候,恢复亮显.
```csharp
//记得加这个flag
public void Pick() {
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
var opts = new PromptSelectionOptions("\n请选择对象:");
opts.AllowNone = true;
opts.AllowArbitraryInput = true; // 允许任意输入
//opts.SingleOnly = true;//只一个对象不回车
opts.SelectEverythingInAperture = true;// 点击模式
// 过滤器
SelectionFilter fr = new (new TypedValue[] {
new TypedValue((int)DxfCode.Start, "LINE"),
});
var ss = ed.SelectImplied();//预选
if (ss.Status == PromptStatus.OK) {
foreach(var id in ss.Value.GetObjectIds()){
if(!fr.Contains(id)){ // 伪代码看懂就行
_ids.Add(id);
}
}
// 清空选择集
ed.SetImpliedSelection(new ObjectId[] { });
}
// 循环选择,重新手选
while(true){
_ids.ForEach=>{ent.Highlight();}//亮显
ss = ed.GetSelection(opts,fr);
if (ss.Status == PromptStatus.OK) {
_ids.ForEach=>{ent.Unhighlight();}//暗显
_ids.AddRange(ss.Value.GetObjectIds());
ed.SetImpliedSelection(new ObjectId[] { });
continue;
}
if(ss.Status == PromptStatus.Cancel) {
/* 键盘钩子发送Esc消息才到这个状态
方案一:
先选中ids,再开启新选择集,然后减选.
我怀疑不行,因为选中状态(缓冲区有对象)会直接跳过手选.
shift按着也可能不切换到新选择集的反选模式.
释放shift也要结束这个选择集
_ids.ForEach=>{ent.Unhighlight();}//暗显
ed.SetImpliedSelection(_ids.ToArray());//重设选择集
var s2 = ed.GetSelection();
if(s2.Status == PromptStatus.OK) {
_ids.RemoveAll(s2.Value.GetObjectIds());
}
方案二:
不重设选择集,获取选择集矩形两个点ss.PickedPoint,然后直接剔除集合
?
*/
}
// 结束循环
_ids.ForEach=>{ent.Unhighlight();}//暗显
break;
}
}
HashSet<ObjectId> _ids = new();
void 键盘钩子(s,e) {
if(e.Key == "shift".KeyCode()){
Acad.Handle.Foucs().发送异步Esc消息();
//这里_ids.事务跨线程!无法操作图元.
}
}
```
选择集的本质:
啊?其实可以自己实现一个两点矩形,然后通过选框范围,再触发四叉树选择.
选框还可以利用透明winform画一个颜色,并且才用滤镜算法...很麻烦吗?
(完)
页:
[1]