Fix assembly reference rod and start-point path creation

This commit is contained in:
tian 2026-03-19 23:12:49 +08:00
parent a55ef42f71
commit 9adf9b5baf
4 changed files with 221 additions and 78 deletions

Binary file not shown.

View File

@ -1,58 +1,104 @@
# unit cylinder for assembly reference rod # unit cylinder for assembly reference rod
# dimensions: length 0.01m along +X, diameter 0.01m # dimensions: length 1.0 along +X, diameter 1.0
# centered at origin # centered at origin
# when Navisworks imports OBJ as centimeters, generated NWC becomes 0.01m base size
o unit_cylinder o unit_cylinder
v -0.005000 0.000000 0.000000 v -0.500000 0.000000 0.000000
v -0.005000 0.005000 0.000000 v 0.500000 0.000000 0.000000
v -0.005000 0.004330 0.002500 v -0.500000 0.500000 0.000000
v -0.005000 0.002500 0.004330 v -0.500000 0.482963 0.129410
v -0.005000 0.000000 0.005000 v -0.500000 0.433013 0.250000
v -0.005000 -0.002500 0.004330 v -0.500000 0.353553 0.353553
v -0.005000 -0.004330 0.002500 v -0.500000 0.250000 0.433013
v -0.005000 -0.005000 0.000000 v -0.500000 0.129410 0.482963
v -0.005000 -0.004330 -0.002500 v -0.500000 0.000000 0.500000
v -0.005000 -0.002500 -0.004330 v -0.500000 -0.129410 0.482963
v -0.005000 0.000000 -0.005000 v -0.500000 -0.250000 0.433013
v -0.005000 0.002500 -0.004330 v -0.500000 -0.353553 0.353553
v -0.005000 0.004330 -0.002500 v -0.500000 -0.433013 0.250000
v 0.005000 0.000000 0.000000 v -0.500000 -0.482963 0.129410
v 0.005000 0.005000 0.000000 v -0.500000 -0.500000 0.000000
v 0.005000 0.004330 0.002500 v -0.500000 -0.482963 -0.129410
v 0.005000 0.002500 0.004330 v -0.500000 -0.433013 -0.250000
v 0.005000 0.000000 0.005000 v -0.500000 -0.353553 -0.353553
v 0.005000 -0.002500 0.004330 v -0.500000 -0.250000 -0.433013
v 0.005000 -0.004330 0.002500 v -0.500000 -0.129410 -0.482963
v 0.005000 -0.005000 0.000000 v -0.500000 0.000000 -0.500000
v 0.005000 -0.004330 -0.002500 v -0.500000 0.129410 -0.482963
v 0.005000 -0.002500 -0.004330 v -0.500000 0.250000 -0.433013
v 0.005000 0.000000 -0.005000 v -0.500000 0.353553 -0.353553
v 0.005000 0.002500 -0.004330 v -0.500000 0.433013 -0.250000
v 0.005000 0.004330 -0.002500 v -0.500000 0.482963 -0.129410
f 2 15 16 v 0.500000 0.500000 0.000000
f 2 16 3 v 0.500000 0.482963 0.129410
f 3 16 17 v 0.500000 0.433013 0.250000
f 3 17 4 v 0.500000 0.353553 0.353553
f 4 17 18 v 0.500000 0.250000 0.433013
f 4 18 5 v 0.500000 0.129410 0.482963
f 5 18 19 v 0.500000 0.000000 0.500000
f 5 19 6 v 0.500000 -0.129410 0.482963
f 6 19 20 v 0.500000 -0.250000 0.433013
f 6 20 7 v 0.500000 -0.353553 0.353553
f 7 20 21 v 0.500000 -0.433013 0.250000
f 7 21 8 v 0.500000 -0.482963 0.129410
f 8 21 22 v 0.500000 -0.500000 0.000000
f 8 22 9 v 0.500000 -0.482963 -0.129410
f 9 22 23 v 0.500000 -0.433013 -0.250000
f 9 23 10 v 0.500000 -0.353553 -0.353553
f 10 23 24 v 0.500000 -0.250000 -0.433013
f 10 24 11 v 0.500000 -0.129410 -0.482963
f 11 24 25 v 0.500000 0.000000 -0.500000
f 11 25 12 v 0.500000 0.129410 -0.482963
f 12 25 26 v 0.500000 0.250000 -0.433013
f 12 26 13 v 0.500000 0.353553 -0.353553
f 13 26 15 v 0.500000 0.433013 -0.250000
f 13 15 2 v 0.500000 0.482963 -0.129410
f 1 3 2 f 3 26 27
f 3 27 4
f 4 27 28
f 4 28 5
f 5 28 29
f 5 29 6
f 6 29 30
f 6 30 7
f 7 30 31
f 7 31 8
f 8 31 32
f 8 32 9
f 9 32 33
f 9 33 10
f 10 33 34
f 10 34 11
f 11 34 35
f 11 35 12
f 12 35 36
f 12 36 13
f 13 36 37
f 13 37 14
f 14 37 38
f 14 38 15
f 15 38 39
f 15 39 16
f 16 39 40
f 16 40 17
f 17 40 41
f 17 41 18
f 18 41 42
f 18 42 19
f 19 42 43
f 19 43 20
f 20 43 44
f 20 44 21
f 21 44 45
f 21 45 22
f 22 45 46
f 22 46 23
f 23 46 47
f 23 47 24
f 24 47 48
f 24 48 25
f 25 48 49
f 25 49 26
f 1 4 3 f 1 4 3
f 1 5 4 f 1 5 4
f 1 6 5 f 1 6 5
@ -63,16 +109,41 @@ f 1 10 9
f 1 11 10 f 1 11 10
f 1 12 11 f 1 12 11
f 1 13 12 f 1 13 12
f 1 2 13 f 1 14 13
f 14 15 16 f 1 15 14
f 14 16 17 f 1 16 15
f 14 17 18 f 1 17 16
f 14 18 19 f 1 18 17
f 14 19 20 f 1 19 18
f 14 20 21 f 1 20 19
f 14 21 22 f 1 21 20
f 14 22 23 f 1 22 21
f 14 23 24 f 1 23 22
f 14 24 25 f 1 24 23
f 14 25 26 f 1 25 24
f 14 26 15 f 1 26 25
f 1 3 26
f 2 27 28
f 2 28 29
f 2 29 30
f 2 30 31
f 2 31 32
f 2 32 33
f 2 33 34
f 2 34 35
f 2 35 36
f 2 36 37
f 2 37 38
f 2 38 39
f 2 39 40
f 2 40 41
f 2 41 42
f 2 42 43
f 2 43 44
f 2 44 45
f 2 45 46
f 2 46 47
f 2 47 48
f 2 48 49
f 2 49 26
f 2 26 27

View File

@ -122,10 +122,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
private ObservableCollection<RailConfigOption<RailPayloadAnchorMode>> _railPayloadAnchorModeOptions; private ObservableCollection<RailConfigOption<RailPayloadAnchorMode>> _railPayloadAnchorModeOptions;
private const double DefaultAssemblyReferenceRodLengthInMeters = 20.0; private const double DefaultAssemblyReferenceRodLengthInMeters = 20.0;
private static readonly double DefaultAssemblyReferenceRodDiameterInMeters = CalculateDefaultAssemblyReferenceRodDiameterInMeters(); private static readonly double DefaultAssemblyReferenceRodDiameterInMeters = CalculateDefaultAssemblyReferenceRodDiameterInMeters();
private const double DefaultAssemblyAnchorVerticalOffsetInMeters = 0.0;
private string _assemblyTerminalObjectName = "未选择"; private string _assemblyTerminalObjectName = "未选择";
private string _assemblyTerminalObjectInfo = "请选择终点处已安装箱体"; private string _assemblyTerminalObjectInfo = "请选择终点处已安装箱体";
private double _assemblyReferenceRodLengthInMeters = DefaultAssemblyReferenceRodLengthInMeters; private double _assemblyReferenceRodLengthInMeters = DefaultAssemblyReferenceRodLengthInMeters;
private double _assemblyReferenceRodDiameterInMeters = DefaultAssemblyReferenceRodDiameterInMeters; private double _assemblyReferenceRodDiameterInMeters = DefaultAssemblyReferenceRodDiameterInMeters;
private double _assemblyAnchorVerticalOffsetInMeters = DefaultAssemblyAnchorVerticalOffsetInMeters;
private string _assemblyStartPointText = "未选择"; private string _assemblyStartPointText = "未选择";
private RailMountMode _assemblyMountMode = RailMountMode.UnderRail; private RailMountMode _assemblyMountMode = RailMountMode.UnderRail;
private RailPayloadAnchorMode _assemblyPayloadAnchorMode = RailPayloadAnchorMode.TopCenter; private RailPayloadAnchorMode _assemblyPayloadAnchorMode = RailPayloadAnchorMode.TopCenter;
@ -374,6 +376,20 @@ namespace NavisworksTransport.UI.WPF.ViewModels
} }
} }
public double AssemblyAnchorVerticalOffsetInMeters
{
get => _assemblyAnchorVerticalOffsetInMeters;
set
{
if (SetProperty(ref _assemblyAnchorVerticalOffsetInMeters, value) && HasAssemblyTerminalObject)
{
RefreshAssemblyTerminalObjectInfo();
RenderAssemblyAnchorMarker();
RefreshAssemblyReferenceRodIfNeeded();
}
}
}
public bool HasAssemblyTerminalObject public bool HasAssemblyTerminalObject
{ {
get => _hasAssemblyTerminalObject; get => _hasAssemblyTerminalObject;
@ -1304,6 +1320,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
HasAssemblyTerminalObject = true; HasAssemblyTerminalObject = true;
AssemblyStartPointText = "未选择"; AssemblyStartPointText = "未选择";
AssemblyTerminalObjectName = ModelItemAnalysisHelper.GetSafeDisplayName(selectedItem); AssemblyTerminalObjectName = ModelItemAnalysisHelper.GetSafeDisplayName(selectedItem);
InitializeAssemblyAnchorVerticalOffsetFromTerminalObject();
RefreshAssemblyTerminalObjectInfo(); RefreshAssemblyTerminalObjectInfo();
RenderAssemblyAnchorMarker(); RenderAssemblyAnchorMarker();
OnPropertyChanged(nameof(CanGenerateAssemblyReferenceRod)); OnPropertyChanged(nameof(CanGenerateAssemblyReferenceRod));
@ -1420,6 +1437,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
Point3D projectedStartPoint = AssemblyReferencePathManager.Instance.ProjectPointToReferenceLine(pickResult.Point); Point3D projectedStartPoint = AssemblyReferencePathManager.Instance.ProjectPointToReferenceLine(pickResult.Point);
_assemblyStartPoint = projectedStartPoint; _assemblyStartPoint = projectedStartPoint;
AssemblyStartPointText = $"({projectedStartPoint.X:F2}, {projectedStartPoint.Y:F2}, {projectedStartPoint.Z:F2})"; AssemblyStartPointText = $"({projectedStartPoint.X:F2}, {projectedStartPoint.Y:F2}, {projectedStartPoint.Z:F2})";
LogManager.Info(
$"[直线装配] 点击点=({pickResult.Point.X:F2}, {pickResult.Point.Y:F2}, {pickResult.Point.Z:F2})" +
$"投影起点=({projectedStartPoint.X:F2}, {projectedStartPoint.Y:F2}, {projectedStartPoint.Z:F2})");
await SafeExecuteAsync(() => await SafeExecuteAsync(() =>
{ {
@ -1450,7 +1470,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
RailPathDefinitionMode = RailPathDefinitionMode.RailCenterLine RailPathDefinitionMode = RailPathDefinitionMode.RailCenterLine
}; };
route.AddPoint(new PathPoint(_assemblyStartPoint, "装配起点", PathPointType.StartPoint)); route.AddPoint(new PathPoint(startPoint, "装配起点", PathPointType.StartPoint));
route.AddPoint(new PathPoint(endPoint, "装配终点", PathPointType.EndPoint)); route.AddPoint(new PathPoint(endPoint, "装配终点", PathPointType.EndPoint));
if (!_pathPlanningManager.AddRoute(route)) if (!_pathPlanningManager.AddRoute(route))
@ -1459,14 +1479,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels
} }
_pathPlanningManager.SetCurrentRoute(route); _pathPlanningManager.SetCurrentRoute(route);
_pathPlanningManager.DrawRouteVisualization(route, isAutoPath: false);
_pathPlanningManager.SavePathToDatabase(route);
if (!_pathPlanningManager.GeneratePath(route)) if (!_pathPlanningManager.GeneratePath(route))
{ {
throw new InvalidOperationException("装配路径生成失败"); throw new InvalidOperationException("装配路径生成失败");
} }
_pathPlanningManager.DrawRouteVisualization(route, isAutoPath: false);
RefreshPathRoutes();
var generatedRouteViewModel = PathRoutes.FirstOrDefault(p => p.Name == route.Name);
if (generatedRouteViewModel != null)
{
SelectedPathRoute = generatedRouteViewModel;
UpdatePassageSpaceVisualizationForPathType(route.PathType);
}
AssemblyTerminalObjectInfo = string.Format( AssemblyTerminalObjectInfo = string.Format(
"对接终点=({0:F2}, {1:F2}, {2:F2}),装配起点={3},安装方式={4},对接基准={5}", "对接终点=({0:F2}, {1:F2}, {2:F2}),装配起点={3},安装方式={4},对接基准={5}",
endPoint.X, endPoint.X,
@ -1477,7 +1504,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
AssemblyPayloadAnchorMode == RailPayloadAnchorMode.TopCenter ? "顶面对接" : "底面对接"); AssemblyPayloadAnchorMode == RailPayloadAnchorMode.TopCenter ? "顶面对接" : "底面对接");
OnPropertyChanged(nameof(PathRoutes)); OnPropertyChanged(nameof(PathRoutes));
LogManager.Info($"[直线装配] 已生成路径: {route.Name}"); LogManager.Info($"[直线装配] 已生成路径: {route.Name},起点=({startPoint.X:F2}, {startPoint.Y:F2}, {startPoint.Z:F2}),终点=({endPoint.X:F2}, {endPoint.Y:F2}, {endPoint.Z:F2})");
} }
private Point3D GetAssemblyTerminalAnchorPoint() private Point3D GetAssemblyTerminalAnchorPoint()
@ -1490,14 +1517,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
var bounds = _assemblyTerminalObject.BoundingBox(); var bounds = _assemblyTerminalObject.BoundingBox();
var center = bounds.Center; var center = bounds.Center;
Vector3D up = ModelItemTransformHelper.GetUpDirectionFromTransform(_assemblyTerminalObject.Transform); Vector3D up = ModelItemTransformHelper.GetUpDirectionFromTransform(_assemblyTerminalObject.Transform);
Vector3D localSize = ModelItemTransformHelper.EstimateLocalBoxSize(bounds, _assemblyTerminalObject.Transform);
double halfHeight = Math.Max(0.0, localSize.Z / 2.0);
double direction = AssemblyPayloadAnchorMode == RailPayloadAnchorMode.TopCenter ? 1.0 : -1.0; double direction = AssemblyPayloadAnchorMode == RailPayloadAnchorMode.TopCenter ? 1.0 : -1.0;
double verticalOffset = UnitsConverter.ConvertFromMeters(AssemblyAnchorVerticalOffsetInMeters);
return new Point3D( return new Point3D(
center.X + up.X * halfHeight * direction, center.X + up.X * verticalOffset * direction,
center.Y + up.Y * halfHeight * direction, center.Y + up.Y * verticalOffset * direction,
center.Z + up.Z * halfHeight * direction); center.Z + up.Z * verticalOffset * direction);
} }
private AssemblyReferenceLine BuildAssemblyReferenceLine() private AssemblyReferenceLine BuildAssemblyReferenceLine()
@ -1548,7 +1574,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (referenceStartPoint != null && referenceEndPoint != null) if (referenceStartPoint != null && referenceEndPoint != null)
{ {
AssemblyTerminalObjectInfo = string.Format( AssemblyTerminalObjectInfo = string.Format(
"中心=({0:F2}, {1:F2}, {2:F2}),尺寸=({3:F2}, {4:F2}, {5:F2}){6}{7}点=({8:F2}, {9:F2}, {10:F2})参考杆起点=({11:F2}, {12:F2}, {13:F2})", "中心=({0:F2}, {1:F2}, {2:F2}),尺寸=({3:F2}, {4:F2}, {5:F2}){6}{7}点=({8:F2}, {9:F2}, {10:F2})垂直偏移={11:F3}m参考杆起点=({12:F2}, {13:F2}, {14:F2})",
bounds.Center.X, bounds.Center.X,
bounds.Center.Y, bounds.Center.Y,
bounds.Center.Z, bounds.Center.Z,
@ -1560,6 +1586,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
referenceEndPoint.X, referenceEndPoint.X,
referenceEndPoint.Y, referenceEndPoint.Y,
referenceEndPoint.Z, referenceEndPoint.Z,
AssemblyAnchorVerticalOffsetInMeters,
referenceStartPoint.X, referenceStartPoint.X,
referenceStartPoint.Y, referenceStartPoint.Y,
referenceStartPoint.Z); referenceStartPoint.Z);
@ -1567,7 +1594,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
} }
AssemblyTerminalObjectInfo = string.Format( AssemblyTerminalObjectInfo = string.Format(
"中心=({0:F2}, {1:F2}, {2:F2}),尺寸=({3:F2}, {4:F2}, {5:F2}){6}{7}点=({8:F2}, {9:F2}, {10:F2})", "中心=({0:F2}, {1:F2}, {2:F2}),尺寸=({3:F2}, {4:F2}, {5:F2}){6}{7}点=({8:F2}, {9:F2}, {10:F2}),垂直偏移={11:F3}m",
bounds.Center.X, bounds.Center.X,
bounds.Center.Y, bounds.Center.Y,
bounds.Center.Z, bounds.Center.Z,
@ -1578,7 +1605,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
anchorText, anchorText,
anchorPoint.X, anchorPoint.X,
anchorPoint.Y, anchorPoint.Y,
anchorPoint.Z); anchorPoint.Z,
AssemblyAnchorVerticalOffsetInMeters);
} }
private void RefreshAssemblyReferenceRodIfNeeded() private void RefreshAssemblyReferenceRodIfNeeded()
@ -1609,6 +1637,20 @@ namespace NavisworksTransport.UI.WPF.ViewModels
} }
} }
private void InitializeAssemblyAnchorVerticalOffsetFromTerminalObject()
{
if (_assemblyTerminalObject == null || !ModelItemAnalysisHelper.IsModelItemValid(_assemblyTerminalObject))
{
return;
}
var bounds = _assemblyTerminalObject.BoundingBox();
Vector3D localSize = ModelItemTransformHelper.EstimateLocalBoxSize(bounds, _assemblyTerminalObject.Transform);
double suggestedOffset = UnitsConverter.ConvertToMeters(Math.Max(0.0, localSize.Z / 2.0));
_assemblyAnchorVerticalOffsetInMeters = suggestedOffset;
OnPropertyChanged(nameof(AssemblyAnchorVerticalOffsetInMeters));
}
private sealed class AssemblyReferenceLine private sealed class AssemblyReferenceLine
{ {
public AssemblyReferenceLine(Point3D startPoint, Point3D endPoint, Vector3D direction) public AssemblyReferenceLine(Point3D startPoint, Point3D endPoint, Vector3D direction)

View File

@ -332,6 +332,7 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Grid.Column="0" <Label Grid.Column="0"
Content="对接基准:" Content="对接基准:"
@ -344,6 +345,35 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管
SelectedValuePath="Value" SelectedValuePath="Value"
DisplayMemberPath="DisplayName" DisplayMemberPath="DisplayName"
ToolTip="选择终点箱体使用顶面中心还是底面中心作为装配终点"/> ToolTip="选择终点箱体使用顶面中心还是底面中心作为装配终点"/>
<Label Grid.Column="2"
Margin="12,0,0,0"
Content="偏移由下方参数控制"
Style="{StaticResource UnitLabelStyle}"
VerticalAlignment="Center"/>
</Grid>
<Grid Margin="0,6,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0"
Content="垂直偏移:"
Style="{StaticResource ParameterLabelStyle}"
VerticalAlignment="Center"/>
<TextBox Grid.Column="1"
Text="{Binding AssemblyAnchorVerticalOffsetInMeters, StringFormat=0.0###}"
Style="{StaticResource ParameterInputStyle}"/>
<Label Grid.Column="2"
Content="米"
Style="{StaticResource UnitLabelStyle}"/>
<TextBlock Grid.Column="3"
Margin="8,0,0,0"
Text="表示箱体中心到真实安装点沿局部上下方向的距离"
Style="{StaticResource StatusTextStyle}"
VerticalAlignment="Center"
TextWrapping="Wrap"/>
</Grid> </Grid>
<Grid Margin="0,6,0,0"> <Grid Margin="0,6,0,0">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>