319 lines
8.5 KiB
Markdown
319 lines
8.5 KiB
Markdown
# 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` 相关示例 - 高级功能示例 |