Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Changing all components material

23 REPLIES 23
SOLVED
Reply
Message 1 of 24
Anonymous
5387 Views, 23 Replies

Changing all components material

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

23 REPLIES 23
Message 2 of 24
Anonymous
in reply to: Anonymous

   ' Get the active assembly document.
    Dim oAsmDoc As AssemblyDocument 
    oAsmDoc = ThisApplication.ActiveDocument

    ' Get the material to assign to all of the parts.
    Dim strMaterialName As String
    strMaterialName = "YOUR MATERIAL HERE"

    Dim oMaterial As Material
    On Error Resume Next
    ' Try to get the material of the specified name.
    oMaterial = oAsmDoc.Materials.Item(strMaterialName)
   
    On Error Goto 0

    ' Iterate through all of the documents refrenced by the assembly.
    Dim oDoc As Document
    For Each oDoc In oAsmDoc.AllReferencedDocuments
        ' Check to see if this is a part.
        If oDoc.DocumentType = kPartDocumentObject Then
            Dim oPartDoc As PartDocument
            oPartDoc = oDoc

            ' Set the material.
            oPartDoc.ComponentDefinition.Material = oMaterial
        End If
    Next

This could be a start for you.

Run in an assembly it will assign all components the same material.

Message 3 of 24
Anonymous
in reply to: Anonymous

Holy Crap that was quick as easy!
That worked almost perfectly. instead of the material name in "your material here" I used the parameter name of the multivalue list so I could control it!.
I wish I had SOME idea about what was going on in this code lol but it works nicely. I do have one problem though that i know this code will cause. This code appears to set ALL parts in the document to that material type. I however need to change groupings of components because we do use small pieces of rubber in our design so i cant have them changing to Stainless Steel. any suggestions?
Thanks!!
Sandro
Message 4 of 24
xiaodongliang
in reply to: Anonymous

as to 'change groupings of components ', do you mean by 'components that within a browser folder', or they have some regular names. If the former, you would need to iterate the folder, get the browser nodes within it, get the corresponding occurrence and change the material. If the latter, it depends the rule you set the name. you could just filter out those occurrences with the specific names.
Message 5 of 24
Anonymous
in reply to: xiaodongliang

well, I dont think its either of those. basically there are a couple of components that can be different types of steel. The fasteners can also be different types of steel. The main assembly is composed of steel with a couple of different rubber parts. The main assembly will have all of its steel either 304 or 316 stainless steel.
I guess this means I have a fair bit of customization but If i could figure out how to change one part im sure i could figure out how to change the rest to what i want.
Message 6 of 24
adam.nagy
in reply to: Anonymous

Hi,

 

Not sure I understand what you mean by "If i could figure out how to change one part"

@Anonymous pasted a code that is doing it for lots of parts.

What is missing?

 

Also, you could check the material name before assigning a new one. 

So if all of them are supposed to be 304 or 316, then you could change values only where it is already one of those.

Would that work?

 

Cheers,



Adam Nagy
Autodesk Platform Services
Message 7 of 24
Anonymous
in reply to: adam.nagy

Adam,

If I am understanding you correctly, yes I think it would work for me if I could check certain components materials and then If they are one way, Change them to another by my preference per job specifications.
You are right, that code changes the material for lots of parts. All parts actually. If I were to change ALL parts to a certain material, I would then lose the correct material for components that are supposed to be Rubber, or a different grade of stainless than the rest of the assembly.
Message 8 of 24
adam.nagy
in reply to: Anonymous

Hi,

 

If your top assembly has a Multi Value list named e.g. "Metals" then using the following code you could check if the part that your code is checking has a material that is included in the Multi value List. 
MultiValue.List returns an ArrayList: https://msdn.microsoft.com/en-us/library/system.collections.arraylist(v=vs.110).aspx and so it has a Contains() method you can use.

values = MultiValue.List("Metals")
If values.Contains("Gold")
  MsgBox("has gold")
End If

This way you could check if the part's material is something that you should modify or not.

 

