Managing changes in Model States (iLogic)

Managing changes in Model States (iLogic)

theo_karypidis
Contributor Contributor
2,394件の閲覧回数
9件の返信
メッセージ1/10

Managing changes in Model States (iLogic)

theo_karypidis
Contributor
Contributor

Model States has brought a lot of new functionality in managing the configurations of our Inventor documents, but also added a bit of complexity in passing down parameters, managing the model state we want active etc.

When we have to do with straightforward models and cases,  it's extremely simple:  Add the Model States you need, make the changes in views, iProperties and Parameters you want for each Model State and you are done. 

 

What happens though when each Model State is not static? It is very often, for example, that we have a model that some of its parameters are ever-changing according to the customer order that we have. Sometimes the variety of a parameter value cannot be cut down to specific cases but can have hundreds of different possible values. That's where it gets complicated. 

 

Every change we make in any model state, it is stored and set in that specific model state. And if we open the Excel spreadsheet that lists all the changes for all our Model States, we can see and manage all those changes. I found myself in such a situation recently. The following ilogic snippets are a solution to the above issue.

 

First, I needed a way to be able to delete that parameter column from the Excel sheet that has its values for each Model State:

Sub DeleteTableColumn(AssDoc As AssemblyDocument, oPart As String, oParam As String)

Dim Occ As Inventor.ComponentOccurrence = AssDoc.ComponentDefinition.Occurrences.ItemByName(oPart)
Dim partdoc As PartDocument = Occ.Definition.FactoryDocument

Try
partdoc.ComponentDefinition.ModelStates.ModelStateTable.TableColumns.Item(oParam).Delete
Catch
End Try
	
End Sub

 

I called the code above to the following snippets according to what I needed to do each time. If you don't need or want to delete the parameter column, just delete or comment the line that calls the above code.

The snippet below will internally activate the specified Model State and change the value of the desired parameter. 

Sub setParamValueInModelState(AssDoc As AssemblyDocument, oPart As String, oModelStateName As String, oParam As String, oParamValue As Integer)

''Choose the part to make the changes
Dim Occ As Inventor.ComponentOccurrence = AssDoc.ComponentDefinition.Occurrences.ItemByName(oPart) 
Dim partdoc As PartDocument = Occ.Definition.FactoryDocument

''Activates the model state to change parameter values
partdoc.ComponentDefinition.ModelStates.Item(oModelStateName).Activate()

''Delete the model state column of the specified parameter
DeleteTableColumn(AssDoc, oPart, oParam)

''Give value to specified model state and parameter
partdoc.ComponentDefinition.Parameters.UserParameters.Item(oParam).Value = oParamValue / 10

AssDoc.Update2
End Sub

 

The snippet below will change the value of the desired parameter in the current Model State the Part is on:

Sub setParamValueInCurrentModelState(AssDoc As AssemblyDocument, oPart As String, oParam As String, oParamValue As Integer)

''Choose the part to make the changes
Dim Occ As Inventor.ComponentOccurrence = AssDoc.ComponentDefinition.Occurrences.ItemByName(oPart) 
Dim partdoc As PartDocument = Occ.Definition.FactoryDocument

''Activate master model state
'If partdoc.ComponentDefinition.ModelStates.ActiveModelState.ModelStateType = ModelStateTypeEnum.kSubstituteModelStateType Then
'   partdoc.ComponentDefinition.ModelStates.Item(1).Activate
'End If

''Delete the model state column of the specified parameter
'DeleteTableColumn(AssDoc, oPart, oParam)

''Give value to specified model state and parameter
partdoc.ComponentDefinition.Parameters.UserParameters.Item(oParam).Value = oParamValue / 10

End Sub

 
The snippet below will activate the specified Model State and change the value of the desired parameter:

Sub setParamValueInActivatedModelState(AssDoc As AssemblyDocument, oPart As String, oModelStateName As String, oParam As String, oParamValue As Integer)

''Choose the part to make the changes
Dim Occ As Inventor.ComponentOccurrence = AssDoc.ComponentDefinition.Occurrences.ItemByName(oPart) 
Dim partdoc As PartDocument = Occ.Definition.FactoryDocument

''Set active model state
Occ.ActiveModelState = oModelStateName	'selects the model state

''Delete the model state column of the specified parameter
DeleteTableColumn(AssDoc, oPart, oParam)

''Give value to specified model state and parameter
partdoc.ComponentDefinition.Parameters.UserParameters.Item(oParam).Value = oParamValue / 10

End Sub

 

I really hope those will help you as much as they helped me!

2,395件の閲覧回数
9件の返信
返信 (9)
メッセージ2/10

CattabianiI
Collaborator
Collaborator

