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

8.5 KiB
Raw Blame History

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 正确的遍历方式

// ✅ 正确:获取所有模型项
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 获取子节点

// ✅ 正确:获取某个节点的所有后代
var childItems = selectedItem.DescendantsAndSelf.Where(x => x != selectedItem);

// ✅ 正确:只获取直接子节点
foreach (ModelItem child in parentItem.Children)
{
    // 处理直接子节点
}

1.3 遍历祖先节点

// ✅ 正确:向上遍历父节点链
var current = selectedItem.Parent;
while (current != null)
{
    // 处理祖先节点
    current = current.Parent;
}

2. 搜索和查询

2.1 使用LINQ查询

// ✅ 正确使用LINQ查询模型项
IEnumerable<ModelItem> results = 
    Application.ActiveDocument.Models.RootItemDescendantsAndSelf
    .Where(x => 
        x.HasGeometry && 
        !x.IsHidden &&
        x.ClassDisplayName.ToLower().Contains("wall"));

2.2 使用Search类

// ✅ 正确使用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 迭代遍历(性能对比)

// ✅ 可用但性能较低:迭代方法
ModelItemCollection searchResults = new ModelItemCollection();
foreach (ModelItem modelItem in Application.ActiveDocument.Models.CreateCollectionFromRootItems().DescendantsAndSelf)
{
    if (modelItem.HasGeometry && !modelItem.IsHidden)
        searchResults.Add(modelItem);
}

3. 选择操作

3.1 操作当前选择

// ✅ 正确:获取当前选择
var currentSelection = document.CurrentSelection.SelectedItems;

// ✅ 正确:清空选择
document.CurrentSelection.Clear();

// ✅ 正确:添加到选择
document.CurrentSelection.Add(modelItem);

// ✅ 正确:复制集合到选择
document.CurrentSelection.CopyFrom(modelItems);

4. 可见性控制

4.1 隐藏和显示

// ✅ 正确:隐藏项目
ModelItemCollection itemsToHide = new ModelItemCollection();
itemsToHide.Add(modelItem);
document.Models.SetHidden(itemsToHide, true);

// ✅ 正确:显示项目
document.Models.SetHidden(itemsToHide, false);

// ✅ 正确:检查是否隐藏
if (modelItem.IsHidden)
{
    // 项目被隐藏
}

5. 文件导出

5.1 基本文件保存

// ✅ 正确保存NWD文件
document.SaveFile(filePath);

// ✅ 正确:指定版本保存
document.SaveFile(filePath, DocumentFileVersion.Current);

5.2 ExportToNwd API

// ✅ 正确使用ExportToNwd导出
var exportOptions = new NwdExportOptions();
exportOptions.ExcludeHiddenItems = true;  // 只导出可见项目
exportOptions.EmbedXrefs = false;
exportOptions.PreventObjectPropertyExport = false;

document.ExportToNwd(saveFilePath, exportOptions);

6. 性能最佳实践

6.1 避免的做法

// ❌ 错误使用不存在的API
// SearchCondition.HasAncestor(items) // 这个API不存在

// ❌ 错误:深度递归遍历
// void RecursiveTraversal(ModelItem item) // 大模型中可能导致堆栈溢出

6.2 推荐的做法

// ✅ 推荐使用内置的DescendantsAndSelf
var allDescendants = rootItem.DescendantsAndSelf;

// ✅ 推荐使用LINQ进行高效查询
var filteredItems = allItems.Where(x => x.HasGeometry);

// ✅ 推荐:批量操作而不是逐个操作
ModelItemCollection batchItems = new ModelItemCollection();
// 添加所有需要处理的项目
document.Models.SetHidden(batchItems, true); // 一次性操作

7. 完整示例:多选节点导出

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 相关示例 - 高级功能示例