Assign Material to a part

george1985
Collaborator
Collaborator

Assign Material to a part

george1985
Collaborator
Collaborator

Hello,


I have an .ipt file, and I am using the code from this topic, to define material of a single part:

 

' Get single part doc
Set oPartDoc = ThisApplication.ActiveDocument

'Get the desired material.
Dim oMaterial As Material
Set oMaterial = oPartDoc.Materials.Item("Glass")

'Assign this material to the part.
oPartDoc.ComponentDefinition.Material = oMaterial

 


However, as mentioned in the upper topic, for some reason General and Physical properties of part's Material are all 'N/A'
The only way for them to correspond to the chose material is to manually using UI, click on the "Update" button inside part's iProperties.

Is there a way to press this 'Update' button with Inventor VBA, VB.NET, C#... ?

 

material properties are NA.png

Any help is appreciated.

0 Likes
Reply
Accepted solutions (1)
1,788 Views
14 Replies
Replies (14)

A.Acheson
Mentor
Mentor

Hi @george1985 

From this post here

InventorVb.DocumentUpdate(False)

Or the command version

 

ThisApplication.CommandManager.ControlDefinitions.Item("AppUpdateMassPropertiesCmd").Execute

 And also another discussion here

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan

george1985
Collaborator
Collaborator

Thank you very much for the two suggestions @A.Acheson .
I tried first one (with all combinations: .Update(), Update(False), Update(True), Update2(), Update2(False), Update2(True)) - but it didn't affect any of the material properties.
The same with :

ThisApplication.CommandManager.ControlDefinitions.Item("AppUpdateMassPropertiesCmd").Execute2(True)

I am running the code from an external WindowsForms app, on a single part (.ipt) drawing. Maybe this is the issue?

0 Likes

WCrihfield
Mentor
Mentor

If the code is being ran from an external Winows Form application, then the term 'InventorVb' will most likely not be recognized, because that is unique to iLogic.  Also the term 'ThisApplication', is defined within Inventor's API, but is also a somewhat common term, and if used elsewhere, it might be pointing to the wrong application.  That command is the one that gets ran when you click that 'Update' button, so the command is the correct one, however, the command is 'blind', which means it is not document specific, so it will likely try to work on whichever document is currently the 'active' one on your screen at that moment, and only if the Inventor application has the system focus at the time.  So, if you have the correct reference to the Inventor application object, and you can make sure the Inventor application has the system focus, and that specific document is currently the 'active' one, when that command is executed, it should work OK.  You could try something like AppActivate(ThisApplication.Caption) on the line just before executing that command, but I'm not sure if that is the proper method in your situation.  You may have to use the more advanced SetForegroundWindow method.

 

Edit / Correction:  Actually that 'ThisApplication' term is a variable that is automatically created for us in the background within the 'ThisRule' Class in each iLogic rule, to represent the Inventor.Application, so it is not actually defined within the Inventor API.  And it can also be used by the VBA system, because it is a ReadOnly Property of the Inventor.VbaApplication Class, which is defined within the C:\Program Files\Autodesk\Inventor 2024\Bin\RxInventor.tlb (Autodesk Inventor Object Library).

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

george1985
Collaborator
Collaborator

Thank you for the help @WCrihfield !

Yes, instead of 'InventorVb.DocumentUpdate(False)' I used 'oPartDoc.Update2(False)' (and its variations with True and Update).

Instead of 'ThisApplication', I used 'app' from the beginning of WindowsForms code (Marshal.GetObject('Inventor.Application'))

 

I also tried using either:
Microsoft.VisualBasic.Interaction.AppActivate(app.Caption)
or:
Microsoft.VisualBasic.Interaction.AppActivate('Inventor')
before calling:
app.CommandManager.ControlDefinitions.Item("AppUpdateMassPropertiesCmd").Execute2(True)

Sadly the material properties are still not updated.


I don't know how to call the 'SetForegroundWindow' method

0 Likes

WCrihfield
Mentor
Mentor

I have a simple example iLogic rule which uses that SetForegroundWindow method.

It will open the iProperties dialog, and navigate to the Physical tab for you.  I think I got this from Mike Deck, an Autodesk API guru.

Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Sub Main
	ThisApplication.CommandManager.ControlDefinitions.Item("AppiPropertiesWrapperCmd").Execute2(False)
	SetForegroundWindow(ThisApplication.MainFrameHWND)
	'System.Windows.Forms.Form.ActiveForm.Handle
	System.Windows.Forms.SendKeys.SendWait("{RIGHT 6}")
	ThisApplication.UserInterfaceManager.DoEvents()
End Sub

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SetForegroundWindow(hWnd As IntPtr) As Integer
End Function

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

A.Acheson
Mentor
Mentor

Hi @george1985 

Your saying your running this in a single part (.ipt) drawing. Is the drawing the active document or the part document? This is very important as you need to target the part document itself and if in the drawing this is the referenced document of the view. 

Can you attach more of the code to understand where your starting from. 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan

george1985
Collaborator
Collaborator

Thank you very much again @WCrihfield 
So 'SetForegroundWindow' function comes from 'user32.dll' file?

0 Likes

WCrihfield
Mentor
Mentor

I just assumed so.  I do not recall ever actually exploring around within that file myself.  I am not a software developer by trade, I just have years worth of dabbling with vb.net due to its usefulness in relation to Inventor's API & iLogic.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

george1985
Collaborator
Collaborator

Hi @A.Acheson 


