Changing all components material

Changing all components material

Anonymous
Not applicable
6,561 Views
23 Replies
Message 1 of 24

Changing all components material

Anonymous
Not applicable

Hi, 

 

I have a feeling this one might be outside of my knowledge base but ill try it out anyway. 

 

I am basically just trying to control the material properties most of my parts all at once. Our products are about 99% stainless steel so ill focus on just that. The issue is we either use type 304L S.S. or 316L S.S. depending on the job. I am trying to create a nice little button to choose either one that will send that information down to all of my parts.

 

I am hoping that is a nice easy way to go and find all exisiting material properties and IF they are/arent one way, change them to another. I have a feeling however that I am going to have to create a line in a rule for each and every component which will definitely take some time but if thats what I have to do, so be it. 

 

So far I have created my own material library so it consists of ONLY the very few materials we use. Basically the only thing I have figured out how to do so far is create a multi-value list of all of the materials in my library. I can't export the text, and can only reference it at top level assembly. I have no idea how to send that information down to all components. 

 

Any help is immensely appreciated!

 

Thanks

Sandro

0 Likes
Accepted solutions (1)
6,562 Views
23 Replies
Replies (23)
Message 21 of 24

JohnBoySarcia
Advocate
Advocate

Yes, this is amazing, and works on the parts within the assembly but doesn't change the parts within sub assembly on this active assembly. Is there still a way to do it?

0 Likes
Message 22 of 24

WCrihfield
Mentor
Mentor

Hi @JohnBoySarcia.  Here is an alternative iLogic rule you can try out.  This version uses Inventor API code, instead of that iLogic shortcut snippet in an attempt to change the material of all parts in the assembly.  When doing it through API code, you need to get the actual MaterialAsset object that represents the material first.  Then you need to make sure there is a 'local' copy of that MaterialAsset saved within the document that is going to be using it, not just a MaterialAsset from an external material library.  So, I am using two shared variables (one for the material's name, and one for the MaterialAsset found in the active external material library, if any).  It attempts to set their values within the Sub Main area.  Then when processing each component, it avoids the component if it just represents the 'welds' in a weldment type assembly.  Then, if it is a 'virtual' component, since I don't think they have an actual 'Document' associated with them, I just try to assign the MaterialAsset directly from the library to it (not sure if that will work).  And if it represents a normal part or assembly, it will attempt to find that MaterialAsset within that parts materials, and use that.  If not found, it then tries to copy the library version to the document, then use that copied 'local' version.  I also slightly changed how the components are being recursively iterated through within the RecurseComponents Sub routine.  There is an important difference between [oComp.Definition.Occurrences] and [oComp.SubOccurrences] in some situations, but not sure if it matters in this situation.

Sub Main
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
		MsgBox("An Assembly Document must be active for this rule to work. Exiting.", vbCritical, "")
		Exit Sub
	End If
	Dim oADoc As AssemblyDocument = ThisDoc.Document
	sMaterial = ""
	Try : sMaterial = oADoc.ComponentDefinition.Parameters.Item("Material").Value : Catch : End Try
	If sMaterial = "" Then Exit Sub 'the parameter could not be found, or had empty value
	Try : oLibMat = ThisApplication.ActiveMaterialLibrary.MaterialAssets.Item(sMaterial) : Catch : End Try
	Dim oOccs As ComponentOccurrences = oADoc.ComponentDefinition.Occurrences
	If oOccs.Count = 0 Then Exit Sub
	RecurseComponents(oOccs, AddressOf ProcessComponent)
	If oADoc.RequiresUpdate Then oADoc.Update2(True)
	MsgBox("This rule's work has finished.", vbInformation, "Job Is Done!")
End Sub

Dim sMaterial As String
Dim oLibMat As MaterialAsset

Sub RecurseComponents(oComps As ComponentOccurrences, ComponentProcess As Action(Of ComponentOccurrence))
	If oComps Is Nothing OrElse oComps.Count = 0 Then Exit Sub
	For Each oComp As ComponentOccurrence In oComps
		ComponentProcess(oComp)
		If oComp.Suppressed = False AndAlso _
			oComp.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
			RecurseComponents(oComp.Definition.Occurrences, ComponentProcess)
		End If
	Next
End Sub

Sub ProcessComponent(oComp As ComponentOccurrence)
	If oComp Is Nothing OrElse oComp.Suppressed Then Exit Sub
	If TypeOf oComp.Definition Is WeldsComponentDefinition Then Exit Sub
	If TypeOf oComp.Definition Is VirtualComponentDefinition Then
		Dim oVCD As VirtualComponentDefinition = oComp.Definition
		Try : oVCD.ActiveMaterial = oLibMat : Catch : End Try
		Exit Sub
	End If
	Dim oDoc As Document = Nothing
	Try : oDoc = oComp.Definition.Document : Catch : End Try
	Dim oDocMats As AssetsEnumerator = Nothing
	Try : oDocMats = oDoc.MaterialAssets : Catch : End Try
	Dim oDocMat As MaterialAsset = Nothing
	Try : oDocMat = oDocMats.Item(sMaterial) : Catch : End Try
	If oDocMat Is Nothing And oLibMat Is Nothing Then Exit Sub
	If oDocMat Is Nothing Then Try : oDocMat = oLibMat.CopyTo(oDoc, True) : Catch : End Try
	If oDocMat Is Nothing Then Exit Sub
	Try : oDoc.ActiveMaterial = oDocMat : Catch : End Try
End Sub

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 23 of 24

JohnBoySarcia
Advocate
Advocate

Thank you very much for your reply. If that's the way to get the material to every component that I need to create a new library of materials, then how do I apply those using ilogic code? Says my material library called "Company Materials", my parameter is Material, and that material has a dropdown list of 304L SS and 316L SS, although only this two but I can replicate more if an ilogic program works fine on this two. I only choose this two for easy switching when I test the ilogic program

0 Likes
Message 24 of 24

WCrihfield
Mentor
Mentor

Hi @JohnBoySarcia.  I am not sure I fully understood your last response.  Those material names that you have within the drop-down list of your multi-value parameter must be names of materials that either already exist in the documents, or that already exist in some material library somewhere.  If they are not found in the 'active' material library, then you can certainly specify a different material library for the code to pull the material specifications from.

 

This following line of code in the Sub Main area of the code I just posted may need to be changed, or replaced with multiple other lines of code, if the material library containing those materials is not the 'active' one, and you need to specify a specific material library for it to look in.

Try : oLibMat = ThisApplication.ActiveMaterialLibrary.MaterialAssets.Item(sMaterial) : Catch : End Try

...that line could be replace with something like:

Try : oLibMat = ThisApplication.AssetLibraries.Item("Company Materials").MaterialAssets.Item(sMaterial) : Catch : End Try

...or you could break it down into multiple lines of code.  One line could declare a variable to hold the custom material library object itself, then another line could set its value, then another line could try to find the specified material asset within that library, and set it to the oLibMat variable.

 

If I am understanding you correctly, then you may be wanting an easier way to populate the multi-value list of your "Material" user parameter, based on a specified material library.  That is certainly fairly easy to do, but I would recommend using a different rule to do that task.  If that is not what you wanted, then I may not have understood your request.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes