我正在尝试创建一个操作来检查 Autodesk Navisworks 中的当前选择是否是特定碰撞测试结果的一部分,最重要的是,选择包含任何选定元素的所有碰撞结果。
我获取碰撞结果和模型项目交集的代码:
internal List<ModelItem> GroupIntersectingClashResults(Guid clashTestId, NW.ModelItemCollection clashResultSelectionToCheck)
{
DocumentClash clashData = doc.GetClash();
DocumentClashTests clashTests = clashData.TestsData;
var targetTest = clashTests.Tests.FirstOrDefault(t => t.Guid == clashTestId) as ClashTest;
if (targetTest == null)
{
Log.Warning("Clash test not found for id: {Id}", clashTestId);
return [];
}
List<IClashResult> intersectingResults = FindIntersectingClashResults(targetTest, clashResultSelectionToCheck);
if (!intersectingResults.Any())
{
Log.Warning("No intersecting items found for clash test id: {Id}", clashTestId);
return [];
}
var mic = new List<ModelItem>();
foreach (IClashResult clashResult in intersectingResults)
{
mic.AddRange(clashResult.Selection1);
mic.AddRange(clashResult.Selection2);
}
return mic;
}
private static List<IClashResult> FindIntersectingClashResults(ClashTest clashTest, NW.ModelItemCollection selectionToCheck)
{
var intersectionResults = new List<IClashResult>();
foreach (SavedItem item in clashTest.Children)
{
if (item is not IClashResult clashResult)
continue;
if (selectionToCheck.IsAnyContained(clashResult.CompositeItemSelection1) || selectionToCheck.IsAnyContained(clashResult.CompositeItemSelection2))
intersectionResults.Add(clashResult);
}
return intersectionResults;
}
这段代码工作正常,我真的根据当前选择的项目获取模型项目。但是,当我尝试使用 Navisworks API 选择它们时,我收到以下代码的空引用异常:
public ClashResultsNavigatorControl()
{
InitializeComponent();
InitializeContextMenu();
_doc = NW.Application.ActiveDocument;
_clashTestNames = new Dictionary<Guid, string>();
NW.Application.ActiveDocument.Models.CollectionChanged += OnDocumentChange;
_doc.CurrentSelection.Changed += OnCurrentSelectionChange;
Disposed += OnDispose;
_doc.GetClash().TestsData.Changed += OnClashTestsDataChange;
}
private void OnCurrentSelectionChange(object sender, EventArgs e)
{
try
{
var clashResultUtils = new ClashResultUtils(_doc);
if (_doc.CurrentSelection.SelectedItems.Count == 0)
return;
List<ModelItem> selection = clashResultUtils
.GroupIntersectingClashResults(_selectedClashTest.Guid, _doc.CurrentSelection.SelectedItems);
foreach (ModelItem modelItem in selection)
{
var a = _doc.Models.FindIdForModelItem(modelItem);
}
if (selection.Count == 0)
return;
_doc.CurrentSelection.Changed -= OnCurrentSelectionChange;
_doc.CurrentSelection.CopyFrom(selection);
}
catch (Exception ex)
{
ExceptionHandler.Handle(ex);
}
finally
{
_doc.CurrentSelection.Changed -= OnCurrentSelectionChange;
_doc.CurrentSelection.Changed += OnCurrentSelectionChange;
}
}
在线:
_doc.CurrentSelection.CopyFrom(selection);
但是该行中没有一个元素为空。 NativeHandle.cs 中的 RuntimeChecks 方法发生异常。
基本上,需要到达几何级别,然后返回到第一个对象。以这种方式创建的模型项集合可以用作当前选择。我尝试过的其他一切都不起作用。
private ModelItemCollection GetModelItemsFromClashResults(List<ClashResult> clashResults)
{
var modelItems = new List<ModelItem>();
foreach (ClashResult clashResult in clashResults)
{
ModelItem firstObject1 = clashResult.CompositeItem1.FindFirstGeometry().Item.FindFirstObjectAncestor();
ModelItem firstObject2 = clashResult.CompositeItem2.FindFirstGeometry().Item.FindFirstObjectAncestor();
modelItems.Add(firstObject1);
modelItems.Add(firstObject2);
}
var collectionToFocus = new ModelItemCollection();
collectionToFocus.AddRange(modelItems);
return collectionToFocus;
}