Using FactoryDocument of ActivatedObject throws an error

Using FactoryDocument of ActivatedObject throws an error

ziconin
Observer Observer
227 Views
1 Reply
Message 1 of 2

Using FactoryDocument of ActivatedObject throws an error

ziconin
Observer
Observer

Hi,

 

I am managing an external tool for Inventor 2022/2023 and we've had issues with the introduction of model states. The case we are trying to give support to is as follows:

  1. User activates a component (right click -> edit)
  2. User opens our external UI in order to set iProperties
  3. User can select if they want the iProperties to be set on all model states or only for the active state
  4. Based on the user's selection, we take the activated object -> get its FactoryDocument -> get FactoryDocuments model states-object -> set EditScope to kEditActiveMember or kEditAllMembers
  5. Set iProperties
  6. Set the previous EditScope back to what it was when process started

Here's a small example of the how we are currently going about with this up to point 4.: 

Private Sub DemoEffect(sOption As String)
    Dim oDoc As Document = API_App.ActiveDocument.ActivatedObject
    Dim factoryDoc As Document = Doc_Get_FactoryDocument(oDoc)
    Dim modelStates As ModelStates = Doc_Get_ModelState(factoryDoc)

    If (sOption.Equals("ALL", StringComparison.InvariantCultureIgnoreCase)) Then
        modelStates.MemberEditScope = MemberEditScopeEnum.kEditAllMembers
    ElseIf (sOption.Equals("ACTIVE", StringComparison.InvariantCultureIgnoreCase)) Then
        modelStates.MemberEditScope = MemberEditScopeEnum.kEditActiveMember
    End If
End Sub

Public Function Doc_Get_FactoryDocument(doc As Document) As Document
    If (doc Is Nothing) Then Return Nothing
    Dim documentType As DocumentTypeEnum = doc.DocumentType
    If (Not (documentType = DocumentTypeEnum.kPartDocumentObject Or
        documentType = DocumentTypeEnum.kAssemblyDocumentObject)) Then
        Return doc
    End If

    If (documentType = DocumentTypeEnum.kPartDocumentObject) Then
        Dim def As PartComponentDefinition = doc.ComponentDefinition
        If (def.IsModelStateMember) Then
            Return def.FactoryDocument
        End If
    End If

    If (documentType = DocumentTypeEnum.kAssemblyDocumentObject) Then
        Dim def As AssemblyComponentDefinition = doc.ComponentDefinition
        If (def.IsModelStateMember) Then
            Return def.FactoryDocument
        End If
    End If

    Return doc
End Function

Public Function Doc_Get_ModelState(oDoc As Document) As ModelStates
    If mdocCompOcc IsNot Nothing Then
        Dim oDocum As Document = Doc_Get_FactoryDocument(mdocCompOcc.Definition.Document)
        Return oDocum.ComponentDefinition.ModelStates
    ElseIf Doc_Is_Assembly(oDoc) Then
        Dim oAsmDoc As AssemblyDocument = oDoc
        Dim oAsmCompDef As AssemblyComponentDefinition = oDoc.ComponentDefinition
        Return oAsmCompDef.ModelStates
    ElseIf Doc_Is_Part(oDoc) Then
        Dim oPrtDoc As PartDocument = oDoc
        Dim oPrtCompDef As PartComponentDefinition = oDoc.ComponentDefinition
        Return oPrtCompDef.ModelStates
    Else
        Return Nothing
    End If

    Return Nothing
End Function

 

This process works perfectly for models, that have been opened to a window and for components, that are selected from model tree. However, the case where user activates the component, requesting the FactoryDocument throws an error "Unspecified error (Exception from HRESULT: 0x80004005 (E_FAIL))" , which means we can't change the EditScope (it can't be changed from ModelStateMember).

 

Is Inventor supposed to support this use case? And is there a way around this issue? 

 

 

0 Likes
228 Views
1 Reply
Reply (1)
Message 2 of 2

WCrihfield
Mentor
Mentor

Hi @ziconin.  Right at the start of your first block of code, assuming your 'API_App' variable represents the Inventor.Application object, I believe you need to change this line of code:

Dim oDoc As Document = API_App.ActiveDocument.ActivatedObject

...to this line of code:

Dim oDoc As Document = API_App.ActiveEditDocument

This is meant for that exact scenario where you are within an assembly (the 'active' document), and are currently in Edit mode of a component (the 'ActiveEditDocument').

 

Also, within your 'Doc_Get_ModelState' function, do not try to get the 'factory' document first, then get the ModelStates object from that.  Just get the ModelStates object from the input document.  The 'factory' document is often miss-understood as representing the 'main' model document, which is not under the influence of any custom model states, but that is not how Autodesk sees it.  The factory document is actually the version of the model document that is under the influence of the documents 'active' ModelState.  That is the only version of the model that you can make edits too, as you would any other model document.  Then to make changes to any other ModelStates of the model, you have to have the model visibly open before you can change its MemberEditScope, and it must be visibly open before you 'Activate' any specific ModelState you want to make changes to (if not all).  You can not just make changes to a ModelState member document, that does not match the model's 'active' ModelState, but you can sometimes read data from one.  Where you sometimes run into an odd situation is when working with an assembly component, and that component is currently set to a ModelState that is a different ModelState from the one that is currently 'active' in the model document in the file.  At any rate, if you want to make edits to a single ModelState, you must visibly open that model document, then make sure its MemberEditScope is set to 'kEditActiveMember', then make sure that specific ModelState is active, or use its Activate method, then make your needed edits.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes