Looking for ilogic code that will map a specific material and color to ALL part files within an assembly?

Looking for ilogic code that will map a specific material and color to ALL part files within an assembly?

chris
Advisor Advisor
811 Views
8 Replies
Message 1 of 9

Looking for ilogic code that will map a specific material and color to ALL part files within an assembly?

chris
Advisor
Advisor

Just wondering if anyone has a iLogic snippet that they don't mind sharing that would replace the material and color of ALL parts within an assembly with a predefined material and color.

 

I have several large assemblies that the "boss" need to have shown as a specific material with a specific color and instead of spending the next 3 weeks single selecting individual parts I was wondering if this could be done in iLogic?

0 Likes
812 Views
8 Replies
Replies (8)
Message 2 of 9

earl_cody
Contributor
Contributor

Here's a start. If you're looking for appearance/color override from the material, that can be done with a few more lines. Also assuming the assembly BOM is flat, but more code can be added to handle subassemblies.

 

iLogicVb.UpdateWhenDone = True

'get material library
Dim libMaterial As Inventor.AssetLibrary = ThisApplication.AssetLibraries.Item("Autodesk Material Library")

'specify material
Dim material As Inventor.MaterialAsset = libMaterial.MaterialAssets.Item("Glass")

'get active assembly document
Dim asmDoc As Inventor.AssemblyDocument = ThisApplication.ActiveDocument

'get assembly's definition
Dim asmDef As Inventor.AssemblyComponentDefinition = asmDoc.ComponentDefinition

'clear any appearance overrides that may be set at the assembly level
Call asmDef.ClearAppearanceOverrides()

'get handle for all part occurrences in the assembly
Dim asmOccurences As Inventor.ComponentOccurrences = asmDef.Occurrences

'for each occurance in the assembly document
For Each occ As Inventor.ComponentOccurrence In asmOccurences
    '** if user has subassemblies, then recursive method to handle those will be needed
    'but keeping it short/straightforward for now   
    
    'if the occurance is of type part document
    'could also add handling for sheetmetal if needed
    If (occ.Definition.Type = Inventor.ObjectTypeEnum.kPartComponentDefinitionObject) Then

        'get handle for the part document
        Dim partDoc As Inventor.PartDocument = occ.Definition.Document
 
       'if the material isn't already set to the specified material, then change the material
        If (partDoc.ActiveMaterial.DisplayName <> material.DisplayName) Then

            'set the material of the part document
            partDoc.ActiveMaterial = material
        End If
    End If
Next

'update the assembly document to propagate sublevel changes
Call asmDoc.Update()

'simple message box to let user know that script has finished
MessageBox.Show("Done")

 

 

0 Likes
Message 3 of 9

chris
Advisor
Advisor

@earl_cody this worked great!!

is it much work to adjust it to work with sub assemblies?

0 Likes
Message 4 of 9

A.Acheson
Mentor
Mentor

Edit:

Just one change I think to change "asmDef.Occurrences" to "asmDef.Occurrences.AllLeafOccurrences"

This will work with the parts in each assembly.

 

https://help.autodesk.com/view/INVNTOR/2022/ENU/?guid=GUID-86E425C0-69CD-4004-A6F6-ECB2878B499F

 

And here is a more digestible article to navigate assemblies. 

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

earl_cody
Contributor
Contributor

@A.Acheson - Thank you for the suggestion!

 

@chris - Nice! This should work for the nested parts now. 

 

 

iLogicVb.UpdateWhenDone = True

'get material library
Dim libMaterial As Inventor.AssetLibrary = ThisApplication.AssetLibraries.Item("Autodesk Material Library")

'specify material
Dim material As Inventor.MaterialAsset = libMaterial.MaterialAssets.Item("Glass")

'get active assembly document
Dim asmDoc As Inventor.AssemblyDocument = ThisApplication.ActiveDocument

'get assembly's definition
Dim asmDef As Inventor.AssemblyComponentDefinition = asmDoc.ComponentDefinition

'clear any appearance overrides that may be set at the assembly level
Call asmDef.ClearAppearanceOverrides()

'get handle for all occurrences in the assembly
Dim asmOccurences As Inventor.ComponentOccurrences = asmDef.Occurrences

'for each leaf occurrence in the assembly document
For Each occ As Inventor.ComponentOccurrence In asmOccurences.AllLeafOccurrences

    If (occ.Definition.Type = Inventor.ObjectTypeEnum.kPartComponentDefinitionObject) Then

		'get handle for the part document
        Dim partDoc As Inventor.PartDocument = occ.Definition.Document

		'if the material isn't already set to the specified material, then change the material
        If (partDoc.ActiveMaterial.DisplayName <> material.DisplayName) Then
            
			'set the material of the part document
            partDoc.ActiveMaterial = material
			
        End If
    End If
Next

'update the assembly document to propagate sublevel changes
Call asmDoc.Update()

'simple message box to let user know that script has finished
MessageBox.Show("Done")

 

0 Likes
Message 6 of 9

chris
Advisor
Advisor

@earl_cody (sorry for the reply), but for some reason I am getting an error on line 37? It was working fine yesterday but it's not working today?

chris_0-1674572639134.pngchris_1-1674572658357.png

 

 

 

 

 

0 Likes
Message 7 of 9

A.Acheson
Mentor
Mentor

Edit: In further testing copying doesn't seem to be necessary.

I would think your material asset is not existing locally in the part document.This is why your getting a string error trying to find its name. Use these lines to check the material locally if it exists then move to set it and if it doesnt then the catch comes into play and copies from material library. See sample setting appearance much the same as setting material asset. 

 

 

 

'specify material
Dim LibMatAsset As MaterialAsset = libMaterial.MaterialAssets.Item("Glass")

' Copy the asset locally.
Try
   Dim LocalMatAsset As MaterialAsset
LocalMatAsset = partDoc.Assets.Item("Glass")
Catch
LocalMatAsset = LibMatAsset.CopyTo(partDoc)
End Try

if the material isn't already set to the specified material, then change the material
If (partDoc.ActiveMaterial.DisplayName <> LocalMatAsset.DisplayName) Then

'set the material of the part document
partDoc.ActiveMaterial = LocalMatAsset
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 8 of 9

J-Camper
Advisor
Advisor

@chris,

 

Just an FYI, you can window select all occurrences in an assembly and change the material and appearance from the dropdown lists without any iLogic:

 

0 Likes
Message 9 of 9

A.Acheson
Mentor
Mentor

If you have content center parts/parts that are read only then you might get an error like this. 

Change this line to ensure document is modifiable. 

 If (partDoc.ActiveMaterial.DisplayName <> material.DisplayName) AndAlso partDoc.IsModifiable Then

If that still fails you will need to place in a logger line like so and you can see what document it is stopping on. 

 

Logger.Info("Document DisplayName: " & partDoc.DisplayName)
			

 

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