I have an assembly with 2 model states. The first will be dynamically controlled through iLogic. The second will be static. Despite a few different attempts. I cannot make changes to the first without affecting the second. In my rule, I first include a statement to set the model state as well as setting the member edit scope:
Dim oModelState As ModelState ThisAssembly.Document.ComponentDefinition.ModelStates.MemberEditScope = MemberEditScopeEnum.kEditActiveMember For Each oModelState In ThisAssembly.Document.ComponentDefinition.ModelStates If oModelState.Name = "[Primary]" Then oModelState.Activate() End If Next
Next, for my dynamic model state, I set the suppression of each part with this type of thing:
If somthing = something Then
Component.IsActive("...") = False
Else
Component.IsActive("...") = True
End If
Next, for the static model state, I switch model states as follows:
For Each oModelState In ThisAssembly.Document.ComponentDefinition.ModelStates If oModelState.Name = "Posts" Then oModelState.Activate() End If Next
And finally, set the suppression state of the appropriate parts in a similar way as seen above.
The rule runs as though kEditAllMembers is set. Is there something I'm missing? Thanks
Solved! Go to Solution.
Solved by WCrihfield. Go to Solution.
Hi @dustinbagley. Where you are using 'ThisAssembly.Document', try using 'ThisDoc.FactoryDocument' instead.
Wesley Crihfield
(Not an Autodesk Employee)
Thanks for responding. I replaced
ThisAssembly.Document.ComponentDefinition.ModelStates.MemberEditScope = MemberEditScopeEnum.kEditActiveMember
with
ThisDoc.FactoryDocument.ComponentDefinition.ModelStates.MemberEditScope = MemberEditScopeEnum.kEditActiveMember
and I am still getting the same results.
I also tried making the same change you recommended in the state switching statements:
For Each oModelState In ThisAssembly.Document.ComponentDefinition.ModelStates If oModelState.Name = "[Primary]" Then oModelState.Activate() End If Next
but intelesense did not have it available so I left those unchanged.
If I understand correctly, you're looking for something like this.
I hope this helps.
Best of luck to you in all of your Inventor pursuits,
Curtis
http://inventortrenches.blogspot.com
something = InputRadioBox("something?", "True", "False", True, "iLogic") Dim oMStates As ModelStates oMStates = ThisAssembly.Document.ComponentDefinition.ModelStates oMStates.MemberEditScope = MemberEditScopeEnum.kEditActiveMember 'set primary active oMStates.Item(1).Activate 'primary If something = True Then Component.IsActive("Comp1") = True Component.IsActive("Comp2") = True Else Component.IsActive("Comp1") = False Component.IsActive("Comp2") = False End If MsgBox("Pause to examine browser" ,, ThisAssembly.Document.ModelStateName) 'set posts MS active oMStates.Item("Posts").Activate If something = True Then Component.IsActive("Comp1") = True Component.IsActive("Comp2") = False Else Component.IsActive("Comp1") = False Component.IsActive("Comp2") = True End If MsgBox("Pause to examine browser" ,, ThisAssembly.Document.ModelStateName) 'set primary active again oMStates.Item(1).Activate 'primary
Yes that's right, my issue however is that, despite setting kActiveMember and despite making suppression modifications only after changing model states, both model states are affected by the changes.
@dustinbagley wrote:
... despite making suppression modifications only after changing model states, both model states are affected by the changes.
I am not seeing that result with the example I posted.
edit: attached is a simple assembly (MS_test.iam) that you can test this on.
Can you confirm that you are seeing unexpected results with this example?
The Intellisense may not show that the properties are available, but the code should still work the way I suggested. I generally tend to not use really long lines of code repetitively though. I like to get important objects like the document and ModelStates collection set to a variable that I can reuse, instead of repeating the long line of code to get to that point. That little change just ensures that you are working with the 'Factory' version of the document, which is the only version that is Read/Write, instead of a 'member' document, which is usually ReadOnly. This is usually not quite as important when working directly with that document, when it is the active document on your screen though. Below is just another example similar to yours, but with a couple things changed.
If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then Exit Sub
Dim oADoc As AssemblyDocument = ThisDoc.FactoryDocument
Dim oMSs As ModelStates = oADoc.ComponentDefinition.ModelStates
'first ModelState (ModelStates.Item(1)) is always Master or Primary
oMSs.MemberEditScope = MemberEditScopeEnum.kEditActiveMember
OriginallyActiveModelState = oMSs.ActiveModelState 'record for later, to restore
oMSs.Item(1).Activate 'activate Primary ModelState
'If something = somethingelse Then
' oADoc.ComponentDefinition.Occurrences.ItemByName("...").Suppress(True) 'same as IsActive = False
' Component.IsActive("...") = False
'Else
' oADoc.ComponentDefinition.Occurrences.ItemByName("...").Unsuppress 'same as IsActive = True
' Component.IsActive("...") = True
'End If
oMSs.Item("Posts").Activate
OriginallyActiveModelState.Activate
Oops...a little late with this responce.
Wesley Crihfield
(Not an Autodesk Employee)
This is just a hunch, because I honestly do not use the Component.IsActive() that much anymore, especially now that I have to deal with ModelStates, so I have another thought. Maybe that iLogic snippet is not good to use while going through multiple ModelStates and activating them, because it doesn't handle the document references correctly. Maybe you need to be capturing the document each time after you have activated a different ModelState, because activating a ModelState changes the active document reference. Maybe something like this would work a little better.
If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then Exit Sub
Dim oADoc As AssemblyDocument = ThisDoc.FactoryDocument
Dim oMSs As ModelStates = oADoc.ComponentDefinition.ModelStates
'first ModelState (ModelStates.Item(1)) is always Master or Primary
oMSs.MemberEditScope = MemberEditScopeEnum.kEditActiveMember
OriginallyActiveModelState = oMSs.ActiveModelState 'record for later, to restore
Dim oMSDoc As AssemblyDocument = Nothing
Dim oOccs As ComponentOccurrences = Nothing
oMSs.Item(1).Activate 'activate Primary ModelState
oMSDoc = oMSs.Item(1).FactoryDocument
oOccs = oMSDoc.ComponentDefinition.Occurrences
'If something = somethingelse Then
' oOccs.ItemByName("...").Suppress(True) 'same as IsActive = False
'Else
' oOccs.ItemByName("...").Unsuppress 'same as IsActive = True
'End If
oMSs.Item("Posts").Activate
oMSDoc = oMSs.Item("Posts").FactoryDocument
oOccs = oMSDoc.ComponentDefinition.Occurrences
'If something = somethingelse Then
' oOccs.ItemByName("...").Suppress(True) 'same as IsActive = False
'Else
' oOccs.ItemByName("...").Unsuppress 'same as IsActive = True
'End If
OriginallyActiveModelState.Activate
Or maybe we could use the StandardObjectProvider / StandardObjectFactory route, while using the ModelState.Document or ModelState.FactoryDocument object as input, so that the Component.IsActive will be referencing the correct document.
SOP = StandardObjectFactory.Create(oMSs.Item("Posts").Document)
SOP.Component.IsActive("...") = True
Wesley Crihfield
(Not an Autodesk Employee)
Can't find what you're looking for? Ask the community or share your knowledge.