fix: add debug log, use NavisApplication alias in EditRotationWindow

This commit is contained in:
tian 2026-06-09 03:18:20 +08:00
parent 9ea3cc0e02
commit 2f16ec0d43

View File

@ -1,5 +1,6 @@
using System;
using System.ComponentModel;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
@ -7,6 +8,7 @@ using System.Windows.Data;
using NavisworksTransport.UI.WPF.Converters;
using NavisworksTransport.Utils;
using NavisworksTransport.Utils.CoordinateSystem;
using NavisApplication = Autodesk.Navisworks.Api.Application;
namespace NavisworksTransport.UI.WPF.Views
{
@ -400,15 +402,16 @@ namespace NavisworksTransport.UI.WPF.Views
private void OnMateToGroundClick(object sender, RoutedEventArgs e)
{
LogManager.Debug("[贴地面] 按钮被点击");
try
{
var assemblyPath = FaceInferToolPlugin.AssemblyPath;
Autodesk.Navisworks.Api.Application.Plugins.AddPluginAssembly(assemblyPath);
NavisApplication.Plugins.AddPluginAssembly(assemblyPath);
var record = (Autodesk.Navisworks.Api.Plugins.ToolPluginRecord)
Autodesk.Navisworks.Api.Application.Plugins.FindPlugin("FaceInferTool.NavisworksTransport");
NavisApplication.Plugins.FindPlugin("FaceInferTool.NavisworksTransport");
var loadedPlugin = record.LoadPlugin();
Autodesk.Navisworks.Api.Application.MainDocument.Tool.Value = Autodesk.Navisworks.Api.Tool.None;
Autodesk.Navisworks.Api.Application.MainDocument.Tool.SetCustomToolPlugin(loadedPlugin);
NavisApplication.MainDocument.Tool.Value = Autodesk.Navisworks.Api.Tool.None;
NavisApplication.MainDocument.Tool.SetCustomToolPlugin(loadedPlugin);
EventHandler<FaceInferResult> handler = null;
handler = (s, result) =>
@ -419,7 +422,7 @@ namespace NavisworksTransport.UI.WPF.Views
{
try
{
Autodesk.Navisworks.Api.Application.MainDocument.Tool.Value = Autodesk.Navisworks.Api.Tool.Select;
NavisApplication.MainDocument.Tool.Value = Autodesk.Navisworks.Api.Tool.Select;
}
catch { }
@ -430,64 +433,59 @@ namespace NavisworksTransport.UI.WPF.Views
return;
}
// 获取宿主 up 方向
var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
var doc = NavisApplication.ActiveDocument;
var worldUp = doc.CurrentViewpoint.Value.WorldUpVector;
var hostUp = new System.Numerics.Vector3((float)worldUp.X, (float)worldUp.Y, (float)worldUp.Z);
hostUp = System.Numerics.Vector3.Normalize(hostUp);
var hostUp = new Vector3((float)worldUp.X, (float)worldUp.Y, (float)worldUp.Z);
hostUp = Vector3.Normalize(hostUp);
var groundDir = -hostUp;
var faceNormal = new System.Numerics.Vector3(
var faceNormal = new Vector3(
(float)result.Normal.X, (float)result.Normal.Y, (float)result.Normal.Z);
faceNormal = System.Numerics.Vector3.Normalize(faceNormal);
faceNormal = Vector3.Normalize(faceNormal);
float dot = System.Numerics.Vector3.Dot(faceNormal, groundDir);
float dot = Vector3.Dot(faceNormal, groundDir);
System.Numerics.Quaternion rotation;
Quaternion rotation;
if (dot > 0.9999f)
{
// 已经对齐
MessageBox.Show("选中面已朝向地面,无需旋转。", "贴地面", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
if (dot < -0.9999f)
{
// 完全相反,绕任意垂直轴转 180°
var perp = Math.Abs(hostUp.X) < 0.9f
? System.Numerics.Vector3.Normalize(System.Numerics.Vector3.Cross(hostUp, new System.Numerics.Vector3(1, 0, 0)))
: System.Numerics.Vector3.Normalize(System.Numerics.Vector3.Cross(hostUp, new System.Numerics.Vector3(0, 0, 1)));
rotation = System.Numerics.Quaternion.CreateFromAxisAngle(perp, (float)Math.PI);
? Vector3.Normalize(Vector3.Cross(hostUp, new Vector3(1, 0, 0)))
: Vector3.Normalize(Vector3.Cross(hostUp, new Vector3(0, 0, 1)));
rotation = Quaternion.CreateFromAxisAngle(perp, (float)Math.PI);
}
else
{
var axis = System.Numerics.Vector3.Normalize(System.Numerics.Vector3.Cross(faceNormal, groundDir));
var axis = Vector3.Normalize(Vector3.Cross(faceNormal, groundDir));
float angle = (float)Math.Acos(dot);
rotation = System.Numerics.Quaternion.CreateFromAxisAngle(axis, angle);
rotation = Quaternion.CreateFromAxisAngle(axis, angle);
}
// 分解为 ZYX Euler 角度
ExtractZyxEuler(rotation, out double xDeg, out double yDeg, out double zDeg);
RotationXDegrees = NormalizeDisplayDegrees(xDeg);
RotationYDegrees = NormalizeDisplayDegrees(yDeg);
RotationZDegrees = NormalizeDisplayDegrees(zDeg);
LogManager.Info($"[贴地面] faceNormal=({faceNormal.X:F3},{faceNormal.Y:F3},{faceNormal.Z:F3}), " +
$"groundDir=({groundDir.X:F3},{groundDir.Y:F3},{groundDir.Z:F3}), " +
$"Euler=({RotationXDegrees:F2}, {RotationYDegrees:F2}, {RotationZDegrees:F2})");
LogManager.Info($"[贴地面] {faceNormal} -> {groundDir}, Euler=({RotationXDegrees:F2},{RotationYDegrees:F2},{RotationZDegrees:F2})");
});
};
FaceInferToolPlugin.FaceInferred += handler;
LogManager.Debug("[贴地面] 取面工具已激活");
}
catch (Exception ex)
{
LogManager.Error($"[贴地面] 激活取面工具失败: {ex.Message}", ex);
LogManager.Error($"[贴地面] 失败: {ex.Message}", ex);
MessageBox.Show($"激活取面工具失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private static void ExtractZyxEuler(System.Numerics.Quaternion q, out double xDeg, out double yDeg, out double zDeg)
private static void ExtractZyxEuler(Quaternion q, out double xDeg, out double yDeg, out double zDeg)
{
// ZYX 顺序: Rz(z) * Ry(y) * Rx(x)
double sinY = -2.0 * (q.X * q.Z - q.W * q.Y);