Change ActiveMaterial back to "Generic" programmatically

Change ActiveMaterial back to "Generic" programmatically

jefries1683
Contributor Contributor
1,726 Views
10 Replies
Message 1 of 11

Change ActiveMaterial back to "Generic" programmatically

jefries1683
Contributor
Contributor

I have already created a command which sets all objects within a selection to a chosen material.  It works as I hoped.

 

Now I am trying to create a command which reverts the objects of a selection back to the 'Generic' material and I cannot seem to get it working.

 

In both instances I cycle through all the available materials looking for a specific one, but 'Generic' is not found.

 

Public Sub ScrubKnData()
        Dim thisDocument As Document = g_inventorApplication.ActiveDocument

                For Each obj As Object In thisDocument.SelectSet
                    Dim thisMaterialName As String = "Generic Material"
                    Dim thisCompOcc As ComponentOccurrence = obj
                    thisDocument = thisCompOcc.Definition.Document
                    Select Case thisDocument.DocumentType
                        Case DocumentTypeEnum.kPartDocumentObject
                            Dim thisPartDoc As PartDocument = thisCompOcc.Definition.Document
                            Dim theseAssets As AssetsEnumerator = g_inventorApplication.ActiveMaterialLibrary.MaterialAssets
                            For Each thisAsset As Asset In theseAssets
                                If thisAsset.DisplayName = thisMaterialName Then
                                    thisPartDoc.ActiveMaterial = thisAsset
                                    thisDocument.Update()
                                    Exit For
                                End If
                            Next
                    End Select
                Next
    End Sub

 

Any help would be appreciated.

 

Thanks,

Jeff

0 Likes
Accepted solutions (1)
1,727 Views
10 Replies
Replies (10)
Message 2 of 11

HermJan.Otterman
Advisor
Advisor

What happens if you try this manualy?

does the appearance then come from the library or from the part it self?

what is the error that you get?

can the material be found at all?

the string should be "Generic" ... not "Generic material"

If this answers your question then please select "Accept as Solution"
Kudo's are also appreciated Smiley Wink

Succes on your project, and have a nice day

Herm Jan


0 Likes
Message 3 of 11

jefries1683
Contributor
Contributor

Thank you for your reply.

 

Manually there is no problem.

The appearances work as expected when manual.

 

I can programmatically change the material from "Generic" to any other material, but not back to "Generic".

 

When I step through the code I observe that it finds 49 out of the 50 materials in the current library.  Generic is the missing material.  My assumption is that there is a specific way to change it to "Generic" similar to "ByLayer" in AutoCAD, but I can't seem to figure it out.

 

There is no error.  If the desired material is not found it does not attempt to change it.

 

I tried "Generic material" out of desperation when I was able to find a material with that name in another library type.  It didn't help and I simply forgot to change it back before I clipped the code here.  I am typically looking for "Generic" only.

 

Thank you,

Jeff

0 Likes
Message 4 of 11

HermJan.Otterman
Advisor
Advisor
Accepted solution

Oke Jefries,

 

I made this code and it work with me.

I made it in VB.net, I think you are also using VB...??

 

So, have an Assembly open with parts in it.

select some parts and start this programm

it wil look in the part to see if the material asset is already local, if not it copies it from the library to local.

then it will set the local asset active.

 

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

ChangeMaterial("Generic")

End Sub

 

 

Private Sub ChangeMaterial(ByVal MaterialName As String)

'current doc = assembly, with parts selected

Dim oAssyDoc As AssemblyDocument = _inventorApplication.ActiveDocument

Dim oSelectSet As SelectSet = oAssyDoc.SelectSet

Dim oOccurrence As ComponentOccurrence = Nothing

Dim oPartDoc As PartDocument = Nothing

For Each oOccurrence In oSelectSet

oPartDoc = oOccurrence.Definition.Document

If oOccurrence.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then

Dim oAsset As Asset = GetMaterialAssetLocal(oOccurrence.Definition.Document, MaterialName)

oPartDoc.ActiveMaterial = oAsset

End If

Next

End Sub

 

 

Private Function GetMaterialAssetLocal(ByVal oPartDoc As PartDocument, ByVal Material As String) As Asset

' check if material already is local

Dim localAsset As Asset = Nothing

Dim oMaterial As Asset

For Each oMaterial In oPartDoc.MaterialAssets

If oMaterial.DisplayName = Material Then

localAsset = oMaterial

Return localAsset

End If

Next

 

' this is from the Inventor API HELP

' Get an asset library by name. Either the displayed name (which

' can changed based on the current language) or the internal name

' (which is always the same) can be used.

Dim assetLib As AssetLibrary = Nothing

assetLib = _inventorApplication.AssetLibraries.Item("Autodesk Material Library")

'Set assetLib = ThisApplication.AssetLibraries.Item("314DE259-5443-4621-BFBD-1730C6CC9AE9")

' Get an asset in the library. Again, either the displayed name or the internal

' name can be used.

Dim libAsset As Asset = Nothing

libAsset = assetLib.MaterialAssets.Item(Material)

'Set libAsset = assetLib.AppearanceAssets.Item("ACADGen-082")

 

' Copy the asset locally.

Try

localAsset = libAsset.CopyTo(oPartDoc)

Catch ex As Exception

End Try

 

Return localAsset

End Function

If this answers your question then please select "Accept as Solution"
Kudo's are also appreciated Smiley Wink

Succes on your project, and have a nice day

Herm Jan


