refactor: 合并坐标系设置——FragmentUp 自动从 CoordinateSystemManager 派生,删除独立的 FragmentUp 控件和检测按钮

This commit is contained in:
tian 2026-07-16 10:03:03 +08:00
parent 0629384639
commit 823c2de74d
4 changed files with 8 additions and 243 deletions

View File

@ -104,7 +104,6 @@ namespace NavisworksTransport.Core.Animation
{
private static PathAnimationManager _instance;
private static readonly Dictionary<string, int> _animationHashToRecordId = new Dictionary<string, int>(); // 动画配置哈希到检测记录ID的映射
private static readonly HashSet<string> _realObjectFragmentUpMismatchHintsShown = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private ModelItem _animatedObject;
private AnimatedObjectMode _animatedObjectMode = AnimatedObjectMode.None;
private double _virtualObjectLength = 0; // 虚拟物体长度(模型单位)
@ -5289,61 +5288,6 @@ namespace NavisworksTransport.Core.Animation
return true;
}
private void ShowRealObjectFragmentUpMismatchHintIfNeeded(Vector3 representativeYAxis, Vector3 representativeZAxis)
{
if (_route == null || (_route.PathType != PathType.Ground && _route.PathType != PathType.Hoisting))
{
return;
}
if (!IsRealObjectMode)
{
return;
}
var doc = NavisApplication.ActiveDocument;
string hostUpAxis = FragmentDefaultUpContext.GetCurrentHostUpAxis(doc);
string configuredFragmentUpAxis = FragmentDefaultUpContext.GetCurrentDocumentFragmentDefaultUpAxis(doc);
Vector3 hostUpVector = string.Equals(hostUpAxis, "Y", StringComparison.OrdinalIgnoreCase)
? Vector3.UnitY
: Vector3.UnitZ;
float yAlignment = Math.Abs(Vector3.Dot(Vector3.Normalize(representativeYAxis), hostUpVector));
float zAlignment = Math.Abs(Vector3.Dot(Vector3.Normalize(representativeZAxis), hostUpVector));
string detectedFragmentUpAxis = zAlignment > yAlignment ? "Z" : "Y";
if (string.Equals(configuredFragmentUpAxis, detectedFragmentUpAxis, StringComparison.OrdinalIgnoreCase))
{
return;
}
string documentKey = FragmentDefaultUpContext.GetCurrentDocumentKey(doc);
if (string.IsNullOrWhiteSpace(documentKey))
{
return;
}
string hintKey = $"{documentKey}|{configuredFragmentUpAxis}|{detectedFragmentUpAxis}";
lock (_realObjectFragmentUpMismatchHintsShown)
{
if (_realObjectFragmentUpMismatchHintsShown.Contains(hintKey))
{
return;
}
_realObjectFragmentUpMismatchHintsShown.Add(hintKey);
}
string message =
$"请到系统管理的坐标系设置中,将 Fragment默认Up 调整为 {detectedFragmentUpAxis}。";
LogManager.Info($"[fragment默认Up提示] 当前值={configuredFragmentUpAxis}, 检测值={detectedFragmentUpAxis}, 模型Up={hostUpAxis}。{message}");
DialogHelper.ShowMessageBox(
message,
"Fragment默认Up提示",
MessageBoxButton.OK,
MessageBoxImage.Information);
}
private bool TryGetRealObjectReferenceRotation(out Quaternion referenceRotation)
{
referenceRotation = Quaternion.Identity;

View File

@ -184,13 +184,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
public ICommand ReadTransformTestCommand { get; private set; }
public ICommand CoordinateSystemExplorerCommand { get; private set; }
public ICommand CaptureRealObjectTransformCommand { get; private set; }
public ICommand DetectFragmentDefaultUpCommand { get; private set; }
public ICommand TestFaceInferCommand { get; private set; }
// 坐标系设置
public ObservableCollection<string> CoordinateSystemOptions { get; private set; }
public ObservableCollection<string> FragmentDefaultUpAxisOptions { get; private set; }
private string _selectedCoordinateSystem = "AutoDetect";
public string SelectedCoordinateSystem
@ -212,21 +210,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
set => SetProperty(ref _currentCoordinateSystemInfo, value);
}
private string _selectedFragmentDefaultUpAxis = "Y";
public string SelectedFragmentDefaultUpAxis
{
get => _selectedFragmentDefaultUpAxis;
set
{
if (SetProperty(ref _selectedFragmentDefaultUpAxis, value))
{
SaveCurrentDocumentFragmentDefaultUpAxis(value);
UpdateMainStatus($"当前文档 fragment 默认Up已设置为: {value}");
LogManager.Info($"[fragment默认Up] 当前文档设置为: {value}");
}
}
}
#endregion
#region
@ -340,18 +323,15 @@ namespace NavisworksTransport.UI.WPF.ViewModels
ReadTransformTestCommand = new RelayCommand(() => ExecuteReadTransformTest());
CoordinateSystemExplorerCommand = new RelayCommand(() => ExecuteCoordinateSystemExplorer());
CaptureRealObjectTransformCommand = new RelayCommand(() => ExecuteCaptureRealObjectTransform());
DetectFragmentDefaultUpCommand = new RelayCommand(() => ExecuteDetectFragmentDefaultUp());
TestFaceInferCommand = new RelayCommand(() => ExecuteTestFaceInfer());
// 初始化坐标系选项
CoordinateSystemOptions = new ObservableCollection<string> { "AutoDetect", "ZUp", "YUp" };
FragmentDefaultUpAxisOptions = new ObservableCollection<string> { "Y", "Z" };
// 从配置加载当前坐标系设置
var configType = ConfigManager.Instance.Current.CoordinateSystem?.Type ?? "AutoDetect";
_selectedCoordinateSystem = configType;
_selectedFragmentDefaultUpAxis = GetCurrentDocumentFragmentDefaultUpAxis();
// 订阅文档事件(用于自动检测坐标系)
SubscribeToDocumentEvents();
@ -470,26 +450,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
var info = CoordinateSystemManager.Instance.GetCurrentInfo();
CurrentCoordinateSystemInfo = $"当前坐标系: {info}";
RefreshFragmentDefaultUpAxisSelectionFromCurrentDocument();
}
private void RefreshFragmentDefaultUpAxisSelectionFromCurrentDocument()
{
string resolvedAxis = FragmentDefaultUpContext.GetCurrentDocumentFragmentDefaultUpAxis();
if (_selectedFragmentDefaultUpAxis != resolvedAxis)
{
SetProperty(ref _selectedFragmentDefaultUpAxis, resolvedAxis, nameof(SelectedFragmentDefaultUpAxis));
}
}
private string GetCurrentDocumentFragmentDefaultUpAxis()
{
return FragmentDefaultUpContext.GetCurrentDocumentFragmentDefaultUpAxis();
}
private void SaveCurrentDocumentFragmentDefaultUpAxis(string axisName)
{
FragmentDefaultUpContext.SetCurrentDocumentFragmentDefaultUpAxis(axisName);
}
private string GetCurrentDocumentKey()
@ -497,16 +457,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
return FragmentDefaultUpContext.GetCurrentDocumentKey();
}
private string GetCurrentHostUpAxis()
{
return FragmentDefaultUpContext.GetCurrentHostUpAxis();
}
private static bool IsSupportedFragmentDefaultUpAxis(string axisName)
{
return FragmentDefaultUpContext.IsSupportedAxis(axisName);
}
private void ShowRootModelRotationHintIfNeeded()
{
string documentKey = GetCurrentDocumentKey();
@ -603,7 +553,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
hintMessage =
$"检测到根模型存在整体旋转(约 {angleDegrees:F1}°),模型可能经过坐标系转换;如后续真实物体姿态异常,请检查 Fragment默认Up 设置。";
$"检测到根模型存在整体旋转(约 {angleDegrees:F1}°),模型可能经过坐标系转换;如后续真实物体姿态异常,请检查坐标系设置。";
return true;
}
@ -738,11 +688,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
});
}
_ = _uiStateManager.ExecuteUIUpdateAsync(() =>
{
RefreshFragmentDefaultUpAxisSelectionFromCurrentDocument();
});
}
#endregion
@ -1577,89 +1522,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}, "捕获真实物体原始位姿");
}
private void ExecuteDetectFragmentDefaultUp()
{
SafeExecute(() =>
{
var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
if (doc == null || doc.IsClear)
{
System.Windows.MessageBox.Show(
"没有活动的文档!请先打开一个模型。",
"错误",
System.Windows.MessageBoxButton.OK,
System.Windows.MessageBoxImage.Error);
return;
}
var selection = doc.CurrentSelection.SelectedItems;
if (selection.Count == 0)
{
System.Windows.MessageBox.Show(
"请先选择一个明显水平放置的真实物体,再执行 fragment 默认Up检测。",
"提示",
System.Windows.MessageBoxButton.OK,
System.Windows.MessageBoxImage.Information);
return;
}
ModelItem item = selection[0];
FragmentOrientationAnalysis fragmentAnalysis = AnalyzeFragmentOrientations(item);
if (fragmentAnalysis == null || !fragmentAnalysis.HasRepresentativeOrientation)
{
System.Windows.MessageBox.Show(
"未能读取选中物体的 fragment 代表姿态无法检测默认Up。",
"提示",
System.Windows.MessageBoxButton.OK,
System.Windows.MessageBoxImage.Warning);
return;
}
string hostUpAxis = GetCurrentHostUpAxis();
if (!RealObjectReferencePoseResolver.TryDetectDefaultUpAxis(
fragmentAnalysis.ValidMatrices,
hostUpAxis,
out string detectedAxis,
out float yAlignment,
out float zAlignment))
{
System.Windows.MessageBox.Show(
"未能从 fragment 姿态中检测默认Up。",
"提示",
System.Windows.MessageBoxButton.OK,
System.Windows.MessageBoxImage.Warning);
return;
}
string currentAxis = SelectedFragmentDefaultUpAxis;
LogManager.Info(
$"[fragment默认Up检测] 对象={item.DisplayName}, 宿主Up={hostUpAxis}, 当前值={currentAxis}, 检测值={detectedAxis}, " +
$"Y对齐度={yAlignment:F4}, Z对齐度={zAlignment:F4}");
if (string.Equals(detectedAxis, currentAxis, StringComparison.OrdinalIgnoreCase))
{
System.Windows.MessageBox.Show(
$"检测完成:当前文档 Fragment默认Up 已是 {currentAxis}。",
"Fragment默认Up检测",
System.Windows.MessageBoxButton.OK,
System.Windows.MessageBoxImage.Information);
UpdateMainStatus($"Fragment默认Up检测完成当前值 {currentAxis} 已匹配");
return;
}
SetProperty(ref _selectedFragmentDefaultUpAxis, detectedAxis, nameof(SelectedFragmentDefaultUpAxis));
SaveCurrentDocumentFragmentDefaultUpAxis(detectedAxis);
System.Windows.MessageBox.Show(
$"检测完成:当前文档 Fragment默认Up 已自动改为 {detectedAxis}。",
"Fragment默认Up检测",
System.Windows.MessageBoxButton.OK,
System.Windows.MessageBoxImage.Information);
UpdateMainStatus($"当前文档 fragment 默认Up已自动更新为: {detectedAxis}");
LogManager.Info($"[fragment默认Up] 检测后自动更新为: {detectedAxis}");
}, "检测Fragment默认Up");
}
private void ClearCapturedRealObjectTransformVisualization()
{
var renderPlugin = PathPointRenderPlugin.Instance;

View File

@ -183,22 +183,6 @@ NavisworksTransport 系统管理页签视图 - 采用与其他页签一致的Nav
Command="{Binding CoordinateSystemExplorerCommand}"
Style="{StaticResource ActionButtonStyle}"
ToolTip="检测当前文档的坐标系信息用于适配Y-up坐标系模型"/>
<TextBlock Text="Fragment默认Up:"
VerticalAlignment="Center"
Margin="8,0,4,0"
FontSize="10"/>
<ComboBox ItemsSource="{Binding FragmentDefaultUpAxisOptions}"
SelectedItem="{Binding SelectedFragmentDefaultUpAxis}"
Width="55"
Margin="0,0,4,0"
ToolTip="当前文档 fragment 默认Up轴族仅用于当前文档运行时设置"/>
<Button Content="检测Fragment Up"
Command="{Binding DetectFragmentDefaultUpCommand}"
Style="{StaticResource ActionButtonStyle}"
ToolTip="选一个明显水平放置的真实物体,检测 fragment 默认Up 更接近 Y 还是 Z若与当前值不同会提示是否自动修改"/>
</StackPanel>
<!-- 当前坐标系信息 -->

View File

@ -7,13 +7,10 @@ namespace NavisworksTransport.Utils.CoordinateSystem
{
/// <summary>
/// 当前文档级的 fragment 默认 Up 运行时状态。
/// 不写入系统配置,只在当前进程内按文档维持
/// 自动从 CoordinateSystemManager 派生,不暴露独立设置
/// </summary>
internal static class FragmentDefaultUpContext
{
private static readonly ConcurrentDictionary<string, string> DocumentFragmentDefaultUpAxes =
new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private static readonly ConcurrentDictionary<int, string> RuntimeDocumentKeys =
new ConcurrentDictionary<int, string>();
@ -81,35 +78,14 @@ namespace NavisworksTransport.Utils.CoordinateSystem
return "Z";
}
/// <summary>
/// 获取当前文档的 Fragment Default Up 轴。
/// 自动从 CoordinateSystemManager 的 ResolvedType 派生。
/// YUp → "Y", ZUp → "Z"。
/// </summary>
public static string GetCurrentDocumentFragmentDefaultUpAxis(Document doc = null)
{
doc = doc ?? Autodesk.Navisworks.Api.Application.ActiveDocument;
string documentKey = GetCurrentDocumentKey(doc);
if (!string.IsNullOrWhiteSpace(documentKey) &&
DocumentFragmentDefaultUpAxes.TryGetValue(documentKey, out string storedAxis) &&
IsSupportedAxis(storedAxis))
{
return storedAxis;
}
return GetCurrentHostUpAxis(doc);
}
public static void SetCurrentDocumentFragmentDefaultUpAxis(string axisName, Document doc = null)
{
if (!IsSupportedAxis(axisName))
{
return;
}
doc = doc ?? Autodesk.Navisworks.Api.Application.ActiveDocument;
string documentKey = GetCurrentDocumentKey(doc);
if (string.IsNullOrWhiteSpace(documentKey))
{
return;
}
DocumentFragmentDefaultUpAxes[documentKey] = axisName;
return CoordinateSystemManager.Instance.ResolvedType == CoordinateSystemType.YUp ? "Y" : "Z";
}
public static bool IsSupportedAxis(string axisName)
@ -120,7 +96,6 @@ namespace NavisworksTransport.Utils.CoordinateSystem
internal static void ResetForTests()
{
DocumentFragmentDefaultUpAxes.Clear();
RuntimeDocumentKeys.Clear();
}
}