Rule to have the same user parameters in all model states

Rule to have the same user parameters in all model states

lsensenbrenner
Contributor Contributor
1,012 Views
7 Replies
Message 1 of 8

Rule to have the same user parameters in all model states

lsensenbrenner
Contributor
Contributor

Hello,
I use the model's state to have the different manufacturing states of my part.
It's a part that uses user parameters and I want these parameters to be the same in the different states of the model without having to check that the extent of the modifications is activated.
To do this, I'd like to create a rule, but I don't know how to set it up.

Can you help me?

Thanks in advance

0 Likes
Accepted solutions (2)
1,013 Views
7 Replies
Replies (7)
Message 2 of 8

WCrihfield
Mentor
Mentor

Hi @lsensenbrenner.  Do you mean that you want to run an iLogic rule that will ensure that all parameters in all ModelStates have the same values, or do you only want some specific parameters have the same values in all ModelStates?  If there are different values for the same parameters within multiple ModelStates, then which ModelState's parameter values should be used as the correct values that should be copied to the other ones?

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 8

WCrihfield
Mentor
Mentor

Here is an example iLogic rule that will attempt to capture all of the current parameter expressions of the active ModelState, then copy those to the same parameters in all other ModelState that are present in that file.

Sub Main
	Dim oDoc As Document = ThisDoc.FactoryDocument
	If oDoc Is Nothing Then Return 'will return Nothing if it was a DrawingDocument
	Dim oMSs As ModelStates = oDoc.ComponentDefinition.ModelStates
	If oMSs.Count < 2 Then Return 'if no custom ModelStates, exit rule
	Dim oOrigMS As ModelState = oMSs.ActiveModelState 'record originally active ModelState
	oMSs.MemberEditScope = MemberEditScopeEnum.kEditActiveMember
	Dim oParams As Inventor.Parameters = oDoc.ComponentDefinition.Parameters
	If oParams.Count = 0 Then Return 'if no parameters, exit rule
	Dim oParam As Inventor.Parameter = Nothing
	'record param names & Expressions of current ModelState, so we can copy the values to other ModelStates
	Dim oMap As NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
	For Each oParam In oParams
		oMap.Add(oParam.Name, oParam.Expression)
	Next
	If oMap.Count = 0 Then Return 'if nothing recorded, exit rule
	'copy that recorded data to other ModelStates
	For Each oMS As ModelState In oMSs
		oMS.Activate
		For Each oParam In oParams
			For i As Integer = 1 To oMap.Count
				If oParam.Name = oMap.Name(i) Then
					oParam.Expression = oMap.Item(i)
				End If
			Next
		Next
	Next 'oMS
	If oMSs.ActiveModelState IsNot oOrigMS Then
		oOrigMS.Activate 'restore originally active ModelState to the currently active one
	End If
	If oDoc.RequiresUpdate Then oDoc.Update2(True)
	'If oDoc.Dirty Then oDoc.Save2(True)
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

EESignature

(Not an Autodesk Employee)

0 Likes
Message 4 of 8

lsensenbrenner
Contributor
Contributor

Hi @WCrihfield,
I just want the user parameters to be identical in all ModelStates, to avoid a diameter being 20mm in the first ModelState and 25mm in the second ModelState.
Thank you in advance and have a nice day

0 Likes
Message 5 of 8

lsensenbrenner
Contributor
Contributor

Hi @WCrihfield,

I tried your code but I got an error on line 23 :

Error on line 23 of the rule: Identical values, in the document: Arbre supérieur.ipt

Irreparable failure (Exception from HRESULT : 0x8000FFFF (E_UNEXPECTED))

More info :

System.Runtime.InteropServices.COMException (0x8000FFFF): Défaillance irrémédiable (Exception de HRESULT : 0x8000FFFF (E_UNEXPECTED))
to System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
to Inventor.Parameter.set_Expression(String )
to ThisRule.Main() dans règle: Valeurs identiques, dans le document Arbre supérieur.ipt:ligne 23
to Autodesk.iLogic.Exec.AppDomExec.ExecRuleInAssembly(Assembly assem)
to iLogic.RuleEvalContainer.ExecRuleEval(String execRule)

 

Can you help me ?

Thank in advance and have a nice day

 

0 Likes
Message 6 of 8

WCrihfield
Mentor
Mentor
Accepted solution

Hi @lsensenbrenner.  For some reason, it must not like setting the 'Expression' of one of the parameters in one of the other ModelStates.  In some situations, like when copying assembly level parameters down into sub components, and if those parameters do not exist yet, creating them...setting a prameter's Expresion can fail due to one or more of the other Parameters whose names are present within the Expression may not exist yet in the target document.  Not sure why it would fail when just copying expressions between different ModelStates of the same file though.  When a parameter (or custom iProperty) is first created in a document with multiple ModelStates, it will exist within all of the ModelStates.  It is most likely another similar timing related issue, where one parameter's Expression is being set before or after another one, when they may need to be set in a different order.  We could enclose that one line of code within a Try...Catch statement, to handle that potential error, and allow the rest of the process to continue, but not sure how to fix the one that did not get changed correctly.  Maybe if the whole loop ran twice, that would fix the one (or more) that experienced problems in the first loop through.

 

