UpdateFromGlobal for Materials

UpdateFromGlobal for Materials

VGonsalves
Advocate Advocate
3,241 Views
26 Replies
Message 1 of 27

UpdateFromGlobal for Materials

VGonsalves
Advocate
Advocate

Hi

 

Is it possible to update a material "style" from the global styles using UpdateFromGlobal?

 

Currently I have a part whose density has been changed locally. I would like to revert this back to the defaults in the Design Data. I have read a few posts where you can update a partslist style using this command. For example http://forums.autodesk.com/t5/Inventor-Customization/ilogic-function-to-update-local-styles-to-match...

I tried replacing using the same idea and replacing the partslist with material but it doesn't work.

 

Can someone advise me on this.

 

Thank you

Accepted solutions (1)
3,242 Views
26 Replies
Replies (26)
Message 21 of 27

WCrihfield
Mentor
Mentor

Hi @CattabianiI.  Correct.  Even though I sometimes suggest solutions that include executing a command (ControlDefinition), or one that uses the SendKeys functionality, I pretty much always warn folks against solutions like that these days.  They are more of a desperate last resort, when you can not figure out any other way of doing something that you need to quickly automate, to save yourself a lot of time.  Any time there is a way to do something using built-in API or iLogic methods, I always try to suggest those first.  If I can not think of any API or iLogic way to do something, but think that I may be able to automate it by executing commands and/or using SendKeys, depending on the scenario, I will usually only use that (or suggest that) sparingly and/or suggest caution.  Executing commands requires that the document that the commend is to act upon be actively visible on your screen at the time, not just some referenced document within an active assembly, or something like that.  Plus, they usually require some sort of object(s) be in the Document.SelectSet just before or after executing the command, and sometimes are complicated to get back out of the command after the primary task is completed.  Using SendKeys can also be pretty dangerous, because there is not a very good way of telling it where you want those keystrokes to be sent to.  And if they get sent to the wrong place, it could potentially cause lots of problems.  The 'AppActivate' method is probably the most basic way I had ever seen to help accomplish what I was attempting to do at the time.  There are some other, more advanced/complex methods that are more accurate to use than that method that I picked up on later, but I still do not like to use SendKeys, if I can avoid it any other way.

 

I was wrong about the timing of the Material & RenderStyle change-over in my previous post.  That happened back in 2013, not 2016.  Below is a link to the online help documentation about that.

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