@A.Acheson wrote:

Hi @george1985 

Your saying your running this in a single part (.ipt) drawing. Is the drawing the active document or the part document? This is very important as you need to target the part document itself and if in the drawing this is the referenced document of the view. 


Thank you @A.Acheson. I am not sure I know the difference between the active document and the part document.
Here is the python code without the WindowsForms functions:

from System.Runtime.InteropServices import Marshal
import Microsoft
import System
import clr

# input
_matName = 'Glass'
_dwg_filePath = R'C:\dwg_to_ipt\autocad.dwg'



# load "Autodesk.Inventor.Interop.dll"
clr.AddReferenceToFileAndPath(R'D:\Program Files\Autodesk\Inventor 2018\Bin\Public Assemblies\Autodesk.Inventor.Interop.dll')
import Inventor

# get 'ThisApplication' of currently running Inventor app
app = Marshal.GetActiveObject('Inventor.Application')



# get DWG Translator
dwgTranslator_id = '{C24E3AC2-122E-11D5-8E91-0010B541CD80}'
dwgTranslator = app.ApplicationAddins.ItemById(dwgTranslator_id)
dwgTranslator.Activate()

# create DataMedium
dataMedium = app.TransientObjects.CreateDataMedium()
dataMedium.FileName = _dwg_filePath

# create translation context
context = app.TransientObjects.CreateTranslationContext()
context.Type = Inventor.IOMechanismEnum.kDataDropIOMechanism

# create options
opt = app.TransientObjects.CreateNameValueMap()

# import DWG
# 3D model is imported as a side effect not as primary output
drawingDoc_dummy = Inventor.TranslatorAddIn.Open(dwgTranslator, dataMedium, context, opt)

# take .dwg's imported 3D model
displayName = System.IO.Path.GetFileNameWithoutExtension(_dwg_filePath)

for doc in app.Documents:
    if doc.DisplayName.startswith(displayName + '1'):  # Inventor 'Translator DWG' always adds '1' to the end of the .dwg file
        break

# apply material
mat = doc.Materials.Item(_matName)
doc.ComponentDefinition.Material = mat

# update all currently opened documents
doc.Update2(True)


# advice by WCrihfield
Microsoft.VisualBasic.Interaction.AppActivate(app.Caption)

# advice by A.Acheson
app.CommandManager.ControlDefinitions.Item("AppUpdateMassPropertiesCmd").Execute2(True)


# save a new .ipt file
ipt_filePath = System.IO.Path.ChangeExtension(_dwg_filePath, 'ipt')
doc.SaveAs(ipt_filePath, False)

# close all docs in Inventor
for doc2 in app.Documents:
    doc2.Close(True)

# release all COM objs
Marshal.ReleaseComObject(doc2)
Marshal.ReleaseComObject(doc)
Marshal.ReleaseComObject(app)
app = None
0 Likes

WCrihfield
Mentor
Mentor

This line of code does not look right to me:

 

drawingDoc_dummy = Inventor.TranslatorAddIn.Open(dwgTranslator, dataMedium, context, opt)

 

Here is the link to the online help page for that method you are using in that line:

https://help.autodesk.com/view/INVNTOR/2024/ENU/?guid=TranslatorAddIn_Open 

I think it would look more like this:

 

dwgTranslator.Open(dataMedium, context, opt, drawingDoc_dummy)

 

...because that is a Sub, it will not 'return' anything.  And I would assume that 'drawingDoc_dummy' variable may need to be declared somewhere beforehand, even if just as an Object.  But I do not often open files with a TranslatorAddIn by code that way, so I don't recall specifically what the expectations are for that last variable.

 

Edit:  Also, what version of Inventor are you using? Because that process of accessing and setting the Material seems outdated to me.  I think it was back around 2013 or 2016 that they changed from Material object to Asset objects that represented the data for things like Material, Appearance, Physical, etc.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Frederick_Law
Mentor
Mentor

VBA, iLogic, VB.NET all behave and do calls differently.

Add you're mixing it with python.

 

Don't look at VBA and iLogic examples.

Use Inventor Addin examples.

 

In case you don't have it:

https://help.autodesk.com/view/INVNTOR/2023/ENU/?guid=GUID-DE98632B-3DC0-422B-A1C6-8A5A15C99E11

 

Example on Mass:

https://help.autodesk.com/view/INVNTOR/2023/ENU/?guid=GUID-79D83C19-6100-4615-AE8A-10205A3BE040

george1985
Collaborator
Collaborator

Thank you very much for the help @Frederick_Law .
That did it perfectly. I set the accuracy, and then called the Area (without this call it didn't work):

oMassProps = oPartDoc.ComponentDefinition.MassProperties
oMassProps.Accuracy = Inventor.MassPropertiesAccuracyEnum.k_Medium
area = oMassProps.Area  # important to call!


However, not it looks as if accuracy is always 'Low'.

And I can't change it to any other value, even manually by using Inventor UI:

Update button blanked out.png


Thank you @WCrihfield .
My call is working. I guess there are differences how languages handle 'out' parameters.

0 Likes

Frederick_Law
Mentor
Mentor
Accepted solution

This could be part of the problem:

MassOption-01.jpg

george1985
Collaborator
Collaborator

Perfect! This worked like a charm! Thank you @Frederick_Law "Update physical properties on save" as unchecked on my Inventor.


@WCrihfieldI forgot to provide this information: I am using Inventor 2018.

0 Likes