The attached text file contains an edited version of my previous code, in which I have added the Try...Catch statement in there, and added an extra loop through all the ModelStates, in an attempt to fix any that may have had problems the first time around.  The only way to keep all your Parameter values the same across all ModelStates is to set the member edit scope to factory scope (all members), and keep it there when editing parameters.  There is no need for an iLogic code for that though, because there are two easy ways to control it through Inventor's user interface.  One on the Manage tab, Author panel, with drop-down list (either Edit Member Scope, or Edit Factory Scope).  The other way is to select the little pencil icon next to the Model States model browser folder.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 7 of 8

lsensenbrenner
Contributor
Contributor

Hi @WCrihfield,

Thank you for your reply, it works very well
Would it be possible to add to this rule, the update of the mass according to the model state?
I tried to use one of the codes you made in the article:
https://forums.autodesk.com/t5/inventor-programming-ilogic/get-mass-properties-from-every-model-stat... 

ub Main
	Dim oDoc As Document = ThisDoc.FactoryDocument
	'If oDoc Is Nothing Then Return 'will return Nothing if it was a DrawingDocument
	Dim oMSs As ModelStates = oDoc.ComponentDefinition.ModelStates
	If oMSs.Count < 2 Then Return 'if no custom ModelStates, exit rule
	Dim oOrigMS As ModelState = oMSs.ActiveModelState 'record originally active ModelState
	oMSs.MemberEditScope = MemberEditScopeEnum.kEditActiveMember
	Dim oParams As Inventor.Parameters = oDoc.ComponentDefinition.Parameters
	If oParams.Count = 0 Then Return 'if no parameters, exit rule
	Dim oParam As Inventor.Parameter = Nothing
	'record param names & Expressions of current ModelState, so we can copy the values to other ModelStates
	Dim oPartNumber As String = iProperties.Value("Project", "Part Number")
	Dim oVendor As String = iProperties.Value("Project", "Vendor")
	Dim oMap As NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
	For Each oParam In oParams
		oMap.Add(oParam.Name, oParam.Expression)
	Next
	If oMap.Count = 0 Then Return 'if nothing recorded, exit rule
	'copy that recorded data to other ModelStates
	'For M As Integer = 1 To 1
		For Each oMS As ModelState In oMSs
			oMS.Activate
			iProperties.Value("Project", "Part Number") = oPartNumber
			iProperties.Value("Project", "Vendor")=oVendor
			Dim oMSDoc As PartDocument = oMS.FactoryDocument
			oMSDoc.Rebuild2(True)
			Dim oMP As MassProperties = oMS.ComponentDefinition.MassProperties
			TryCreateUpdateCustomProperty(oMSDoc, oMS.Name & "_Mass", oMP.Mass)
			
			For Each oParam In oParams
				For i As Integer = 1 To oMap.Count
					If oParam.Name = oMap.Name(i) Then
						Try
							Dim sExpression As String = oMap.Item(i).ToString
							oParam.Expression = sExpression
						Catch 'what to do if that fails
							Logger.Error("Error copying Expression to Parameter named " & oParam.Name _
							& " in ModelState named " & oMS.Name)
						End Try
					End If
				Next
			Next
		Next 'oMS
	'Next 'M
	If oMSs.ActiveModelState IsNot oOrigMS Then
		oOrigMS.Activate 'restore originally active ModelState to the currently active one
	End If
	If oDoc.RequiresUpdate Then oDoc.Update2(True)
	'If oDoc.Dirty Then oDoc.Save2(True)
End Sub

Sub TryCreateUpdateCustomProperty(oDoc As Inventor.Document, sPropName As String, _
oValue As Object, Optional sExpression As String = vbNullString)
	If IsNothing(oDoc) Or sPropName = "" Or oValue Is Nothing Then Exit Sub
	If oDoc.IsModifiable = False Then Exit Sub
	Dim oCProps As Inventor.PropertySet = oDoc.PropertySets.Item(4)
	Dim oCProp As Inventor.Property = Nothing
	Try
		oCProp = oCProps.Item(sPropName)
	Catch
		oCProp = oCProps.Add(oValue, sPropName)
	End Try
	If String.IsNullOrEmpty(sExpression) Then
		If oCProp.Value <> oValue Then oCProp.Value = oValue
	Else
		If oCProp.Expression <> sExpression Then oCProp.Expression = sExpression
	End If
End Sub

 

But I get the following error:

Error on line 27 of rule: Identical values, in document: ---

The 'ComponentDefinition' public member of type 'ModelState' cannot be found.

 

Thank you in advance and have a nice day

0 Likes
Message 8 of 8

WCrihfield
Mentor
Mentor
Accepted solution

After a quick review of the last code you posted, and counting rows down to Line 27, I can see why that line is throwing an error.  Where these three lines of code are:

Dim oMSDoc As PartDocument = oMS.FactoryDocument
oMSDoc.Rebuild2(True)
Dim oMP As MassProperties = oMS.ComponentDefinition.MassProperties

...that third line should be using the oMSDoc variable that represents a Document, instead of the oMS variable, which represents a ModelState object.  When I looked at the code posted in that other linked post, that like of code was already using the 'oMSDoc' variable, as seen in the following line:

Dim oMP As MassProperties = oMSDoc.ComponentDefinition.MassProperties

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes