Flattening an Assembly

I had an internal request recently for a utility to take any assembly and create an equivalent single-level assembly.  In this particular case they had a large assembly whose structure didn’t make sense for their current use and the structure made it difficult to delete individual components.  By flattening the assembly they’re now able to quickly remove portions of the assembly and get something they can begin working with.  In this specific case, to begin building fixtures around it.

Here’s the VBA macro code that does the flattening.  (I had to add some line continuations that I wouldn’t normally use to get the code to fit within the narrow space I have here.)

' Macro that creates a new assembly that represents a flattened
' version of the current active assembly.  The result is a single
' level assembly of occurrences.  There are not constraints and
' each occurrence is grounded.
Public Sub FlattenAssembly() 
   ' Get the active assembly. 
   Dim sourceAsmDoc As AssemblyDocument 
   On Error Resume Next 
   Set sourceAsmDoc = ThisApplication.ActiveDocument 
   If Err Then 
  MsgBox "An assembly must active." 
  Exit Sub 
   End If 
   On Error GoTo 0

   ' Create the new, empty assembly. 
   Dim targetAsmDoc As AssemblyDocument 
   Set targetAsmDoc = ThisApplication.Documents.Add( _
  kAssemblyDocumentObject, _
  ThisApplication.FileManager.GetTemplateFile( _
  kAssemblyDocumentObject))

   ' Traverse through the existing assembly getting 
   ' each leaf component and creating an occurrence 
   ' in the new assembly that represents it. 
   Call CopyAssemblyAsFlat(targetAsmDoc.ComponentDefinition, _ 
   sourceAsmDoc.ComponentDefinition.Occurrences)
End Sub

' Utility sub used by FlattenAssembly macro.  This sub is call
' recursively to traverse an entire assembly.  It creates new
' top-level occurrences in the target assembly to represent each
' of the occurrences found in the source assembly.
'
' TargetAsm – The component definition of the target assembly.
' Occurrences – The occurrences collection of the assembly
' to traverse.
Private Sub CopyAssemblyAsFlat( _
   TargetAsm As AssemblyComponentDefinition, _ 
   Occurrences As ComponentOccurrences) 
   ' Iterate through the occurrences in the current level 
   ' of the assembly. 
   Dim occ As ComponentOccurrence 
   For Each occ In Occurrences 
  ' Skip any invisible, suppressed, or excluded components. 
  If occ.Visible And Not occ.Suppressed And _
  Not occ.Excluded Then 
' Check to see if this occurrence is a part or assembly. 
If occ.DefinitionDocumentType = kPartDocumentObject Then 
    ' Create an occurrence in the target assembly 
    ' for this part. 
    Dim newOcc As ComponentOccurrence 
    Set newOcc = _
   TargetAsm.Occurrences.AddByComponentDefinition( _ 
occ.Definition, occ.Transformation) 
    newOcc.Grounded = True 
Else 
    ' Recursively call this sub to continue 
    ' traversing the assembly. 
    Call CopyAssemblyAsFlat(TargetAsm, occ.SubOccurrences) 
    End If 
End If 
   Next
End Sub

The macro uses somewhat of a brute force method.  It creates a new, empty assembly, traverses the existing assembly to determine what parts are used and where they’re located and then reconstructs the original assembly by placing parts in the new assembly.  The parts are positioned correctly in the new assembly but there aren’t any constraints and they’re all grounded.

You can see that there’s really not much code needed to do this.  It’s actually just a variation of the assembly traversal code from a previous post.

Update (March 29, 2010)
A couple of limitations with the program have been pointed out to me and are worth noting.

  1. All assembly features are lost.
  2. All weldment data is lost (preparations, welds, finishing).

Luckily I don’t believe these are an issue in most cases where the program would be used, but in case you do have assembly features or weldments you should be aware of these limitations.


Comments

5 responses to “Flattening an Assembly”

  1. JLackey Avatar
    JLackey

    I pasted the macro, however, it is telling me the sub is not defined. I am very new to VBA and know barely anything about. I have been trying to do some reading about it, but have not really been able to practice anything with it. I initially pasted all the text in one module, but got an error telling me nothing but comments were allowed after the end sub statement, so I pasted the private sub on a seperate module. ANy help would be greatly appreciated.

  2. BRENDAN HENDERSON Avatar
    BRENDAN HENDERSON

    Add both sets of text into the 1 module. Edit the long lines that end in _ so that the lines are joined together (see example below) :-
    hello, _
    there,
    Becomes :-
    hello, there
    Save the macro and run it. It works fine for me.

  3. BRENDAN HENDERSON Avatar
    BRENDAN HENDERSON

    Add both sets of text into the 1 module. Edit the long lines that end in _ so that the lines are joined together (see example below) :-
    hello, _
    there,
    Becomes :-
    hello, there
    Save the macro and run it. It works fine for me.

  4. How can I alter this code to selectively remove or ignore components going in to the new assembly? I can place a value in an excel file indicating a particular component is not needed.

  5. Alessandro Ferraz Avatar
    Alessandro Ferraz

    Hello, I work with Inventor 2011 in Portuguese, and when I create a rule in iLogic and have to put the unit “s_m” it does not work, this unit in English is “ul”
    when I do the same thing the inventor in English it works, tell me know if there is some code that I put to identify the unit of the inventor in Portuguese? Or is there a plugin to fix?
    grateful
    Alessandro

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading