Export Specific Model State To .step & .dxf File

Export Specific Model State To .step & .dxf File

matthew.johnson200
Enthusiast Enthusiast
2,269 Views
7 Replies
Message 1 of 8

Export Specific Model State To .step & .dxf File

matthew.johnson200
Enthusiast
Enthusiast

We currently have a rule which goes through the parts in an assembly and exports .step & .dxf files for any parts that need to be sent to a supplier for manufacture. The code we have works great for what we need it to do.

 

We have recently installed Inventor 2022.1 and we are starting to use models states to show pre-production parts as well as the final part e.g. a hollow section that we buy in blank but then drill holes out in the workshop. What I would like is for the rule to be tweaked so that before exporting each part, it will check if it has a model state named 'Pre-Production'. If it does then it should export the .step & .dxf file using that model state. If its not there, then just export using the master model state (as not all parts require a pre-production model state). 

 

I have attached our current code.

 

Thanks in advance.

 

Sub Main()
	
	Dim ans As String
	ans = MessageBox.Show("Before running this rule, please check the following:" + vbCrLf + "" + vbCrLf + "For parts where the face side is critical e.g. polished stainless steel, please make sure to create a flat pattern manually or define an A-Side" + vbCrLf + "" + vbCrLf + "Inventor will ask you to check out any files that are not checked out that need to be flat patterned.", "Caution", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1)
	If ans = vbCancel Then
		Exit Sub
	End If

	'CREATE FOLDER / CHECK IF EXISTS
    Dim fdObj As Object
    fdObj = CreateObject("Scripting.FileSystemObject")
    If fdObj.FolderExists("C:\KIT OF PARTS") Then
        'DO NOTHING
    Else
    	fdObj.CreateFolder("C:\KIT OF PARTS") 
	End If
  
    Dim oAsmDoc As AssemblyDocument 
	oAsmDoc = ThisApplication.ActiveDocument 
	
    TraverseAssembly(oAsmDoc.ComponentDefinition.Occurrences, 1)
	
	MessageBox.Show("KIT OF PARTS SAVED IN C:\KIT OF PARTS", "Title")

	fOPath = "C:\KIT OF PARTS\"

	Call Shell("explorer.exe " & fOPath, vbNormalFocus)
	
End Sub 


Sub TraverseAssembly(Occurrences As ComponentOccurrences, Level As Integer) 
    
    Dim oOcc As ComponentOccurrence 
	
	'STEP CREATOR
    Dim oContext As TranslationContext
    oContext = ThisApplication.TransientObjects.CreateTranslationContext
    Dim oOptions As NameValueMap
    oOptions = ThisApplication.TransientObjects.CreateNameValueMap
	Dim oSTEPTranslator As TranslatorAddIn
	oSTEPTranslator = ThisApplication.ApplicationAddIns.ItemById("{90AF7F40-0C01-11D5-8E83-0010B541CD80}")

	If oSTEPTranslator Is Nothing Then
		
		MessageBox.Show("Could not access STEP translator.", "ERROR")
	    Exit Sub
		
	End If
	
    For Each oOcc In Occurrences

	    If oOcc.Suppressed Then
        
			'DONT CREATE STEP FILE FOR SUPPRESSED FILES
            
        Else 'not suppressed
		   
		        If oOcc.DefinitionDocumentType = kAssemblyDocumentObject Then
            
	                'DONT CREATE STEP FILE FOR ASSEMBLY FILES

                	Call TraverseAssembly(oOcc.SubOccurrences, Level + 1)
                
            	Else 'NOT ASSY
            
	                If oOcc.BOMStructure = 51972 Or oOcc.BOMStructure = 51971 Then 
	                                    
	                    'PART SET TO REF.OR PHANTOM DO NOT CREATE STEP
						
	                Else
	                
	                    'CHECK IF PARAMETER EXISTS

						Try
                    
		                    If oOcc.Definition.Document.PropertySets.Item("Inventor User Defined Properties").Item("Purchased").Value = "-" And _
							   oOcc.Definition.Document.PropertySets.Item("Inventor User Defined Properties").Item("Stores").Value = "-" And _	
							   oOcc.Definition.Document.PropertySets.Item("Inventor User Defined Properties").Item("Laser Stock").Value = "-" Then
				
								'CHECK IF ALREADY EXIST
								DPS = ThisDoc.Document.PropertySets.Item("Design Tracking Properties")
								ISI = ThisDoc.Document.PropertySets.Item("Inventor Summary Information")
								
								Dim PN As String
								Dim REVI As String
								PN = oOcc.Definition.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value 
								REVI = oOcc.Definition.Document.PropertySets.Item("Inventor Summary Information").Item("Revision Number").Value 
								'CHECK IF STEP ALREADY EXISTS
								If Not Dir("C:\KIT OF PARTS\" & PN & " - " & REVI & ".stp", vbDirectory) = vbNullString Then
								
								    'FILE ALREADY EXISTS - SKIP

								Else

									'OPEN FILE
			                    	oNewDoc = ThisApplication.Documents.Open(oOcc.Definition.Document.FullFileName, True)
										
										If TypeOf ThisApplication.ActiveDocument.ComponentDefinition Is SheetMetalComponentDefinition Then
											'FLAT PATTERN FUNCTIONS
											
											Dim oDoc As PartDocument
											oDoc = ThisApplication.ActiveDocument
											Dim oCompDef As SheetMetalComponentDefinition
											oCompDef = oDoc.ComponentDefinition
											If oCompDef.HasFlatPattern = False Then
												oCompDef.Unfold									
											Else
												oCompDef.FlatPattern.Edit
											End If

											'FLAT PATTERN DXF Settings
											Dim sOut As String
											Dim sPATH As String
											sOut = "FLAT PATTERN DXF?AcadVersion=2004&RebaseGeometry=True&OuterProfileLayer=0&OuterProfileLayerColor=0;0;0&InteriorProfilesLayer=0&InteriorProfilesLayerColor=0;0;0;IV_OUTER_PROFILE;IV_INTERIOR_PROFILES;IV_FEATURE_PROFILES;IV_FEATURE_PROFILES_DOWN;IV_ALTREP_FRONT;IV_ALTREP_BACK;IV_ROLL_TANGENT;IV_ROLL&InvisibleLayers=IV_BEND;IV_BEND_DOWN;IV_TANGENT;IV_TOOL_CENTER;IV_TOOL_CENTER_DOWN;IV_ARC_CENTERS;IV_UNCONSUMED_SKETCHES"
											Dim sFname As String
											sFname = "C:\KIT OF PARTS\" & PN & " - " & REVI & ".DXF"

											'Export the DXF and fold the model back up
											oCompDef.DataIO.WriteDataToFile( sOut, sFname)
											Dim oSMDef As SheetMetalComponentDefinition
											oSMDef = oDoc.ComponentDefinition
											oSMDef.FlatPattern.ExitEdit
											
											'END OF FLAT PATTERN FUNCTIONS
										
										End If
									
								    If oSTEPTranslator.HasSaveCopyAsOptions(ThisApplication.ActiveDocument, oContext, oOptions) Then

								        oOptions.Value("ApplicationProtocolType") = 3
								        oContext.Type = kFileBrowseIOMechanism
								        Dim oData As DataMedium
								        oData = ThisApplication.TransientObjects.CreateDataMedium
								        oData.FileName = "C:\KIT OF PARTS\" & PN & " - " & REVI & ".stp"
								         
								        'Publish document.
								        Call oSTEPTranslator.SaveCopyAs(oNewDoc, oContext, oOptions, oData)
																		    
								    End If
									
									'Check for flat pattern >> create one if needed


			                    	oNewDoc.Close

								End If
														
	                    	End If
						
						Catch
								
							'MessageBox.Show("PARAMETER MISSING", oOcc.Definition.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value)

						End Try
	                    
	                End If
                        
            End If
                    
      	End If	
		
    Next
	
End Sub

 

0 Likes
Accepted solutions (1)
2,270 Views
7 Replies
Replies (7)
Message 2 of 8

WCrihfield
Mentor
Mentor

Hi @matthew.johnson200.  The new ModelStates in Inventor 2022 are still fairly new to most of us, so we're still exploring the possibilities and limits of what we are capable or not capable of doing with them, both manually, and especially by code.  The ModelState object has a couple of Properties that represent Document object.  One is called just called "Document" (ModelState.Document), and the other is called "FactoryDocument" (ModelState.FactoryDocument).  The one just called Document is supposed to return the "model state member Document that associates with this model state", while the one called FactoryDocument is supposed to return the "model state factory Document", and also notes "If the model state factory document is not open, query this property will cause it open."  The term 'member' coincides with the terminology used with iParts, iAssemblies, & iFeatures, which would represent a simple 'slave' type resulting document with a single set of specifications, while the term 'factory' would represent the one main document which contains all specifications for all variations of the parts, assemblies, or features, and is used to generate the 'member' documents.  Knowing this, I would assume you could get the ModelState.Document (again, a Document object) from the ModelState (if one other than "Master" is found) and use that as the input to your Export process.  I believe that would ensure the model would be set-up according to the settings in that specific model state.

 

PS.  If using the ModelState.Document doesn't work in your tests, try using the Document returned from the ModelState.FactoryDocument, just to be thorough.  If your testing succeeds with one, but not the other, be sure and let us know which one is working for you, and/or which one fails.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 8

JelteDeJong
Mentor
Mentor
Accepted solution

I did have a look at your code and changed it so I could understand better how it works. Here is it all but for your question in the opening post you only need the function: "GetModelStateDocument()"

In that function, the correct model state is activated end returns the correct document.

 

Public Class ThisRule

    Private _STEPTranslator As TranslatorAddIn
    Private Const _sheetMetalPartGUID = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}"
    Private Const _mainExportFolder = "C:\KIT OF PARTS"

    Sub Main()

        Dim ans As String = MessageBox.Show("Before running this rule, please check the following:" +
                vbCrLf + "" + vbCrLf +
                "For parts where the face side is critical e.g. polished stainless steel, " + 
				"please make sure to create a flat pattern manually or define an A-Side" +
                vbCrLf + "" + vbCrLf +
                "Inventor will ask you to check out any files that are not checked out that need to be flat patterned.",
                "Caution", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1)
        If ans = vbCancel Then
            Exit Sub
        End If

        If (IO.Directory.Exists(_mainExportFolder) = False) Then
            IO.Directory.CreateDirectory(_mainExportFolder)
        End If

        SetSTEPTranslator()

        Dim doc As AssemblyDocument = ThisDoc.Document

        Dim refDocs = doc.AllReferencedDocuments.Cast(Of Document).Where(AddressOf NeedExport)
        For Each refDoc As Document In refDocs
            refDoc = ThisApplication.Documents.Open(refDoc.FullFileName, True)
            refDoc = GetModelStateDocument(refDoc)

            ExportDxf(refDoc)
            ExportStep(refDoc)
            ' refDoc.Close()
        Next


         MessageBox.Show("KIT OF PARTS SAVED IN: " & _mainExportFolder, "Title")
         Call Shell("explorer.exe " & _mainExportFolder, vbNormalFocus)

    End Sub

    Public Function GetModelStateDocument(doc As PartDocument)
        Dim def As PartComponentDefinition = doc.ComponentDefinition

        If (def.IsModelStateMember Or def.IsModelStateFactory) Then
            doc = def.FactoryDocument
            def = doc.ComponentDefinition
        Else
            Return doc
        End If

        Dim masterDoc As Document = Nothing
        Dim PreProductionDoc As Document = Nothing
        For Each modelState As ModelState In def.ModelStates
            If (ModelState.Name = "Master") Then
                If (PreProductionDoc Is Nothing) Then
                    ModelState.Activate()
                End If
                masterDoc = ModelState.FactoryDocument
            End If
            If (ModelState.Name = "Pre-Production") Then
                ModelState.Activate()
                PreProductionDoc = ModelState.FactoryDocument
            End If
        Next

        If (PreProductionDoc Is Nothing) Then
            Return masterDoc
        Else
            Return PreProductionDoc
        End If
    End Function

    Private Sub ExportDxf(oDoc As Document)
        If (oDoc.SubType = _sheetMetalPartGUID) Then

            Dim oCompDef As SheetMetalComponentDefinition = oDoc.ComponentDefinition
            If oCompDef.HasFlatPattern = False Then
                oCompDef.Unfold()
            Else
                oCompDef.FlatPattern.Edit()
            End If

            Dim DPS As PropertySet = oDoc.PropertySets.Item("Design Tracking Properties")
            Dim ISI As PropertySet = oDoc.PropertySets.Item("Inventor Summary Information")
            Dim fileName As String = String.Format("{0}\{1} - {2}.dxf",
                _mainExportFolder,
                DPS.Item("Part Number").Value,
                ISI.Item("Revision Number").Value)

            'FLAT PATTERN DXF Settings
            Dim sOut As String = "FLAT PATTERN DXF?AcadVersion=2004&RebaseGeometry=True&OuterProfileLayer=0&OuterProfileLayerColor=0;0;0&InteriorProfilesLayer=0&InteriorProfilesLayerColor=0;0;0;IV_OUTER_PROFILE;IV_INTERIOR_PROFILES;IV_FEATURE_PROFILES;IV_FEATURE_PROFILES_DOWN;IV_ALTREP_FRONT;IV_ALTREP_BACK;IV_ROLL_TANGENT;IV_ROLL&InvisibleLayers=IV_BEND;IV_BEND_DOWN;IV_TANGENT;IV_TOOL_CENTER;IV_TOOL_CENTER_DOWN;IV_ARC_CENTERS;IV_UNCONSUMED_SKETCHES"

            'Export the DXF and fold the model back up
            oCompDef.DataIO.WriteDataToFile(sOut, fileName)

            oCompDef.FlatPattern.ExitEdit()

        End If
    End Sub

    Private Sub ExportStep(oDoc As Document)
        Dim oOptions As NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
        Dim oContext As TranslationContext = ThisApplication.TransientObjects.CreateTranslationContext

        Dim DPS As PropertySet = oDoc.PropertySets.Item("Design Tracking Properties")
        Dim ISI As PropertySet = oDoc.PropertySets.Item("Inventor Summary Information")
        Dim fileName As String = String.Format("{0}\{1} - {2}.stp",
                _mainExportFolder,
                DPS.Item("Part Number").Value,
                ISI.Item("Revision Number").Value)

        If _STEPTranslator.HasSaveCopyAsOptions(oDoc, oContext, oOptions) Then

            oOptions.Value("ApplicationProtocolType") = 3
            oContext.Type = IOMechanismEnum.kFileBrowseIOMechanism
            Dim oData As DataMedium
            oData = ThisApplication.TransientObjects.CreateDataMedium
            oData.FileName = fileName

            'Publish document.
            Call _STEPTranslator.SaveCopyAs(oDoc, oContext, oOptions, oData)

        End If
    End Sub

    Public Function findAllWhere(doc As AssemblyDocument,
                predicate As Func(Of ComponentOccurrence, Boolean)) As IEnumerable(Of ComponentOccurrence)

        Dim list As IEnumerable(Of ComponentOccurrence) = doc.ComponentDefinition.
        Occurrences.Cast(Of ComponentOccurrence).
        Where(predicate)

        Dim assemblyList As IEnumerable(Of ComponentOccurrence) = doc.ComponentDefinition.
        Occurrences.Cast(Of ComponentOccurrence).
        Where(Function(o) o.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject)

        For Each assOcc As ComponentOccurrence In assemblyList
            If TypeOf assOcc.Definition Is VirtualComponentDefinition Then Continue For
            Dim assDoc As AssemblyDocument = assOcc.ReferencedDocumentDescriptor.ReferencedDocument
            Dim listToAdd As IEnumerable(Of ComponentOccurrence) = findAllWhere(assDoc, predicate)
            list = list.Concat(listToAdd)
        Next
        Return list
    End Function

    Private Function NeedExport(doc As Document) As Boolean
        If (doc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject) Then Return False
        If (doc.ComponentDefinition.BOMStructure = BOMStructureEnum.kReferenceBOMStructure) Then Return False
        If (doc.ComponentDefinition.BOMStructure = BOMStructureEnum.kPhantomBOMStructure) Then Return False

        Dim UDP As PropertySet = doc.PropertySets.Item("Inventor User Defined Properties")
        Dim DPS As PropertySet = doc.PropertySets.Item("Design Tracking Properties")
        Dim ISI As PropertySet = doc.PropertySets.Item("Inventor Summary Information")

        If (UDP.Item("Purchased").Value = "-" And UDP.Item("Stores").Value = "-" And
                UDP.Item("Laser Stock").Value = "-") = False Then Return False

        Dim fileName As String = String.Format("{0}\{1} - {2}.stp",
                _mainExportFolder,
                DPS.Item("Part Number").Value,
                ISI.Item("Revision Number").Value)
        If (IO.File.Exists(fileName)) Then Return False

        Return True
    End Function

    Private Function SetSTEPTranslator()
        _STEPTranslator = ThisApplication.ApplicationAddIns.ItemById("{90AF7F40-0C01-11D5-8E83-0010B541CD80}")
        If _STEPTranslator Is Nothing Then
            Throw New Exception("Could not access STEP translator.")
        End If
    End Function

End Class

 

Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Blog: hjalte.nl - github.com

Message 4 of 8

matthew.johnson200
Enthusiast
Enthusiast

This works great. Thanks for your help!

0 Likes
Message 5 of 8

dalton98
Collaborator
Collaborator

@JelteDeJong 

I have a code very similar that I use. We only burn certain parts so we just eye test them in our drawing sets. I wrote a rule that exports the first view in the active sheet as a ".dxf", but it doesn't work with model states.

'get view document
Dim
oDoc As PartDocument oDoc = oView.ReferencedDocumentDescriptor.ReferencedDocument
Dim oCompDef As SheetMetalComponentDefinition oCompDef = oDoc.ComponentDefinition
'''''code
oCompDef.DataIO.WriteDataToFile( sOut, sFname)

I tried doing this

Dim oDoc As PartDocument
oDoc = oView.ReferencedDocumentDescriptor.ReferencedDocument
Dim oCompDef As SheetMetalComponentDefinition
oCompDef = oDoc.ComponentDefinition
oDoc = oCompDef.FactoryDocument
oCompDef = oDoc.ComponentDefinition

 Any feedback would be greatly appreciated.

0 Likes
Message 6 of 8

dalton98
Collaborator
Collaborator

Nvm. I did this and it worked fine

Dim oDoc As Document
oDoc = oView.ReferencedDocumentDescriptor.ReferencedDocument
oDoc = oDoc.ComponentDefinition.Document
0 Likes
Message 7 of 8

basslagter
Participant
Participant

Hi @dalton98 ,

 

I am also working on a code to export all model states from a drawing document. Did you manage to do that, and would you mind sharing the whole code?

 

If so, thanks in advance.

If not, please let me know as well.

0 Likes
Message 8 of 8

dalton98
Collaborator
Collaborator

@basslagter The problem I was having was trying to unfold the model states. I ended up creating a separate rule for it. You should just make a post on the forums and tell what you are exactly trying to do and someone will help.

Heres a snippet of mine

SETFilePath = ThisApplication.DesignProjectManager.ActiveDesignProject.WorkspacePath & "/"

Dim oDrawingDoc As DrawingDocument
oDrawingDoc = ThisApplication.ActiveDocument

Dim oSheet As Sheet
For Each oSheet In oDrawingDoc.Sheets

Dim oView As DrawingView
oView = oSheet.DrawingViews.Item(1)

Dim oDoc As Document
oDoc = oView.ReferencedDocumentDescriptor.ReferencedDocument
If Not oDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject Then Continue For
If Not oDoc.DocumentSubType.DocumentSubTypeID = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}" Then Continue For

Dim oCompDef As SheetMetalComponentDefinition
oCompDef = oDoc.ComponentDefinition

'DXF Settings
Dim sOut As String
Dim sPATH As String
sOut = "FLAT PATTERN DXF?AcadVersion=2000&OuterProfileLayer=IV_INTERIOR_PROFILES&TangentLayer=DELETE&ArcCentersLayer=DELETE&BendDownLayer=IV_BEND&UnconsumedSketchesLayer=DELETE"
Dim sFname As String
sFname = SETFilePath & "\" & oDoc.PropertySets.Item(3).Item("Part Number").Value & " " & oDoc.PropertySets.Item(3).Item("Description").Value & ".dxf"

'Export the DXF and fold the model back up
oCompDef.DataIO.WriteDataToFile( sOut, sFname)
Dim oSMDef As SheetMetalComponentDefinition
oSMDef = oDoc.ComponentDefinition

'ThisDoc.Launch("C:\Temp\Copy and Paste in AutoCad Command Box.txt")'open the file
Process.Start(sFname)
Next