Using iLogic to Change the Model State of Native Part Component Occurrence in an Assembly

justinS3RHN
Participant
Participant

Using iLogic to Change the Model State of Native Part Component Occurrence in an Assembly

justinS3RHN
Participant
Participant

Hello. There is likely a very simple solution for this but I'm really struggling with getting this working properly for our department. 


I want to modify the native model state of a part component occurrence in an assembly, but what's happening is it appears that it's only changing the part model state within the context of the parent assembly that it's in. When I open the part on its own, the model state is still set on [Primary] and it wasn't updated properly. 

 

I'm essentially doing this:

 

Dim oAsmCompDef As AssemblyComponentDefinition
    'Getting access to the parent assembly
    oAsmCompDef = ThisApplication.ActiveDocument.ComponentDefinition

Dim oOccurrence As ComponentOccurrence
    'Don't worry about oPath or oMatrix... Those are set more complexly but will access a part that was created from a template and added to the assembly. I can access this correctly without issue.
    oOccurrence = oAsmCompDef.Occurrences.Add(oPath, oMatrix)
    oOccurrence.ActiveModelState = modelStateStringName

RuleParametersOutput()
InventorVb.DocumentUpdate()

 

I've tried figuring out how to access the NativeObject of the component occurrence so that it sets the model state of the part itself and not just within the context of the parent assembly, but I don't think I was doing it correctly.
Within iLogic, do I need to actually open the part up on its own to change the model state and then close it?

 

Thanks for your help!

0 Likes
Reply
Accepted solutions (1)
410 Views
8 Replies
Replies (8)

WCrihfield
Mentor
Mentor

Hi @justinS3RHN.  There are at least 2 ways to get to the actual Document object that the assembly component is referencing, so that you can make changes at that level.  Both start from the ComponentOccurrence object.  One path would be to use its Definition property to get the ComponentDefinition of the part, which will actually be the more specific Type (PartComponentDefinition) if it was a part.

 

The other path would be to use the ComponentOccurrence.ReferencedDocumentDescriptor property, which returns a DocumentDescriptor, then use its DocumentDescriptor.ReferencedDocument property to get to the Document object.  Then get its ComponentDefinition as a PartComponentDefinition.

 

After either of those steps, you have a PartComponentDefinition, which has the ModelStates property, which is a collection of all its ModelStates.  Then you can get the one you want, and activate it ModelState.Activate.  However, if you want to see the change in your main assembly, you will likely still have to set the assembly component to that ModelState also, as you have already done.  It is like a representation of the part.

 

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes

justinS3RHN
Participant
Participant

Hi @WCrihfield, thank you for providing that thorough explanation; It makes sense.
I'm going to lay out my code below according to what you're describing (although it's not liking it and I'm getting errors... Seemingly because I'm not accessing the properties in the right way but maybe you can point out where it's wrong).

 

Dim oAsmCompDef As AssemblyComponentDefinition
    oAsmCompDef = ThisApplication.ActiveDocument.ComponentDefinition
Dim oOccurrence As ComponentOccurrence
    oOccurrence = oAsmCompDef.Occurrences.Add(oPath, oMatrix)

'This is for the first part of your provided direction. This should end up as type PartComponentDefinition.
Dim channelPartCompDef As ComponentDefinition
    channelPartCompDef = oOccurrence.Definition

'This is for the second part of your direction and should set the model state in the part itself.
Dim mS As ModelState = channelPartCompDef.ModelStates(modelStateStringName)
    mS.Activate		

'As before, this also sets the model state of the part within the context of the assembly it's in.					
oOccurrence.ActiveModelState = modelStateStringName

RuleParametersOutput()
InventorVb.DocumentUpdate()

 

With the above code, there's an unspecified error at Ln12: mS.Activate 
The model state exists, but I don't think I'm accessing it correctly. 

0 Likes

Curtis_Waguespack
Consultant
Consultant

@justinS3RHN , see the examples at this link, they might (or might not) shed some light on your errors.

 

Hope this helps,

Curtis

 

https://forums.autodesk.com/t5/inventor-programming-ilogic/changing-model-states-of-parts-in-an-asse...

EESignature

0 Likes

justinS3RHN
Participant
Participant

@Curtis_Waguespack Thank you for providing some more examples to study. Unfortunately I wasn't able to implement what was being used in the link, although I was able to follow what was going on for the most part. 

 

It seems my PartComponentDefinition isn't allowing me to access the ModelStates property... Meaning, the properties that I should be able to access aren't coming up when trying to access the properties of my PartComponentDefinition even though I clearly define it As such... Almost like there's a type error, but there shouldn't be.

 

In the description provided my @WCrihfield above, it looks straightforward but I can't access things that I should be able to access according to that workflow.

0 Likes

WCrihfield
Mentor
Mentor

Hi @justinS3RHN.  Can you please explain why you need to activate a specific ModelState within the PartDocument that the assembly component is referencing?  Knowing this might help us understand how to help you achieve your overall goals better.

 

When you have assemblies, with all their components and referenced documents, then you add multiple ModelStates into the mix, whether it be the main assembly itself that has them, or some of the referenced documents that have them, or both, then there is going to be a lot of complexity involved in attempting to make changes to some of those referenced documents.  Normally, there is only one Document defined within each Inventor File, but when a model File has multiple ModelStates defined within it, that can mean that File also has multiple Documents defined within it.  And when that is the case, we are only allowed to make changes to one of those Documents (the 'factory' version), while the other Documents ('members') within it will act like they are ReadOnly.  And when we try to make changes to a ModelState 'member' Document directly, it will throw errors.

 

