Demote browser folders to phantom assemblies

Demote browser folders to phantom assemblies

andrew_canfield
Collaborator Collaborator
707 Views
9 Replies
Message 1 of 10

Demote browser folders to phantom assemblies

andrew_canfield
Collaborator
Collaborator

Hello

I'd like to restructure a number of subassemblies.

the Assembly template was set up with folders for 'Bought Out Parts' & 'Fasteners'.

Like like to demote the contents of 'Bought Out Parts' to a Phantom assembly called 'Bought Out Parts.iam'

And demote  the contents of the  'Fasteners' folder to a Phantom assembly called 'Fasteners.iam'

The remaining parts then demote to a phantom assembly with the same name as the current assembly but a GA suffix added.

I'll start looking at API examples - i can do the workflow manually & it produces the results I want.

 

Haven't tackled anything this complicated before!

 

Regards

 

Andrew

0 Likes
708 Views
9 Replies
Replies (9)
Message 2 of 10

JamieVJohnson2
Collaborator
Collaborator

A point in the right direction, hopefully:

From:

C:\Users\Public\Documents\Autodesk\Inventor%202019\Local%20Help\ADMAPI_23_0.chm::/HTML/BrowserPaneObject_Reorder_Demote_Sample.htm Demote occurence

Demote occurence API Sample

Public Sub Demote()
    ' Get the active assembly document
    Dim oDoc As AssemblyDocument
    Set oDoc = ThisApplication.ActiveDocument

    Dim oDef As AssemblyComponentDefinition
    Set oDef = oDoc.ComponentDefinition

    ' Get the occurrence to be demoted
    Dim oOcc As ComponentOccurrence
    Set oOcc = oDef.Occurrences.Item(1)

    ' Create a new sub-assembly to demote the occurrence into
    Dim oNewSubAssy As AssemblyDocument
    Set oNewSubAssy = ThisApplication.Documents.Add(kAssemblyDocumentObject, , False)

    Dim oMat As Matrix
    Set oMat = ThisApplication.TransientGeometry.CreateMatrix

    ' Create an instance of the new sub-assembly
    Dim oSubAssyOcc As ComponentOccurrence
    Set oSubAssyOcc = oDef.Occurrences.AddByComponentDefinition(oNewSubAssy.ComponentDefinition, oMat)

    ' Get the model browser
    Dim oPane As BrowserPane
    Set oPane = oDoc.BrowserPanes.Item("Model")

    ' Get the browser node that corresponds to the new sub-assembly occurrence
    Dim oSubAssyNode As BrowserNode
    Set oSubAssyNode = oPane.GetBrowserNodeFromObject(oSubAssyOcc)

    ' Get the last visible child node under the sub-assembly occurrence
    Dim oTargetNode As BrowserNode
    Dim i As Long
    For i = oSubAssyNode.BrowserNodes.Count To 1 Step -1
        If oSubAssyNode.BrowserNodes.Item(i).Visible Then
            Set oTargetNode = oSubAssyNode.BrowserNodes.Item(i)
            Exit For
        End If
    Next

    ' Get the browser node that corresponds to the occurrence to be demoted
    Dim oSourceNode As BrowserNode
    Set oSourceNode = oPane.GetBrowserNodeFromObject(oOcc)

    ' Demote the occurrence
    Call oPane.Reorder(oTargetNode, False, oSourceNode)
End Sub

Since Folders are also browser nodes, this may be possible using these techniques, but I haven't tested for it.

 

Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
0 Likes
Message 3 of 10

chandra.shekar.g
Autodesk Support
Autodesk Support

@andrew_canfield,

 

Demote occurence API Sample is also available at below help documentation link.

 

http://help.autodesk.com/view/INVNTOR/2019/ENU/?guid=GUID-7F3C848A-B240-40BC-9ECB-056567FE4D41

 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes
Message 4 of 10

andrew_canfield
Collaborator
Collaborator

I'm thinking - it's possible to suppress the contents of a browser folder, then,

Iterate to find the suppressed parts - I've never been able to iterate!!

 

For example - i've frankensteined this code & have no idea how to see the value of oAsmCompDef

(what kind of a variable is oAsmCompDef? )

In my simpleness i figured copy to a variable (xx) & display in a message box - not so simple, i guess it's not text.

I'd like to list each part in the assembly & see if it's suppressed

If it's suppressed then demote it - the demote code referenced does work but it does the whole assembly & i need to figure out how to fine tune (it's the next step). 

 

Below I added the code in the red loop which is totally wrong but hopefully it indicates what I'm trying to achieve.

 

iterate.JPG

0 Likes
Message 5 of 10

JamieVJohnson2
Collaborator
Collaborator

You want to get the iProperties of a particular component?  Or multiple Components?

AssemblyComponentDefinition (acd for short) is the core dataset of all that stuff you see in the model browser.

This core data then breaks down each item as a ComponentOccurrence (co for short) from the acd.Occurrences collection property.

The .Occurrences is a collection of ComponentOccurrence objects.

Each ComponentOccurrence object is the equivalent of a single inserted part or assembly.

ComponentOccurrence objects have reference to the Definition of that occurrence.

Definition for a part will be a PartComponentDefinition, for an assembly as you see above, an AssemblyComponentDefinition.

From the ComponentDefinition (cd for short), you can get the iProperties.  VB.Net requires you to get an iProperty (or just property) from the cd.PropertySets(propertyset name or index).Properties(property name or index)

iLogic code has a shortcut using iProperties.Value("part1:1", "Project", "Part Number") aka (ComponentOrDocName, PropertySetName, PropertyName)

ComponentOccurrences have a .Name property to help with the first value,

a PropertySet is generally the same as a single tab on the iProperties window, but the name differ a bit (look up the api reference in the help file for a complete list).

A property is generally the same name as the text beside the line on the iProperty window.

 

So to iterate them all you would (pseudo code):

dim invApp as Inventor.Application = ThisApplication '(for iLogic and VBA, but not VB.Net)

dim asmDoc as AssemblyDocument = invApp.ActiveDocument '(assuming the assembly file is the active file)

Dim acd as AssemblyComponentDefinition = asmDoc.Definition '(your first question of what is this variable)

for each co as component occurrence in acd.Occurrences

     dim propValue as object = nothing

     propValue = iProperties.Value(co.Name,"PropSetName","PropName")

     'do something with your propValue

next

 

Now notice I said data core.  The above method references the underlying structure.  However you could also iterate the user interface browser structure.  You can get the occurrences from the browser tree nodes.

Dim bPane As BrowserPane = asmDoc.BrowserPanes("Model")
Dim nTop As BrowserNode = bPane.TopNode

Each browser node has a .NativeObject property, and can be of the type ComponentOccurrence, or BrowserFolder.

They all have a property .BrowserNodes that you would iterate looking for the .Name to find your desired folder.

Then use the .NativeObject to get the ComponentOccurrence and proceed from there.

 

 

Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
Message 6 of 10

JamieVJohnson2
Collaborator
Collaborator

Also, I've already written a basic set of routines to get the Occurrences (all of them) from a single browser folder with a given name.  This is VB.Net code so it will only work in the Visual Studio or iLogic api, but not the VBA (without being modified).  Running GetOccurrencesByFolder is the beginning of this 'tree' of code.

    Public Function GetOccurrencesByFolder(ByRef asmDoc As AssemblyDocument, ByRef strFolderName As String) As List(Of ComponentOccurrence)
        Dim ocs As New List(Of ComponentOccurrence)
        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)
                    ElseIf TypeOf bn.NativeObject Is OccurrencePattern Then
                        ocs.AddRange(FindOccurrencesFromPattern(bn))
                    End If
                Next
            Next
        End If
        Return ocs
    End Function

    Public Function FindBrowserFoldersInNodes(nTop As BrowserNode, strFolderName As String) As List(Of BrowserFolder)
        Dim bfs As New List(Of BrowserFolder)
        For Each bNode As BrowserNode In nTop.BrowserNodes
            If TypeOf bNode.NativeObject Is BrowserFolder Then
                Dim bf As BrowserFolder = bNode.NativeObject
                If bf.Name = strFolderName Then
                    bfs.Add(bf)
                End If
            ElseIf 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
        Next
        Return bfs
    End Function

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

Hope that helps,

 

Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
Message 7 of 10

andrew_canfield
Collaborator
Collaborator

Hello

The code above will add a new sub- assembly if one is already present - i've been looking for a way to rename the sub-assembly. Any clues?

rename.JPG

0 Likes
Message 8 of 10

JamieVJohnson2
Collaborator
Collaborator

To change the visible name in the browser, use the component occurrence returned from what you created and use the  .Name property. 

Ex: oSubAssyOcc.Name = "mynewawesomesubassembly"

 

Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
0 Likes
Message 9 of 10

andrew_canfield
Collaborator
Collaborator

 

 

 

Thanks - I have tried this in a few places - still early days for my programming know how!

AssyRename.JPG

0 Likes
Message 10 of 10

JamieVJohnson2
Collaborator
Collaborator

Confused, but one warning, make user you are not duplicating names, all browser items must have a unique name.

 

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