diff --git a/IFLOW.md b/IFLOW.md index 6553336..39b6197 100644 --- a/IFLOW.md +++ b/IFLOW.md @@ -350,6 +350,31 @@ msiexec /i NavisworksTransport.Setup.msi /qn /l*v install.log - **对外输出**: 转换为米(m)单位(用户界面、日志、数据库存储等) - **单位转换**: 使用 `UnitsConverter.ConvertToMeters()` 和 `UnitsConverter.ConvertFromMeters()` 进行转换 - **向后兼容**: 不写回退和向后兼容代码,出错即抛异常 +- **代码复用**: 优先使用现有的辅助方法和工具类,避免重复代码。例如: + - 查找物流属性模型时,使用 `CategoryAttributeManager.GetLogisticsItemsByType()` 而不是手动创建 Search 对象 + - 提取几何数据时,使用 `GeometryHelper` 中的现有方法 + - 计算距离时,使用 `GeometryHelper.CalculatePointDistance()` 等工具方法 +- **车辆尺寸与XYZ轴关系** (关键约定): + - **X轴**: 长度方向(车辆前进方向,车头到车尾) + - **Y轴**: 宽度方向(车辆侧面,左右两侧) + - **Z轴**: 高度方向(垂直方向) + - **朝向规则**: 车辆沿路径移动时,X轴(长度方向)指向路径前进方向 + - **尺寸参数**: `VehicleLength` = X轴尺寸,`VehicleWidth` = Y轴尺寸,`VehicleHeight` = Z轴尺寸 + - **通行空间计算**(路径周围的可通行区域,沿路径延伸的"管道"): + - `passageAlongPath`: 沿路径方向的长度 = 路径本身的长度(渲染时使用) + - `passageAcrossPath`: 垂直于路径方向的截面尺寸1 + - `passageNormalToPath`: 垂直于路径方向的截面尺寸2 + - **水平路径**(地面、空轨)截面:使用车辆的**宽度**和**高度** + - `passageAcrossPath` = 车辆宽度(Y轴)+ 2×间隙 + - `passageNormalToPath` = 车辆高度(Z轴)+ 间隙 + - **垂直路径**(吊装)截面:使用车辆的**宽度**和**长度** + - `passageAcrossPath` = 车辆宽度(Y轴)+ 2×间隙 + - `passageNormalToPath` = 车辆长度(X轴)+ 2×间隙 +- **单位系统**: + - **内部计算**: 统一使用模型单位(避免频繁转换,提高性能) + - **对外输出**: 转换为米(m)单位(用户界面、日志、数据库存储等) + - **单位转换**: 使用 `UnitsConverter.ConvertToMeters()` 和 `UnitsConverter.ConvertFromMeters()` 进行转换 +- **向后兼容**: 不写回退和向后兼容代码,出错即抛异常 - **代码复用**: 优先使用现有的辅助方法和工具类,避免重复代码。例如: - 查找物流属性模型时,使用 `CategoryAttributeManager.GetLogisticsItemsByType()` 而不是手动创建 Search 对象 - 提取几何数据时,使用 `GeometryHelper` 中的现有方法 diff --git a/src/Core/VirtualVehicleManager.cs b/src/Core/VirtualVehicleManager.cs index df75875..d770780 100644 --- a/src/Core/VirtualVehicleManager.cs +++ b/src/Core/VirtualVehicleManager.cs @@ -258,14 +258,14 @@ namespace NavisworksTransport.Core // 🔥 对于虚拟车辆,直接应用缩放比例(不动态读取当前尺寸) // 原因:虚拟车辆可能被旋转,导致包围盒尺寸不准确 // 单位立方体是 0.01m × 0.01m × 0.01m - // X方向 = 车辆宽度,Y方向 = 车辆长度,Z方向 = 车辆高度 + // X方向 = 车辆长度(前进方向),Y方向 = 车辆宽度(侧面),Z方向 = 车辆高度 double baseSizeMeters = 0.01; - double scaleX = widthMeters / baseSizeMeters; // X方向 = 车辆宽度 - double scaleY = lengthMeters / baseSizeMeters; // Y方向 = 车辆长度 + double scaleX = lengthMeters / baseSizeMeters; // X方向 = 车辆长度(前进方向) + double scaleY = widthMeters / baseSizeMeters; // Y方向 = 车辆宽度(侧面) double scaleZ = heightMeters / baseSizeMeters; // Z方向 = 车辆高度 - LogManager.Info($"目标尺寸: {lengthMeters:F2}m × {widthMeters:F2}m × {heightMeters:F2}m"); - LogManager.Info($"缩放比例: X={scaleX:F2}, Y={scaleY:F2}, Z={scaleZ:F2}"); + LogManager.Info($"目标尺寸: 长度={lengthMeters:F2}m, 宽度={widthMeters:F2}m, 高度={heightMeters:F2}m"); + LogManager.Info($"缩放比例: X(长度)={scaleX:F2}, Y(宽度)={scaleY:F2}, Z(高度)={scaleZ:F2}"); // 使用Transform3DComponents进行缩放 // 获取当前模型的变换并分解 diff --git a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs index f81a29d..f8f6b3a 100644 --- a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs +++ b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs @@ -2437,32 +2437,32 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (UseVirtualVehicle) { - // 虚拟车辆的xy定义:X方向 = 宽度(1.0m),Y方向 = 长度(1.2m),Z方向 = 高度(2.0m) + // 虚拟车辆的xyz定义:X方向 = 长度(前进方向),Y方向 = 宽度(侧面),Z方向 = 高度 if (CurrentPathRoute.PathType == NavisworksTransport.PathType.Hoisting) { // 吊装路径:通行空间四面都加检测间隙 - passageAcrossPath = VirtualVehicleWidth + 2 * safetyMargin; // X方向 + 2*间隙(垂直于路径方向) - passageNormalToPath = VirtualVehicleLength + 2 * safetyMargin; // Y方向 + 2*间隙(法线方向) - passageAlongPath = VirtualVehicleHeight + 2 * safetyMargin; // Z方向 + 2*间隙(沿路径方向) - LogManager.Info($"[通行空间可视化] 吊装路径使用虚拟车辆尺寸: X方向={VirtualVehicleWidth:F2}m, Y方向={VirtualVehicleLength:F2}m, Z方向={VirtualVehicleHeight:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m"); + passageAcrossPath = VirtualVehicleLength + 2 * safetyMargin; // X方向(长度)+ 2*间隙(垂直于路径方向) + passageNormalToPath = VirtualVehicleWidth + 2 * safetyMargin; // Y方向(宽度)+ 2*间隙(法线方向) + passageAlongPath = VirtualVehicleHeight + 2 * safetyMargin; // Z方向(高度)+ 2*间隙(沿路径方向) + LogManager.Info($"[通行空间可视化] 吊装路径使用虚拟车辆尺寸: X方向(长度)={VirtualVehicleLength:F2}m, Y方向(宽度)={VirtualVehicleWidth:F2}m, Z方向(高度)={VirtualVehicleHeight:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m"); } else if (CurrentPathRoute.PathType == NavisworksTransport.PathType.Ground) { - // 地面路径:物体的宽度方向(X轴)朝向路径方向 - // 通行空间沿路径方向 = X方向尺寸,垂直于路径方向 = Y方向尺寸,高度上方加间隙(下方不需要,因为有地面) - passageAcrossPath = VirtualVehicleLength + 2 * safetyMargin; // Y方向 + 2*间隙(垂直于路径方向) - passageNormalToPath = VirtualVehicleHeight + safetyMargin; // Z方向 + 间隙(法线方向,只有上方) - passageAlongPath = VirtualVehicleWidth; // X方向(沿路径方向) - LogManager.Info($"[通行空间可视化] 地面路径使用虚拟车辆尺寸: X方向={VirtualVehicleWidth:F2}m, Y方向={VirtualVehicleLength:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m"); + // 地面路径:物体的长度方向(X轴,前进方向)朝向路径方向 + // 通行空间沿路径方向 = X方向尺寸(长度),垂直于路径方向 = Y方向尺寸(宽度),高度上方加间隙(下方不需要,因为有地面) + passageAcrossPath = VirtualVehicleWidth + 2 * safetyMargin; // Y方向(宽度)+ 2*间隙(垂直于路径方向) + passageNormalToPath = VirtualVehicleHeight + safetyMargin; // Z方向(高度)+ 间隙(法线方向,只有上方) + passageAlongPath = VirtualVehicleLength; // X方向(长度,沿路径方向) + LogManager.Info($"[通行空间可视化] 地面路径使用虚拟车辆尺寸: X方向(长度)={VirtualVehicleLength:F2}m, Y方向(宽度)={VirtualVehicleWidth:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m"); } else // Rail { - // 空轨路径:物体的宽度方向(X轴)朝向路径方向 - // 通行空间沿路径方向 = X方向尺寸,垂直于路径方向 = Y方向尺寸,高度上下都加间隙(在空中) - passageAcrossPath = VirtualVehicleLength + 2 * safetyMargin; // Y方向 + 2*间隙(垂直于路径方向) - passageNormalToPath = VirtualVehicleHeight + 2 * safetyMargin; // Z方向 + 2*间隙(法线方向,上下都加) - passageAlongPath = VirtualVehicleWidth; // X方向(沿路径方向) - LogManager.Info($"[通行空间可视化] 空轨路径使用虚拟车辆尺寸: X方向={VirtualVehicleWidth:F2}m, Y方向={VirtualVehicleLength:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m"); + // 空轨路径:物体的长度方向(X轴,前进方向)朝向路径方向 + // 通行空间沿路径方向 = X方向尺寸(长度),垂直于路径方向 = Y方向尺寸(宽度),高度上下都加间隙(在空中) + passageAcrossPath = VirtualVehicleWidth + 2 * safetyMargin; // Y方向(宽度)+ 2*间隙(垂直于路径方向) + passageNormalToPath = VirtualVehicleHeight + 2 * safetyMargin; // Z方向(高度)+ 2*间隙(法线方向,上下都加) + passageAlongPath = VirtualVehicleLength; // X方向(长度,沿路径方向) + LogManager.Info($"[通行空间可视化] 空轨路径使用虚拟车辆尺寸: X方向(长度)={VirtualVehicleLength:F2}m, Y方向(宽度)={VirtualVehicleWidth:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m"); } } else if (SelectedAnimatedObject != null) @@ -2472,39 +2472,39 @@ namespace NavisworksTransport.UI.WPF.ViewModels double metersToModelUnits = UnitsConverter.GetMetersToUnitsConversionFactor(); // 将模型单位转换为米 - double sizeX = (bbox.Max.X - bbox.Min.X) / metersToModelUnits; - double sizeY = (bbox.Max.Y - bbox.Min.Y) / metersToModelUnits; - double sizeZ = (bbox.Max.Z - bbox.Min.Z) / metersToModelUnits; + double sizeX = (bbox.Max.X - bbox.Min.X) / metersToModelUnits; // X方向 = 长度(前进方向) + double sizeY = (bbox.Max.Y - bbox.Min.Y) / metersToModelUnits; // Y方向 = 宽度(侧面) + double sizeZ = (bbox.Max.Z - bbox.Min.Z) / metersToModelUnits; // Z方向 = 高度 // 根据路径类型确定通行空间的尺寸 if (CurrentPathRoute.PathType == NavisworksTransport.PathType.Hoisting) { // 吊装路径(严格垂直路径): // 通行空间四面都加检测间隙 - passageAcrossPath = sizeX + 2 * safetyMargin; // X方向 + 2*间隙(垂直于路径方向) - passageNormalToPath = sizeY + 2 * safetyMargin; // Y方向 + 2*间隙(法线方向) - passageAlongPath = sizeZ + 2 * safetyMargin; // Z方向 + 2*间隙(沿路径方向) - LogManager.Info($"[通行空间可视化] 吊装路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): X方向={sizeX:F2}m, Y方向={sizeY:F2}m, Z方向={sizeZ:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m"); + passageAcrossPath = sizeX + 2 * safetyMargin; // X方向(长度)+ 2*间隙(垂直于路径方向) + passageNormalToPath = sizeY + 2 * safetyMargin; // Y方向(宽度)+ 2*间隙(法线方向) + passageAlongPath = sizeZ + 2 * safetyMargin; // Z方向(高度)+ 2*间隙(沿路径方向) + LogManager.Info($"[通行空间可视化] 吊装路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): X方向(长度)={sizeX:F2}m, Y方向(宽度)={sizeY:F2}m, Z方向(高度)={sizeZ:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m"); } else if (CurrentPathRoute.PathType == NavisworksTransport.PathType.Ground) { // 地面路径(可能有坡度): - // 物体的宽度方向(X轴)朝向路径方向 - // 通行空间沿路径方向 = X方向尺寸,垂直于路径方向 = Y方向尺寸,高度上方加间隙(下方不需要,因为有地面) - passageAcrossPath = sizeY + 2 * safetyMargin; // Y方向 + 2*间隙(垂直于路径方向) - passageNormalToPath = sizeZ + safetyMargin; // Z方向 + 间隙(法线方向,只有上方) - passageAlongPath = sizeX; // X方向(沿路径方向) - LogManager.Info($"[通行空间可视化] 地面路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): X方向={sizeX:F2}m, Y方向={sizeY:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m"); + // 物体的长度方向(X轴,前进方向)朝向路径方向 + // 通行空间沿路径方向 = X方向尺寸(长度),垂直于路径方向 = Y方向尺寸(宽度),高度上方加间隙(下方不需要,因为有地面) + passageAcrossPath = sizeY + 2 * safetyMargin; // Y方向(宽度)+ 2*间隙(垂直于路径方向) + passageNormalToPath = sizeZ + safetyMargin; // Z方向(高度)+ 间隙(法线方向,只有上方) + passageAlongPath = sizeX; // X方向(长度,沿路径方向) + LogManager.Info($"[通行空间可视化] 地面路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): X方向(长度)={sizeX:F2}m, Y方向(宽度)={sizeY:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m"); } else // Rail { // 空轨路径(可能有坡度): - // 物体的宽度方向(X轴)朝向路径方向 - // 通行空间沿路径方向 = X方向尺寸,垂直于路径方向 = Y方向尺寸,高度上下都加间隙(在空中) - passageAcrossPath = sizeY + 2 * safetyMargin; // Y方向 + 2*间隙(垂直于路径方向) - passageNormalToPath = sizeZ + 2 * safetyMargin; // Z方向 + 2*间隙(法线方向,上下都加) - passageAlongPath = sizeX; // X方向(沿路径方向) - LogManager.Info($"[通行空间可视化] 空轨路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): X方向={sizeX:F2}m, Y方向={sizeY:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m"); + // 物体的长度方向(X轴,前进方向)朝向路径方向 + // 通行空间沿路径方向 = X方向尺寸(长度),垂直于路径方向 = Y方向尺寸(宽度),高度上下都加间隙(在空中) + passageAcrossPath = sizeY + 2 * safetyMargin; // Y方向(宽度)+ 2*间隙(垂直于路径方向) + passageNormalToPath = sizeZ + 2 * safetyMargin; // Z方向(高度)+ 2*间隙(法线方向,上下都加) + passageAlongPath = sizeX; // X方向(长度,沿路径方向) + LogManager.Info($"[通行空间可视化] 空轨路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): X方向(长度)={sizeX:F2}m, Y方向(宽度)={sizeY:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m"); } } else diff --git a/src/UI/WPF/ViewModels/PathEditingViewModel.cs b/src/UI/WPF/ViewModels/PathEditingViewModel.cs index fc83e9c..b555662 100644 --- a/src/UI/WPF/ViewModels/PathEditingViewModel.cs +++ b/src/UI/WPF/ViewModels/PathEditingViewModel.cs @@ -2586,20 +2586,20 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (pathType == PathType.Hoisting) { // 吊装路径:通行空间四面都加检测间隙 - passageAcrossPath = VehicleWidth + 2 * SafetyMargin; // X方向 + 2*间隙(垂直于路径方向) - passageNormalToPath = VehicleLength + 2 * SafetyMargin; // Y方向 + 2*间隙(法线方向) + passageAcrossPath = VehicleLength + 2 * SafetyMargin; // X方向(长度)+ 2*间隙(垂直于路径方向) + passageNormalToPath = VehicleWidth + 2 * SafetyMargin; // Y方向(宽度)+ 2*间隙(法线方向) } else if (pathType == PathType.Rail) { // 空轨路径:高度上下都加间隙 - passageAcrossPath = VehicleLength + 2 * SafetyMargin; // Y方向 + 2*间隙(垂直于路径方向) - passageNormalToPath = VehicleHeight + 2 * SafetyMargin; // Z方向 + 2*间隙(法线方向) + passageAcrossPath = VehicleWidth + 2 * SafetyMargin; // Y方向(宽度)+ 2*间隙(垂直于路径方向) + passageNormalToPath = VehicleHeight + 2 * SafetyMargin; // Z方向(高度)+ 2*间隙(法线方向) } else // Ground { // 地面路径:高度只有上方加间隙 - passageAcrossPath = VehicleLength + 2 * SafetyMargin; // Y方向 + 2*间隙(垂直于路径方向) - passageNormalToPath = VehicleHeight + SafetyMargin; // Z方向 + 间隙(法线方向,只有上方) + passageAcrossPath = VehicleWidth + 2 * SafetyMargin; // Y方向(宽度)+ 2*间隙(垂直于路径方向) + passageNormalToPath = VehicleHeight + SafetyMargin; // Z方向(高度)+ 间隙(法线方向,只有上方) } // 设置通行空间参数到渲染插件