- New FaceInferToolPlugin: pixel-neighborhood method with {2,5,10}px offsets
- New FaceInferResult data class
- Test button in SystemManagement page
- Cursor: MarkupAutoPoly (arrow + dashed box)
- Uses project-standard tools: FindNamedParentContainer, viewpoint.Position
- Design doc at doc/design/2026/face-infer-tool-design.md
3.4 KiB
3.4 KiB
快速取面工具设计
创建时间:2026-06-02
目标
新增一个独立 ToolPlugin,通过单点+像素邻域法快速推断鼠标点击位置所在面的法向量。
和取点工具 PathClickToolPlugin 并列,互斥激活。
核心算法
单点+像素邻域法 —— 一次点击内做三次 PickItemFromPoint:
中心点: PickItemFromPoint(x, y) → p0
右邻域: PickItemFromPoint(x+δ, y) → p1
下邻域: PickItemFromPoint(x, y+δ) → p2
v1 = p1 - p0
v2 = p2 - p0
normal = normalize(cross(v1, v2))
偏移量 δ 三级递进:2px → 5px → 10px,小偏移共线时自动退到更大偏移。
新增文件
| 文件 | 职责 |
|---|---|
src/Models/FaceInferResult.cs |
结果数据类 |
src/Core/FaceInferToolPlugin.cs |
ToolPlugin 主体 |
不修改任何现有文件。
架构
FaceInferToolPlugin : ToolPlugin
│
├── Plugin("FaceInferTool", "NavisworksTransport")
│
├── Static 成员
│ ├── event FaceInferred # 外部订阅事件
│ ├── AssemblyPath # 用于动态加载
│ └── TriggerFaceInferred() # 允许外部手动触发
│
├── GetCursor → Cursor.MarkupQuickPick
│
├── MouseDown(x, y)
│ ├── centerPick = PickItemFromPoint(x, y)
│ ├── rightPick = PickItemFromPoint(x + δ, y)
│ ├── downPick = PickItemFromPoint(x, y + δ)
│ ├── 同构件校验 (ModelItem 比较)
│ ├── 共线校验 (cross.Length < 0.001 → 退到下一级 δ)
│ ├── 法向量归一化
│ ├── 朝向统一 (dot with viewDir, 始终指向相机)
│ └── 触发 FaceInferred 事件
│
└── MouseMove → 暂不处理(轻量原则)
FaceInferResult 数据结构
public class FaceInferResult
{
public Point3D HitPoint { get; } // 命中点(宿主坐标系)
public Vector3D Normal { get; } // 面法向量(已归一化,朝向相机)
public ModelItem ModelItem { get; } // 命中的 ModelItem
public bool IsValid { get; } // 推断是否成功
}
所有坐标均为宿主坐标系(PickItemFromPoint 原始输出)。
激活方式
与 PathClickToolPlugin 完全相同的流程,仅插件名不同:
var assemblyPath = FaceInferToolPlugin.AssemblyPath;
Application.Plugins.AddPluginAssembly(assemblyPath);
var record = (ToolPluginRecord)Application.Plugins.FindPlugin("FaceInferTool.NavisworksTransport");
var plugin = record.LoadPlugin();
Application.MainDocument.Tool.SetCustomToolPlugin(plugin);
光标
使用 Cursor.MarkupQuickPick。Navisworks Cursor 枚举无平行四边形,此为最接近的选项。
与 PathClickToolPlugin 的关系
- 两者都是
ToolPlugin,同一时刻只有一个激活 - 互斥切换:取面时取点失活,取面结束切回取点
- 切换流程与项目中已有的「导航工具 ↔ ClickTool」切换模式一致
暂不实现
| 项目 | 原因 |
|---|---|
| 透视近大远小动态 δ 调整 | 先验证精度,不够再加 |
| 跨面距离检测 (maxDist) | 同构件判断已覆盖基本场景 |
| 曲面曲率分析 | 不同业务需求 |
| MouseMove 实时预览 | 保持轻量 |
下一步
- 实现两个新文件
- 在已知平面上验证法向量精度(误差应在 1° 以内)
- 后续由调用方(ViewModel)按需集成激活/切换逻辑