Hi,
Before model states were introduced i used the following iLogic to push the value from a user parameter in my current assembly to all occurrences where a user parameter with the same name existed. This still works fine, except for parts with model states, for which 1. .IsModifiable returns false and 2.even if i circumvent that it still does not update the parameter. I already make sure that the parts are set to "edit all model states" as the parameters i want to change are supposed to have the same value for all model states.
I already saw solutions where parameters in specific model states were edited by referencing specific model state names or parameter names, but i need a "general" solution, which just works like "if the parameter with that name exists, i change the value". Also this is supposed to work in big assemblies, so I can't update the assembly after changing a model state parameter, as i also saw proposed somewhere.
Maybe someone has a simple solution so that my parameter-pushing works for all occurences again?
Thanks.
Public Class ChangeParameterOfSameName Public Sub Main() If ThisDoc.Document.DocumentType <> Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then MsgBox("The active document must be an assembly.") Return End If CopyUserParams() iLogicVb.UpdateWhenDone = True End Sub Private Sub CopyUserParams() Dim asmDoc As Inventor.AssemblyDocument = ThisDoc.Document For Each refDoc As Inventor.Document In asmDoc.AllReferencedDocuments If Not CheckPartValidity(refDoc) Then GoTo NextItem End If Dim refDocUserParams As UserParameters If refDoc.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then Dim assyDoc As AssemblyDocument = refDoc refDocUserParams = assyDoc.ComponentDefinition.Parameters.UserParameters Else If refDoc.DocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Then Dim partDoc As PartDocument = refDoc refDocUserParams = partDoc.ComponentDefinition.Parameters.UserParameters End If Dim index As Integer = 0 For Each asmUserParam As UserParameter In asmDoc.ComponentDefinition.Parameters.UserParameters Dim checkParam As UserParameter = Nothing Try checkParam = refDocUserParams.Item(asmUserParam.Name) 'checkParam.Expression = asmUserParam.Expression copies the expression, below copies the constant value, no formulas checkParam.Value = asmUserParam.Value index += 1 Catch ex As Exception checkParam = Nothing End Try Next If index > 0 Then Try If (refDoc.DocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Or refDoc.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject) Then refDoc.Rebuild End If Catch MessageBox.Show(refDoc.DisplayName + " konnte nicht aktualisiert werden") End Try index = 0 End If NextItem: Next End Sub Private Function CheckPartValidity(refDoc As Inventor.Document) As Boolean If Not (refDoc.DocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Or refDoc.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject) Then 'MsgBox("Part wrong doc type:" + refDoc.DisplayName ) Return False End If 'will also filter out docs with modelstates If Not refDoc.IsModifiable 'MsgBox("Part not modifiable:" + refDoc.ModelStateName ) Return False End If Return True End Function End Class
Solved! Go to Solution.
Hi,
Before model states were introduced i used the following iLogic to push the value from a user parameter in my current assembly to all occurrences where a user parameter with the same name existed. This still works fine, except for parts with model states, for which 1. .IsModifiable returns false and 2.even if i circumvent that it still does not update the parameter. I already make sure that the parts are set to "edit all model states" as the parameters i want to change are supposed to have the same value for all model states.
I already saw solutions where parameters in specific model states were edited by referencing specific model state names or parameter names, but i need a "general" solution, which just works like "if the parameter with that name exists, i change the value". Also this is supposed to work in big assemblies, so I can't update the assembly after changing a model state parameter, as i also saw proposed somewhere.
Maybe someone has a simple solution so that my parameter-pushing works for all occurences again?
Thanks.
Public Class ChangeParameterOfSameName Public Sub Main() If ThisDoc.Document.DocumentType <> Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then MsgBox("The active document must be an assembly.") Return End If CopyUserParams() iLogicVb.UpdateWhenDone = True End Sub Private Sub CopyUserParams() Dim asmDoc As Inventor.AssemblyDocument = ThisDoc.Document For Each refDoc As Inventor.Document In asmDoc.AllReferencedDocuments If Not CheckPartValidity(refDoc) Then GoTo NextItem End If Dim refDocUserParams As UserParameters If refDoc.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then Dim assyDoc As AssemblyDocument = refDoc refDocUserParams = assyDoc.ComponentDefinition.Parameters.UserParameters Else If refDoc.DocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Then Dim partDoc As PartDocument = refDoc refDocUserParams = partDoc.ComponentDefinition.Parameters.UserParameters End If Dim index As Integer = 0 For Each asmUserParam As UserParameter In asmDoc.ComponentDefinition.Parameters.UserParameters Dim checkParam As UserParameter = Nothing Try checkParam = refDocUserParams.Item(asmUserParam.Name) 'checkParam.Expression = asmUserParam.Expression copies the expression, below copies the constant value, no formulas checkParam.Value = asmUserParam.Value index += 1 Catch ex As Exception checkParam = Nothing End Try Next If index > 0 Then Try If (refDoc.DocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Or refDoc.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject) Then refDoc.Rebuild End If Catch MessageBox.Show(refDoc.DisplayName + " konnte nicht aktualisiert werden") End Try index = 0 End If NextItem: Next End Sub Private Function CheckPartValidity(refDoc As Inventor.Document) As Boolean If Not (refDoc.DocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Or refDoc.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject) Then 'MsgBox("Part wrong doc type:" + refDoc.DisplayName ) Return False End If 'will also filter out docs with modelstates If Not refDoc.IsModifiable 'MsgBox("Part not modifiable:" + refDoc.ModelStateName ) Return False End If Return True End Function End Class
Solved! Go to Solution.
Solved by WCrihfield. Go to Solution.
Hi @hoeckesfeld. This process has definitely gotten more complicated with the inclusion of ModelStates. When working a top down approach to editing either components or referenced documents within an assembly, one thing to keep in mind is that every component that represents a model which contains more than one ModelState will be seen as a 'member', rather than a 'factory'. Another thing to keep in mind is that when you have the situation where you may have multiple components in your assembly that reference the same model file on disk, but represent different ModelState versions of that model, you may be able to edit the first one you encounter, but the next one you encounter which references the same file, but maybe a different ModelState will need to be updated before you will be able to edit it, because the edit to the other version of the same file may still need to register (or something like that). This has something to do with the fact that you normally can not write to a ModelState member document, only the ModelState factory document. And the factory document is not necessarily the version representing the original ModelState, but simply the one that is being controlled by the file's active ModelState. One way to get around that problem is to edit the values of already existing parameter values through the ModelStateTable, because that table will include every ModelState (each row represents a different ModelState, similar to iPart/iAssembly factory table). But when doing so, you will want to get the reference to that ModelStateTable through the factory document version of the file, so that you will be allowed to make the edits.
Below are also a couple of utility methods you could try out:
Autodesk.iLogic.Runtime.ModelStateUtils.AssignFactoryParameter(oDoc, sMSName, sColumnName, sValue)
Autodesk.iLogic.Runtime.ModelStateUtils.AssignTableCell(oDoc, sMSName, sColumnName, sValue)
Wesley Crihfield
(Not an Autodesk Employee)
Hi @hoeckesfeld. This process has definitely gotten more complicated with the inclusion of ModelStates. When working a top down approach to editing either components or referenced documents within an assembly, one thing to keep in mind is that every component that represents a model which contains more than one ModelState will be seen as a 'member', rather than a 'factory'. Another thing to keep in mind is that when you have the situation where you may have multiple components in your assembly that reference the same model file on disk, but represent different ModelState versions of that model, you may be able to edit the first one you encounter, but the next one you encounter which references the same file, but maybe a different ModelState will need to be updated before you will be able to edit it, because the edit to the other version of the same file may still need to register (or something like that). This has something to do with the fact that you normally can not write to a ModelState member document, only the ModelState factory document. And the factory document is not necessarily the version representing the original ModelState, but simply the one that is being controlled by the file's active ModelState. One way to get around that problem is to edit the values of already existing parameter values through the ModelStateTable, because that table will include every ModelState (each row represents a different ModelState, similar to iPart/iAssembly factory table). But when doing so, you will want to get the reference to that ModelStateTable through the factory document version of the file, so that you will be allowed to make the edits.
Below are also a couple of utility methods you could try out:
Autodesk.iLogic.Runtime.ModelStateUtils.AssignFactoryParameter(oDoc, sMSName, sColumnName, sValue)
Autodesk.iLogic.Runtime.ModelStateUtils.AssignTableCell(oDoc, sMSName, sColumnName, sValue)
Wesley Crihfield
(Not an Autodesk Employee)
hi @WCrihfield ,
thanks for your answer.
how can I control whether I access the "ModelState factory document" instead of a "member document" in my assembly ? the information online and in the api reference is ... sparse. If you had a link to some more information on how the model states work "behind the scene" I'd appreciate that.
hi @WCrihfield ,
thanks for your answer.
how can I control whether I access the "ModelState factory document" instead of a "member document" in my assembly ? the information online and in the api reference is ... sparse. If you had a link to some more information on how the model states work "behind the scene" I'd appreciate that.
Hi @hoeckesfeld. There are several built-in resources that can help, but will likely involve a learning curve. Working with them manually, through the user interface (Link1, Link2), they seem just fine, but when working with them by code, that's when things get really...interesting. I have attached a couple of my own resources (PDF's), for reference. The first, simplest, and most obvious place to start, when working with iLogic rules, is the 'ThisDoc.FactoryDocument' reference, which will work good in parts & assemblies, but will return 'Nothing' if used in a drawing. Then there is the similar 'ThisDoc.ActiveModelState' reference, which allows you to either Get the name of the currently active ModelState, or Set which ModelState is active, by specifying its name. The main thing to remember is that you need to be working with the document that is being controlled by the file's active ModelState, because that will be the factory document. If the document you have a reference to is currently under the control of a ModelState that is not the active one, and you need to make edits to that specific version document, then you will need to activate the ModelState that is controlling that document, so that you can make edits to that ModelState/Document.
Wesley Crihfield
(Not an Autodesk Employee)
Hi @hoeckesfeld. There are several built-in resources that can help, but will likely involve a learning curve. Working with them manually, through the user interface (Link1, Link2), they seem just fine, but when working with them by code, that's when things get really...interesting. I have attached a couple of my own resources (PDF's), for reference. The first, simplest, and most obvious place to start, when working with iLogic rules, is the 'ThisDoc.FactoryDocument' reference, which will work good in parts & assemblies, but will return 'Nothing' if used in a drawing. Then there is the similar 'ThisDoc.ActiveModelState' reference, which allows you to either Get the name of the currently active ModelState, or Set which ModelState is active, by specifying its name. The main thing to remember is that you need to be working with the document that is being controlled by the file's active ModelState, because that will be the factory document. If the document you have a reference to is currently under the control of a ModelState that is not the active one, and you need to make edits to that specific version document, then you will need to activate the ModelState that is controlling that document, so that you can make edits to that ModelState/Document.
Wesley Crihfield
(Not an Autodesk Employee)
Thanks man, way more than I expected, I can work from that. For now, as I needed to get on with a solution for "production", as a quick and dirty fix I derived the parameters from a normal "parameterhelper" part in my modelstate parts and also placed that "parameterhelper" in my master assembly. Now the parameterhelper part gets updated as usual and the modelstate parts correctly derive the new values 😄 ...
Thanks man, way more than I expected, I can work from that. For now, as I needed to get on with a solution for "production", as a quick and dirty fix I derived the parameters from a normal "parameterhelper" part in my modelstate parts and also placed that "parameterhelper" in my master assembly. Now the parameterhelper part gets updated as usual and the modelstate parts correctly derive the new values 😄 ...
Can't find what you're looking for? Ask the community or share your knowledge.