I think it's very wrong to delete the table column for your purpose, you're loosing so much information about model states you're currently not interested into. And you're basically not leveraging model states concept. Why are you doing that?

Another related thing:
when you work on partDoc = occ.Definition.FactoryDocument, you're not necessarily affecting the occurrence*.
I don't know what are supposed to do the caller of setParamValueInActivatedModelState function but to set the parameter in your occurrence you should do something like that:

 

Dim partdoc As PartDocument = Occ.Definition.FactoryDocument 

''Set desired model state in the occurrence
Occ.ActiveModelState = oModelStateName	

' Set the model state I want to work with in the factory too
' It's from the factory where you're setting the parameter
partDoc.ComponentDefinition.ModelStatesoMStates.Item(oModelStateName).Activate()

' DO NOT DO THAT
''Delete the model state column of the specified parameter
' DeleteTableColumn(AssDoc, oPart, oParam)

''Set paramete in the model state active in partDoc (the factory)
partdoc.ComponentDefinition.Parameters.UserParameters.Item(oParam).Value = oParamValue / 10

 

 

0 件のいいね
メッセージ3/10

zoe.baker-bushby
Enthusiast
Enthusiast

Hi!

I notice the oParamValue / 10 is this due units? Having issues with this bit myself where my only work around is this divide by 10.

So I've got it to work, just curious if there are any alternatives?

Thanks

 

0 件のいいね
メッセージ4/10

theo_karypidis
Contributor
Contributor
Thank you CattabianiI I will try what you suggested!!

As for the column deletion, well you don't always want a parameter value to be set in a model state table. I am sure there must be a way that I could not find, but some parameters you need to change them for all Model States. Parameters like the length of a part that can in any case take values from 600 mm to 1400 mm with increment of 1 mm cannot be set to cases.
0 件のいいね
メッセージ5/10

theo_karypidis
Contributor
Contributor
Hello! Indeed, it is a units matter. It is because Inventor sees cm instead of my desired mm. It is the same if you do it from another language, outside Inventor.
メッセージ6/10

CattabianiI
Collaborator
Collaborator

Hi @zoe.baker-bushby,
as I said in the other thread check this article to have a better understanding on how to work with database units in ilogic: https://adndevblog.typepad.com/manufacturing/2012/07/unitsofmeasure-object-and-example.html
Dividing by 10 works if the length units are millimeter; it's an hardcoded way to deal with the issue I do not recommend.

0 件のいいね
メッセージ7/10

CattabianiI
Collaborator
Collaborator

hi @theo_karypidis 
about column deletion.
I understand your workflow and the granularity issue but column deletion is not the way unless you want to stop to manage that parameter per model state from now on.
Set ModelStates.MemberEditScope instead to edit all members:

modelStates.MemberEditScope = MemberEditScopeEnum.kEditAllMembers

 

If you have a length param set per model state, let's say: 
msname: short, length: 100
msname: medium, length: 200
msname: long, length: 400
and you want to create a new part which stores 110, 200, 400 as lengths, in this case it's clearly wrong to delete the entire column.
If you want to stores 110, 210, 410 instead, it's still useless to delete the column because:
- the graphic is not up to date for each model states, 
- once you deleted the column and set 110 in the param of short model state, you don't know which is the lenght in  the other model states; it would probably be the lenght of the active model state before to set the parameter so 100 and it sounds terribly wrong.

0 件のいいね
メッセージ8/10

rob
Advocate
Advocate

Old thread, but could you please post all the code to push an example parameter value down into a component for all of its model states (i.e. same parameter regardless of model state)?  Thanks!

IV Pro 2020.2
0 件のいいね
メッセージ9/10

CattabianiI
Collaborator
Collaborator

It's really just that line. And the operations to change param for all model states via iLogic are one-to-one with operations via UI.
So I recommend to understand very well the Toggle Edit Scope button before doing that via iLogic.

Anyway here's some code:

' Set length param in the active model state
Parameter("length") = 10

' Enable edit on all model states
Dim mss As ModelStates = ThisApplication.ActiveDocument.ComponentDefinition.ModelStates
mss.MemberEditScope = MemberEditScopeEnum.kEditAllMembers

' Set length param 
Parameter("length") = 15

' Enable edit on active model state only
mss.MemberEditScope = MemberEditScopeEnum.kEditActiveMember
0 件のいいね
メッセージ10/10

rob
Advocate
Advocate

Thanks for that.  This changes the parameter for all model states in the currently active document, which is part of the solution. 

 

What I'm really after is a way to push the value from the active assembly to a specified component in the assembly, where both have identically defined model states.  I did post a query on the forum and have a solution already, but am curious to know your approach.

IV Pro 2020.2
0 件のいいね