NavisworksTransport/.agents/skills/nw-api/references/api-usage-patterns.md

293 lines
7.1 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 常用模式
## 1. 模型遍历
### 遍历所有模型项
```csharp
// 获取所有模型项
IEnumerable<ModelItem> 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);
```