(if that Link does not work, just click on the ? [help] in Inventor, then navigate to Programming Interface > Inventor API User's Manual > General Concepts > Materials & Appearances)

So, according to that documentation, we should not be continuing to count on PartDocument.ComponentDefinition.Material property for these types of tasks, because it is long outdated, and they have only maintained them for a while, due to some folks having some pre-existing automation solutions that were relying on them, to support their functionality for a while, until they could get their stuff updated or changed to the new way of doing things.

 

But I must have updated my code since I posted those text files here back in July 2023, because when I compared that code (the last text file - purge & update using iLogic) to my latest code, it is different.  I have expanded the portion of the Function where it is attempting to obtain the library version of the Asset, to first check the Asset.AssetType property, where its Value is a variation of the AssetTypeEnum, to check if it is for a material, appearance, or physical, then use that knowledge to choose which library to get the matching library Asset object from, instead of just blindly trying each library one at a time, in a specific order.  You could also incorporate a document type check into either the 'Main' or Function portion of it if you wanted, to avoid it trying to run on something like a drawing, but that is up to you.  You could also specify just one, or multiple custom AssetLibraries, instead of the built-in ones, if needed.  Just keep in mind that a material library can contain both materials and appearances, not just materials.  As you can see when you inspect the properties of a MaterialAsset object (a Type derived from the regular Asset Type), it has a reference to an appearance asset, and a physical asset, so most likely, the same library can hold assets used for all 3 purposes.  We do have one custom material library, with a small number of materials in it, but we use the built-in material libraries for most stuff.  I have attached that updated iLogic code as a text file again, just for reference.

 

That code could be converted to purely Inventor API (removing iLogic dependency), with a few changes, if needed.  One thing would be to get rid of the RuleArguments portion of the code, and the 'ThisDoc.Document' phrase, which was included to optionally support the functionality of running this rule from another rule (or not), where that other rule used a NameValueMap with a Document object put into it (as the rule arguments to send), as a means of telling this rule which document to focus its attention on when it runs.  Another thing would be to compensate for use of the 'ThisApplication' veriable, which is defined for us in both iLogic and VBA, behind the scenes.  Then you would need to either delete or replace the 'Logger' functionality, on the Catch side of the Try...Catch statement, because 'Logger' is also a 'Rule Object' (variable defined by iLogic, behind the scenes of every rule we create).

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 22 of 27

CattabianiI
Collaborator
Collaborator

thank you, complete and exhaustive as always @WCrihfield 
I have a question about these lines though : 

If oDocAsset.IsUsed = False Then
  oDocAsset.Delete

In the Update command via UI, that thing is implemented without listing the unused materials? 

CattabianiI_0-1704793556510.png

 

0 Likes
Message 23 of 27

WCrihfield
Mentor
Mentor

That is correct, if you clicked on the Update ribbon button in the Styles and Standards panel of the Manage tab.  You would have to then click on the Purge button right below the Update button, to see the list of unused styles that can be purged from the document.  My code was designed to do both tasks at the same time.  If you do not want it to delete any unused styles, you can remove that portion of the code, or change it by removing the whole 'Asset.IsUsed' checking If...Then statement, and promoting the ElseIf portion of the code within it up a level.  Also, if not purging anything, then the Do...Loop statement may not be needed in the Sub Main area.  That loop helps facilitate deleting sub-styles that are no longer being used for anything, after another Style has been deleted in the previous iteration of the loop that was referencing it.  I doubt something like that would be needed if just updating styles, but might be useful if adding more styles to the existing ones, and some of those may reference or replace other existing styles.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 24 of 27

PolemEngineering
Advocate
Advocate

@WCrihfield Compliments for the neat code. The purge command works as expected. Can you (or anyone) just explain why the update doesn't seem to be working?
I copied the code, as a whole, into a new local iLogic rule in a new Part Document. I then adjusted the active material (from the active material library Autodesk Material Library) (Color Appearance of Glass changed from Clear to Bronze).
In the Material Browser, this material is now indicated as differs from the active library material, as expected. Update in "Styles and Standards" also indicates that the material has local changes.
The iLogic rule does not change this.
If I adjust the code in line 33 slightly:

 

 

				Try : oLibAsset = oLibMatAssets.Item(oDocAsset.Name) : Catch ex As Exception : Logger.Info(ex.ToString) : End Try

 

 

 

I get:

 

 

INFO|System.ArgumentException: De parameter is onjuist. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))
   at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
   at Inventor.AssetsEnumerator.get_Item(Object Index)
   at ThisRule.PurgeAndUpdateModelAssets(Document oModelDoc) in C:\Users\myname\AppData\Local\Temp\iLogic Rules\TestWithMaterialAssets.ipt.Rule0.vb:line 40

 

 

The variables from the command all seem to have a value. What is striking is that .name values differ between library and local. The one for Glass is 1:Glass (local) vs MaterialInv_002 (library).
Perhaps this approach no longer works? I am currently using Inventor 2023.4.1.

René van der Starre

0 Likes
Message 25 of 27

WCrihfield
Mentor
Mentor

Hi @PolemEngineering.  The Asset API object has two different properties that can be used there (DisplayName and Name).  The documentation for the Item property of the AssetsEnumerator API object suggests that we can specify an Integer, or String there, and the String can be either its Name or its DisplayName.  So, if using the Name property is causing problems for you, try using the DisplayName there instead.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 26 of 27

PolemEngineering
Advocate
Advocate

I have already changed the .Name to .DisplayName. A match will then be found.

Unfortunately the final code (with the .CopyTo) then throws an exception similar to the previous.

 

Quite strange in my opinion, because .Name should be the language-independent identifier. This concerns the standard, (afaik) unmodified library of Autodesk Inventor 2023. That's why I wondered whether this was still a functioning approach.
From your answer I understand that I have to look for the problem somewhere in my own installation. Any suggestions?

René van der Starre

0 Likes
Message 27 of 27

WCrihfield
Mentor
Mentor

Is it possible that the document is ReadOnly for some reason (such as Content Center, ModelState member, library file)?  If so, then making nearly any type of changes by code will either cause errors, or simply not work as intended.  This can easily be checked with the Document.IsModifiable property.  However, that property does not offer any explanation about why it may not be modifiable.  Another couple properties that can be checked are:

PartComponentDefinition.IsContentMember 

PartComponentDefinition.IsModelStateMember 

It has been years since I used iParts, so I can not remember if an iPart member (PartComponentDefinition.IsiPartMember ) is ReadOnly, but I do not think they are.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes