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.
- All assembly features are lost.
- 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.