From a0651d60cd2917c29b6c6f634755dbfea51c063b Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Wed, 4 Feb 2026 21:50:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20Navisworks=20API=20?= =?UTF-8?q?=E5=BC=80=E5=8F=91Skill?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .agents/skills/nw-api/SKILL.md | 137 ++++++++ .../nw-api/references/api-usage-patterns.md | 292 +++++++++++++++++ .../nw-api/references/net-examples-guide.md | 309 ++++++++++++++++++ .../skills/nw-api/references/plugin-types.md | 286 ++++++++++++++++ 4 files changed, 1024 insertions(+) create mode 100644 .agents/skills/nw-api/SKILL.md create mode 100644 .agents/skills/nw-api/references/api-usage-patterns.md create mode 100644 .agents/skills/nw-api/references/net-examples-guide.md create mode 100644 .agents/skills/nw-api/references/plugin-types.md diff --git a/.agents/skills/nw-api/SKILL.md b/.agents/skills/nw-api/SKILL.md new file mode 100644 index 0000000..c08dd29 --- /dev/null +++ b/.agents/skills/nw-api/SKILL.md @@ -0,0 +1,137 @@ +--- +name: nw-api +description: Navisworks API 开发助手,用于开发 Navisworks 插件。功能包括:(1) 查看 NET API 文档位置和使用方法,(2) 查看官方 NET API 示例代码,(3) 搜索 Navisworks NET API 使用方法和示例。当用户询问 Navisworks API、插件开发、NET API、C# 开发相关内容时使用此技能。 +--- + +# Navisworks NET API 开发助手 + +帮助开发 Autodesk Navisworks 插件的专用技能。主要基于 .NET API,COM API 作为补充参考。 + +## 本地文档位置 + +### API 文档(主要) + +| 类型 | 路径 | 格式 | +|------|------|------| +| NET API | `doc/navisworks_api/NET/documentation/NET API.chm` | CHM 帮助文件 | +| NET API HTML | `doc/navisworks_api/NET/documentation/NetAPIHtml/` | HTML 文档 | + +**HTML 文档入口**: `doc/navisworks_api/NET/documentation/NetAPIHtml/html/index.html` + +### API 文档搜索方法 + +HTML 文档已生成为可搜索的网页形式,可以直接用 Grep 工具搜索: + +```bash +# 搜索 ModelItem 的属性 +Grep -i "ModelItem.*property" doc/navisworks_api/NET/documentation/NetAPIHtml/html/ + +# 搜索特定方法 +Grep -i "BoundingBox" doc/navisworks_api/NET/documentation/NetAPIHtml/html/ + +# 搜索类定义 +Grep "class.*ModelItem" doc/navisworks_api/NET/documentation/NetAPIHtml/html/ +``` + +**文件命名规律**: + +- 类型页面: `T_Autodesk_Navisworks_Api_{ClassName}.htm` +- 属性页面: `P_Autodesk_Navisworks_Api_{ClassName}_{PropertyName}.htm` +- 方法页面: `M_Autodesk_Navisworks_Api_{ClassName}_{MethodName}.htm` +- 所有成员: `AllMembers_T_Autodesk_Navisworks_Api_{ClassName}.htm` +- 属性列表: `Properties_T_Autodesk_Navisworks_Api_{ClassName}.htm` +- 方法列表: `Methods_T_Autodesk_Navisworks_Api_{ClassName}.htm` + +### 官方示例代码(NET API) + +| 示例类型 | 路径 | +|----------|------| +| 基础插件 | `doc/navisworks_api/NET/examples/Basic Examples/CSharp/` | +| 插件集合 | `doc/navisworks_api/NET/examples/PlugIns/` | +| 自动化 | `doc/navisworks_api/NET/examples/Automation/` | +| 控件集成 | `doc/navisworks_api/NET/examples/Controls/` | +| 工具插件 | `doc/navisworks_api/NET/examples/Tools/` | + +### 项目设计文档 + +- `doc/design/2026/NavisworksAPI使用方法.md` - API 使用指南 +- `doc/migration/API_Migration_Analysis_2017_to_2026.md` - 版本迁移指南 +- `doc/migration/Navisworks_2026_API_Changes.md` - 2026 API 变更 + +## COM API 参考(补充) + +| 类型 | 路径 | +|------|------| +| COM API 文档 | `doc/navisworks_api/COM/documentation/NavisWorksCOM.chm` | +| COM 示例 | `doc/navisworks_api/COM/examples/` | + +## 在线资源 + +- **Autodesk Platform Services**: +- **AEC DevBlog**: +- **ApiDocs (2017-2018)**: + +## 快速参考 + +### 命名空间 + +```csharp +// 核心 API +using Autodesk.Navisworks.Api; +using Autodesk.Navisworks.Api.Plugins; +using Autodesk.Navisworks.Api.Clash; +using Autodesk.Navisworks.Api.Timeliner; + +// COM API(需要时) +using Autodesk.Navisworks.ComApi; +using Autodesk.Navisworks.Interop.ComApi; +``` + +### 插件类型 + +| 基类 | 用途 | 示例位置 | +|------|------|----------| +| `DockPanePlugin` | 停靠面板插件 | `Basic Examples/CSharp/BasicDockPanePlugin/` | +| `ToolPlugin` | 鼠标交互工具 | `PlugIns/InputAndRenderHandling/` | +| `RenderPlugin` | 3D 渲染插件 | `PlugIns/InputAndRenderHandling/` | +| `AddInPlugin` | 简单命令插件 | `PlugIns/Examiner/` | +| `EventWatcherPlugin` | 监听文档事件 | `PlugIns/ClashDetective/EventLog/` | + +### 关键 API 入口 + +```csharp +// 当前文档 +Document doc = Application.ActiveDocument; + +// 当前选择 +ModelItemCollection selection = doc.CurrentSelection.SelectedItems; + +// 模型遍历 +foreach (ModelItem item in doc.Models.RootItemDescendantsAndSelf) { } + +// 搜索 +Search search = new Search(); +search.SearchConditions.Add(SearchCondition.HasCategoryByName(PropertyCategoryNames.Geometry)); +ModelItemCollection results = search.FindAll(doc, false); +``` + +## 参考资料 + +- **常用 API 模式**: 见 `references/api-usage-patterns.md` +- **插件类型详解**: 见 `references/plugin-types.md` +- **NET 示例速查**: 见 `references/net-examples-guide.md` + +## Web 搜索 + +如需查找最新的 API 用法或示例,使用 `SearchWeb` 工具搜索: + +``` +SearchWeb: "Navisworks .NET API {query} example C#" +``` + +常用搜索模板: + +- `Navisworks .NET API ModelItem transform example` +- `Navisworks .NET API plugin DockPane C#` +- `Navisworks .NET API search condition example` +- `Navisworks 2026 .NET API changes` diff --git a/.agents/skills/nw-api/references/api-usage-patterns.md b/.agents/skills/nw-api/references/api-usage-patterns.md new file mode 100644 index 0000000..767bb9a --- /dev/null +++ b/.agents/skills/nw-api/references/api-usage-patterns.md @@ -0,0 +1,292 @@ +# Navisworks API 常用模式 + +## 1. 模型遍历 + +### 遍历所有模型项 + +```csharp +// 获取所有模型项 +IEnumerable allItems = + Application.ActiveDocument.Models.RootItemDescendantsAndSelf; + +// 遍历特定模型 +foreach (Model model in document.Models) +{ + foreach (ModelItem item in model.RootItem.DescendantsAndSelf) + { + // 处理每个模型项 + } +} +``` + +### 获取子节点 + +```csharp +// 获取所有后代(不包括自己) +var childItems = selectedItem.DescendantsAndSelf.Where(x => x != selectedItem); + +// 只获取直接子节点 +foreach (ModelItem child in parentItem.Children) { } + +// 向上遍历祖先 +var current = selectedItem.Parent; +while (current != null) +{ + current = current.Parent; +} +``` + +## 2. 搜索和查询 + +### 使用 Search 类 + +```csharp +Search search = new Search(); + +// 添加搜索条件 +search.SearchConditions.Add( + SearchCondition.HasCategoryByName(PropertyCategoryNames.Geometry)); +search.SearchConditions.Add( + SearchCondition.HasPropertyByName(PropertyCategoryNames.Item, DataPropertyNames.ItemHidden) + .EqualValue(VariantData.FromBoolean(false))); + +// 设置搜索范围 +search.Selection.SelectAll(); +search.Locations = SearchLocations.DescendantsAndSelf; + +// 执行搜索 +ModelItemCollection results = search.FindAll(document, false); +``` + +### 使用 LINQ 查询 + +```csharp +var results = document.Models.RootItemDescendantsAndSelf + .Where(x => x.HasGeometry && !x.IsHidden) + .Where(x => x.ClassDisplayName.ToLower().Contains("wall")); +``` + +## 3. 选择操作 + +```csharp +// 获取当前选择 +var currentSelection = document.CurrentSelection.SelectedItems; + +// 清空选择 +document.CurrentSelection.Clear(); + +// 添加到选择 +document.CurrentSelection.Add(modelItem); + +// 复制集合到选择 +document.CurrentSelection.CopyFrom(modelItems); +``` + +## 4. 可见性控制 + +```csharp +// 隐藏项目 +ModelItemCollection itemsToHide = new ModelItemCollection(); +itemsToHide.Add(modelItem); +document.Models.SetHidden(itemsToHide, true); + +// 显示项目 +document.Models.SetHidden(itemsToHide, false); + +// 检查是否隐藏 +if (modelItem.IsHidden) { } +``` + +## 5. 文件导出 + +```csharp +// 保存 NWD 文件 +document.SaveFile(filePath); + +// 使用导出选项 +var exportOptions = new NwdExportOptions(); +exportOptions.ExcludeHiddenItems = true; +exportOptions.EmbedXrefs = false; +exportOptions.PreventObjectPropertyExport = false; + +document.ExportToNwd(saveFilePath, exportOptions); +``` + +## 6. Transform 变换操作 + +### 核心概念 + +- `ModelItem.Transform` - 返回设计文件中的原始变换(只读) +- `OverridePermanentTransform()` - 应用增量变换(累积) +- `ResetPermanentTransform()` - 清除所有增量变换 +- `ModelItem.BoundingBox()` - 返回当前实际显示的包围盒 + +### 应用变换 + +```csharp +// 获取原始 Transform +Transform3D originalTransform = modelItem.Transform; + +// 应用增量变换 +var doc = Application.ActiveDocument; +var modelItems = new ModelItemCollection { modelItem }; +doc.Models.OverridePermanentTransform(modelItems, newTransform, false); + +// 重置到原始位置 +doc.Models.ResetPermanentTransform(modelItems); +``` + +### 绕物体中心旋转(需要补偿) + +```csharp +// 关键:API 的旋转总是绕世界原点(0,0,0) +// 要实现绕物体中心旋转,需要计算补偿 + +double deltaYaw = newYaw - currentYaw; +double cos = Math.Cos(deltaYaw); +double sin = Math.Sin(deltaYaw); + +// 计算绕原点旋转后的位置 +double rotatedX = currentPosition.X * cos - currentPosition.Y * sin; +double rotatedY = currentPosition.X * sin + currentPosition.Y * cos; + +// 计算补偿平移 +var compensatedTranslation = new Vector3D( + newPosition.X - rotatedX, + newPosition.Y - rotatedY, + newPosition.Z - currentPosition.Z +); + +// 组合变换 +var identity = Transform3D.CreateTranslation(new Vector3D(0, 0, 0)); +var components = identity.Factor(); +components.Rotation = new Rotation3D(new UnitVector3D(0, 0, 1), deltaYaw); +components.Translation = compensatedTranslation; + +var incrementalTransform = components.Combine(); +doc.Models.OverridePermanentTransform(modelItems, incrementalTransform, false); +``` + +## 7. 属性访问 + +### NET API 方式 + +```csharp +// 查找属性分类 +var category = item.PropertyCategories.FindCategoryByDisplayName("Material"); + +// 基础属性 +string displayName = item.DisplayName; +string className = item.ClassName; +bool hasGeometry = item.HasGeometry; +bool isHidden = item.IsHidden; +``` + +### COM API 方式(当 NET API 不满足需求时使用) + +**参考**: `doc/navisworks_api/NET/examples/Basic Examples/CSharp/APICallsCOMPlugin/` + +```csharp +using Autodesk.Navisworks.ComApi; +using Autodesk.Navisworks.Interop.ComApi; + +// 获取 COM 状态 +ComApi.InwOpState10 state = ComApiBridge.State; + +// 获取属性节点 +InwOpSelection2 selection = state.CurrentSelection as InwOpSelection2; +InwGUIPropertyNode2 propertyNode = + state.GetGUIPropertyNode(selection.Paths()[1], true) as InwGUIPropertyNode2; + +// 遍历属性分类 +foreach (InwGUIAttribute2 guiAttribute in propertyNode.GUIAttributes()) +{ + foreach (InwOaProperty property in guiAttribute.Properties()) + { + string name = property.name; + string value = property.value; + } +} +``` + +### 添加自定义属性(COM API) + +```csharp +InwOaPropertyVec propertyVector = + state.ObjectFactory(nwEObjectType.eObjectType_nwOaPropertyVec); + +InwOaProperty property = + state.ObjectFactory(nwEObjectType.eObjectType_nwOaProperty); +property.name = "CustomProperty1"; +property.UserName = "自定义属性1"; +property.value = value; + +propertyVector.Properties().Add(property); +propertyNode.SetUserDefined(0, categoryName, internalName, propertyVector); +``` + +## 8. 线程安全 - 关键 + +**所有 Navisworks API 调用必须在主 UI 线程中执行** + +```csharp +// ❌ 错误:在后台线程调用 +await Task.Run(() => +{ + var document = Application.ActiveDocument; // 可能崩溃 +}); + +// ✅ 正确:使用 Dispatcher.Invoke +await Task.Run(() => +{ + System.Windows.Application.Current.Dispatcher.Invoke(() => + { + var document = Application.ActiveDocument; + document.ExportToNwd(path, options); // 安全执行 + }); +}); +``` + +### 检查线程状态 + +```csharp +var apartmentState = System.Threading.Thread.CurrentThread.GetApartmentState(); +bool isMainThread = System.Windows.Application.Current.Dispatcher.CheckAccess(); +``` + +## 9. 碰撞检测 (ClashDetective) + +```csharp +// 获取碰撞测试 +document.ClashTestsData.Tests; + +// 创建碰撞选择 +var selectionA = new ClashSelection(modelItemsA, document); +var selectionB = new ClashSelection(modelItemsB, document); + +// 创建碰撞测试 +var clashTest = new ClashTest(); +clashTest.Name = "Test Name"; +clashTest.TestType = ClashTestType.Hard; +clashTest.SelectionA = selectionA; +clashTest.SelectionB = selectionB; +``` + +## 10. TimeLiner 集成 + +```csharp +// 获取 TimeLiner 数据 +var timeliner = document.Timeliner; + +// 添加任务 +var task = new TimelinerTask(); +task.Name = "Task Name"; +task.SimulationStatus = SimulationStatus.Active; +task.StartDate = DateTime.Now; +task.EndDate = DateTime.Now.AddDays(7); + +timeliner.Tasks.Add(task); + +// 关联模型项 +task.Selection.CopyFrom(modelItems); +``` diff --git a/.agents/skills/nw-api/references/net-examples-guide.md b/.agents/skills/nw-api/references/net-examples-guide.md new file mode 100644 index 0000000..58f9563 --- /dev/null +++ b/.agents/skills/nw-api/references/net-examples-guide.md @@ -0,0 +1,309 @@ +# Navisworks NET API 示例指南 + +## 示例代码位置总览 + +所有示例位于:`doc/navisworks_api/NET/examples/` + +## 基础示例 (Basic Examples) + +### 1. BasicDockPanePlugin + +**路径**: `Basic Examples/CSharp/BasicDockPanePlugin/` + +最简单的停靠面板插件示例。 + +```csharp +[Plugin("BasicDockPanePlugin.BasicDockPanePlugin", "ADSK", + DisplayName = "BasicDockPanePlugin", + ToolTip = "Basic Docking Pane Plugin")] +[DockPanePlugin(100, 300)] +public class BasicDockPanePlugin : DockPanePlugin +{ + public override Control CreateControlPane() + { + HelloWorldControl control = new HelloWorldControl(); + control.Dock = DockStyle.Fill; + control.CreateControl(); + return control; + } + + public override void DestroyControlPane(Control pane) + { + pane.Dispose(); + } +} +``` + +### 2. WPF DockPane + +**路径**: `Basic Examples/CSharp/WPF/WpfDockPane/` + +使用 WPF 控件的停靠面板插件。 + +```csharp +public override Control CreateControlPane() +{ + // 使用 ElementHost 托管 WPF 控件 + ElementHost host = new ElementHost(); + host.Child = new WPFHelloWorldControl(); + host.Dock = DockStyle.Fill; + host.CreateControl(); + return host; +} +``` + +### 3. DatabaseDockPane + +**路径**: `Basic Examples/CSharp/WPF/DatabaseDockPane/` + +展示如何在停靠面板中使用模型数据库。 + +### 4. BasicPlugIn + +**路径**: `Basic Examples/CSharp/BasicPlugIn/` + +最简单的 AddIn 插件示例。 + +### 5. APICallsCOMPlugin + +**路径**: `Basic Examples/CSharp/APICallsCOMPlugin/` + +展示如何在 NET API 插件中调用 COM API。 + +### 6. CustomRibbon + +**路径**: `Basic Examples/CSharp/CustomRibbon/` + +自定义 Ribbon 界面示例,使用 XAML 定义 Ribbon。 + +## 插件示例 (PlugIns) + +### 1. Examiner + +**路径**: `PlugIns/Examiner/` + +全面的 LINQ 搜索和模型操作示例。 + +**关键功能**: + +- 使用 LINQ 查询模型项 +- 属性搜索和过滤 +- 颜色和透明度覆盖 +- Required/Hidden 状态修改 +- 导出结果到 NWD + +**核心代码片段**: + +```csharp +// LINQ 搜索示例 +IEnumerable result = + Application.ActiveDocument.Models.RootItemDescendantsAndSelf + .Where(x => x.HasGeometry) + .Where(x => !x.IsHidden) + .Where(x => x.DisplayName.Contains(searchName)); + +// 颜色覆盖 +ModelItemCollection items = new ModelItemCollection(); +items.AddRange(result); +Application.ActiveDocument.Models.OverridePermanentColor(items, color); +``` + +### 2. SearchComparisonPlugIn + +**路径**: `PlugIns/SearchComparisonPlugIn/` + +对比不同搜索方法的性能。 + +### 3. InputAndRenderHandling + +**路径**: `PlugIns/InputAndRenderHandling/` + +ToolPlugin 和 RenderPlugin 的综合示例。 + +**关键功能**: + +- 鼠标输入处理 +- 自定义渲染 +- 3D 拾取 + +```csharp +[ToolPlugin("InputAndRenderHandling", "ADSK")] +[RenderPlugin("InputAndRenderHandling", "ADSK")] +public class InputAndRenderHandling : ToolPlugin +{ + public override bool MouseDown(MouseButton button, int x, int y) + { + // 处理鼠标点击 + return true; + } + + public override void Render(View view, RenderContext context) + { + // 自定义渲染 + } +} +``` + +### 4. ClashDetective 示例集合 + +**路径**: `PlugIns/ClashDetective/` + +包含多个碰撞检测相关示例: + +| 示例 | 说明 | +|------|------| +| `ClashGrouper/` | 碰撞结果分组 | +| `ClashMarkers/` | 碰撞标记显示 | +| `EventLog/` | 事件日志监听 | +| `GenerateMatrix/` | 生成碰撞矩阵 | +| `SimpleUI/` | 简单 UI 界面 | + +**碰撞测试基础代码**: + +```csharp +// 创建碰撞测试 +ClashTest clashTest = new ClashTest(); +clashTest.Name = "Test Name"; +clashTest.TestType = ClashTestType.Hard; + +// 设置选择 +clashTest.SelectionA = new ClashSelection(itemsA, document); +clashTest.SelectionB = new ClashSelection(itemsB, document); + +// 添加到文档 +document.ClashTestsData.Tests.Add(clashTest); +``` + +### 5. Timeliner 示例 + +**路径**: `PlugIns/Timeliner/` + +TimeLiner 集成示例,展示 4D 模拟功能。 + +```csharp +// 获取 Timeliner 数据 +var timeliner = document.Timeliner; + +// 创建任务 +TimelinerTask task = new TimelinerTask(); +task.Name = "Construction Task"; +task.StartDate = DateTime.Now; +task.EndDate = DateTime.Now.AddDays(7); +task.SimulationStatus = SimulationStatus.Active; + +// 关联模型 +task.Selection.CopyFrom(modelItems); + +// 添加任务 +timeliner.Tasks.Add(task); +``` + +### 6. Takeoff 示例 + +**路径**: `PlugIns/Takeoff/` + +工程量计算 (Quantification) 示例。 + +## 自动化示例 (Automation) + +### 1. CallExaminer + +**路径**: `Automation/CallExaminer/` + +展示如何通过自动化接口调用 Examiner 插件。 + +```csharp +// 启动 Navisworks 自动化 +NavisworksApplication app = new NavisworksApplication(); +app.OpenFile(filePath); + +// 执行插件 +app.ExecutePlugin("Examiner.Examiner", parameters); +``` + +### 2. MessageClientServer + +**路径**: `Automation/MessageClientServer/` + +展示插件间通信机制。 + +### 3. MessageSenderReceiver + +**路径**: `Automation/MessageSenderReceiver/` + +消息发送和接收示例。 + +## 控件示例 (Controls) + +### 1. Viewers + +**路径**: `Controls/Viewers/` + +独立的 Navisworks 查看器控件示例。 + +| 示例 | 说明 | +|------|------| +| `SDIViewer/` | 单文档界面查看器 | +| `MDIViewer/` | 多文档界面查看器 | + +```csharp +// 使用 DocumentControl +DocumentControl docControl = new DocumentControl(); +docControl.Dock = DockStyle.Fill; +this.Controls.Add(docControl); + +// 打开文件 +docControl.Document.OpenFile(filePath); +``` + +### 2. PublishFile + +**路径**: `Controls/PublishFile/` + +文件发布选项示例。 + +## 工具示例 (Tools) + +### 1. AppInfo + +**路径**: `Tools/AppInfo/` + +展示应用程序信息和事件监听。 + +### 2. CodeRun + +**路径**: `Tools/CodeRun/` + +动态代码执行工具,支持 C# 和 IronPython。 + +## 按功能查找示例 + +| 功能需求 | 推荐示例 | +|----------|----------| +| 创建停靠面板 | `BasicDockPanePlugin/`, `WpfDockPane/` | +| 使用 WPF | `WpfDockPane/`, `DatabaseDockPane/` | +| 模型搜索 | `Examiner/`, `SearchComparisonPlugIn/` | +| 鼠标交互 | `InputAndRenderHandling/` | +| 自定义渲染 | `InputAndRenderHandling/` | +| 碰撞检测 | `ClashDetective/` 下的各个示例 | +| TimeLiner | `Timeliner/` | +| 独立查看器 | `Controls/Viewers/` | +| 插件通信 | `MessageClientServer/` | + +## 项目文件参考 + +每个示例包含的项目文件: + +- `.csproj` - C# 项目文件 +- `Properties/AssemblyInfo.cs` - 程序集信息 +- 源代码文件 (.cs) + +## 构建和部署 + +1. 打开 `doc/navisworks_api/NET/examples/Examples.sln` +2. 选择项目并构建 +3. 插件输出到 Navisworks 插件目录: + + ``` + C:\ProgramData\Autodesk\Navisworks Manage 2026\plugins\ + ``` diff --git a/.agents/skills/nw-api/references/plugin-types.md b/.agents/skills/nw-api/references/plugin-types.md new file mode 100644 index 0000000..4e5753a --- /dev/null +++ b/.agents/skills/nw-api/references/plugin-types.md @@ -0,0 +1,286 @@ +# Navisworks 插件类型详解 + +## 插件基类对比 + +| 基类 | 继承关系 | 主要用途 | 触发方式 | +|------|---------|---------|---------| +| `DockPanePlugin` | ← `Plugin` | 停靠面板 UI | 用户点击 Ribbon 按钮 | +| `ToolPlugin` | ← `Plugin` | 鼠标 3D 交互工具 | 用户点击后进入工具模式 | +| `RenderPlugin` | ← `Plugin` | 自定义 3D 渲染 | 自动在渲染时调用 | +| `AddInPlugin` | ← `Plugin` | 简单命令 | 用户点击 Ribbon 按钮 | +| `EventWatcherPlugin` | ← `Plugin` | 监听文档事件 | 自动注册,事件触发 | +| `CommandHandlerPlugin` | - | 自定义命令处理器 | 命令调用时触发 | + +## 1. DockPanePlugin + +用于创建停靠在 Navisworks 窗口中的面板。 + +```csharp +[DockPanePlugin(400, 600, FixedSize = false)] +[Plugin("PluginName", "DeveloperID", DisplayName = "Display Name")] +[RibbonLayout("RibbonTabName")] +[RibbonTab("Home", DisplayName = "Home")] +[Command("CommandName", DisplayName = "Open Panel", Icon = "icon.png")] +public class MyDockPanePlugin : DockPanePlugin +{ + public override Control CreateControlPane() + { + // 返回 Windows Forms 或 WPF 控件 + var host = new ElementHost(); + host.Child = new MyWpfUserControl(); + host.Dock = DockStyle.Fill; + return host; + } + + public override void DestroyControlPane(Control control) + { + control?.Dispose(); + } +} +``` + +## 2. ToolPlugin + +用于创建需要与 3D 视图交互的工具。 + +```csharp +[ToolPlugin("ToolName", "DeveloperID", DisplayName = "Tool Display Name")] +[Plugin("PluginName", "DeveloperID")] +[RibbonLayout("RibbonTabName")] +[RibbonTab("Home", DisplayName = "Home")] +[Command("CommandName", DisplayName = "Activate Tool", Icon = "icon.png")] +public class MyToolPlugin : ToolPlugin +{ + public override bool MouseDown(MouseButton button, int x, int y) + { + // 处理鼠标按下 + // 返回 true 表示已处理事件 + return true; + } + + public override bool MouseMove(int x, int y) + { + // 处理鼠标移动 + return true; + } + + public override bool MouseUp(MouseButton button, int x, int y) + { + // 处理鼠标释放 + return true; + } + + public override void OnActivate() + { + // 工具激活时调用 + base.OnActivate(); + } + + public override void OnDeactivate() + { + // 工具停用时调用 + base.OnDeactivate(); + } +} +``` + +### 获取 3D 点击坐标 + +```csharp +public override bool MouseDown(MouseButton button, int x, int y) +{ + if (button == MouseButton.Left) + { + // 将屏幕坐标转换为 3D 射线 + var view = Application.ActiveDocument.CurrentViewpoint; + var pickResult = view.PickItemFromPoint(x, y); + + if (pickResult != null) + { + Point3D point = pickResult.Point; + // 使用点击的 3D 坐标 + } + } + return true; +} +``` + +## 3. RenderPlugin + +用于在 3D 视图中渲染自定义图形。 + +```csharp +[RenderPlugin("RenderPluginName", "DeveloperID")] +[Plugin("PluginName", "DeveloperID")] +public class MyRenderPlugin : RenderPlugin +{ + public override void Render(View view, RenderContext context) + { + // 在这里进行自定义渲染 + // 使用 context 绘制线条、点、文本等 + + // 示例:绘制一条红线 + var points = new List + { + new Point3D(0, 0, 0), + new Point3D(10, 10, 10) + }; + + context.DrawLines(points, new Color(1, 0, 0), 2.0f); + } +} +``` + +## 4. AddInPlugin + +最简单的插件类型,用于执行一次性命令。 + +```csharp +[AddInPlugin("AddInName", "DeveloperID", DisplayName = "Command Name")] +[RibbonTab("Home", DisplayName = "Home")] +[Command("CommandName", DisplayName = "Run Command", Icon = "icon.png")] +public class MyAddInPlugin : AddInPlugin +{ + public override int Execute(params string[] parameters) + { + // 执行命令逻辑 + MessageBox.Show("Hello from AddIn!"); + return 0; // 返回 0 表示成功 + } +} +``` + +## 5. EventWatcherPlugin + +用于监听文档事件。 + +```csharp +[EventWatcherPlugin("EventWatcherName", "DeveloperID")] +[Plugin("PluginName", "DeveloperID")] +public class MyEventWatcher : EventWatcherPlugin +{ + public override void OnDocumentChanged(object sender, DocumentEventArgs e) + { + // 文档变更时触发 + } + + public override void OnSelectionChanged(object sender, EventArgs e) + { + // 选择变更时触发 + } + + public override void OnViewChanged(object sender, ViewEventArgs e) + { + // 视图变更时触发 + } +} +``` + +## 插件属性详解 + +### Plugin 属性 + +```csharp +[Plugin("PluginName", "DeveloperID", + DisplayName = "显示名称", + ToolTip = "鼠标悬停提示", + LoadForCanExecute = true)] +``` + +### RibbonTab 属性 + +```csharp +[RibbonTab("TabName", DisplayName = "Tab 显示名称")] +``` + +### RibbonLayout 属性 + +```csharp +[RibbonLayout("LayoutName")] +``` + +### Command 属性 + +```csharp +[Command("CommandName", + DisplayName = "命令显示名称", + ToolTip = "命令提示", + Icon = "icon.png", + LargeIcon = "icon_large.png", + Shortcut = "Ctrl+Shift+X")] +``` + +### DockPanePlugin 属性 + +```csharp +[DockPanePlugin(width, height, + FixedSize = false, // 是否固定大小 + MinimumWidth = 200, // 最小宽度 + MinimumHeight = 300, // 最小高度 + HasDockingFrames = true)] // 是否有停靠框架 +``` + +## COM 插件注册 + +COM 插件需要注册到系统注册表。 + +### 1. 为程序集添加 GUID + +```csharp +// 在 AssemblyInfo.cs 中 +[assembly: Guid("YOUR-GUID-HERE")] + +// 在插件类上添加 ProgId +[ProgId("YourCompany.YourPlugin")] +public class YourPlugin : DockPanePlugin { } +``` + +### 2. 注册插件 + +```bash +# 使用 Visual Studio 自动注册(开发时) +# 或在注册表中手动添加: +# HKLM\SOFTWARE\Autodesk\Navisworks Manage\23.0\COM Plugins +# 创建字符串值,名称为 ProgId,值为空 + +# 或使用 nwregasm.bat +nwregasm.bat "path\to\your\plugin.dll" +``` + +## 项目文件配置 + +### 必要的引用 + +```xml + + + + + + + +``` + +### 输出路径 + +插件应该输出到 Navisworks 插件目录: + +``` +C:\ProgramData\Autodesk\Navisworks Manage 2026\plugins\YourPluginName\ +``` + +## 调试插件 + +1. 设置启动外部程序: + - 路径:`C:\Program Files\Autodesk\Navisworks Manage 2026\Roamer.exe` + +2. 附加到进程调试: + - 在 Visual Studio 中选择 "附加到进程" + - 选择 `Roamer.exe` + +3. 日志输出: + + ```csharp + // 使用 System.Diagnostics.Debug + System.Diagnostics.Debug.WriteLine("Debug message"); + ```