Running a command on T&P Add-in Occurrence in Drawing

Running a command on T&P Add-in Occurrence in Drawing

A.Acheson
Mentor Mentor
4,052 Views
20 Replies
Message 1 of 21

Running a command on T&P Add-in Occurrence in Drawing

A.Acheson
Mentor
Mentor

Is it possible to run a command on specific assembly occurrences in the drawing environment.

 

Using the add-in Tube and pipe. If you right click on the Run assembly occurrence in the browser you are presented with a command “Include Route Centerlines”

I placed this snippet

 

(ThisApplication.CommandManager.ControlDefinitions(“CADC:Drawing:CenterlineRecoveryChecked”).Execute)

 

at the point where the loop found the Occurrence.
Using this method the button is not triggered.

 

 I am guessing this is the case because the command manager is trying to act on the whole drawing and not on the specific Occurrences.  Is there a method to do this?.

 

Commands:

Include Route Centerlines - CADC:Drawing:CenterlineRecoveryChecked
Include Route Centerlines - CADC:Drawing:CenterlineRecoveryTriState
Include Route Centerlines - CADC:Drawing:CenterlineRecoveryUnchecked

Resources used.

https://modthemachine.typepad.com/my_weblog/2009/03/running-commands-using-the-api.html

 

 

Any help greatly appreciated.

 

 

 

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
4,053 Views
20 Replies
Replies (20)
Message 2 of 21

gcoombridge
Advisor
Advisor

Hi Alan, I've had a quick look at this - it seems to me you would need to run the control def with a brower node selected (because this is the manual way you would do it). Have a look at these references:

 

Expand browser and select part by selecting edge in drawing view - Manufacturing DevBlog (typepad.co...

Select Multiple Browser Nodes in Drawing - Autodesk Community - Inventor

 

Iterating through the browser nodes seems to require the pane and topnode to be defined first.

 

Use iLogic Copy? Please consider voting for this long overdue idea (not mine):https://forums.autodesk.com/t5/inventor-ideas/string-replace-for-ilogic-design-copy/idi-p/3821399
0 Likes
Message 3 of 21

A.Acheson
Mentor
Mentor

@gcoombridge 

Thankyou for your reply. I got as far as to select the node manually and have the node display name show up but as far as I can gather the command as I have it is trying to work on the complete drawing and not on the node. My knowledge is limited in most of this so it is like walking in the dark. 

 

 

'https://adndevblog.typepad.com/manufacturing/2013/01/get-items-selected-in-the-browser-pane-.html
Sub Main
	GetSelectedItemsInBrowser()
End Sub

Sub GetSelectedItemsInBrowser()
    Dim doc As Document
    doc = ThisApplication.ActiveDocument

    If Not TypeOf doc Is DrawingDocument Then
        MsgBox ("Open a drawing document first")
        Exit Sub
    End If

    Dim bp As BrowserPane
    bp = doc.BrowserPanes("DlHierarchy")
    
    Dim items As String
    items = GetSelectedItems(bp.TopNode.BrowserNodes)
    
    MsgBox(items)
	
	ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryChecked").Execute
	

	'ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryTriState").Execute
	'ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryUnchecked").Delete
	
End Sub

Function GetSelectedItems(nodes As BrowserNodesEnumerator) As String
    Dim node As BrowserNode
    For Each node In nodes
        If node.Selected Then
            GetSelectedItems = GetSelectedItems _
                + vbCrLf + node.BrowserNodeDefinition.Label
        End If
        
        GetSelectedItems = GetSelectedItems _
            + GetSelectedItems(node.BrowserNodes)
			
	
			
    Next
End Function



 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 4 of 21

gcoombridge
Advisor
Advisor

I can't seem to expand the browsernodes in the drawing without looping through each layer as below. This seems pretty untidy. I can find the one I was looking for ("Piping" in this case) but the control def doesn't have any effect.

 

I thought the BrowserPane.GetBrowserNodeFromObject Method would be the answer but I can't get that to work either when using the occurrence as the object. Probably a bit beyond my ilogic skills... I have used control defs in the past but they've all related to select sets in the model window - I've never looked at accessing the browser pane before

 

 

Dim oDoc As DrawingDocument = ThisDoc.Document
Dim oSheet As Sheet = oDoc.ActiveSheet

Dim oPane As BrowserPane = oDoc.BrowserPanes.Item("Model")
Dim oTopNode As BrowserNode = oPane.TopNode

Dim oNode As BrowserNode
Dim oSubNode As BrowserNode
Dim oSubSubNode As BrowserNode
Dim oCont As ControlDefinition

oTopNode.Expanded = True

For Each oNode In oTopNode.BrowserNodes
	For Each oSubNode In oNode.BrowserNodes
		For Each oSubSubNode In oSubNode.BrowserNodes
			If oSubSubNode.BrowserNodeDefinition.Label = "Piping" Then
				MsgBox("I found it...")

			End If
		Next
	Next
Next oNode

 

 

Use iLogic Copy? Please consider voting for this long overdue idea (not mine):https://forums.autodesk.com/t5/inventor-ideas/string-replace-for-ilogic-design-copy/idi-p/3821399
0 Likes
Message 5 of 21

A.Acheson
Mentor
Mentor

@gcoombridge 

We have a Winner...........................

Some how after much stumbling in the dark.  Turns out I may have been there yesterday getting the browser node to expand only for the description on the command being the opposite of what maybe it should be. The only drawback at the moment is the Browser Node label needs to be Fixed. Perhaps there is a contains "Some String" method that could be used.  

'https://forums.autodesk.com/t5/inventor-customization/select-multiple-browser-nodes-in-drawing/td-p/8020926
Sub Main()
    Dim oDoc As DrawingDocument
    oDoc = ThisApplication.ActiveDocument
    
    Dim oTopBrowserNode As BrowserNode
    oTopBrowserNode = oDoc.BrowserPanes.ActivePane.TopNode
    
    Dim objColl As ObjectCollection
    objColl = ThisApplication.TransientObjects.CreateObjectCollection
    
    Call Get_SelectedNodes(oTopBrowserNode, objColl)
    
    Dim oNode As BrowserNode
	For Each oNode In objColl
		
		oNode.Expanded = True   
   		oNode.DoPreSelect() 
		oNode.DoSelect()
       	        Dim oControlDef As ControlDefinition
	
		Selection = InputRadioBox("Pick One", "Include Route Centerlines", "Exclude Route Centerlines", Selection, Title := "iLogic")
		
		If Selection = True
			'Unsure of it's Function
			'ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryTriState").Execute
			
			'Includes the Route centerline....(opposite to it's name)
			oControlDef = ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryUnchecked")
		 	oControlDef.Execute
			
		Else
			'Excludes the Route centerline....(opposite to it's name)
        	        oControlDef = ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryChecked")
			oControlDef.Execute
		End If
			
    Next
	
	
    
End Sub

Sub Get_SelectedNodes(oTopBrowserNode As BrowserNode, ByRef objColl As ObjectCollection)
    Dim oNode As BrowserNode
    For Each oNode In oTopBrowserNode.BrowserNodes
		'For manual selection
    	'If oNode.Selected = True Then
	
		'Node Label needs to be Exact
		If oNode.BrowserNodeDefinition.Label = "Tube & Pipe Runs" Then
			Call objColl.Add(oNode)
        ElseIf oNode.BrowserNodes.Count > 0 Then
            Call Get_SelectedNodes(oNode, objColl)
		ElseIf oNode.BrowserNodes.Count < 0 Then
        End If
		
	Next
		
		
End Sub

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
Message 6 of 21

greggeorgi
Contributor
Contributor

Congrats on finding a solution! Here is an alternative way of thinking about the problem if you are interested. It may also include code snippets that you may or may not be familiar with. This approach hides or shows all centerlines in all runs on the active sheet. It uses the route object as the primary node though less efficient, it can be easily adapted to use the top level tube&run nodes. I did not include a radio button like you did.

 

As for your label concern, the label property is a string type so you can use

if oNode.BrowserNodeDefinition.Label.Contains("some text") then ....
Sub Main
	If Not TypeOf ThisDoc.Document Is DrawingDocument Then
		MsgBox("Open a drawing document first")
		Exit Sub
	End If

	Dim doc As DrawingDocument = ThisDoc.Document
	doc.SelectSet.Clear
	
	Dim bp As BrowserPane = doc.BrowserPanes("Model")
	
	Call GetRouteBrowserNodes(bp.GetBrowserNodeFromObject(doc.ActiveSheet).BrowserNodes) 'only touch active sheet.

	ThisApplication.CommandManager.ControlDefinitions.Item("AppBrowserCollapseAllCmd").Execute2(True)
	For Each obj As BrowserNode In tosel
		Dim n As BrowserNode = obj
		While n.Parent.Type = obj.Type
			n = n.Parent
			n.Expanded = True
		End While
		obj.DoSelect 'the command seems to act on the last selected object
		'ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryUnchecked").Execute2(True) 'shows centers if currently hidden
		ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryChecked").Execute2(True) 'hides centers if currently showinh
	Next
	ThisApplication.CommandManager.ControlDefinitions.Item("AppBrowserCollapseAllCmd").Execute2(True)
	doc.SelectSet.Clear
	
	'ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryTriState").Execute
End Sub

Dim tosel As New ArrayList 'store valid browsernodes

Sub GetRouteBrowserNodes(nodes As BrowserNodesEnumerator)
	For Each node As BrowserNode In nodes
		If node.NativeObject IsNot Nothing Then
			'Logger.Info(CType(node.NativeObject.type, ObjectTypeEnum).ToString)
			If (node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject)
				If (node.FullPath.Contains("Route")) 'assuming these are not renamed
					tosel.add(node)
					'Logger.Info(node.FullPath)
					Return 'a "route" will always be the final stage
				End If
			End If

			If node.NativeObject.type = ObjectTypeEnum.kDrawingViewObject OrElse
				node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject OrElse
				node.NativeObject.type = ObjectTypeEnum.kAssemblyComponentDefinitionObject Then
				GetRouteBrowserNodes(node.BrowserNodes)	'recursively search, only want to search valid node types
			End If
		End If
	Next
End Sub

 

Message 7 of 21

greggeorgi
Contributor
Contributor

Hello again! After digging a little, i found this other post https://forums.autodesk.com/t5/inventor-forum/ilogic-change-tube-run-color/m-p/7129296/highlight/tru... which showed a method to determine if a ComponentOccurrence is a piping occurrence! This means the browser node label does not matter if this method is used. I have updated my code from above to reflect the change. I also saw unreliable behavoir sometimes, so i added a DoEvents. which slows down the process a bit,  it seems to work more reliably.

Sub Main
	If Not TypeOf ThisDoc.Document Is DrawingDocument Then
		MsgBox("Open a drawing document first")
		Exit Sub
	End If

	Dim doc As DrawingDocument = ThisDoc.Document
	doc.SelectSet.Clear
	
	Dim bp As BrowserPane = doc.BrowserPanes("Model")
	
	Call GetRouteBrowserNodes(bp.GetBrowserNodeFromObject(doc.ActiveSheet).BrowserNodes) 'only touch active sheet.

	ThisApplication.CommandManager.ControlDefinitions.Item("AppBrowserCollapseAllCmd").Execute2(True)
	For Each obj As BrowserNode In tosel
		Dim n As BrowserNode = obj
		While n.Parent.Type = obj.Type
			n = n.Parent
			n.Expanded = True
		End While
		obj.DoSelect 'the command seems to act on the last selected object
		ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryUnchecked").Execute2(True) 'shows centers if currently hidden
		'ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryChecked").Execute2(True) 'hides centers if currently showing
           ThisApplication.UserInterfaceManager.DoEvents 'lets inventor catch up
	Next
	ThisApplication.CommandManager.ControlDefinitions.Item("AppBrowserCollapseAllCmd").Execute2(True)
	doc.SelectSet.Clear
	
	'ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryTriState").Execute
End Sub

Dim tosel As New ArrayList 'store valid browsernodes

Sub GetRouteBrowserNodes(nodes As BrowserNodesEnumerator)
	For Each node As BrowserNode In nodes
		If node.NativeObject IsNot Nothing Then
			'Logger.Info(CType(node.NativeObject.type, ObjectTypeEnum).ToString)
			If (node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject)
								If node.NativeObject.Definition.Document.DocumentInterests.HasInterest("Piping Runs Environment")
					'Use "Piping Runs Environment" for the top level run defintion
					'Use "Piping Run Environment" for individual runs like Run00, Run01
					'Use "Piping Route Environment"	for individual routes
					tosel.add(node)
					'Logger.Info(node.FullPath)
					Return 'this run is taken care of so don't search any deeper
				End If
			End If

			If node.NativeObject.type = ObjectTypeEnum.kDrawingViewObject OrElse
				node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject OrElse
				node.NativeObject.type = ObjectTypeEnum.kAssemblyComponentDefinitionObject Then
				GetRouteBrowserNodes(node.BrowserNodes)	'recursively search, only want to search valid node types
			End If
		End If
	Next
End Sub

 

0 Likes
Message 8 of 21

A.Acheson
Mentor
Mentor

@greggeorgi @gcoombridge 

 

Thank you very much for all this work it certainly has turbo charged this effort. My Drawing browser Node knowledge is slim to none. It works great in the main assembly with T&P main assembly and runs beneath.

1. Main Assembly

     1a. T&P Top Level

          1b. Runs

               1c.Routes

 

It is falling down when base view comes in at the lower levels for detailing. See example 1a-1 picture. 1a is the main assembly now and I think there is an issue with the recursive function. It isn't finding all the runs. I change the filter if statement to find all the run's. it only brings back one. 

	'Use "Piping Run Environment" for individual runs like Run00, Run01

Leaving  this filter in brings nothing back. Most likely working on the wrong level 

'Use "Piping Runs Environment" for the top level run defintion

 

 Changing the filter to routes see picture 1a-2 again the recursive function doesn't bring back all the routes. It is catching one route in each run. 

 

I read an article about issues passing a variable into a recursive function would this be the issue here? I tried a separate recursive rule yesterday and was getting it to stop even though when testing a list box would bring back all the correct values for the loop.

 

https://stackoverflow.com/questions/33071556/how-to-pass-my-previous-n-variables-in-for-loop-recursi...

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 9 of 21

greggeorgi
Contributor
Contributor

Test with using "Piping Route Environment" in the document interests line and commenting out the Return statement at the end of the IF statement in the recursive loop. It works for me that way currently. (basically same as filtering by Route label in your 1a-2 picture). The return statement is what was causing subsequent routes to be skipped. This will cause it to run slower overall, but it may be possible to refine the loop further depending on success/fail. The return statement worked originally because i was accessing the top level T&P element, but you've shown it is not always top level under the assembly definition. I do not use T&P so i didn't think of making views of the lower assemblies like that.

 

From what I can experience, in that detail state where the Runs are toplevel, I was not even able to show the centerline manually by r'clicking on the Run node. I had to go deeper to the Route Node to get the centerline. Also when i first open a T&P drawing, sometimes the ilogic will not work for hide or showing. It wont work until I manually run the command on a node? Have you experience that at all?

 

There is no issue with recusing here. The job of the recursive loop is to navigate the browser tree to all depths and find valid nodes. Attempting to speed up the recursing speed is done by filtering nodes. Unknown use cases could potentially cause the filter to skip over something that is not desired. The article you linked talked about retaining information of the previous loop, but this use case doesn't care about the past.

0 Likes
Message 10 of 21

greggeorgi
Contributor
Contributor

The method I just described also would also work if you make a view out of the Runs themselves, exept it seems to have the same bug as i descirbied above? I can't show the centerlines at all.

 

greggeorgi_0-1612387763392.png

 

0 Likes
Message 11 of 21

A.Acheson
Mentor
Mentor

@greggeorgi 

 

Fantastic I tried your suggestions. Yes I have seen the same thing as you did. working with 1b.Run as base view  if you expand the route node you cannot include centerlines until the Run has them included first. So I think we will need to target the Run assembly at each level and forget about the route approach. 

 

The overall goal is to be able to run this rule in a larger auto drawing creation rule from the main assembly that will loop through and automatically place the assembly base views switch the centerlines on when at the following levels in red. Drawings will be created at each level.  See attached pictures

1. Main Assembly

     1a. T&P Top Level Run

           1b. Runs

               1c.Routes

 

Appreciate the effort. I will sharpen the pencil a bit more. 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 12 of 21

greggeorgi
Contributor
Contributor

I think you missed attaching the pictures?

 

I think there is enough groundwork here for you to make something work. It will just be trial and error to the finish line. Let me know if you need any assistance as you progress and I will be happy to help.

 

One last issue I came across is the loop filter would only work for basic drawing views, it wouldn't work for detail views or other distinct view types. If you decide you need other view types, I modified the filter code to be

If node.NativeObject IsNot Nothing AndAlso 
	(TypeOf node.NativeObject Is DrawingView OrElse
	node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject OrElse
	node.NativeObject.type = ObjectTypeEnum.kAssemblyComponentDefinitionObject) Then
	    GetRouteBrowserNodes(node.BrowserNodes) 'recursively search, only want to search valid node types
End If

 This works because all DrawingViews extend the DrawingView type, while using Inventor's ObjectTypeEnum is intended to represent a single type always. Using TypeOf is quicker than checking against all the DrawingView type enum values and less typing.

0 Likes
Message 13 of 21

A.Acheson
Mentor
Mentor

@greggeorgi 

Attached pictures. I will attempt it again in the next few days no urgency.

Thankyou

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 14 of 21

A.Acheson
Mentor
Mentor

The below code will  activate tube and pipe routes in all runs at  1.Main Assembly

1a. T&P Top level Run and 1b Run. when placed as Views. This rule has worked well on it's own or when ran with a drawing creation rule placing each run in a drawing and activating the route centerlines. .
 
Due to a bug!! It is necessary to right mouse click on a T&P assembly Browser Node containing Include centerlines. Once the menu has opened once as shown below ( no need to click any button internally in the menu), there is no need to perform this operation again in this inventor session. Closing the session and starting a new requires this process to be repeated. 

Activating  Context Menu by RMB on T&P Browser node containing Route Centerline.png

'Error with clicking vs select set
'https://forums.autodesk.com/t5/inventor-customization/what-is-the-difference-between-selectset-select-and-clicking-on/td-p/9249928

Sub Main
	
	If Not TypeOf ThisApplication.ActiveDocument Is DrawingDocument Then
		MsgBox("Open a drawing document first")
		Exit Sub
	End If
	
	Dim doc As DrawingDocument
	doc = ThisApplication.ActiveDocument
	doc.SelectSet.Clear
	Dim bp As BrowserPane = doc.BrowserPanes("Model")
	
    Call GetRouteBrowserNodes(bp.GetBrowserNodeFromObject(doc.ActiveSheet).BrowserNodes) 'only touch active sheet.
    Call GetRunBrowserNodes(bp.GetBrowserNodeFromObject(doc.ActiveSheet).BrowserNodes)
	
	ThisApplication.CommandManager.ControlDefinitions.Item("AppBrowserCollapseAllCmd").Execute2(True)
	  For Each obj As BrowserNode In tosel
		Dim n As BrowserNode = obj
		While n.Parent.Type = obj.Type
			n = n.Parent
			n.Expanded = True 
		End While
		obj.DoPreSelect
		'Attempt to activate the context menu by RMB ona browser node containing routecenterline. This does not work as may be unsupported.
		'Imports System.Windows.Forms (Place in Header)
		'SendKeys.SendWait("+({F10})")'The parentheses indicates that F10 should be pressed while Shift is held down

		obj.DoSelect 'the command seems to act on the last selected object
 			'Includes the Route centerline....(opposite to it's name)
			oControlDef = ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryUnchecked")
		 	oControlDef.Execute
		
			'Excludes the Route centerline....(opposite to it's name)
'        	oControlDef = ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryChecked")
'			oControlDef.Execute
		 
		Call ThisApplication.UserInterfaceManager.DoEvents 'lets inventor catch up
	  Next
		ThisApplication.CommandManager.ControlDefinitions.Item("AppBrowserCollapseAllCmd").Execute2(True)
		doc.SelectSet.Clear
End Sub

Dim tosel As New ArrayList 'store valid browsernodes

Sub GetRouteBrowserNodes(nodes As BrowserNodesEnumerator)
	On Error Resume Next
	For Each node As BrowserNode In nodes
	
		If node.NativeObject IsNot Nothing Then
			'Logger.Info(CType(node.NativeObject.type, ObjectTypeEnum).ToString)
				
			If (node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject)
				
								If node.NativeObject.Definition.Document.DocumentInterests.HasInterest("Piping Route Environment")
									tosel.Add(node)
									End If
									
								'Use "Piping Runs Environment" for the top level run defintion
								'Use "Piping Run Environment" for individual runs like Run00, Run01
								'Use "Piping Route Environment"	for individual routes
								
								'Logger.Info(node.FullPath)
								'Return 'this run is taken care of so don't search any deeper
								
			End If
					If node.NativeObject IsNot Nothing AndAlso 
						(TypeOf node.NativeObject Is DrawingView OrElse
						node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject OrElse
						node.NativeObject.type = ObjectTypeEnum.kAssemblyComponentDefinitionObject) Then
						    GetRouteBrowserNodes(node.BrowserNodes) 'recursively search, only want to search valid node types
					End If
		End If
	Next
End Sub
Sub GetRunBrowserNodes(nodes As BrowserNodesEnumerator)
	On Error Resume Next
	For Each node As BrowserNode In nodes
	
		If node.NativeObject IsNot Nothing Then
			'Logger.Info(CType(node.NativeObject.type, ObjectTypeEnum).ToString)
				
			'If (node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject)
								If (node.FullPath.Contains("Run")) 'assuming these are not renamed
									
									tosel.add(node)
								End If
								'Use "Piping Runs Environment" for the top level run defintion
								'Use "Piping Run Environment" for individual runs like Run00, Run01
								'Use "Piping Route Environment"	for individual routes
								
								'Logger.Info(node.FullPath)
								'Return 'this run is taken care of so don't search any deeper
							
			End If
					If node.NativeObject IsNot Nothing AndAlso 
						(TypeOf node.NativeObject Is DrawingView OrElse
						node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject) Then
						    GetRunBrowserNodes(node.BrowserNodes) 'recursively search, only want to search valid node types
					End If
		'End If
	Next

End Sub

 

 

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
Message 15 of 21

greggeorgi
Contributor
Contributor

@A.Acheson 

 

Hi Alan. I am happy you got it working for all of your cases it seems. Your description of that bug got me thinking and I went back and optimized and cleaned up the code.

 

A comment related to your code first. Your second call on GetRunBrowserNodes is not guaranteed to work because you removed the check for kAssemblyComponentDefinitionObject. It is only working because the assembly has "Run" in its name and you are checking the node label. In your workflow, the Run will probably always have "Run" in the name but it would be better to not rely on it I think. The recursion does not actually search deeper than the drawing view top level nodes. From an efficiency stand point though, looping through the browser nodes twice is not a good idea as it takes a while. Your second run is quick because it only ends up one deep, but still not necessary when the first recursive loop already searches those nodes.

 

Now on to the new stuff. I originally added the node expanding part to try and combat the bug, it seems it was unnecessary as after the user shows the context menu it seems to work fine?, so I removed the node expanding stuff. I also made the recursive loop use the node parent object for showing the centerlines. This seems to be better compatible with all the different use cases. I also added status bar text so in larger assemblies, the user has some idea of whats going on. I also added/modified some comments.

 

 

Sub Main
	If Not TypeOf ThisDoc.Document Is DrawingDocument Then
		MsgBox("Open a drawing document first")
		Exit Sub
	End If

	Dim doc As DrawingDocument = ThisDoc.Document
	Call doc.SelectSet.Clear
	Dim bp As BrowserPane = doc.BrowserPanes("Model")

	ThisApplication.StatusBarText = "Scanning Browser Nodes..."
	Call GetRouteBrowserNodes(bp.GetBrowserNodeFromObject(doc.ActiveSheet).BrowserNodes) 'only touch active sheet.
	ThisApplication.StatusBarText = "Showing Centerlines..."

	For Each obj As BrowserNode In tosel
		Call obj.DoSelect 'only one browser node can be selected in this manner per the API
		Call ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryUnchecked").Execute2(True) 'shows centers, execute synchronously
		'ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryChecked").Execute2(True) 'hides centers if currently showinh
		Call ThisApplication.UserInterfaceManager.DoEvents 'delay is not actually needed here, may want to remove if large assemblies?
	Next
	Call doc.SelectSet.Clear
	ThisApplication.StatusBarText = ""
End Sub

Dim tosel As New ArrayList 'stores valid browsernodes

Sub GetRouteBrowserNodes(nodes As BrowserNodesEnumerator)
	For Each node As BrowserNode In nodes
		If node.NativeObject IsNot Nothing Then
			If (node.NativeObject.Type = ObjectTypeEnum.kComponentOccurrenceObject) Then
				If node.NativeObject.Definition.Document.DocumentInterests.HasInterest("Piping Route Environment") Then 'matches the 'route' node/part environment type
					tosel.add(node.Parent) 'add the parent object so it works with views where the run sub assembly is the top level view component, otherwise this is assumed to always be a 'run' type subnode
				End If
			End If

			If node.NativeObject IsNot Nothing AndAlso
				(TypeOf node.NativeObject Is DrawingView OrElse 'match all drawing views
				node.NativeObject.Type = ObjectTypeEnum.kComponentOccurrenceObject OrElse 'match components that are not the top level
				node.NativeObject.Type = ObjectTypeEnum.kAssemblyComponentDefinitionObject) Then 'top level assembly node under view node
				GetRouteBrowserNodes(node.BrowserNodes)	'recursively search, only want to search valid node types
			End If
		End If
	Next
End Sub

 

 

0 Likes
Message 16 of 21

A.Acheson
Mentor
Mentor

Thanks for posting this, much to learn on working with the browser nodes. I noticed the latest version isn't working as good as the previous posted. Mainly due to it only exposing it's parent. For the  T&P main assembly to function correctly  You have to right click and expose the menu on each drawing in a session as opposed to once per session.

 

On the previous code:

Replacing the contains Run filter with the two below eliminates any naming convention issues. 

	If node.NativeObject.Definition.Document.DocumentInterests.HasInterest("Piping Runs Environment")
									tosel.Add(node)
									End If
								If node.NativeObject.Definition.Document.DocumentInterests.HasInterest("Piping Run Environment")
									tosel.Add(node)
									End If

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 17 of 21

greggeorgi
Contributor
Contributor

I did some more testing, and it appears this situation is just plain weird. I might've been too quick to remove the node expanding part. It almost seems like expanding them caches them or something so next time they don't have to be expanded, or each T&P node type needed to be observed at least once? Not really sure....and sometimes it took a few tries to "get it going" to where it would hide/show 100% of the time after a session restart. At this point it seems to just be a battle with Inventor quirks/bugs so I would argue to just use whatever seems to work reliably. Hopefully your assemblies aren't too massive and that it will always run at a decent speed.

Message 18 of 21

AleksanderMyklebust5924
Contributor
Contributor

'Did some cleaning of this code, and it seem to work

'Added an selection switch to turn Centerlines on or off 

'Error with clicking vs select set
'https://forums.autodesk.com/t5/inventor-customization/what-is-the-difference-between-selectset-select-and-clicking-on/td-p/9249928
Class ShowCenters
	Dim ShowLines As Boolean =True
Sub Main
	Dim que As MsgBoxResult = MsgBox("Show Center Lines", vbYesNo, "Select")
	If que = vbYes Then
		ShowLines=True
		Else
			ShowLines=False
		End If
	If Not TypeOf ThisApplication.ActiveDocument Is DrawingDocument Then
		MsgBox("Open a drawing document first")
		Exit Sub
	End If
	
	Dim doc As DrawingDocument
	doc = ThisApplication.ActiveDocument
	doc.SelectSet.Clear
	Dim bp As BrowserPane = doc.BrowserPanes("Model")
	
    Call GetRouteBrowserNodes(bp.GetBrowserNodeFromObject(doc.ActiveSheet).BrowserNodes) 'only touch active sheet.
    Call GetRunBrowserNodes(bp.GetBrowserNodeFromObject(doc.ActiveSheet).BrowserNodes)
	
'	ThisApplication.CommandManager.ControlDefinitions.Item("AppBrowserCollapseAllCmd").Execute2(True)
'	  For Each obj As BrowserNode In tosel
'		Dim n As BrowserNode = obj
'		While n.Parent.Type = obj.Type
'			n = n.Parent
'			n.Expanded = True 
'		End While
'		obj.DoPreSelect
'		'Attempt to activate the context menu by RMB ona browser node containing routecenterline. This does not work as may be unsupported.
'		'Imports System.Windows.Forms (Place in Header)
'		'SendKeys.SendWait("+({F10})")'The parentheses indicates that F10 should be pressed while Shift is held down

'		obj.DoSelect 'the command seems to act on the last selected object
' 			'Includes the Route centerline....(opposite to it's name)
'			'oControlDef = ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryUnchecked")
'		 	'oControlDef.Execute
		
'			'Excludes the Route centerline....(opposite to it's name)
'        '	oControlDef = ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryChecked")
'		'	oControlDef.Execute
		 
'		Call ThisApplication.UserInterfaceManager.DoEvents 'lets inventor catch up
		
'	  Next
		ThisApplication.CommandManager.ControlDefinitions.Item("AppBrowserCollapseAllCmd").Execute2(True)
		doc.SelectSet.Clear
End Sub

Dim tosel As New ArrayList 'store valid browsernodes

Sub GetRouteBrowserNodes(nodes As BrowserNodesEnumerator)
	On Error Resume Next
	For Each node As BrowserNode In nodes
	
		If node.NativeObject IsNot Nothing Then
			'Logger.Info(CType(node.NativeObject.type, ObjectTypeEnum).ToString)
				
			If (node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject)
				
								If node.NativeObject.Definition.Document.DocumentInterests.HasInterest("Piping Route Environment")
									tosel.Add(node)
									End If
									
								'Use "Piping Runs Environment" for the top level run defintion
								'Use "Piping Run Environment" for individual runs like Run00, Run01
								'Use "Piping Route Environment"	for individual routes
								If node.FullPath.Contains("Route") Then
									node.DoSelect
								If ShowLines Then
									
											'If the "Include Route Centerline" is unchecked the code will check it 
								ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryUnchecked").Execute 
														
								Else
										'If the "Include Route Centerline" is checked the code will uncheck it 
								ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryChecked").Execute 
							End If
								Logger.Info(node.FullPath)
							End If
								'Return 'this run is taken care of so don't search any deeper
								
			End If
					If node.NativeObject IsNot Nothing AndAlso 
						(TypeOf node.NativeObject Is DrawingView OrElse
						node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject OrElse
						node.NativeObject.type = ObjectTypeEnum.kAssemblyComponentDefinitionObject) Then
						    GetRouteBrowserNodes(node.BrowserNodes) 'recursively search, only want to search valid node types
					End If
		End If
	Next
End Sub
Sub GetRunBrowserNodes(nodes As BrowserNodesEnumerator)
	On Error Resume Next
	For Each node As BrowserNode In nodes
	
		If node.NativeObject IsNot Nothing Then
			'Logger.Info(CType(node.NativeObject.type, ObjectTypeEnum).ToString)
				
			'If (node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject)
								If (node.FullPath.Contains("Run")) 'assuming these are not renamed
									
									tosel.add(node)
								End If
								'Use "Piping Runs Environment" for the top level run defintion
								'Use "Piping Run Environment" for individual runs like Run00, Run01
								'Use "Piping Route Environment"	for individual routes
								
								'Logger.Info(node.FullPath)
								'Return 'this run is taken care of so don't search any deeper
							
			End If
					If node.NativeObject IsNot Nothing AndAlso 
						(TypeOf node.NativeObject Is DrawingView OrElse
						node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject) Then
						    GetRunBrowserNodes(node.BrowserNodes) 'recursively search, only want to search valid node types
					End If
		'End If
	Next

End Sub


End Class

 

Aleksander Myklebust
0 Likes
Message 19 of 21

AleksanderMyklebust5924
Contributor
Contributor

Did som simplification of the code, and it seems to work

'Error with clicking vs select set
'https://forums.autodesk.com/t5/inventor-customization/what-is-the-difference-between-selectset-select-and-clicking-on/td-p/9249928
Class ShowCenters
	Dim ShowLines As Boolean =True
Sub Main
	Dim que As MsgBoxResult = MsgBox("Show Center Lines", vbYesNo, "Select")
	If que = vbYes Then
		ShowLines=True
		Else
			ShowLines=False
		End If
	If Not TypeOf ThisApplication.ActiveDocument Is DrawingDocument Then
		MsgBox("Open a drawing document first")
		Exit Sub
	End If
	
	Dim doc As DrawingDocument
	doc = ThisApplication.ActiveDocument
	doc.SelectSet.Clear
	Dim bp As BrowserPane = doc.BrowserPanes("Model")
	
    Call GetRouteBrowserNodes(bp.GetBrowserNodeFromObject(doc.ActiveSheet).BrowserNodes) 'only touch active sheet.
    Call GetRunBrowserNodes(bp.GetBrowserNodeFromObject(doc.ActiveSheet).BrowserNodes)
	
'	ThisApplication.CommandManager.ControlDefinitions.Item("AppBrowserCollapseAllCmd").Execute2(True)
'	  For Each obj As BrowserNode In tosel
'		Dim n As BrowserNode = obj
'		While n.Parent.Type = obj.Type
'			n = n.Parent
'			n.Expanded = True 
'		End While
'		obj.DoPreSelect
'		'Attempt to activate the context menu by RMB ona browser node containing routecenterline. This does not work as may be unsupported.
'		'Imports System.Windows.Forms (Place in Header)
'		'SendKeys.SendWait("+({F10})")'The parentheses indicates that F10 should be pressed while Shift is held down

'		obj.DoSelect 'the command seems to act on the last selected object
' 			'Includes the Route centerline....(opposite to it's name)
'			'oControlDef = ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryUnchecked")
'		 	'oControlDef.Execute
		
'			'Excludes the Route centerline....(opposite to it's name)
'        '	oControlDef = ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryChecked")
'		'	oControlDef.Execute
		 
'		Call ThisApplication.UserInterfaceManager.DoEvents 'lets inventor catch up
		
'	  Next
		ThisApplication.CommandManager.ControlDefinitions.Item("AppBrowserCollapseAllCmd").Execute2(True)
		doc.SelectSet.Clear
End Sub

Dim tosel As New ArrayList 'store valid browsernodes

Sub GetRouteBrowserNodes(nodes As BrowserNodesEnumerator)
	On Error Resume Next
	For Each node As BrowserNode In nodes
	
		If node.NativeObject IsNot Nothing Then
			'Logger.Info(CType(node.NativeObject.type, ObjectTypeEnum).ToString)
				
			If (node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject)
				
								If node.NativeObject.Definition.Document.DocumentInterests.HasInterest("Piping Route Environment")
									tosel.Add(node)
									End If
									
								'Use "Piping Runs Environment" for the top level run defintion
								'Use "Piping Run Environment" for individual runs like Run00, Run01
								'Use "Piping Route Environment"	for individual routes
								If node.FullPath.Contains("Route") Then
									node.DoSelect
								If ShowLines Then
									
											'If the "Include Route Centerline" is unchecked the code will check it 
								ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryUnchecked").Execute 
														
								Else
										'If the "Include Route Centerline" is checked the code will uncheck it 
								ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryChecked").Execute 
							End If
								Logger.Info(node.FullPath)
							End If
								'Return 'this run is taken care of so don't search any deeper
								
			End If
					If node.NativeObject IsNot Nothing AndAlso 
						(TypeOf node.NativeObject Is DrawingView OrElse
						node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject OrElse
						node.NativeObject.type = ObjectTypeEnum.kAssemblyComponentDefinitionObject) Then
						    GetRouteBrowserNodes(node.BrowserNodes) 'recursively search, only want to search valid node types
					End If
		End If
	Next
End Sub
Sub GetRunBrowserNodes(nodes As BrowserNodesEnumerator)
	On Error Resume Next
	For Each node As BrowserNode In nodes
	
		If node.NativeObject IsNot Nothing Then
			'Logger.Info(CType(node.NativeObject.type, ObjectTypeEnum).ToString)
				
			'If (node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject)
								If (node.FullPath.Contains("Run")) 'assuming these are not renamed
									
									tosel.add(node)
								End If
								'Use "Piping Runs Environment" for the top level run defintion
								'Use "Piping Run Environment" for individual runs like Run00, Run01
								'Use "Piping Route Environment"	for individual routes
								
								'Logger.Info(node.FullPath)
								'Return 'this run is taken care of so don't search any deeper
							
			End If
					If node.NativeObject IsNot Nothing AndAlso 
						(TypeOf node.NativeObject Is DrawingView OrElse
						node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject) Then
						    GetRunBrowserNodes(node.BrowserNodes) 'recursively search, only want to search valid node types
					End If
		'End If
	Next

End Sub


End Class
Aleksander Myklebust
0 Likes
Message 20 of 21

AleksanderMyklebust5924
Contributor
Contributor

Update:

'Error with clicking vs select set
'https://forums.autodesk.com/t5/inventor-customization/what-is-the-difference-between-selectset-select-and-clicking-on/td-p/9249928
Class ShowCenters
	Dim ShowLines As Boolean =True
Sub Main
	Dim que As MsgBoxResult = MsgBox("Show Center Lines",vbYesNo,"Select")
	If que = vbYes Then
		ShowLines=True
		Else
			ShowLines=False
		End If
	If Not TypeOf ThisApplication.ActiveDocument Is DrawingDocument Then
		MsgBox("Open a drawing document first")
		Exit Sub
	End If
	
	Dim doc As DrawingDocument
	doc = ThisApplication.ActiveDocument
	doc.SelectSet.Clear
	Dim bp As BrowserPane = doc.BrowserPanes("Model")
	
    Call GetRouteBrowserNodes(bp.GetBrowserNodeFromObject(doc.ActiveSheet).BrowserNodes) 'only touch active sheet.
    Call GetRunBrowserNodes(bp.GetBrowserNodeFromObject(doc.ActiveSheet).BrowserNodes)
	
'	'ThisApplication.CommandManager.ControlDefinitions.Item("AppBrowserCollapseAllCmd").Execute2(True)
'	  For Each obj As BrowserNode In tosel
'		Dim n As BrowserNode = obj
'		While n.Parent.Type = obj.Type
'			n = n.Parent
'			n.Expanded = True 
'		End While
'		obj.DoPreSelect
'		'Attempt to activate the context menu by RMB ona browser node containing routecenterline. This does not work as may be unsupported.
'		'Imports System.Windows.Forms (Place in Header)
'		'SendKeys.SendWait("+({F10})")'The parentheses indicates that F10 should be pressed while Shift is held down

'		obj.DoSelect 'the command seems to act on the last selected object
' 			'Includes the Route centerline....(opposite to it's name)
'			'oControlDef = ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryUnchecked")
'		 	'oControlDef.Execute
		
'			'Excludes the Route centerline....(opposite to it's name)
'        '	oControlDef = ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryChecked")
'		'	oControlDef.Execute
		 
'		Call ThisApplication.UserInterfaceManager.DoEvents 'lets inventor catch up
		
'	  Next
		ThisApplication.CommandManager.ControlDefinitions.Item("AppBrowserCollapseAllCmd").Execute2(True)
		doc.SelectSet.Clear

					
					
End Sub

Dim tosel As New ArrayList 'store valid browsernodes

Sub GetRouteBrowserNodes(nodes As BrowserNodesEnumerator)
	On Error Resume Next
	For Each node As BrowserNode In nodes
	
		If node.NativeObject IsNot Nothing Then
			'Logger.Info(CType(node.NativeObject.type, ObjectTypeEnum).ToString)
				
			If (node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject)
				
								If node.NativeObject.Definition.Document.DocumentInterests.HasInterest("Piping Route Environment")
									tosel.Add(node)
									End If
									
								'Use "Piping Runs Environment" for the top level run defintion
								'Use "Piping Run Environment" for individual runs like Run00, Run01
								'Use "Piping Route Environment"	for individual routes
								If node.FullPath.Contains("Route") Then
									node.DoSelect
									'This needs run before setting the state 
									ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryTriState").Execute 
								If ShowLines Then
									
											'If the "Include Route Centerline" is unchecked the code will check it 
								ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryUnchecked").Execute 
														
								Else
										'If the "Include Route Centerline" is checked the code will uncheck it 
								ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryChecked").Execute 
							End If
								Logger.Info(node.FullPath)
							End If
								'Return 'this run is taken care of so don't search any deeper
								
			End If
					If node.NativeObject IsNot Nothing AndAlso 
						(TypeOf node.NativeObject Is DrawingView OrElse
						node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject OrElse
						node.NativeObject.type = ObjectTypeEnum.kAssemblyComponentDefinitionObject) Then
						    GetRouteBrowserNodes(node.BrowserNodes) 'recursively search, only want to search valid node types
					End If
		End If
	Next
End Sub
Sub GetRunBrowserNodes(nodes As BrowserNodesEnumerator)
	On Error Resume Next
	For Each node As BrowserNode In nodes
	
		If node.NativeObject IsNot Nothing Then
			'Logger.Info(CType(node.NativeObject.type, ObjectTypeEnum).ToString)
				
			'If (node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject)
								If (node.FullPath.Contains("Run")) 'assuming these are not renamed
									
									tosel.add(node)
								End If
								'Use "Piping Runs Environment" for the top level run defintion
								'Use "Piping Run Environment" for individual runs like Run00, Run01
								'Use "Piping Route Environment"	for individual routes
								
								'Logger.Info(node.FullPath)
								'Return 'this run is taken care of so don't search any deeper
							
			End If
					If node.NativeObject IsNot Nothing AndAlso 
						(TypeOf node.NativeObject Is DrawingView OrElse
						node.NativeObject.type = ObjectTypeEnum.kComponentOccurrenceObject) Then
						    GetRunBrowserNodes(node.BrowserNodes) 'recursively search, only want to search valid node types
					End If
		'End If
	Next

End Sub


End Class
'This needs run before setting the state 
									ThisApplication.CommandManager.ControlDefinitions.Item("CADC:Drawing:CenterlineRecoveryTriState").Execute 

 

Aleksander Myklebust
0 Likes