Hi everyone,
I created this iLogic rule to build out a "LOD model state" in the top level assembly and subassemblies, rather than having to open each file and add the state. I haven't tested it much, but thought I'd share it here.... if you run into issues just post here.
I hope this helps.
Best of luck to you in all of your Inventor pursuits,
Curtis
http://inventortrenches.blogspot.com
Update: see next post
Update to the previous.... it wasn't activating the model state in nested subassemblies
Sub Main
oName = InputBox("Prompt", "iLogic", "LOD State")
Dim oDoc As AssemblyDocument
oDoc = ThisApplication.ActiveDocument
Dim oAsmCompDef As AssemblyComponentDefinition
oAsmCompDef = oDoc.ComponentDefinition
Dim oModelState As ModelState
'create ModelState in the top level
Try
oModelState = oDoc.ComponentDefinition.ModelStates.Add(oName)
oDoc.ActiveModelState = oName
Catch
End Try
Call TraverseAssembly(oDoc.ComponentDefinition.Occurrences, oName)
InventorVb.DocumentUpdate()
End Sub
Sub TraverseAssembly(Occurrences As ComponentOccurrences, oName As String)
Dim oDoc As AssemblyDocument
Dim oOcc As ComponentOccurrence
For Each oOcc In Occurrences
If oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
CreateModelState(oOcc, oName)
Call TraverseAssembly(oOcc.SubOccurrences, oName)
'get the parent, if it exists, open it and
'activate the model states in it
If oOcc.ParentOccurrence IsNot Nothing Then
Logger.Info("oOcc: " & oOcc.Name)
Logger.Info("parent: " & oOcc.ParentOccurrence.Name)
oParent = oOcc.ParentOccurrence.Definition.Document.fullfilename
oDoc = ThisApplication.Documents.Open(oParent, False)
oDoc.ComponentDefinition.ModelStates.item(oName).activate
For Each iOcc In oDoc.ComponentDefinition.Occurrences
If iOcc.Definition.Document Is oOcc.Definition.Document Then
iOcc.ActiveModelState = oName
oDoc.Close
End If
Next
End If
End If
Next
End Sub
Sub CreateModelState(oOcc As ComponentOccurrence,oName As String )
oMSFactory = oOcc.Definition.FactoryDocument
Try
'try to create new model state
oModelState = oMSFactory.ComponentDefinition.ModelStates.add(oName)
Catch
'catch errors when state already exists, etc
End Try
Try
oOcc.ActiveModelState = oName
Catch
End Try
End Sub
Here is another version that allows you to select components and suppress them... might be a little buggy, but seemed to work pretty well.
Sub Main
Dim oDoc As AssemblyDocument
oDoc = ThisApplication.ActiveDocument
Dim oAsmCompDef As AssemblyComponentDefinition
oAsmCompDef = oDoc.ComponentDefinition
oCurrrent = oDoc.ModelStateName
Dim oList As New ArrayList
oList.Add("*** Create New State ***")
Dim oModelState As ModelState
For Each oModelState In oDoc.ComponentDefinition.ModelStates
oList.Add(oModelState.Name)
Next
oName = InputListBox("Select one to use", oList, oCurrrent, "iLogic", "List")
If oName = "*** Create New State ***" Then
oName = InputBox("Enter name for new model state", "iLogic", oCurrrent)
End If
If oName = "" Then Return 'exit rule
oFound = False
'look for Modelstate and set active if found
For Each oModelState In oDoc.ComponentDefinition.ModelStates
If oModelState.Name = oName Then
oDoc.ComponentDefinition.ModelStates.Item(oName).Activate()
oFound = True
End If
Next
'create ModelState in the top level
If oFound = False Then
oModelState = oDoc.ComponentDefinition.ModelStates.Add(oName)
End If
Call TraverseAssembly(oDoc.ComponentDefinition.Occurrences, oName)
InventorVb.DocumentUpdate()
While True
oMsg = "Select components to suppress (press ESC to continue)"
oOcc = ThisApplication.CommandManager.Pick(
SelectionFilterEnum.kAssemblyLeafOccurrenceFilter, oMsg)
' If nothing gets selected then we're done
If IsNothing(oOcc) Then Exit While
'work with first level components
If oOcc.ParentOccurrence Is Nothing Then
If oOcc.Suppressed = True Then
oOcc.Unsuppress
Else
oOcc.Suppress
End If
'work with lower level components
Else If oOcc.ParentOccurrence IsNot Nothing Then
Logger.Info("oOcc: " & oOcc.Name)
Logger.Info("parent: " & oOcc.ParentOccurrence.Name)
oParent = oOcc.ParentOccurrence.Definition.Document.fullfilename
oAction = "SetSuppress"
Call ActivateSub_ModelState(oParent, oName, oAction, oOcc)
End If
InventorVb.DocumentUpdate()
End While
End Sub
Sub TraverseAssembly(Occurrences As ComponentOccurrences, oName As String)
Dim oDoc As AssemblyDocument
Dim oOcc As ComponentOccurrence
For Each oOcc In Occurrences
If oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
CreateModelState(oOcc, oName)
Logger.Info("oOcc: " & oOcc.Name)
Try
Call TraverseAssembly(oOcc.SubOccurrences, oName)
Catch Ex As Exception
'Logger.Info("TraverseAssembly, Exception: " & Ex.Message)
End Try
'get the parent, if it exists, open it and
'activate the model states in it
If oOcc.ParentOccurrence IsNot Nothing Then
Logger.Info("oOcc: " & oOcc.Name)
Logger.Info("parent: " & oOcc.ParentOccurrence.Name)
oParent = oOcc.ParentOccurrence.Definition.Document.fullfilename
oDoc = ThisApplication.Documents.Open(oParent, False)
oDoc.ComponentDefinition.ModelStates.item(oName).activate
For Each iOcc In oDoc.ComponentDefinition.Occurrences
If iOcc.Definition.Document Is oOcc.Definition.Document Then
iOcc.ActiveModelState = oName
oDoc.Close
End If
Next
End If
End If
Next
End Sub
Sub CreateModelState(oOcc As ComponentOccurrence,oName As String )
Logger.Info("CreateModelState, oOcc: " & oOcc.Name)
Try
'try to create new model state
oMSFactory = oOcc.Definition.FactoryDocument
oModelState = oMSFactory.ComponentDefinition.ModelStates.add(oName)
Catch ex As Exception
'catch errors when state already exists, etc
'Logger.Info("CreateModelState, ModelStates.add, Exception: " & ex.Message)
End Try
Try
oOcc.ActiveModelState = oName
Catch ex As Exception
'Logger.Info("CreateModelState, ActiveModelState, Exception: " & ex.Message)
End Try
End Sub
Sub ActivateSub_ModelState(oParent As String, oName As String, oAction As String, oOcc As ComponentOccurrence)
' Logger.Info("ActivateSub_ModelState, oOcc: " & oOcc.Name)
' Logger.Info("oParent: " & oParent)
' Logger.Info("oName: " & oName)
' Logger.Info("oAction: " & oAction)
oDoc = ThisApplication.Documents.Open(oParent, False)
oDoc.ComponentDefinition.ModelStates.item(oName).activate
If oAction = "Activate" Then
If oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
For Each iOcc In oDoc.ComponentDefinition.Occurrences
Logger.Info("iOcc name " & iOcc.Name)
If iOcc.Definition.Document Is oOcc.Definition.Document Then
iOcc.ActiveModelState = oName
End If
Next
End If
End If
If oAction = "SetSuppress" Then
xOcc = oDoc.ComponentDefinition.Occurrences.ItemByName(oOcc.Name)
Logger.Info("__________ " & xOcc.Name)
If xOcc.suppressed = True Then
xOcc.unsuppress
Else
xOcc.suppress
End If
End If
oDoc.Close
End Sub
Thanks...
But have your tried loading some iproperties onto the master state and then go to your custom level and find that all the loaded iproperties are gone?
I then load them onto the custom state and find that master iproperties are gone...
these model states are causing a lot of problems.. specially if you work with derived parts it seems...
Hi,
Thanks for this snippet, it has sparked an idea.
Before Model States we would use iLogic to make a "cut-out" in an occurrence, in a sub-assembly, by making the occurrence independent and replacing it with another part.
Thus ensuring that none of the other occurrences in the pattern had a "cut-out".
So our thoughts are that we could use Model States to make the independent "cut-out" without the need for the "replace component" operation...???
Does that make sense and is there a way, using iLogic, to create a Model State in an independent occurrence in a pattern, in an assembly...???
Thanks. 😉
We received some great code here, thanks everyone. 👍
Solved: Create Model States using iLogic - Autodesk Community - Inventor
Hi Curtis
Very useful code! It seems like something that many people are looking for.
I am trying to use the code in one of my assemblies but the weights in the top level model do not seem to change nor do parts hidden get suppressed in sub-assemblies. Can you please give a run down on how your code should be used
Thanks
it is possible to create a similar rule but which allows, within the PART, to create a model state with the same name as the modified parameter (For example, parameter name HEIGHT = 30 MODEL STATUS = 30)
and if it does not exist, create it otherwise activate the already existing one? I think you can also use the way of a list that is updated with each new value.
Can't find what you're looking for? Ask the community or share your knowledge.