Export Sheet Metal DXF files from Assembly?

Export Sheet Metal DXF files from Assembly?

adminGJMH6
Observer Observer
700 Views
5 Replies
Message 1 of 6

Export Sheet Metal DXF files from Assembly?

adminGJMH6
Observer
Observer

Hi

 

I am currently trying to export all the sheetmetal dxf files from multiple assemblies which I've copied and worked on some code from a few different posts already covering this topic @JhoelForshav . My problem is that I need each dxf to have the naming convention: Part Number_Material_Thickness_Quantity. The code below does this for the first file in the assembly but for the rest I get the error: HRESULT 0x80004005 (E_FAIL). I'm not that familiar with this sort of programming so any help would be appreciated. 

Sub Main
	'iLogic Code by Jhoel Forshav - originally posted at https://clintbrown.co.uk/ilogic-export-all-flat-patterns-to-one-dxf
	'Check that the active document is an assembly file
	If ThisApplication.ActiveDocument.DocumentType <> kAssemblyDocumentObject Then
		MessageBox.Show("This rule can only run from an Assembly file", "DXF-creator", MessageBoxButtons.OK, MessageBoxIcon.Error)
		Exit Sub
	End If
	'Dim the active document as AssemblyDocument
	Dim oDoc As AssemblyDocument = ThisApplication.ActiveDocument
	'Make sure the assembly is saved
	If oDoc.FullFileName = ""
		MessageBox.Show("Please save the Assembly before running this rule.", "DXF-creator", MessageBoxButtons.OK, MessageBoxIcon.Information)
		Exit Sub
	End If
	'Get the assembly filename without extension
	Dim oAsmName As String = System.IO.Path.GetFileNameWithoutExtension(oDoc.FullFileName)
	'Get the assembly filepath
	Dim oPath As String = System.IO.Path.GetDirectoryName(oDoc.FullFileName)

	'Get the parts only BOM.
	Dim oBOM As BOM = oDoc.ComponentDefinition.BOM
	'Make sure Parts Only is activated
	oBOM.PartsOnlyViewEnabled = True
	'Parts only will be last BomView (difficult to get by name since it's different depending on your language)
	Dim oBOMview As BOMView = oBOM.BOMViews.Item(oBOM.BOMViews.Count)


	'Set a reference to the TransientGeometry object
	Dim oTG As TransientGeometry = ThisApplication.TransientGeometry
	'oX and oY will be used to create points for view placement
	Dim oX As Double = 0
	Dim oY As Double = 0
	'Create the Baseview options to place flatpattern-views
	Dim oBaseViewOptions As NameValueMap
	oBaseViewOptions = ThisApplication.TransientObjects.CreateNameValueMap
	oBaseViewOptions.Add("SheetMetalFoldedModel", False)
	'Set a variable for the drawing document
	Dim oDrawing As DrawingDocument
	'declare the variable for the Sheet object
	Dim oSheet As Sheet
	'Create a String to return a message if any SM-parts are not saved
	Dim unsavedSmParts As String = ""

	Dim i As Integer = 1
	Dim oInfo As String = ""

	'Traverse Parts Only BOM
	For Each oRow As BOMRow In oBOMview.BOMRows
		Try
			'Get the component definition for the part
			Dim oDef As ComponentDefinition = oRow.ComponentDefinitions(1)
			'Check if the part is SheetMetal
			If TypeOf (oDef) Is SheetMetalComponentDefinition
				'Set a reference to the partdocument
				Dim smPartDoc As PartDocument = oDef.Document
				'Check if the part is saved
				If smPartDoc.FullFileName = "" Then
					If unsavedSmParts = "" Then unsavedSmParts = "The fallowing SM-documents were not saved and therefore " & _
					"no drawingviews were created:" & vbCrLf
					unsavedSmParts = unsavedSmParts & vbCrLf & oDef.Document.DisplayName
					Continue For
				End If
				'Create flatpattern if it doesn't already exist
				If Not oDef.HasFlatPattern
					oDef.Unfold()
					oDef.FlatPattern.ExitEdit()
				End If
				'Create the drawing if it doesn't already exist
				If oDrawing Is Nothing
					oDrawing = ThisApplication.Documents.Add(DocumentTypeEnum.kDrawingDocumentObject, _
					, False)
					'Set the drawings length units to the same as the assemblys length units
					oDrawing.UnitsOfMeasure.LengthUnits = oDoc.UnitsOfMeasure.LengthUnits
				End If

				'Set a reference to the drawing sheet
				If oSheet Is Nothing Then
					oSheet = oDrawing.ActiveSheet
				Else
					oSheet = oDrawing.Sheets.Add()
				End If

				'Create the flatpattern view
				Dim oView As DrawingView = oSheet.DrawingViews.AddBaseView(smPartDoc, oTG.CreatePoint2d(oX, oY), 1 _
				, ViewOrientationTypeEnum.kDefaultViewOrientation, DrawingViewStyleEnum.kHiddenLineRemovedDrawingViewStyle, _
				"FlatPattern", , oBaseViewOptions)

				oView.Name = smPartDoc.DisplayName & vbNewLine & "Thickness: " & smPartDoc.ComponentDefinition.Thickness.Expression _
				& vbNewLine & "Material: " & smPartDoc.PropertySets("Design Tracking Properties")("Material").Value & _
				vbCrLf & "Quantity: " & oDoc.ComponentDefinition.Occurrences.AllReferencedOccurrences(smPartDoc).Count
				oView.ShowLabel = True

				'Set the position with our oX and oY
				oView.Position = oTG.CreatePoint2d(oView.Position.X + oView.Width / 2, oView.Position.Y)
				'Move oX to place the next view to the right of this one
				oX = oView.Left + oView.Width + 1
				'Remove the bend lines of the view
				RemoveBendLines(oView, oDef.FlatPattern)'You could comment out this line to keep bend lines

				oInfo = oInfo & If (i = 1, "", vbCrLf) & i & ". " & smPartDoc.PropertySets.Item("Design Tracking Properties"). _
				Item("Part Number").Value & " - Thickness: " & oDef.Thickness.Expression & " - Material: " _
				& smPartDoc.PropertySets("Design Tracking Properties")("Material").Value & " - Quantity: " & _
				oDoc.ComponentDefinition.Occurrences.AllReferencedOccurrences(smPartDoc).Count

				i += 1

				'Close the part
				'probably either not needed, or not possible, because it is being referenced by the assembly
					If oDrawing IsNot Nothing
					'Create the save location string for the DXF
					Dim oDXFName As String = oPath & "\" & smPartDoc.PropertySets.Item("Design Tracking Properties"). _
				Item("Part Number").Value & "_" & smPartDoc.PropertySets("Design Tracking Properties")("Material").Value & "_" & oDef.Thickness.Expression & "_" & oDoc.ComponentDefinition.Occurrences.AllReferencedOccurrences(smPartDoc).Count & "pcs" & ".dxf"
					'Save the DXF
					oINI = "C:\Documents\Publish_DXF.ini" 'Specify your INI file location here (eg C:\TEMP\DXF Export.ini)

					If oINI = "" Then
					MessageBox.Show("You need to specify an INI file location in the code - Look for oINI and set the path", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
					End If
					SaveDXF(oDrawing, oDXFName, oINI)
					'Create the save location string for the information txt
					Dim oInfoName As String = oPath & "\" & oAsmName & "_FlatPatterns.txt"
					'Create the txt
					CreateTXT(oInfo, oInfoName)
					End If
				smPartDoc.Close(True)
			End If
				'Close the drawing
				oDrawing.Close
		Catch Ex As Exception
			MsgBox(Ex.Message)
		End Try
	Next


	'return information about any unsaved parts
	If unsavedSmParts <> "" Then _
	MessageBox.Show(unsavedSmParts, "Some parts were not saved", _
	MessageBoxButtons.OK, MessageBoxIcon.Information)
	'Update the assembly (could be dirty if any flatpatterns were created)
	oDoc.Update
End Sub



Sub RemoveBendLines(oView As DrawingView, oFlattPattern As FlatPattern)
	'Get all the bend edges from the FlatPattern
	Dim oBendEdgesUp As Edges = oFlattPattern.GetEdgesOfType(FlatPatternEdgeTypeEnum.kBendUpFlatPatternEdge)
	Dim oBendEdgesDown As Edges = oFlattPattern.GetEdgesOfType(FlatPatternEdgeTypeEnum.kBendDownFlatPatternEdge)

	For Each oEdge As Edge In oBendEdgesUp
		'Get the curves representing these edges in the drawing view
		For Each oCurve As DrawingCurve In oView.DrawingCurves(oEdge)
			For Each oSegment As DrawingCurveSegment In oCurve.Segments
				'Set visibility to false
				oSegment.Visible = False
			Next
		Next
	Next
	For Each oEdge As Edge In oBendEdgesDown
		For Each oCurve As DrawingCurve In oView.DrawingCurves(oEdge)
			For Each oSegment As DrawingCurveSegment In oCurve.Segments
				oSegment.Visible = False
			Next
		Next
	Next
End Sub

Sub SaveDXF(oDrawing As DrawingDocument, oFileName As String, oIniFile As String)
							'Set a reference to the DFX translator
							Dim DXFAddIn As TranslatorAddIn
							DXFAddIn = ThisApplication.ApplicationAddIns.ItemById("{C24E3AC4-122E-11D5-8E91-0010B541CD80}")
							'Create translation context
							Dim oContext As TranslationContext = ThisApplication.TransientObjects.CreateTranslationContext
							oContext.Type = IOMechanismEnum.kFileBrowseIOMechanism
							'Create options for the translation
							Dim oOptions As NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
						'Create a DataMedium object
						Dim oDataMedium As DataMedium = ThisApplication.TransientObjects.CreateDataMedium
						'Set the options (which .ini-file to use)
						If DXFAddIn.HasSaveCopyAsOptions(oDrawing, oContext, oOptions) Then
						oOptions.Value("Export_Acad_IniFile") = oIniFile
						End If
						'Set the filename property of the DataMedium object
							oDataMedium.FileName = oFileName
						Try
						'Try to save the DXF
						DXFAddIn.SaveCopyAs(oDrawing, oContext, oOptions, oDataMedium)
						MessageBox.Show("Dxf saved to: " & oFileName, "DXF SAVED", MessageBoxButtons.OK, MessageBoxIcon.Information)
						Catch
						MessageBox.Show("Couldn't save dxf!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
						End Try
					End Sub
					
Sub CreateTXT(oText As String, oFileName As String)
	Dim oTxtWriter As System.IO.StreamWriter = System.IO.File.CreateText(oFileName)
	oTxtWriter.WriteLine(oText)
	oTxtWriter.Close()
End Sub

  

0 Likes
701 Views
5 Replies
Replies (5)
Message 2 of 6

A.Acheson
Mentor
Mentor

Hi @adminGJMH6 

I’m not currently near a computer to test but can help you start to debug. To start with your error message you posted is not too useful. To get a more meaningful one click the more info tab of the error message and screenshot that message.

 

Next take a message box or logger.info statement and start steeping through the code line by line and see can you get the message to appear for each line. When the message box stop appearing and the error message appears you will have your problem line. 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 3 of 6

adminGJMH6
Observer
Observer

Thanks for the response, is there a setting I'm missing because there is no additional information with the error message. Screenshot below:

adminGJMH6_0-1714386739105.png

 

Cheers

0 Likes
Message 4 of 6

A.Acheson
Mentor
Mentor

Hi @adminGJMH6 

From the image that message box is actually a user generated message box and it's displaying an error message that isn't too helpfull. But here is where it is located. 

	End If
				'Close the drawing
				oDrawing.Close
		Catch Ex As Exception
			MsgBox(Ex.Message)
		End Try

 Your next challenge is to see why it's erroring out. It could be an issue unfolding the flat pattern or carrying out another operation. So to diagnose step through that loop of code with a logger statement like Logger.Info("No Error"). Move it one line at a time and see cna you find the error. I would suggest you comment of the message box temporarily so you don't get a repetitive error you have to cancel. Alternatively you can replace the message box with a logger statement.

 

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 5 of 6

adminGJMH6
Observer
Observer

So I've done some more work on this and from what I can tell the issue is not with the parts or making the flat patterns as the first dxf always comes out fine. The issue I think is that the code was written to make a single drawing with each part being on a new sheet that is then exported. The logic I am trying to create is that each part has it's own drawing and dxf and this is the part that is tripping me up as I cannot get the logic to create an individual drawing for each part. I hope that makes sense as I'm at a bit of a loss on how to get that loop to function correctly.

 

0 Likes
Message 6 of 6

A.Acheson
Mentor
Mentor

If you want to avoid creating a additional sheets in the open drawing set the object to Nothing or bring the drawing close line inside the If statement for filtering sheetmetal parts. Currently the drawing document is checked to be nothing and if so creates a drawing, same for the sheet caries out the action and for the next BomRow the Drawing document is not nothing and also the sheet and so the drawing is used again and a new sheet added. 

'Create the drawing if it doesn't already exist
				oDrawing = Nothing
				oDrawing = ThisApplication.Documents.Add(DocumentTypeEnum.kDrawingDocumentObject, True)

 or 

		If TypeOf (oDef) Is SheetMetalComponentDefinition
				
				'Do Something....................................
				
				'Close the drawing
				oDrawing.Close
		End If
If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes