Capturing the browser node name in a multi-level patterns with iLogic

Capturing the browser node name in a multi-level patterns with iLogic

Anonymous
Not applicable
1,726 Views
8 Replies
Message 1 of 9

Capturing the browser node name in a multi-level patterns with iLogic

Anonymous
Not applicable

I am looking for help modifying a code I found. The code below works great for single level patterns, however I would like to expand this to search multi-level patterns. The highlight items in the screen shot are the parts that I am attempting to grab the Browsers Node names.   

mlp.JPG

Dim doc = ThisDoc.DocumentDim

BrowserPane = doc.BrowserPanes("Model")

Dim TopNode = BrowserPane.TopNode

Dim CompNode As ComponentOccurrence

EndFound = False

For Each node As BrowserNode In TopNode.BrowserNodes 

   If node.BrowserNodeDefinition.Label Like "GAS MOUNTING PATTERN" Then EndFound = True

    If EndFound = True Then

        CompName = node.BrowserNodes.Item(1).BrowserNodes.Item(1).BrowserNodeDefinition.Label

        CompNode = doc.ComponentDefinition.Occurrences.ItemByName(CompName) 

       Exit For

    End If

Next

If Not CompNode Is Nothing Then MessageBox.Show("CompNodeName = " & CompNode.Name, "Title")

 

 

 

0 Likes
1,727 Views
8 Replies
Replies (8)
Message 2 of 9

JamieVJohnson2
Collaborator
Collaborator

You want self recursive routine, here is a similar one I used to dive into nodes looking for folders of a particular name:

Public Function FindBrowserFoldersInNodes(nTop As BrowserNode, strFolderName As String) As List(Of BrowserFolder)
    Dim bfs As New List(Of BrowserFolder)
    Try
        For Each bNode As BrowserNode In nTop.BrowserNodes
            Try
                If bNode.NativeObject IsNot Nothing Then
                    If TypeOf bNode.NativeObject Is ComponentOccurrence Then
                        If bNode.BrowserFolders.Count > 0 Then
                            Dim bf As BrowserFolder = FindBrowserFolder(bNode, strFolderName)
                            If bf IsNot Nothing Then
                                bfs.Add(bf)
                            End If
                        End If
                        If bNode.BrowserNodes.Count > 0 Then
                            Dim bfsNew As List(Of BrowserFolder) = FindBrowserFoldersInNodes(bNode, strFolderName)
                            If bfsNew.Count > 0 Then
                                For Each bfNew As BrowserFolder In bfsNew
                                    If bfs.Contains(bfNew) = False Then
                                        bfs.Add(bfNew)
                                    End If
                                Next
                            End If
                        End If
                    End If
                End If
            Catch
                'MsgBox (bnode.fullpath)
            End Try
        Next
    Catch
        MsgBox("FindFoldersInNode")
    End Try
    Return bfs
End Function

 And the other part:

Public Function FindBrowserFolder(bn As BrowserNode, strFolderName As String) As BrowserFolder
    Try
        For Each bf As BrowserFolder In bn.BrowserFolders
            If bf.Name = strFolderName Then
                Return bf
            End If
        Next
    Catch
        MsgBox("FindFolder")
    End Try
    Return Nothing
End Function

And the header routing that uses it:

Public Function GetOccurrencesByFolder(ByRef asmDoc As AssemblyDocument, ByRef strFolderName As String) As List(Of ComponentOccurrence)
    Dim ocs As New List(Of ComponentOccurrence)
    Try
        Dim bPane As BrowserPane = asmDoc.BrowserPanes("Model")
        Dim nTop As BrowserNode = bPane.TopNode
        Dim bfs As List(Of BrowserFolder) = FindBrowserFoldersInNodes(nTop, strFolderName)
        If bfs.Count > 0 Then
            For Each bfFound As BrowserFolder In bfs
                For Each bn As BrowserNode In bfFound.BrowserNode.BrowserNodes
                    If TypeOf bn.NativeObject Is ComponentOccurrence Then
                        ocs.Add(bn.NativeObject)
                    End If
                Next
            Next
        End If
    Catch
        MsgBox("GetFolderOccurences")
    End Try
    Return ocs
End Function

and the highest level calling line:

Dim coCounterWeights As List(Of ComponentOccurrence) = GetOccurrencesByFolder(aDoc, "CounterWeight")
Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
0 Likes
Message 3 of 9

clutsa
Collaborator
Collaborator

Can I ask what your end goal is? Is the browser node name different then the part name and you need it for some other future use? 

If I've helped you, please help me by supporting this idea.
Mass Override for Each Model State

Custom Glyph Icon for iMates

0 Likes
Message 4 of 9

Anonymous
Not applicable

I am using the Browser Node Name to locate files for suppression, ipart member replacement, or pass parameters to a sub-part or sub-assembly. The goal is to build a configurator for a product. Originally the plan, that worked well, was to rename the Browser Node giving a static target to find (see code below). Only After loading the project into the live system I discovered our document management software renames the Browser Node blowing away the static name. Now I am locating parts by there location in the Browser or suppressing parts in a folder. However the pattern numbers change with different iterations of the product, so again I am left with a moving target in the Browser. That is why I what to find the parts through their browser names based on the location in a pattern. I am open to other idea's on how to accomplish this task.

 

= iPart.FindRow("Exhaust Angle1", "Code", "=", Parameter("ExhaustAngleCode1"))

 

If Component.IsActive("Exhaust Door") = True

 

 

                Parameter("Exhaust Door", "UnitWidth")=Parameter("UnitWidth")

                Parameter("Exhaust Door", "MembraneLength")=Parameter("MembraneLength")

                Parameter("Exhaust Door", "HighPressure")=Parameter("HighPressure")

                Parameter("Exhaust Door", "MembraneType")=Parameter("MembraneType")

                Parameter("Exhaust Door", "Construction")=Parameter("Construction")

                Parameter("Exhaust Door", "ForceTo4inchAngle")=Parameter("ForceTo4inchAngle")

                Parameter("Exhaust Door", "ForceTo_2_Door") = Parameter("ForceTo2Door")

                Parameter("Exhaust Door", "Flow") = Parameter("DoorExhaustFlow")

                Parameter("Exhaust Door", "UnitSize")= Parameter("UnitSize")

     

        iProperties.Value("Exhaust Door", "Project", "Description") = Parameter("ExhaustDoorDescription")  

        Else

        Parameter("ExhaustDoorDescription") = "Not Used"

    End If

0 Likes
Message 5 of 9

clutsa
Collaborator
Collaborator

Take a look at "Attribute Sets" & "Attribute Set" 

https://modthemachine.typepad.com/my_weblog/2009/07/introduction-to-attributes.html

 

Edit: I forgot those don't work great on Factory parts because of the fact the members don't carry over the attr sets. I'll think some more.

If I've helped you, please help me by supporting this idea.
Mass Override for Each Model State

Custom Glyph Icon for iMates

0 Likes
Message 6 of 9

Anonymous
Not applicable

Thank you both.

Jamie, I am not sure how to incorporate that as it is a bit over my skill level. I am not a programmer, however as I get deeper into iLogic I want to learn more.  

Clusta, I will try to check out that article tomorrow.

0 Likes
Message 7 of 9

JamieVJohnson2
Collaborator
Collaborator

Not being a programmer will change as soon as you attempt to change something to work 'out of its box'.  So welcome to the struggle.

 

Well as others suggest you may want to approach your problem differently.  If the browser node's name is not reliable, and your not really looking through the browser for any other reason than to find component occurrences (think node), then you can approach this problem looking straight at the component definition list of the active assembly.  Still the recursive program (a program that calls itself) is the way to break down the tree.  

 

Inventor assembly structure is as follows, you have an assembly component definition (the assembly), then the acd breaks down in to component occurrences (the inserted parts and sub assemblies and component patterns), when the occurrence is a part, you collect it, when it is an assembly, you start an inner loop.  When each loop finishes, you return the collection of found parts back to the calling program (the upper level loop), then merges the parts into its running collection. 

 

Another concept worth mentioning is that of a xxxProxy (ComponentOccurrenceProxy for example).  Proxies are used when you want to get the 'translated position and size' data from the inserted object in terms of the assembly its inserted into.  They wrap the ComponentOccurence and add that data as needed.  If your interested in only labels, this this will not be of concern.

 

Once you have the component occurrence, you can check for its Name (browser node name should match), its Definiton (stuff you see in the browser when you open just that file), and Document type (aka part, assembly).

 

Here is a single example of a recursive routine that looks for ComponentOccurences that fit a name keyword.

Dim aDoc As AssemblyDocument = ThisDoc.Document
        Dim cd As ComponentDefinition = aDoc.ComponentDefinition
        Dim coLoads As New List(Of ComponentOccurrence)

        coLoads = GetSubOccurrenceProxiesByName(cd, "LOAD:", True)
Public Function GetSubOccurrenceProxiesByName(ByRef cdAssembly As ComponentDefinition, ByVal subOccName As String, Optional PartialName As Boolean = False) As List(Of ComponentOccurrence)
    Dim cops As New List(Of ComponentOccurrence)
    Dim cop As ComponentOccurrenceProxy = Nothing
    For Each co As ComponentOccurrence In cdAssembly.Occurrences
        If PartialName = True Then
            If co.Name.Contains(subOccName) Then cops.Add(co)
        Else
            If co.Name = subOccName Then cops.Add(co)
        End If
        If co.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
            Dim scos As List(Of ComponentOccurrence) = GetSubOccurrenceProxiesByName(co.Definition, subOccName, PartialName)
            If scos.Count > 0 Then
                For Each sco As ComponentOccurrence In scos
                    co.CreateGeometryProxy(sco, cop)
                    cops.Add(cop)
					co.Definition
		Next
            End If
        End If
    Next
    Return cops
End Function
Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
Message 8 of 9

Anonymous
Not applicable

Thank you for the great information. Looks like I am going to have to dive deeper into learning to program. Do you have any suggested avenues to learn more on this topic?

In the interim to get this project released I am considering inserting an additional copy of all the parts that need to be identified into the assemble. These parts will be suppressed reference parts that are placed into a folder marked “Ref” at the top of the Browser. Now I can find them and perform the replace all needed based on the required product configuration. It is a very crude method (see code below), but will get me out of a bind. From there I hope to have the time to learn and incorporate better methods. 

 

'VARIABLES TO BE REPLACED

My_Variable1 = ThisDoc.Document.ComponentDefinition.Occurrences.Item(1).Name

My_Variable2 = ThisDoc.Document.ComponentDefinition.Occurrences.Item(2).Name

 

 

   'Allows “Part Number” to be extracted from next line

i = iPart.FindRow(My_Variable1)'Extract "Part Number" parameter My_Variable1

i2 = iProperties.Value(My_Variable1,"Project", "Part Number")

'Extract "Part Number" parameter for My_Variable2

i3 = iProperties.Value(My_Variable2,"Project", "Part Number")

 

’----------------------------------------------------------------

'loop that looks at each component for replacement

 

Dim oAsmDoc as Inventor.AssemblyDocument

oAsmDoc = ThisDoc.Document

 

Dim comp As Inventor.ComponentOccurrence

For Each comp In oAsmDoc.ComponentDefinition.Occurrences

 

     Comp.UnSuppress

 

    If iProperties.Value(comp.Name,"Project", "Part Number") = i2

 

        i= iPart.FindRow(comp.Name, "CODE1", "=", Parameter("CODE1"))

 

    End If

 

    If iProperties.Value(comp.Name,"Project", "Part Number") = i3

 

        i= iPart.FindRow(comp.Name, "CODE2", "=", Parameter("CODE2"))

 

    End If

   

 Next

’-----------------------------------------------------------------

0 Likes
Message 9 of 9

JamieVJohnson2
Collaborator
Collaborator

The Inventor API had less resources for me to learn from (aka 3rd party references).  I learned most of it from the API help, references, and samples.  The best of them all was the object chart "C:\Users\Public\Documents\Autodesk\Inventor 2019\SDK\DeveloperTools\Docs\Inventor2019ObjectModel.pdf"  Which broke down the Inventor API into its logical components, and makes a nice poster to hang on your wall too.  You can find all this in the developertools.msi and the usertools.msi files.  Then the final location for extra info is here.  Most forum users here are pretty friendly with the basics, but when it gets complicated (such as reaching the limits of the program's abilities), your better off having a developers account subscription with the ADN (Autodesk Developer's Network), where your questions placed here will get direct attention from Autodesk if not answered by forum users.  Since that's not free, you'd best wait until you've reached that level.

 

I also use vb.Net as my base platform for programming, and get all the info I need for that from MSDN.

 

Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
0 Likes