202 lines
10 KiB
C#
202 lines
10 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Windows;
|
|
using Autodesk.Navisworks.Api;
|
|
using Autodesk.Navisworks.Api.Plugins;
|
|
using ComApi = Autodesk.Navisworks.Api.Interop.ComApi;
|
|
using ComApiBridge = Autodesk.Navisworks.Api.ComApi.ComApiBridge;
|
|
using NavisworksTransport.Utils;
|
|
|
|
namespace NavisworksTransport.Commands
|
|
{
|
|
/// <summary>
|
|
/// 坐标系检测命令 - 用于探索 Navisworks API 中的坐标系相关信息
|
|
/// </summary>
|
|
[Plugin("CoordinateSystemExplorer", "NavisworksTransport", DisplayName = "坐标系检测")]
|
|
[AddInPlugin(AddInLocation.AddIn)]
|
|
public class CoordinateSystemExplorerCommand : AddInPlugin
|
|
{
|
|
public override int Execute(params string[] parameters)
|
|
{
|
|
try
|
|
{
|
|
var doc = Application.ActiveDocument;
|
|
if (doc == null || doc.IsClear)
|
|
{
|
|
MessageBox.Show("没有活动的文档!", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
return 1;
|
|
}
|
|
|
|
var sb = new StringBuilder();
|
|
sb.AppendLine("=== Navisworks 坐标系检测 ===\n");
|
|
|
|
// 1. Document 级别信息
|
|
sb.AppendLine("【1. Document 级别信息】");
|
|
sb.AppendLine($"文档名称: {doc.FileName}");
|
|
sb.AppendLine($"文档标题: {doc.Title}");
|
|
sb.AppendLine($"模型数量: {doc.Models.Count}");
|
|
sb.AppendLine();
|
|
|
|
// 2. Model 级别信息
|
|
sb.AppendLine("【2. Model 级别信息】");
|
|
int modelIndex = 0;
|
|
foreach (Model model in doc.Models)
|
|
{
|
|
sb.AppendLine($"模型 [{modelIndex}]: {model.Title}");
|
|
sb.AppendLine($" - 源文件名: {model.SourceFileName}");
|
|
sb.AppendLine($" - 源格式: {model.SourceFileFormat}");
|
|
|
|
var rootItem = model.RootItem;
|
|
if (rootItem != null)
|
|
{
|
|
sb.AppendLine($" - RootItem.DisplayName: {rootItem.DisplayName}");
|
|
sb.AppendLine($" - RootItem.Transform: {rootItem.Transform}");
|
|
|
|
var components = rootItem.Transform.Factor();
|
|
sb.AppendLine($" - Transform.Translation: ({components.Translation.X:F4}, {components.Translation.Y:F4}, {components.Translation.Z:F4})");
|
|
sb.AppendLine($" - Transform.Rotation.Axis: ({components.Rotation.Axis.X:F4}, {components.Rotation.Axis.Y:F4}, {components.Rotation.Axis.Z:F4})");
|
|
sb.AppendLine($" - Transform.Rotation.Angle: {components.Rotation.Angle:F6} rad ({components.Rotation.Angle * 180 / Math.PI:F2}°)");
|
|
sb.AppendLine($" - Transform.Scale: ({components.Scale.X:F4}, {components.Scale.Y:F4}, {components.Scale.Z:F4})");
|
|
|
|
var bbox = rootItem.BoundingBox();
|
|
sb.AppendLine($" - 包围盒 Min: ({bbox.Min.X:F4}, {bbox.Min.Y:F4}, {bbox.Min.Z:F4})");
|
|
sb.AppendLine($" - 包围盒 Max: ({bbox.Max.X:F4}, {bbox.Max.Y:F4}, {bbox.Max.Z:F4})");
|
|
|
|
double xSpan = bbox.Max.X - bbox.Min.X;
|
|
double ySpan = bbox.Max.Y - bbox.Min.Y;
|
|
double zSpan = bbox.Max.Z - bbox.Min.Z;
|
|
sb.AppendLine($" - 跨度: X={xSpan:F2}, Y={ySpan:F2}, Z={zSpan:F2}");
|
|
sb.AppendLine($" - 坐标系推测: {(ySpan > zSpan * 2 ? "可能是 Y-Up" : "可能是 Z-Up")}");
|
|
}
|
|
sb.AppendLine();
|
|
modelIndex++;
|
|
}
|
|
|
|
// 3. 当前选择项的 Transform 详情
|
|
sb.AppendLine("【3. 当前选择项信息】");
|
|
var selection = doc.CurrentSelection.SelectedItems;
|
|
if (selection.Count > 0)
|
|
{
|
|
var item = selection.First();
|
|
sb.AppendLine($"选中项: {item.DisplayName}");
|
|
sb.AppendLine($" - ClassName: {item.ClassName}");
|
|
sb.AppendLine($" - ClassDisplayName: {item.ClassDisplayName}");
|
|
sb.AppendLine($" - HasGeometry: {item.HasGeometry}");
|
|
|
|
var transform = item.Transform;
|
|
var comp = transform.Factor();
|
|
sb.AppendLine($" - Transform.Translation: ({comp.Translation.X:F4}, {comp.Translation.Y:F4}, {comp.Translation.Z:F4})");
|
|
sb.AppendLine($" - Transform.Rotation.Axis: ({comp.Rotation.Axis.X:F4}, {comp.Rotation.Axis.Y:F4}, {comp.Rotation.Axis.Z:F4})");
|
|
sb.AppendLine($" - Transform.Rotation.Angle: {comp.Rotation.Angle:F6} rad");
|
|
|
|
var itemBbox = item.BoundingBox();
|
|
sb.AppendLine($" - 包围盒 Center: ({itemBbox.Center.X:F4}, {itemBbox.Center.Y:F4}, {itemBbox.Center.Z:F4})");
|
|
}
|
|
else
|
|
{
|
|
sb.AppendLine("当前没有选择项");
|
|
}
|
|
sb.AppendLine();
|
|
|
|
// 4. Viewpoint 信息
|
|
sb.AppendLine("【4. Viewpoint 信息】");
|
|
var vp = doc.CurrentViewpoint.Value;
|
|
sb.AppendLine($"WorldUpVector: ({vp.WorldUpVector.X:F4}, {vp.WorldUpVector.Y:F4}, {vp.WorldUpVector.Z:F4})");
|
|
sb.AppendLine($"Position: ({vp.Position.X:F4}, {vp.Position.Y:F4}, {vp.Position.Z:F4})");
|
|
sb.AppendLine($"Rotation.Axis: ({vp.Rotation.Axis.X:F4}, {vp.Rotation.Axis.Y:F4}, {vp.Rotation.Axis.Z:F4})");
|
|
sb.AppendLine($"Rotation.Angle: {vp.Rotation.Angle:F6} rad");
|
|
sb.AppendLine();
|
|
|
|
// 5. COM API 探索
|
|
sb.AppendLine("【5. COM API 探索】");
|
|
try
|
|
{
|
|
var comState = ComApiBridge.ToInwOpState(doc);
|
|
sb.AppendLine($"COM State 类型: {comState.GetType().FullName}");
|
|
|
|
// 尝试获取模型的 COM 表示
|
|
if (doc.Models.Count > 0)
|
|
{
|
|
var firstModel = doc.Models[0];
|
|
// 注意:这里可能需要不同的方法来获取 COM 模型对象
|
|
sb.AppendLine($"尝试访问 COM 模型对象...");
|
|
|
|
// 通过选择获取 COM 对象
|
|
var modelCollection = new ModelItemCollection { firstModel.RootItem };
|
|
var comSelection = ComApiBridge.ToInwOpSelection(modelCollection);
|
|
sb.AppendLine($"COM Selection 路径数: {comSelection.Paths().Count}");
|
|
|
|
// 释放 COM 对象
|
|
System.Runtime.InteropServices.Marshal.ReleaseComObject(comSelection);
|
|
}
|
|
|
|
sb.AppendLine("COM API 访问成功");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
sb.AppendLine($"COM API 访问失败: {ex.Message}");
|
|
sb.AppendLine($"堆栈: {ex.StackTrace}");
|
|
}
|
|
sb.AppendLine();
|
|
|
|
// 6. 坐标系推测总结
|
|
sb.AppendLine("【6. 坐标系推测总结】");
|
|
if (doc.Models.Count > 0)
|
|
{
|
|
var rootBounds = doc.Models[0].RootItem.BoundingBox();
|
|
double xSpan = rootBounds.Max.X - rootBounds.Min.X;
|
|
double ySpan = rootBounds.Max.Y - rootBounds.Min.Y;
|
|
double zSpan = rootBounds.Max.Z - rootBounds.Min.Z;
|
|
|
|
sb.AppendLine($"模型跨度分析:");
|
|
sb.AppendLine($" - X (左右): {xSpan:F2} 单位");
|
|
sb.AppendLine($" - Y (前后/上下): {ySpan:F2} 单位");
|
|
sb.AppendLine($" - Z (上下/前后): {zSpan:F2} 单位");
|
|
sb.AppendLine();
|
|
|
|
sb.AppendLine($"启发式判断:");
|
|
if (ySpan > zSpan * 3)
|
|
{
|
|
sb.AppendLine($" - Y 跨度显著大于 Z 跨度 ({ySpan/zSpan:F1}x)");
|
|
sb.AppendLine($" - 推测: Y-Up 坐标系 (Y轴向上)");
|
|
}
|
|
else if (zSpan > ySpan * 3)
|
|
{
|
|
sb.AppendLine($" - Z 跨度显著大于 Y 跨度 ({zSpan/ySpan:F1}x)");
|
|
sb.AppendLine($" - 推测: Z-Up 坐标系 (Z轴向上)");
|
|
}
|
|
else
|
|
{
|
|
sb.AppendLine($" - Y 和 Z 跨度相近");
|
|
sb.AppendLine($" - 无法确定坐标系,可能是特殊模型或 Z-Up");
|
|
}
|
|
}
|
|
|
|
// 显示结果
|
|
string result = sb.ToString();
|
|
|
|
// 保存到日志
|
|
LogManager.Info(result);
|
|
|
|
// 显示对话框(如果内容太长,可能需要截断)
|
|
const int maxLength = 4000;
|
|
string displayText = result.Length > maxLength
|
|
? result.Substring(0, maxLength) + "\n\n... (内容已截断,请查看完整日志)"
|
|
: result;
|
|
|
|
MessageBox.Show(displayText, "坐标系检测结果", MessageBoxButton.OK, MessageBoxImage.Information);
|
|
|
|
return 0;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
string errorMsg = $"坐标系检测失败: {ex.Message}\n{ex.StackTrace}";
|
|
LogManager.Error(errorMsg);
|
|
MessageBox.Show(errorMsg, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
}
|