Getting XYZ or Navisworks Insertion Point through automation .net or VBA
Here are the steps and sample code I made to learn about getting the navisworks insertion point or midpoint of a component. I know how to find the component by its id (I am using AutoPLANT component id), now I know how to find the midpoint of that component or the location of that component.
Steps to find the navisworks insertion point
- Accessing the file units and location information using Navisworks .NET API
- A pdf primer on Navisworks basic objects and how those objects are related (key resource)
- I made some VBA to put pause points and look at objects as they went by. In short
- start with a path object – in this code example – the currently selected objects (so select one to keep it easy!!!)
- Pause points/Interest points are the Beep lines which might have been replaced with Debug.Print lines
- In our example, I am looking for AutoPLANT components with a unique id that would similar to “AT_HSHF31AB_2Q7” (the 2nd set of strings is the doc id and the last part is the unique AutoPLANT part id in that doc)
- look for through the code below for *********** ANSWER *********** to get where we get the Navisworks Insertion or midpoint of our component
Code to find the navisworks insertion point – read the comments to follow along
Sub FindSomething() Dim nwObj As NavisworksAutomationAPI10.Document Set nwObj = GetObject(, "Navisworks.Document.10") 'nw 2013 Debug.Print "Visible:" & nwObj.Visible nwObj.Visible = True nwObj.StayOpen ' critical!!!! See http://elbsolutions.com/projects/getobjectclassnamehere-only-works-the-first-time-why-a-look-into-the-rot-table-navisworks-and-other-apps-too-that-use-activex/ 'nwObj.state.CurrentView = nwObj.state.SavedViews(1).anonview Dim mstate As InwOpState Set mstate = nwObj.state Dim bob As VarEnum Dim b As Variant Dim b1 As InwSelectionPathsColl Dim myPath As InwOaPath Dim N As Variant Dim myNode As InwOaNode Dim n1 As InwOaPartition Dim bBox As InwLBox3f Dim a As Variant Dim a1 As InwOaPublishAttribute Dim a2 As InwOaPropertyAttribute Dim a3 As InwOaPropertyAttribute Dim a4 As InwOaPropertyAttribute Beep 'Pause here For Each b In mstate.CurrentSelection.Paths Set myPath = b Debug.Print "ObjectName: " & myPath.ObjectName 'The loop here was added near the end of the investigation so we can see how ' myPath is assembled/represented - in specific UserName For Each N In myPath.Nodes Set myNode = N Debug.Print "Class: " & myNode.ClassName & " ClassUserName:" & myNode.ClassUserName & " UserName: " & myNode.username 'Beep 'Pause here Next 'This is the orignal loop looking at attributes and other properties of the nodes in each path For Each N In myPath.Nodes Set myNode = N Set bBox = myNode.GetBoundingBox(False, False) Beep ' pause here to take a look at myNode and bBox ' the myNode nodes seem to transverse the heirarchy from the root downwards ' down the path 'b' If (VBA.Left(myNode.username, 3) = "AT_") Then ' this line was added after I looked at the UserName property and it was the string I was interested in Debug.Print "" Debug.Print "myPath.Nodes.ObjectName:" & N.ObjectName Debug.Print "myPath.Nodes.ObjectName (isGeometry):" & myNode.IsGeometry Debug.Print "myPath.Nodes.ObjectName (isGeometry):" & myNode.IsGeometry If Not bBox.IsEmpty Then ' Here is the bounding box's limits and average (mid point) ' the mid point is the xyz location we are intereseted in. ' ******** ANSWER ************ Debug.Print "Data1 min: " & bBox.min_pos.Data1 & " max: " & bBox.max_pos.Data1 & " avg: " & ((bBox.min_pos.Data1 + bBox.max_pos.Data1) / 2) Debug.Print "Data2 min: " & bBox.min_pos.Data2 & " max: " & bBox.max_pos.Data2 & " avg: " & ((bBox.min_pos.Data2 + bBox.max_pos.Data2) / 2) Debug.Print "Data3 min: " & bBox.min_pos.Data3 & " max: " & bBox.max_pos.Data3 & " avg: " & ((bBox.min_pos.Data3 + bBox.max_pos.Data3) / 2) End If 'Set n1 = n If N.ObjectName <> "nwOaPath" And N.ObjectName <> "nwOaPartition" Then Beep For Each a In N.Attributes Debug.Print vbTab & "** attribute.ObjectName:" & a.ObjectName 'Beep ' Pause Here ' I think the info below is a red-herring for what I require Select Case a.ObjectName Case "nwOaPublishAttribute" Set a1 = a Debug.Print "author:" & a1.Author Debug.Print "ClassName:" & a1.ClassName Debug.Print "ClassUserName:" & a1.ClassUserName Debug.Print "Comments:" & a1.Comments Debug.Print "Copyright:" & a1.Copyright 'Debug.Print "ExpiryDate:" & CStr(a1.ExpiryDate) Debug.Print "flags:" & a1.flags Debug.Print "Keywords:" & a1.Keywords Debug.Print "ObjectName:" & a1.ObjectName Debug.Print "Subject:" & a1.Subject Debug.Print "Title:" & a1.Title Debug.Print "UserName:" & a1.username Case "nwOaPartition" Beep Case "nwOaMaterial" Dim mat As InwOaMaterial Set mat = a Case Else Dim apart As InwOaPartition Dim apropa As InwOaPropertyAttribute ' Set apropa = a ' Set apart = a Beep End Select 'Set a1 = a Beep Next Beep End If End If Next Next mstate.CurrentSelection.Paths Beep End Sub