When we open drawings or assemblies, which are referencing other Inventor files, those other files that they reference also get partially loaded into Inventor's session memory, invisibly (no document tabs shown for them, but the numbers will increase at right end of Inventor's status bar).  With this in mind, if your assembly has components in it that reference files that have multiple ModelStates in them, then those referenced documents, which are already partially loaded in Inventor, will be understood as ModelState 'member' Documents, which makes it complicated to make changes to them directly, while that assembly remains open.  Not necessarily impossible, but complicated.  In order to make any changes to a ModelState member Document, we must first get access to the ModelState factory Document version of that file, because it will have the required control to access the other ModelStates & their member Documents in that file, and can be used to initiate changes to them.  The ModelState factory document only exists when there are 2 or more ModelStates in a file, and is the document associated with the file's active ModelState at that moment, so it can change when different ModelStates are activated.

 

So, simply activating a ModelState in an assemblies referenced document is not really going to accomplish anything on its own, and may not even be possible of the referenced Document we are working with is a 'member' instead of the 'factory'.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes

justinS3RHN
Participant
Participant

@WCrihfield Thanks for the information. I'll explain what we're doing for clarity:


When we draw LED lighting into our models it can often get quite messy with part numbers and such (for our supplier) and our hardware lists are prone to having lighting errors. We wanted to streamline the process of incorporating channel lighting into our models so that there are less errors and it's more tightly managed, so I developed a form that our engineers fill out with what they want and then iLogic handles building the lighting aluminum channel, adding any lighting components from our library and filling out the iProperties accurately (part number, description, etc).

 

Depending on the selected option in the second field (channel type), iLogic will grab the appropriate template .ipt for either a recessed, angled or surface mount channel. Each of those channel .ipt models have several built-in model states. The correct model state is activated when the new led channel is generated in order to properly show the other selections that the user had made (end cap types, lead type... male or female, etc). 

 

justinS3RHN_0-1726582418544.png

 

When the user hits the build button, it generates the new aluminum channel .ipt from the correct template file and sets the right model state of it and adds that .ipt, along with any other components chosen in the form, to a new lighting bundle assembly (the .iam that manages the form itself). 

 

The channel .ipt updates perfectly when it's generated and everything looks good within the lighting bundle .iam itself, however if we then open that .ipt up on it's own (or place it separately into another assembly... the assembly which is the actual model we're drawing like a cabinet for example), then it will often revert to the primary model state and won't appear right. We want the correct model state that was set to actual hold within the channel .ipt itself, as it won't ever change after the first time it's generated.

 

I believe when I am setting the model state originally in iLogic, I'm probably doing it incorrectly within the lighting bundle .iam context and so the .ipt itself is actually still on [primary] as far as it knows, so any visual things like end caps, lead types and even channel length are all wrong when it's on [primary].

 

Let me know if any further clarification is needed. Thank you for taking the time 🙂 

 

0 Likes

WCrihfield
Mentor
Mentor
Accepted solution

Hi @justinS3RHN.  Thank you for the additional information.  That helps a lot.  There is a special step that you can take that may help in this situation.  I will try to explain this as best as I can, because there is some other stuff you should understand, in order to make it work good for you in the future.

 

  • Understanding the difference between FullFileName and FullDocumentName
    • The FullFileName is the full path of the file, and the name of the file, and the file's extension, as one String type value.
    • The FullDocumentName will 'start with' the FullFileName, but 'may' also include extra information after that.
      • The extra information after that will usually be between"<" and ">" brackets, immediately after the file extension.
      • It may be the name of an iPart member, iAssembly member, or ModelState member (there may be other possibilities also).
      • This additional information is used by Inventor, to specify which 'member' variation should be used, when the model file has 'members'.  It is not used by the file system on our computer's operating system.

When you use the ComponentOccurrences.Add method, it says that it want us to specify the 'FullDocumentName', not just the 'FullFileName'.  And it also tells us that if we only specify FullFileName, then the 'master' (or primary) Document within that file will be used.  So, if you want to directly insert an assembly component occurrence into your assembly that references a specific ModelState version of a model File that has multiple ModelStates defined within it, you must specify the FullDocumentName of that variation to that method.

 

To help with this process, we have some Inventor API tools.  One of which is the FileManager object.  This can be obtained directly from the Inventor.Application object ('ThisApplication' within the code).  It has methods for extracting these two different parts of a FullDocumentName to individual String values, and methods for putting those two different String values together into one resulting that can be used as FullDocumentName.

FileManager.GetFullDocumentName( FullFileName As String, [ModelStateName] As String ) As String 

FileManager.GetFullFileName( FullDocumentName As String ) As String 

FileManager.GetModelStateName( FullDocumentName As String ) As String 

It also has other methods related to ModelStates that you might find useful.

FileManager.GetLastActiveModelState( FullFileName As String ) As String 

FileManager.GetModelStates( FullFileName As String ) As String() 

Anyways, if you have the FullFileName, but do not have the FullDocumentName that you want to specify, then you can use the 'GetFullDocumentName' method referenced above, put the FullFileName, and ModelState name into it, and get the FullDocumentName as a result.  Then you can specify that within your Occurrences.Add method.  Then, you will not need to 'set' that component to a different ModelState afterwards.  And another benefit that you may not even think about is...it will not be opening two different versions of that 'File' into Inventor's session memory, because only the one version has been referenced so far.  Unless of course you add other components into the assembly that reference other ModelState variations of that same File later.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes

justinS3RHN
Participant
Participant

@WCrihfield What an insightful response, thank you so much.

 

I was able to bring the channel part into the lighting bundle assembly directly with it already in the correct model state (without having to change it after the fact as you suggested).
That was a great solution, I used FullDocumentName to bring in the ipt with the desired ModelState string specified after the filename extension by adding: & "<" & "modelstatestringhere" & ">".

 

Thanks for taking the time to help me out!

0 Likes