NavisworksTransport/doc/design/2026/NavisworksAPI使用方法.md
2025-08-18 23:55:01 +08:00

319 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Navisworks API 使用方法指南
基于真实官方示例的正确API用法总结
## 参考示例来源
基于以下官方示例文件的真实API用法
- `C:\Users\Tellme\apps\NavisworksTransport\doc\navisworks_api\NET\examples\PlugIns\SearchComparisonPlugIn\SearchComparisonPlugIn.cs`
- `C:\Users\Tellme\apps\NavisworksTransport\doc\navisworks_api\NET\examples\PlugIns\Examiner\Examiner.cs`
## 1. 模型遍历和节点访问
### 1.1 正确的遍历方式
```csharp
// ✅ 正确:获取所有模型项
IEnumerable<ModelItem> allItems =
Application.ActiveDocument.Models.RootItemDescendantsAndSelf;
// ✅ 正确:遍历特定模型的所有项
foreach (Model model in document.Models)
{
foreach (ModelItem item in model.RootItem.DescendantsAndSelf)
{
// 处理每个模型项
}
}
// ✅ 正确:只获取顶级节点
foreach (Model model in document.Models)
{
foreach (ModelItem topLevelItem in model.RootItem.Children)
{
// 处理顶级节点
}
}
```
### 1.2 获取子节点
```csharp
// ✅ 正确:获取某个节点的所有后代
var childItems = selectedItem.DescendantsAndSelf.Where(x => x != selectedItem);
// ✅ 正确:只获取直接子节点
foreach (ModelItem child in parentItem.Children)
{
// 处理直接子节点
}
```
### 1.3 遍历祖先节点
```csharp
// ✅ 正确:向上遍历父节点链
var current = selectedItem.Parent;
while (current != null)
{
// 处理祖先节点
current = current.Parent;
}
```
## 2. 搜索和查询
### 2.1 使用LINQ查询
```csharp
// ✅ 正确使用LINQ查询模型项
IEnumerable<ModelItem> results =
Application.ActiveDocument.Models.RootItemDescendantsAndSelf
.Where(x =>
x.HasGeometry &&
!x.IsHidden &&
x.ClassDisplayName.ToLower().Contains("wall"));
```
### 2.2 使用Search类
```csharp
// ✅ 正确使用Search API
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);
```
### 2.3 迭代遍历(性能对比)
```csharp
// ✅ 可用但性能较低:迭代方法
ModelItemCollection searchResults = new ModelItemCollection();
foreach (ModelItem modelItem in Application.ActiveDocument.Models.CreateCollectionFromRootItems().DescendantsAndSelf)
{
if (modelItem.HasGeometry && !modelItem.IsHidden)
searchResults.Add(modelItem);
}
```
## 3. 选择操作
### 3.1 操作当前选择
```csharp
// ✅ 正确:获取当前选择
var currentSelection = document.CurrentSelection.SelectedItems;
// ✅ 正确:清空选择
document.CurrentSelection.Clear();
// ✅ 正确:添加到选择
document.CurrentSelection.Add(modelItem);
// ✅ 正确:复制集合到选择
document.CurrentSelection.CopyFrom(modelItems);
```
## 4. 可见性控制
### 4.1 隐藏和显示
```csharp
// ✅ 正确:隐藏项目
ModelItemCollection itemsToHide = new ModelItemCollection();
itemsToHide.Add(modelItem);
document.Models.SetHidden(itemsToHide, true);
// ✅ 正确:显示项目
document.Models.SetHidden(itemsToHide, false);
// ✅ 正确:检查是否隐藏
if (modelItem.IsHidden)
{
// 项目被隐藏
}
```
## 5. 文件导出
### 5.1 基本文件保存
```csharp
// ✅ 正确保存NWD文件
document.SaveFile(filePath);
// ✅ 正确:指定版本保存
document.SaveFile(filePath, DocumentFileVersion.Current);
```
### 5.2 ExportToNwd API
```csharp
// ✅ 正确使用ExportToNwd导出
var exportOptions = new NwdExportOptions();
exportOptions.ExcludeHiddenItems = true; // 只导出可见项目
exportOptions.EmbedXrefs = false;
exportOptions.PreventObjectPropertyExport = false;
document.ExportToNwd(saveFilePath, exportOptions);
```
## 6. 性能最佳实践
### 6.1 避免的做法
```csharp
// ❌ 错误使用不存在的API
// SearchCondition.HasAncestor(items) // 这个API不存在
// ❌ 错误:深度递归遍历
// void RecursiveTraversal(ModelItem item) // 大模型中可能导致堆栈溢出
```
### 6.2 推荐的做法
```csharp
// ✅ 推荐使用内置的DescendantsAndSelf
var allDescendants = rootItem.DescendantsAndSelf;
// ✅ 推荐使用LINQ进行高效查询
var filteredItems = allItems.Where(x => x.HasGeometry);
// ✅ 推荐:批量操作而不是逐个操作
ModelItemCollection batchItems = new ModelItemCollection();
// 添加所有需要处理的项目
document.Models.SetHidden(batchItems, true); // 一次性操作
```
## 7. 完整示例:多选节点导出
```csharp
public void ExportSelectedNodes(List<ModelItem> selectedItems, string filePath)
{
var document = Application.ActiveDocument;
var nodesToKeepVisible = new HashSet<ModelItem>();
// 1. 收集需要保持可见的节点
foreach (var selectedItem in selectedItems)
{
// 添加选中节点本身
nodesToKeepVisible.Add(selectedItem);
// 添加所有祖先节点
var current = selectedItem.Parent;
while (current != null)
{
nodesToKeepVisible.Add(current);
current = current.Parent;
}
// 添加所有子节点(可选)
var childItems = selectedItem.DescendantsAndSelf.Where(x => x != selectedItem);
foreach (ModelItem child in childItems)
{
nodesToKeepVisible.Add(child);
}
}
// 2. 收集顶级节点并决定隐藏哪些
var itemsToHide = new ModelItemCollection();
foreach (Model model in document.Models)
{
foreach (ModelItem topLevelItem in model.RootItem.Children)
{
bool shouldKeep = false;
// 检查是否包含选中节点
foreach (var selectedItem in selectedItems)
{
var current = selectedItem;
while (current != null)
{
if (current == topLevelItem)
{
shouldKeep = true;
break;
}
current = current.Parent;
}
if (shouldKeep) break;
}
if (!shouldKeep)
{
itemsToHide.Add(topLevelItem);
}
}
}
// 3. 执行隐藏和导出
try
{
document.Models.SetHidden(itemsToHide, true);
var exportOptions = new NwdExportOptions();
exportOptions.ExcludeHiddenItems = true;
document.ExportToNwd(filePath, exportOptions);
}
finally
{
// 4. 恢复可见性
document.Models.SetHidden(itemsToHide, false);
}
}
```
## 8. 常用属性和方法速查
### ModelItem 常用属性
- `HasGeometry` - 是否有几何体
- `IsHidden` - 是否隐藏
- `IsRequired` - 是否必需
- `IsInsert` - 是否为插入对象
- `IsLayer` - 是否为图层
- `DisplayName` - 显示名称
- `ClassName` - 类名
- `ClassDisplayName` - 类显示名称
- `Parent` - 父节点
- `Children` - 子节点集合
- `DescendantsAndSelf` - 所有后代节点(包括自己)
### Document 常用方法
- `SaveFile(string path)` - 保存文件
- `ExportToNwd(string path, NwdExportOptions options)` - 导出NWD
- `CurrentSelection` - 当前选择
- `Models` - 模型集合
### Models 常用方法
- `SetHidden(ModelItemCollection items, bool hidden)` - 设置隐藏状态
- `SetRequired(ModelItemCollection items, bool required)` - 设置必需状态
- `RootItemDescendantsAndSelf` - 所有根项目的后代
## 9. 错误避免指南
1. **不要使用不存在的API**:如 `SearchCondition.HasAncestor`
2. **避免深度递归**:使用内置的 `DescendantsAndSelf` 代替手写递归
3. **批量操作**:使用 `ModelItemCollection` 进行批量设置,而不是逐个操作
4. **正确的命名空间**:确保引用 `using Autodesk.Navisworks.Api;`
5. **异常处理**文件操作和API调用要适当处理异常
6. **资源清理**:隐藏操作后要恢复原始状态
## 10. 参考官方示例
强烈建议查看以下官方示例了解更多用法:
- `SearchComparisonPlugIn.cs` - 搜索性能对比
- `Examiner.cs` - LINQ查询示例
- `BasicDockPanePlugin.cs` - 基础插件结构
- `ClashDetective` 相关示例 - 高级功能示例