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
Solved! Go to Solution.
Solved by adam.nagy. Go to Solution.
' 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.
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,
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,
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
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
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,
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
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:
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:
Attached is the modified zip.
Cheers,
On the code below, why I'm getting an error message of
Error on Line 9 : Type 'm_parameter_Material' is not defined.
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?
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
(Not an Autodesk Employee)
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
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
(Not an Autodesk Employee)
Can't find what you're looking for? Ask the community or share your knowledge.