7.1 KiB
7.1 KiB
Navisworks API 常用模式
1. 模型遍历
遍历所有模型项
// 获取所有模型项
IEnumerable<ModelItem> allItems =
Application.ActiveDocument.Models.RootItemDescendantsAndSelf;
// 遍历特定模型
foreach (Model model in document.Models)
{
foreach (ModelItem item in model.RootItem.DescendantsAndSelf)
{
// 处理每个模型项
}
}
获取子节点
// 获取所有后代(不包括自己)
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 类
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 查询
var results = document.Models.RootItemDescendantsAndSelf
.Where(x => x.HasGeometry && !x.IsHidden)
.Where(x => x.ClassDisplayName.ToLower().Contains("wall"));
3. 选择操作
// 获取当前选择
var currentSelection = document.CurrentSelection.SelectedItems;
// 清空选择
document.CurrentSelection.Clear();
// 添加到选择
document.CurrentSelection.Add(modelItem);
// 复制集合到选择
document.CurrentSelection.CopyFrom(modelItems);
4. 可见性控制
// 隐藏项目
ModelItemCollection itemsToHide = new ModelItemCollection();
itemsToHide.Add(modelItem);
document.Models.SetHidden(itemsToHide, true);
// 显示项目
document.Models.SetHidden(itemsToHide, false);
// 检查是否隐藏
if (modelItem.IsHidden) { }
5. 文件导出
// 保存 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()- 返回当前实际显示的包围盒
应用变换
// 获取原始 Transform
Transform3D originalTransform = modelItem.Transform;
// 应用增量变换
var doc = Application.ActiveDocument;
var modelItems = new ModelItemCollection { modelItem };
doc.Models.OverridePermanentTransform(modelItems, newTransform, false);
// 重置到原始位置
doc.Models.ResetPermanentTransform(modelItems);
绕物体中心旋转(需要补偿)
// 关键: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 方式
// 查找属性分类
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/
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)
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 线程中执行
// ❌ 错误:在后台线程调用
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); // 安全执行
});
});
检查线程状态
var apartmentState = System.Threading.Thread.CurrentThread.GetApartmentState();
bool isMainThread = System.Windows.Application.Current.Dispatcher.CheckAccess();
9. 碰撞检测 (ClashDetective)
// 获取碰撞测试
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 集成
// 获取 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);