Cheers,



Adam Nagy
Autodesk Platform Services
Message 9 of 24
Anonymous
in reply to: adam.nagy

Hi Adam, 

 

I am a little confused by the code you posted so I think I am not being clear enough. I have attached a file of one of my models to hopefully explain a little bit better. Please open it and set the view rep to "Default" and the LOD to "iLogic".

 

I am not sure how the pack and go feature works with regards to Material libraries so I hope I can explain properly. 

 

Please open up the parameters window. You will notice the last 5 parameters are the exact same multivalue liss but with different names (created with a rule). I was hoping to potentially control the materials with these lists but they will be useful for me to explain to you my intentions. I should mention these paramters have nothing to do with the actual model I am attaching.

 

The first of the last 5 is named "All_Materials" I used this list to simply GET all of the materials available in my custom library.

The next 4 parameters are the actual parameters I need control of. The "Stem_Material" Parameter in reality can either be 304 or 316 S.S. regardless of the rest of the assembly. 

The "Pedestal_Material" in reality can either be Galvanized Steel, and 304 or 316 S.S., regardless of the rest of the assembly. 

The "Hardware_Material" is for all of the fasnteners and they can either be 304 or 316 regardless of the rest of the assembly. 

The "Stainless_Grade" is for what I keep referring to as the "rest of the assembly". I feel this might be the trickiest part. The rest of the assembly is one large assembly made up of a few sub-assembies. It is composed of mostly S.S. but it does have  a couple rubber components to it which is why the previously mentioned code that changes all materials does not work the way I want it to. In this large assembly I need to be able to change all of the STEEL to either 304 or 316. 

 

I feel like there has to be as easy way to accomplish this. The reason I created the multivalue lists is because I thought I would simply be able to write a rule that would look something like this

IF Pedestal_Material = "GALVANIZED STEEL" Then

iProperties....Material = "GALVANIZED STEEL"

End if

 

Please let me know if this makes sense...

 

Thanks

Sandro

 

 

Message 10 of 24
Anonymous
in reply to: Anonymous

Update...

I don't know if this means anything but I was just screwing around with rules and I figured out that using this line:
iProperties.MaterialOfComponent("Rising Stem:1") = Stem_Material
I was able to change the material of that component very easily to exactly what I want. Now, this was only easy because it just so happens this component is ONE part. If this is the only solution to my problem, this means that I will have to create a rule like this which includes EVERY part in my entire assembly which means it will be incredibly time consuming (once). It also means that since suppressed parts will be mentioned, when the rule runs I will probably have some difficulties...
Is any of that correct?

Thanks Sandro
Message 11 of 24
adam.nagy
in reply to: Anonymous

It's quite easy to test what happens if you suppress a component whose material you are trying to change.

And it seems that in that case the material of that component will not get changed.

Is that OK or in your wokflow even suppressed parts' material you should be able to control from the Multi Value List parameter?

 

If so, then you could go back to the original code, because that should work in that case as well.

 

The question is how you identify which parts should be controlled by which Multi value List parameter.

If you don't mind handling them one by one in the code then it should be quite easy that could be done based on their exact names: that is something that iLogic seems to expect as well, where you have to provide the exact component name you want to control.

 

You could also write something that could be more generic: e.g. Stem_Material parameter would only control all documents whose name starts with "Stem", etc 



Adam Nagy
Autodesk Platform Services
Message 12 of 24
Anonymous
in reply to: adam.nagy

Adam,

Yes I decided to give it a test and suppressed components don't cause any issues. They can stay whatever material they are in the background because it doesn't affect my BOM.
I agree with you about the question at hand. I am really trying to avoid creating a rule that lists every single part. Even though I would probably only have to do it once, there are hundreds of small parts and that would be very time consuming.
I am very inexperienced with the API or VBA code, I only have a pretty good handle on the default snippets in iLogic so I dont even know of the option to control parts like you described from pieces of their names. That method seems like it would be perfect however I am nervous thinking about it because i anticipate having to rename everything or having to remember this method when I name new parts.
I have thought about this alot and had a new idea. I haven't tested it yet but do you think I could possibly use the very first code mentioned in this thread to control ALL parts material, but instead of inserting that code at my top level assembly could I insert it into each sub-assembly ensuring all material within that sub-assembly is identical? I feel I could then control the parameter within those sub-assemblies from my top level assembly and not worry about EVERYTHING changing to one material type.

Does this sound like a possible idea? It sounds much better than naming every single part since I only have a handful of sub-assemblies.

Thanks
Sandro
Message 13 of 24
adam.nagy
in reply to: Anonymous

In the sample assembly you attached there were parts also directly under the main assembly - not only under the subassembly.

So you would still need to set the material at the top level assembly as well.

 

There could be multiple ways of achieving what you need, but you know best how the assemblies and parts will be used, which parts' material should be controlled from where, etc.

 

Also, are the parts only used from a single assembly? Because once you set the material for them it will be the same in all the assemblies they are being used in. I'm assuming for each assembly you create you copy those parts into the assembly's folder, or something like that?



Adam Nagy
Autodesk Platform Services
Message 14 of 24
Anonymous
in reply to: adam.nagy

Adam, 

 

To be honest with you we have not implemented Inventor into any jobs at our company yet. Right now I am trying to make complete models of all our products. I am creating each product so that it is fully adaptable with iLogic to be any size or configuration that we need to cut down on our design time almost entirely.

 

This means that I am not too concerned about changing the material type for an assembly that is used in multiple locations that may have a different material than what I am working on at the moment. I am not sure exactly if this is the right direction to be headed but I am not too experienced with Inventor so I figure I'll deal with that when I get there.

 

For the moment I am uploading the same assembly again but with some important updates to help convey what I am trying to accomplish. I would really appreciate you taking a look at it. I changed the model so that the top level assembly is only composed of sub-assemblies with no stray parts. The top level assembly is composed of three sub-assemblies, If you enter each sub-assembly you will find a rule called "Forum Test" and within it is the code that was given at the beginning of this thread. I tried to control the material is this code from my top level assemblies multi-value lists but was unsuccessful. That code still grabs the material for EVERYTHING in the model even if the rule is placed in a sub-assembly. Please make sure you are on the "iLogic" LOD.

 

I hope this makes sense and gives you a better understanding at what I am trying to do. I appreciate the help!

 

Thanks

Sandro

Message 15 of 24
adam.nagy
in reply to: Anonymous

Hi Sandro,

 

In order to be able to set the material for the derived component, it's best to set its Derived Part Properties so that it's not inheriting the material color from the original part:

 

DerivedPart.png

 

You do not even need to modify the iProperties but can simply rely on the Parameter values. I commented out the iProperty parts. I was also wondering in the beginning if it was interfering with things.

 

In the rules inside the sub assemblies you have to change something. You are using ThisApplication.ActiveDocument, but that will return the top assembly when the rule is called as a result of you changing parameters in the top assembly. You should use ThisDoc.Document instead, which return the document that the rule resides in. 

 

Now all seems fine:

 

AllFine.png

 

Attached is the modified zip.

 

Cheers,

 



Adam Nagy
Autodesk Platform Services
Message 16 of 24
Anonymous
in reply to: adam.nagy

I KNEW IT! This is fantastic!! I knew there had to be a way. I almost just accepted that I would have to type in material properties for every single little part. This saves DAYS of typing. I can't thank you enough! I will be using this code on every single one of our product models! One thing however, since there are suppressed parts within a sub-assembly, the code iLogicVb.RunRule("Forum Test") had to be added to a separate rule within the sub-assembly so that the unsuppressed part would change its material. Other than that, this worked perfect!!Thanks again! Thanks Sandro
Message 17 of 24
JohnBoySarcia
in reply to: Anonymous

On the code below, why I'm getting an error message of 

Error on Line 9 : Type 'm_parameter_Material' is not defined.

jsMK4JH_0-1693883475959.png

I'm also having this target to change all parts within the component as the same material as what I have selected in multivalue list. Or is my parameter Material is creating those problem?

Message 18 of 24
WCrihfield
in reply to: JohnBoySarcia

Hi @JohnBoySarcia.  In this case there are a couple things going on.  First of all, unless you are still using Inventor 2016 version, the 'Material' object type no longer exists.  That pretty much changed after that year to MaterialAsset object type, and can no longer be used exactly the same way as the old Material object was used.  The MaterialAsset object has its own set of methods and properties.  At the same time the Render styles also changed to a regular Asset type object.  And now you access them through AssemblyDocument.MaterialAssets or PartDocument.MaterialAssets, instead of AssemblyDocument.Materials.  And can set the active one for a part through the PartDocument.ActiveMaterial property, which will accept either a MaterialAsset object or regular Asset object as input.

 

And yes, due to you having the local multi-value parameter named "Material" that is being recognized within your rule as a parameter, that is messing with your ability to 'declare' the oMaterial variable's Type.  Some of the old Material & RenderStyle functionality may still be supported, but just to support old code functionality, so you should not use those terms in any new code solutions.  A common issue in any type of coding is naming your variable the same spelling and capitalization as the object's Type, which causes confusion and errors.

 

Edit:  My mistake on when the change happened.  The change happened between 2013 & 2014 releases.  Here is a link to a page describing the changes.

https://help.autodesk.com/view/INVNTOR/2024/ENU/?guid=GUID-2912C0FB-885F-47ED-81C3-AF19584EA9C1 

If the link does not work, you can click the Help button in Inventor, then navigate to Programming Interface > Inventor API User's Manual > General Concepts > Materials and Appearances

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 19 of 24
JohnBoySarcia
in reply to: WCrihfield

Thank you for your response, the link shows mostly on appearance as an example and need to pick occurrences prior to change. Would it be possible to have an ilogic code from Autodesk inventor 2022 version to have all material within assembly will be change based on selection? my parameter Material has selection. Also, on those examples the set command doesn't exist on my current version. Thanks

Message 20 of 24
WCrihfield
in reply to: JohnBoySarcia

Hi @JohnBoySarcia.  Almost all Autodesk provided sample codes are provided in VBA, instead of iLogic, unfortunately.  And that 'Set' keyword is used in VBA when setting the value of a variable who's Type is something other than (String, Integer, Double, and similar data types).  That keyword is not needed in iLogic rules.  There are a few other differences between VBA and vb.net also (iLogic uses vb.net).  Both coding languages are pretty similar, and both based on Visual Basic, but VBA is older and not properly maintained anymore, while vb.net is a newer (but not really new) coding language that continues to be maintained.

 

There is a handy iLogic shortcut snippet that we may be able to use in this situation:

iProperties.Material("ComponentName") = "MaterialName"

I do not recall its 'scope' (if it will only work on top level components, or if it will work on components at all levels), so it may require some testing on your end.  The online documentation does not mention its scope.  I do not really know if you need this code to only work on top level components, or if you need it to work on all components in all levels of the assembly, so the example code is for the all levels scenario, and is a bit longer.  There is another way of changing the 'material' of the parts being referenced by the components, but the other way requires much more lines of Inventor API code, and can get a bit more complicated.

Here is the iLogic rule example code you can try out.

Sub Main
	'Material is the name of a multi-value text type user parameter in the assembly
	sMaterial = Material
	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
	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 'shared among routines

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.SubOccurrences, 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 VirtualComponentDefinition Then Exit Sub
	If TypeOf oComp.Definition Is WeldsComponentDefinition Then Exit Sub
	Try 'only works on components that reference parts
		iProperties.Material(oComp.Name) = sMaterial
	Catch oEx As Exception
		Logger.Error("Error setting Material of component named:  " & oComp.Name _
		& vbCrLf & oEx.Message & vbCrLf & oEx.StackTrace & vbCrLf)
	End Try
End Sub

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report