Detect user selected model state ( Open > Options button)

Detect user selected model state ( Open > Options button)

Curtis_Waguespack
Consultant Consultant
786 Views
7 Replies
Message 1 of 8

Detect user selected model state ( Open > Options button)

Curtis_Waguespack
Consultant
Consultant

When a user opens a file, I want to programmatically set the active model state to a named model state ( let's call it "My Standard Model State") 

 

But if the user uses the options button in the Open dialog, and chooses a different Model State ( such as "All Suppressed") then I want to honor their selection, and not set the active model state.

 

I had a quick look about the API, but didn't see a way to detect if the user has selected a different model state than the one that the file was last saved in... but maybe I overlooked something.

 

Anyone have any ideas? 

 

Curtis_Waguespack_0-1683229410126.png

 

EESignature

0 Likes
Accepted solutions (2)
787 Views
7 Replies
Replies (7)
Message 2 of 8

Curtis_Waguespack
Consultant
Consultant

I thought for a second I could use GetLastActiveModelState, but that seems to get updated using the Options, so that doesn't seems to work.


    Dim strFullFileName As String
    strFullFileName = ThisApplication.ActiveDocument.FullFileName
    
    ' Set a reference to the FileManager object.
    Dim oFileManager As FileManager
    oFileManager = ThisApplication.FileManager
    
    ' Get the name of the last active model state.
    Dim strLastActiveMS As String
    strLastActiveMS = oFileManager.GetLastActiveModelState(strFullFileName)
	
	MsgBox(strLastActiveMS)

 

EESignature

0 Likes
Message 3 of 8

WCrihfield
Mentor
Mentor

It would be nice if Autodesk finally got around to further developing the FileDialogEvents.OnOptions Event handler method, so that the 'Context' (NameValueMap) would be filled in with the options that were chosen within.  That event has been available since 2008, and it still says "This argument is currently empty."  If they had that updated, you could have used that to determine the situation.  There are a few other nice Classes under Autodesk.iLogic.Runtime for ModelStates, but I don't see anything particularly useful for this situation right now, at lest on my 2022.4.1 installation.  If you have a newer version, you could check to see if more have been added, because I don't think there is any official documentation in the online help for any of them.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 4 of 8

richterBKSAC
Advocate
Advocate

Hi @Curtis_Waguespack ,

 

you could make your "My Standard Model State" a preset via Application Options - File tab - File Open Options.

The downside would be that it affects all files. I assume that's probably not what you intend to do.

The preset files are stored at C:\Users\username\AppData\Roaming\Autodesk\Inventor version\Presets

 

 

 

 

 

Message 5 of 8

Michael.Navara
Advisor
Advisor
Accepted solution

It is not exactly what do you ask, but you can switch ModelState during open process. You need to use the opening sequence to determine which ModelState is requested by user.

Side effect is you are not able to directly open [Primary] model state

It is little bit more code, but I hope you will understand it 

 

Sub Main()
    Dim applicationEventsWrapperSharedVariable = "ApplicationEventsWrapper"

    If SharedVariable.Exists(applicationEventsWrapperSharedVariable) Then
        Dim existingApplicationEventsWrapper = SharedVariable(applicationEventsWrapperSharedVariable)
        existingApplicationEventsWrapper.Dispose()
    End If


    Dim applicationEventsWrapper = New ApplicationEventsWrapper(ThisApplication)
    SharedVariable.Value(applicationEventsWrapperSharedVariable) = applicationEventsWrapper

End Sub

Class ApplicationEventsWrapper
    Implements IDisposable

    Private ReadOnly requestedModelState As String = "My Standard Model State"
    Private ReadOnly inventor As Inventor.Application
    Private ReadOnly applicationEvents As ApplicationEvents

    Private openedDocuments As New List(Of String)

    Public Sub New(inventor As Inventor.Application)
        Me.inventor = inventor
        applicationEvents = Me.inventor.ApplicationEvents
        AddHandler applicationEvents.OnOpenDocument, AddressOf ApplicationEvents_OnOpenDocument
    End Sub

    Public Sub Dispose() Implements IDisposable.Dispose
        RemoveHandler applicationEvents.OnOpenDocument, AddressOf ApplicationEvents_OnOpenDocument
        openedDocuments.Clear()
    End Sub

    Private Sub ApplicationEvents_OnOpenDocument(documentObject As _Document,
                                                 fullDocumentName As String,
                                                 beforeOrAfter As EventTimingEnum,
                                                 context As NameValueMap,
                                                 ByRef handlingCode As HandlingCodeEnum)

        handlingCode = HandlingCodeEnum.kEventNotHandled

        Select Case beforeOrAfter
            Case EventTimingEnum.kBefore
                If NotSpecifiedModelState(fullDocumentName) Then
                    openedDocuments.Add(fullDocumentName)
                End If
            Case EventTimingEnum.kAfter
                If openedDocuments.Contains(fullDocumentName) Then
                    TrySwitchModelState(documentObject)
                    openedDocuments.Remove(fullDocumentName)
                End If
            Case EventTimingEnum.kAbort
                If openedDocuments.Contains(fullDocumentName) Then
                    openedDocuments.Remove(fullDocumentName)
                End If

        End Select

    End Sub

    Private Function NotSpecifiedModelState(fullDocumentName As String) As Boolean
        Dim fullFileName As String = inventor.FileManager.GetFullFileName(fullDocumentName)
        Return fullFileName = fullDocumentName
    End Function

    Private Sub TrySwitchModelState(documentObject As _Document)

        Dim modelState As ModelState = GetRequestedModelState(documentObject)
        If modelState Is Nothing Then Return
        modelState.Activate()
    End Sub

    Private Function GetRequestedModelState(documentObject As _Document) As ModelState

        Dim modelStates As ModelStates
        Select Case documentObject.DocumentType
            Case DocumentTypeEnum.kAssemblyDocumentObject
                Dim asm As AssemblyDocument = documentObject
                modelStates = asm.ComponentDefinition.ModelStates
            Case DocumentTypeEnum.kPartDocumentObject
                Dim prt As PartDocument = documentObject
                modelStates = prt.ComponentDefinition.ModelStates
            Case Else
                Return Nothing
        End Select

        Try
            Dim modelState As ModelState = modelStates(requestedModelState)
            Return modelState
        Catch ex As Exception
            Return Nothing
        End Try
    End Function
End Class

 

Message 6 of 8

Curtis_Waguespack
Consultant
Consultant

Hi @richterBKSAC 

 

This seemed like it would be a helpful thing to have in place, but I'm not seeing a way to add presets to the Open Options. 


Am I overlooking something?

 

Thank you,
Curtis

EESignature

0 Likes
Message 7 of 8

Curtis_Waguespack
Consultant
Consultant
Accepted solution

@WCrihfield and @Michael.Navara 

 

Thanks for both of your replies!

 

These both helped me arrive at a solution for this.

 

Here's what I did, in case it helps someone else in the future:

 

  • I used the Event Watcher to watch the OnOpenDocument event
    • ( c:\users\public\documents\autodesk\inventor 2023\sdk\developertools\tools\)
  • I saved my assembly with the active model states called "NO HARDWARE"
  • Then I opened it with Open Options and selected a different model state called "ALL SUPPRESSED"

 

Curtis_Waguespack_0-1683307891266.png

 

  • The event watcher provided the following:

 

Curtis_Waguespack_1-1683308090146.png

 

  • Then I used the context.name and context.value to get the name of the TopLevelFileName before opening and after opening.

Curtis_Waguespack_2-1683308446771.png

 

  • Once I had the names I just compared them, and if the before name is the same as the after name, I set the Model State to the standard Model State. 

 

Sub from add-in

Private Sub m_Events_OnOpenDocument(DocumentObject As _Document,
	FullDocumentName As String,
	BeforeOrAfter As EventTimingEnum,
	Context As NameValueMap,
	ByRef HandlingCode As HandlingCodeEnum)


	If BeforeOrAfter = EventTimingEnum.kBefore Then
		' where oTopLevelNameBefore is global variable
		oTopLevelNameBefore = Context.Value(Context.Name(1))
	End If


	If DocumentObject Is Nothing Then Exit Sub
	If Not DocumentObject Is _invApp.ActiveDocument Then Exit Sub
	If Not DocumentObject.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then Exit Sub

	If BeforeOrAfter = EventTimingEnum.kAfter Then

		Dim oTopLevelNameAfter As String
		oTopLevelNameAfter = Context.Value(Context.Name(1))

		If oTopLevelNameBefore = oTopLevelNameAfter Then
			Try
				DocumentObject.ComponentDefinition.ModelStates.item("My Standard Model State").Activate
			Catch
			End Try
		End If
	End If
End Sub

 

EESignature

0 Likes
Message 8 of 8

richterBKSAC
Advocate
Advocate

Hi Curtis,

 

to be honest I haven't looked into creating such preset file and I don't even know if it is possible, I just found this option.

But couldn't you make use of it anyway? I have two possible options there "primary" and "last active". If you set it to "primary" your ilogic could tell if the user selected something else than "primary".

 

best regards

Matthias

0 Likes