用ClashDetective API的标准用法重构碰撞检测部分,增加了碰撞分组;
三维视图选点光标改成十字形,当失去焦点时,按空格键切换回来。
This commit is contained in:
parent
3ba3d328b8
commit
101c929f15
110
CHANGELOG.md
110
CHANGELOG.md
@ -1,5 +1,115 @@
|
||||
# NavisworksTransport 变更日志
|
||||
|
||||
## [0.10.0] - 2025-09-06
|
||||
|
||||
### 🎯 路径编辑用户体验重大提升 - 工具切换与视觉反馈优化
|
||||
|
||||
#### 核心功能突破
|
||||
|
||||
**🔥 智能工具切换系统**
|
||||
|
||||
- **十字光标精确指示**
|
||||
- PathClickToolPlugin返回Cursor.Measure,提供清晰的十字光标视觉反馈
|
||||
- 路径点选择时显示专业的精确定位光标
|
||||
- 告别默认箭头光标的模糊体验,明确当前处于路径编辑模式
|
||||
|
||||
- **空格键快速切换**
|
||||
- 实现一键切换:从导航模式瞬间回到路径编辑模式
|
||||
- 智能检测当前工具状态,只在需要时执行切换操作
|
||||
- 支持所有路径编辑状态:Creating、AddingPoints、EditingPoint
|
||||
|
||||
**🔥 工具状态管理重构**
|
||||
|
||||
- **准确的状态检测机制**
|
||||
- ReactivateToolPlugin改为检查实际Tool.Value而非内部标志
|
||||
- 强制重置_isToolPluginActive标志,确保完整的工具重新激活
|
||||
- 解决导航工具覆盖后的状态同步问题
|
||||
|
||||
- **完整的工具重置流程**
|
||||
- ActivateToolPlugin统一使用Tool.None进行工具状态重置
|
||||
- 先重置再设置:Tool.None → SetCustomToolPlugin → 十字光标显示
|
||||
- 与DeactivateToolPlugin保持一致的重置逻辑
|
||||
|
||||
#### 重大技术突破
|
||||
|
||||
**🔧 PathInputMonitor架构简化**
|
||||
|
||||
- **单一职责优化**:
|
||||
- 移除重复的鼠标点击处理逻辑,避免与PathClickToolPlugin冲突
|
||||
- PathInputMonitor专注于空格键切换功能
|
||||
- PathClickToolPlugin负责所有鼠标点击处理
|
||||
- 消除工具间的交互干扰和重复处理
|
||||
|
||||
- **导航操作保护**:
|
||||
- 用户使用导航工具时,点击操作专用于导航而非路径编辑
|
||||
- 避免在旋转、平移等导航操作中误触路径点添加
|
||||
- 明确分离导航操作与路径编辑操作的边界
|
||||
|
||||
**🔧 ClashDetective碰撞检测API重构**
|
||||
|
||||
- **标准API迁移**:
|
||||
- 完全使用Navisworks官方ClashDetective API替代自制碰撞算法
|
||||
- 重构ClashDetectiveIntegration使用标准Search和DocumentClash API
|
||||
- 提升碰撞检测的准确性和性能表现
|
||||
|
||||
- **分组管理增强**:
|
||||
- 新增碰撞分组功能,支持按类型、区域、时间等维度组织碰撞结果
|
||||
- 实现批量碰撞测试管理,提升大型项目的碰撞分析效率
|
||||
- 集成Navisworks原生测试管理机制,确保结果可靠性
|
||||
|
||||
#### 用户体验革命
|
||||
|
||||
**🔧 流畅的工作流设计**
|
||||
|
||||
- **直观的操作模式**:
|
||||
1. 路径编辑开始 → 自动显示十字光标
|
||||
2. 使用导航工具 → 保持导航光标,点击用于导航
|
||||
3. 按空格键 → 瞬间切换回十字光标,继续路径编辑
|
||||
|
||||
- **视觉状态反馈**:
|
||||
- 十字光标:明确指示当前可进行路径点选择
|
||||
- 导航光标:保持原生Navisworks导航体验
|
||||
- 状态切换:按空格键看到即时的光标变化
|
||||
|
||||
**🔧 零干扰导航体验**
|
||||
|
||||
- **导航操作保护**:
|
||||
- 旋转、平移、缩放等操作不会意外触发路径编辑
|
||||
- 用户可在路径编辑过程中自由使用导航功能
|
||||
- 导航和编辑状态明确分离,避免功能冲突
|
||||
|
||||
### 技术架构成果
|
||||
|
||||
**架构质量提升**
|
||||
|
||||
- **工具管理统一化**:建立清晰的工具状态管理机制,消除状态不一致问题
|
||||
- **职责分离优化**:各组件专注单一职责,减少耦合和冲突
|
||||
- **标准API集成**:使用Navisworks官方API,提升系统稳定性和兼容性
|
||||
|
||||
**用户体验突破**
|
||||
|
||||
- **操作直观性**:通过视觉反馈让用户清晰了解当前工具状态
|
||||
- **工作流顺畅性**:空格键快速切换,不中断用户思路
|
||||
- **功能边界清晰**:导航和编辑功能明确分工,避免误操作
|
||||
|
||||
### 验证结果 ✅
|
||||
|
||||
- ✅ 十字光标正确显示,提供清晰的路径编辑视觉指示
|
||||
- ✅ 空格键切换功能完美工作,从导航模式瞬间回到编辑模式
|
||||
- ✅ 导航操作不受干扰,用户可正常旋转、平移、缩放模型
|
||||
- ✅ 工具状态检测准确,避免状态不一致导致的功能异常
|
||||
- ✅ ClashDetective API重构完成,碰撞检测更准确更可靠
|
||||
- ✅ 分组管理功能正常,支持复杂项目的碰撞分析需求
|
||||
|
||||
### 技术里程碑
|
||||
|
||||
- **用户体验设计**:从功能实现到体验优化的转型,建立专业级的交互设计
|
||||
- **架构简化重构**:消除冗余组件和重复逻辑,建立清晰的系统边界
|
||||
- **标准API集成**:从自制算法到官方API的升级,提升系统可靠性
|
||||
- **工具状态管理**:建立完整的工具生命周期管理机制
|
||||
|
||||
---
|
||||
|
||||
## [0.9.0] - 2025-09-04
|
||||
|
||||
### 🎯 核心架构重构与性能优化突破 - 代码解耦与搜索引擎优化
|
||||
|
||||
@ -1 +1 @@
|
||||
0.9.0
|
||||
0.10.0
|
||||
|
||||
@ -1645,3 +1645,112 @@ using Autodesk.Navisworks.Api.Controls;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Tool Enumeration
|
||||
|
||||
Member name Description
|
||||
None No active tool
|
||||
Select Select
|
||||
SelectBox Select Box
|
||||
RedlineFreehand Redline Freehand
|
||||
RedlineLine Redline Line
|
||||
RedlineEllipse Redline Ellipse
|
||||
RedlineCloud Redline Cloud
|
||||
RedlineLineString Redline Line String
|
||||
RedlineTag Redline Tag
|
||||
RedlineText Redline Text
|
||||
RedlineErase Redline Erase
|
||||
RedlineArrow Redline Arrow
|
||||
MeasurePointToPoint Measure Point To Point
|
||||
MeasurePointToMultiplePoints Measure Point To Multiple Points
|
||||
MeasurePointLine Measure Point Line
|
||||
MeasureAccumulate Measure Accumulate
|
||||
MeasureAngle Measure Angle
|
||||
MeasureArea Measure Area
|
||||
MeasureSingle
|
||||
BasicViewObjectWheel Basic View Object Wheel
|
||||
BasicTourBuildingWheel Basic Tour Building Wheel
|
||||
FullNavigationWheel Full Navigation Wheel
|
||||
MiniViewObjectWheel Mini View Object Wheel
|
||||
MiniTourBuildingWheel Mini Tour Building Wheel
|
||||
MiniFullNavigationWheel Mini Full Navigation Wheel
|
||||
Full2DNavigationWheel Full 2D Navigation Wheel
|
||||
CommonPan Pan common across all Autodesk products
|
||||
CommonZoom Zoom common across all Autodesk products
|
||||
CommonZoomWindow Zoom Window common across all Autodesk products
|
||||
CommonOrbit Orbit common across all Autodesk products
|
||||
CommonFreeOrbit Free Orbit common across all Autodesk products
|
||||
CommonConstrainedOrbit Constrained Orbit common across all Autodesk products
|
||||
CommonLookAt Look At common across all Autodesk products
|
||||
CommonLookAround Look Around common across all Autodesk products
|
||||
CommonWalk Walk common across all Autodesk products
|
||||
CommonCenter Center common across all Autodesk products
|
||||
NavigateFixed Camera fixed in place
|
||||
NavigateFreeLookAround Classic Navisworks Free Look Around (Swivel)
|
||||
NavigateFreeOrbit Classic Navisworks Free Orbit (Examine)
|
||||
NavigateWalk Classic Navisworks Walk
|
||||
NavigateFly Classic Navisworks Fly
|
||||
NavigateConstrainedOrbit Classic Navisworks Constrained Orbit (Turntable)
|
||||
NavigateZoom Classic Navisworks Zoom
|
||||
NavigatePan Classic Navisworks Pan
|
||||
NavigateConstrainedPan Classic Navisworks Constrained Pan
|
||||
NavigateLookAround Clasic Navisworks Look Around (Swivel)
|
||||
NavigateOrbit Classic Navisworks Orbit
|
||||
NavigateZoomWindow Classic Navisworks Zoom Window (Zoom Box)
|
||||
CustomToolPlugin Functionality is provided by a ToolPlugin
|
||||
|
||||
|
||||
### Cursor枚举成员:
|
||||
|
||||
| 成员名称 | 描述 |
|
||||
|-----------------|----------------------------|
|
||||
| Unhandled | 特殊情况。如果已经处理则由GetCursor()返回 |
|
||||
| Handled | 已处理光标 |
|
||||
| Walk | 行走光标 |
|
||||
| Fly | 飞行光标 |
|
||||
| Orbit | 环绕光标 |
|
||||
| Swivel | 旋转光标 |
|
||||
| Examine | 检查光标 |
|
||||
| Pan | 平移光标 |
|
||||
| Zoom | 缩放光标 |
|
||||
| Turntable | 转盘光标 |
|
||||
| Focus | 聚焦光标 |
|
||||
| Application | 应用程序光标 |
|
||||
| ZoomBox | 缩放框光标 |
|
||||
| Measure | 测量光标(十字线) |
|
||||
| HyperHand | 超级手势光标 |
|
||||
| PanWorld | 世界平移光标 |
|
||||
| Roll | 滚动光标 |
|
||||
| Stop | 停止光标 |
|
||||
| MeasureEdge | 测量边缘光标 |
|
||||
| MeasureVertex | 测量顶点光标 |
|
||||
| Redline | 红线光标 |
|
||||
| Erase | 擦除光标 |
|
||||
| Wheel | 滚轮光标 |
|
||||
| MarkupSelection | 标记选择光标 |
|
||||
| MarkupSnapping | 标记捕捉光标 |
|
||||
| MarkupEraser | 标记擦除光标 |
|
||||
| MarkupQuickPick | 标记快速选择光标 |
|
||||
| MarkupBucket | 标记桶光标 |
|
||||
| MarkupAutoPoly | 标记自动多边形光标 |
|
||||
|
||||
使用方式:
|
||||
|
||||
```csharp
|
||||
public class PathClickToolPlugin : ToolPlugin
|
||||
{
|
||||
....
|
||||
|
||||
/// <summary>
|
||||
/// 重写光标样式,使用捕捉光标提供更好的视觉反馈
|
||||
/// </summary>
|
||||
/// <param name="view">当前视图</param>
|
||||
/// <param name="modifier">键盘修饰键</param>
|
||||
/// <returns>返回捕捉光标</returns>
|
||||
public override Cursor GetCursor(View view, KeyModifiers modifier)
|
||||
{
|
||||
// 使用捕捉光标,提供更好的视觉反馈用于精确路径点选择
|
||||
return Cursor.MarkupSnapping;
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -2,10 +2,15 @@
|
||||
|
||||
## 功能点
|
||||
|
||||
### [2025/09/05]
|
||||
|
||||
1. [x] (功能)把三维视图选点光标改成十字形,当失去焦点时,按空格键切换回来。
|
||||
|
||||
### [2025/09/04]
|
||||
|
||||
1. [x] (代码重构)将节点关系和几何体关系代码从动画管理器中抽取出来,形成工具类
|
||||
2. [ ] (BUG) 多层建筑动画碰撞有结果,但ClashDetective检测不出来
|
||||
2. [ ] (BUG) 特殊的运动物体(树)动画碰撞有结果(正确),但ClashDetective检测不出来(可能是因为树只是线,不是solid类型)
|
||||
3. [x] (优化) 用ClashDetective API的标准用法重构碰撞检测部分,增加了碰撞分组
|
||||
|
||||
### [2025/09/03]
|
||||
|
||||
|
||||
@ -105,5 +105,17 @@ namespace NavisworksTransport
|
||||
// 暂时不处理鼠标移动事件,避免日志过多
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重写光标样式,使用捕捉光标提供更好的视觉反馈
|
||||
/// </summary>
|
||||
/// <param name="view">当前视图</param>
|
||||
/// <param name="modifier">键盘修饰键</param>
|
||||
/// <returns>返回捕捉光标</returns>
|
||||
public override Cursor GetCursor(View view, KeyModifiers modifier)
|
||||
{
|
||||
// 使用测量光标(十字线),提供更好的视觉反馈用于精确路径点选择
|
||||
return Cursor.Measure;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14,67 +14,14 @@ namespace NavisworksTransport
|
||||
{
|
||||
/// <summary>
|
||||
/// 鼠标按下事件处理
|
||||
/// 在路径编辑模式下捕获鼠标点击,即使ToolPlugin失活也能响应
|
||||
/// 不处理鼠标点击,让PathClickToolPlugin和导航工具正常工作
|
||||
/// </summary>
|
||||
public override bool MouseDown(View view, KeyModifiers modifiers, ushort button, int x, int y, double timeOffset)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 只处理左键点击
|
||||
if (button != 1) return false;
|
||||
|
||||
// 获取PathPlanningManager实例
|
||||
var pathManager = PathPlanningManager.GetActivePathManager();
|
||||
if (pathManager == null) return false;
|
||||
|
||||
// 只在路径编辑模式下处理
|
||||
if (pathManager.PathEditState == PathEditState.AddingPoints ||
|
||||
pathManager.PathEditState == PathEditState.EditingPoint)
|
||||
{
|
||||
LogManager.WriteLog("[InputMonitor] 检测到路径编辑模式下的鼠标点击");
|
||||
|
||||
// 如果ToolPlugin未激活,自动重新激活
|
||||
if (!pathManager.IsToolPluginActive)
|
||||
{
|
||||
LogManager.WriteLog("[InputMonitor] ToolPlugin未激活,自动重新激活");
|
||||
pathManager.ReactivateToolPlugin();
|
||||
|
||||
// 给用户一个视觉反馈
|
||||
var uiStateManager = UIStateManager.Instance;
|
||||
uiStateManager?.QueueUIUpdate(() =>
|
||||
{
|
||||
// 这里可以添加状态栏提示或其他UI反馈
|
||||
});
|
||||
}
|
||||
|
||||
// 获取精确的3D坐标
|
||||
PickItemResult itemResult = view.PickItemFromPoint(x, y);
|
||||
if (itemResult != null)
|
||||
{
|
||||
LogManager.WriteLog($"[InputMonitor] 获取到3D坐标: ({itemResult.Point.X:F3}, {itemResult.Point.Y:F3}, {itemResult.Point.Z:F3})");
|
||||
|
||||
// 触发PathClickToolPlugin的事件,复用现有的完整处理逻辑
|
||||
// 这确保了自动路径、手动路径的所有模式都能正常工作
|
||||
PathClickToolPlugin.TriggerMouseClicked(this, itemResult);
|
||||
|
||||
LogManager.WriteLog("[InputMonitor] 已触发PathClickToolPlugin事件");
|
||||
return true; // 返回true表示已处理,阻止其他处理程序
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.WriteLog("[InputMonitor] 未点击到有效对象");
|
||||
}
|
||||
|
||||
return false; // 让其他处理程序继续处理
|
||||
}
|
||||
|
||||
return false; // 不在编辑模式,不处理
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.WriteLog($"[InputMonitor] 处理鼠标点击异常: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
// 不处理鼠标点击,让PathClickToolPlugin和导航工具正常工作
|
||||
// PathClickToolPlugin会在CustomToolPlugin模式下处理点击
|
||||
// 导航工具会在导航模式下处理点击
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -98,13 +45,17 @@ namespace NavisworksTransport
|
||||
{
|
||||
var pathManager = PathPlanningManager.GetActivePathManager();
|
||||
if (pathManager != null &&
|
||||
(pathManager.PathEditState == PathEditState.AddingPoints ||
|
||||
pathManager.PathEditState == PathEditState.EditingPoint) &&
|
||||
!pathManager.IsToolPluginActive)
|
||||
(pathManager.PathEditState == PathEditState.Creating ||
|
||||
pathManager.PathEditState == PathEditState.AddingPoints ||
|
||||
pathManager.PathEditState == PathEditState.EditingPoint))
|
||||
{
|
||||
LogManager.WriteLog("[InputMonitor] 用户按空格键,重新激活工具");
|
||||
pathManager.ReactivateToolPlugin();
|
||||
return true;
|
||||
var currentTool = Application.MainDocument.Tool.Value;
|
||||
if (currentTool != Tool.CustomToolPlugin)
|
||||
{
|
||||
LogManager.WriteLog($"[InputMonitor] 用户按空格键,当前工具为{currentTool},重新激活工具");
|
||||
pathManager.ReactivateToolPlugin();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2282,6 +2282,13 @@ namespace NavisworksTransport
|
||||
|
||||
// 4. 设置为活动工具
|
||||
LogManager.WriteLog("[ToolPlugin] 步骤4: 设置为活动工具");
|
||||
|
||||
// 先重置工具状态,清除可能的导航工具
|
||||
// 这一步很重要,确保从导航工具(如Pan、Orbit)切换回自定义工具
|
||||
Application.MainDocument.Tool.Value = Tool.None;
|
||||
LogManager.WriteLog("[ToolPlugin] 已重置工具状态为None");
|
||||
|
||||
// 然后设置自定义工具插件
|
||||
Application.MainDocument.Tool.SetCustomToolPlugin(loadedPlugin);
|
||||
LogManager.WriteLog("[ToolPlugin] ✓ 工具设置成功");
|
||||
|
||||
@ -2317,28 +2324,40 @@ namespace NavisworksTransport
|
||||
{
|
||||
try
|
||||
{
|
||||
// 只有在编辑模式且工具未激活时才重新激活
|
||||
if (!_isToolPluginActive &&
|
||||
(PathEditState == PathEditState.AddingPoints ||
|
||||
// 检查当前状态和实际工具值
|
||||
if ((PathEditState == PathEditState.Creating ||
|
||||
PathEditState == PathEditState.AddingPoints ||
|
||||
PathEditState == PathEditState.EditingPoint))
|
||||
{
|
||||
LogManager.WriteLog("[ReactivateToolPlugin] 开始重新激活ToolPlugin");
|
||||
|
||||
// 调用现有的激活方法,但不重复订阅事件
|
||||
if (ActivateToolPlugin(false))
|
||||
// 检查当前工具是否为自定义工具,如果不是则需要重新激活
|
||||
var currentTool = Application.MainDocument.Tool.Value;
|
||||
if (currentTool != Tool.CustomToolPlugin)
|
||||
{
|
||||
LogManager.WriteLog("[ReactivateToolPlugin] ToolPlugin重新激活成功");
|
||||
RaiseStatusChanged("工具已重新激活", PathPlanningStatusType.Info);
|
||||
LogManager.WriteLog($"[ReactivateToolPlugin] 当前工具为{currentTool},开始重新激活ToolPlugin");
|
||||
|
||||
// 重要:先将激活标志设置为false,强制执行完整的激活流程
|
||||
_isToolPluginActive = false;
|
||||
|
||||
// 调用现有的激活方法,但不重复订阅事件
|
||||
if (ActivateToolPlugin(false))
|
||||
{
|
||||
LogManager.WriteLog("[ReactivateToolPlugin] ToolPlugin重新激活成功");
|
||||
RaiseStatusChanged("工具已重新激活", PathPlanningStatusType.Info);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.WriteLog("[ReactivateToolPlugin] ToolPlugin重新激活失败");
|
||||
RaiseErrorOccurred("无法重新激活编辑工具");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.WriteLog("[ReactivateToolPlugin] ToolPlugin重新激活失败");
|
||||
RaiseErrorOccurred("无法重新激活编辑工具");
|
||||
LogManager.WriteLog("[ReactivateToolPlugin] 当前已是CustomToolPlugin,无需重新激活");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.WriteLog($"[ReactivateToolPlugin] 跳过重新激活 - IsToolPluginActive: {_isToolPluginActive}, PathEditState: {PathEditState}");
|
||||
LogManager.WriteLog($"[ReactivateToolPlugin] 跳过重新激活 - PathEditState: {PathEditState}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user