0 Likes
Message 5 of 11

jefries1683
Contributor
Contributor

That did it.  Thank you.

 

Can you help teach a man to fish?  I have the Inventor SDK, but I do not know of an 'API help' which you mention in your code.  Where can I find that?

 

Thanks,

Jeff

0 Likes
Message 6 of 11

MechMachineMan
Advisor
Advisor

@jefries1683 check out the links in my signature.


--------------------------------------
Did you find this reply helpful ? If so please use the 'Accept as Solution' or 'Like' button below.

Justin K
Inventor 2018.2.3, Build 227 | Excel 2013+ VBA
ERP/CAD Communication | Custom Scripting
Machine Design | Process Optimization


iLogic/Inventor API: Autodesk Online Help | API Shortcut In Google Chrome | iLogic API Documentation
Vb.Net/VBA Programming: MSDN | Stackoverflow | Excel Object Model
Inventor API/VBA/Vb.Net Learning Resources: Forum Thread

Sample Solutions:Debugging in iLogic ( and Batch PDF Export Sample ) | API HasSaveCopyAs Issues |
BOM Export & Column Reorder | Reorient Skewed Part | Add Internal Profile Dogbones |
Run iLogic From VBA | Batch File Renaming| Continuous Pick/Rename Objects

Local Help: %PUBLIC%\Documents\Autodesk\Inventor 2018\Local Help

Ideas: Dockable/Customizable Property Browser | Section Line API/Thread Feature in Assembly/PartsList API Static Cells | Fourth BOM Type
0 Likes
Message 7 of 11

HermJan.Otterman
Advisor
Advisor

Go to Inventor,

click the down arrow next to the "?" Upper right, go to Help,  than Programming/Api Help

 

 

If this answers your question then please select "Accept as Solution"
Kudo's are also appreciated Smiley Wink

Succes on your project, and have a nice day

Herm Jan


0 Likes
Message 8 of 11

jefries1683
Contributor
Contributor

Huh, look at that.  Right under my nose.

 

Thanks again to you and MechMachineMan,

Jeff

0 Likes
Message 9 of 11

bernd.schreck
Contributor
Contributor

@HermJan.Otterman Hi, I know this is an older discussion but I´m currently not able to proceed.

I´m programming an Add-in for Inventor (2020) using VB.NET.

I used  exactly your code and when the ActiveMaterial should be set (line: oPartDoc.ActiveMaterial = oAsset), I get the following error:
System.Runtime.InteropServices.COMException: 'Member not found. (Exception from HRESULT: 0x80020003 (DISP_E_MEMBERNOTFOUND))'

Does not matter if the material is in the local Asset or not.

Do you have a idea what triggers this error and why I can not set the active material of the part?

0 Likes
Message 10 of 11

HermJan.Otterman
Advisor
Advisor

Hello Bernd,

 

always difficult these kind of errors. do you use the right .net version? for 2020 this should be 4.7.

are you sure you are in a part document?

can this document be changed? (or is it maybe readonly?)

is the oAsset not nothing?

 

after that I have to see what is happening, by seeing the code or what you do

in that case, send me a private message.

If this answers your question then please select "Accept as Solution"
Kudo's are also appreciated Smiley Wink

Succes on your project, and have a nice day

Herm Jan


0 Likes
Message 11 of 11

bernd.schreck
Contributor
Contributor
Hello Herm Jan,

sorry that I reply that late, was on "vacation".
The .net version is 4.7.2
I using Vault (2020 Pro) and the file is Checked-out (but also does not work on non-Vault files).
I use the following code to call a helper function which gives me the materialasset (see below). The error is at line 3.
Even if the current material is the same as the selected one (in the code it is hard coded), I get the error. It seems that something internal is slightly different between the objects.

Private Sub ButtonSave_Click(sender As Object, e As EventArgs) Handles ButtonSave.Click

oDoc.ActiveMaterial = GetMaterialAssetLocal(oDoc, "POM")
oDoc.Update()
oDoc.Save()

Me.DialogResult =
System.Windows.Forms.DialogResult.OK
Me.Close()

End Sub

The helper function looks if the current asset is the wished material and if it is stored locally (in the file). Otherwise it copies it to it. I use a custom library, maybe this is the problem?

Private Function GetMaterialAssetLocal(ByVal oPartDoc As PartDocument, ByVal Material As String) As MaterialAsset

' check if material already is local

Dim localAsset As MaterialAsset = Nothing

Dim oMaterial As MaterialAsset

For Each oMaterial In oPartDoc.MaterialAssets

If oMaterial.DisplayName = Material Then

localAsset = oMaterial

Return localAsset

End If

Next



' this is from the Inventor API HELP

' Get an asset library by name. Either the displayed name (which

' can changed based on the current language) or the internal name

' (which is always the same) can be used.

Dim assetLib As AssetLibrary = Nothing

assetLib = invApp.AssetLibraries.Item("CommonMaterials")

'Set assetLib = ThisApplication.AssetLibraries.Item("314DE259-5443-4621-BFBD-1730C6CC9AE9")

' Get an asset in the library. Again, either the displayed name or the internal

' name can be used.

Dim libAsset As Asset = Nothing

libAsset = assetLib.MaterialAssets.Item(Material)

'Set libAsset = assetLib.AppearanceAssets.Item("ACADGen-082")



' Copy the asset locally.

Try

localAsset = libAsset.CopyTo(oPartDoc)

Catch ex As Exception

End Try



Return localAsset

End Function
0 Likes