Submitted by Jlansdown on Tue, 08/11/2015 - 14:04
Forums:
Hi! I am fairly new to journaling in NX and this forum and website have been a fantastic source of knowledge and has provided excellent guidance thus far. Thank you! However, I have run into an issue when trying to batch export my .prt files to .stl files.
I am looking to export ~100 .prt files to the .stl format and have not been able to so far. I have been referencing this link: http://www.nxjournaling.com/content/exporting-stl-files but I cannot get it to work for 1 file let alone the whole batch.
I was hoping someone could provide some guidance or tips so that I can get this working.
Thanks a lot in advance.

re: export STL
What do you want to export from the part file?
All the bodies?
One or more user selected bodies?
A particular body or bodies in a part file based on layer, name, group, etc?
Also, what version of NX are you using?
re:
Hi, thanks for the speedy response. I am looking to export all the bodies in the file.
I am using NX 7.5
Thanks!
J
re: export STL
Try the following journal. It will collect all the solid bodies in the work part and export them to an .STL file.
This is fantastic. Thank you.
This is fantastic. Thank you. I can get it to work for one part now. However, when I try to implement this code for all the files in a directory with the code below (borrowed from your website, thank you) I get an error that List is not defined in the "Dim theSolids As New List(Of Body)" line. Any ideas? Thank you for all your help.
Option Strict Off Imports System Imports System.IO Imports System.Collections Imports System.Windows.Forms Imports NXOpen Imports NXOpenUI Imports NXOpen.UF Module Cycle_Files_and_Folders_b Dim theSession As Session = Session.GetSession Dim theUfSession As UFSession = UFSession.GetUFSession() Dim LW As ListingWindow = theSession.ListingWindow Dim workPart As Part = theSession.Parts.Work Dim displayPart As Part = theSession.Parts.Display Dim initialPart As Part = theSession.Parts.Display Dim nTotalPartFiles As Integer = 0 Sub Main() Dim strOutputFolder As String LW.Open() Try Dim FolderBrowserDialog1 As New FolderBrowserDialog ' Change the .SelectedPath property to the default location With FolderBrowserDialog1 ' Desktop is the root folder in the dialog. .RootFolder = Environment.SpecialFolder.Desktop ' Change the following line to default to a given path .SelectedPath = "C:\" ' Prompt the user with a custom message. .Description = "Select the directory to scan" If .ShowDialog = DialogResult.OK Then ' Display the selected folder if the user clicked on the OK button. 'msgbox(.SelectedPath) strOutputFolder = .SelectedPath Else 'user pressed "cancel", exit the journal Exit Sub End If End With LW.WriteLine("Cycle All Parts in a Folder Tree") LW.WriteLine("Start Time: " & CType(TimeOfDay(), String)) LW.WriteLine("") processParts(strOutputFolder, False) LW.WriteLine("") LW.WriteLine("Total Part Files Scanned: " & nTotalPartFiles) LW.WriteLine("Stop Time: " & CType(TimeOfDay(), String)) Catch ex As NXException LW.WriteLine("Cycle Files and Folders Error: " & ex.Message) Exit Sub End Try End Sub '*************************************************************************** 'Process All Parts in a Directory Sub processParts(ByVal directoryPath As String, ByVal includeSubDirs As Boolean) Try Dim nPartFiles As Integer = 0 Dim part1 As Part Dim files() As String If includeSubDirs Then files = Directory.GetFiles(directoryPath, "*.prt", SearchOption.AllDirectories) Else files = Directory.GetFiles(directoryPath, "*.prt", SearchOption.TopDirectoryOnly) End If For Each fileName As String In files nPartFiles += 1 nTotalPartFiles += 1 LW.WriteLine(" " & nPartFiles & " " & Path.GetFileName(fileName)) If (IsNothing(initialPart)) OrElse (initialPart.FullPath <> fileName) Then part1 = theSession.Parts.OpenDisplay(fileName, Nothing) Else 'LW.WriteLine("initial part equals display part: " & initialPart.Equals(displayPart).ToString) part1 = displayPart End If displayPart = theSession.Parts.Display workPart = theSession.Parts.Display 'do something 'write your own subroutines and/or functions to process the part and call them from here Const undoMarkName As String = "export solids to STL" Dim markId1 As Session.UndoMarkId markId1 = theSession.SetUndoMark(Session.MarkVisibility.Invisible, undoMarkName) Dim theSolids As New List(Of Body) 'collect the solid bodies in the work part For Each temp As Body In workPart.Bodies If temp.IsSolidBody Then theSolids.Add(temp) End If Next Try ExportSTL(workPart.FullPath, theSolids, 0.003, 0.003) Catch ex As NXException LW.WriteLine("NX Error: " & ex.Message) Catch ex As Exception LW.WriteLine("Error: " & ex.Message) End Try 'close file unless this file was initially open If (IsNothing(initialPart)) OrElse (initialPart.FullPath <> fileName) Then 'part1.Save(BasePart.SaveComponents.True, BasePart.CloseAfterSave.True) part1.Close(BasePart.CloseWholeTree.False, BasePart.CloseModified.UseResponses, Nothing) part1 = Nothing workPart = Nothing displayPart = Nothing End If If Not IsNothing(initialPart) Then Dim partLoadStatus1 As PartLoadStatus Dim status1 As PartCollection.SdpsStatus status1 = theSession.Parts.SetDisplay(initialPart, False, False, partLoadStatus1) displayPart = theSession.Parts.Display partLoadStatus1.Dispose() theSession.Parts.SetWork(displayPart) workPart = theSession.Parts.Work End If Next fileName Catch ex As Exception LW.WriteLine("Part Scan Error: " & ex.Message) End Try End Sub '*************************************************************************** Sub ExportSTL(ByVal FileName As String, ByVal theObjects As List(Of Body), ByVal triangleTolerance As Double, ByVal adjacencyTolerance As Double) Dim NumErrors As Integer Dim FileHandle As IntPtr Dim InfoError() As UFStd.StlError Dim Header, FileBaseName As String 'Dim numNegated As Integer 'Dim Negated() As Tag 'Negated = Nothing InfoError = Nothing FileName = IO.Path.ChangeExtension(FileName, ".stl") FileBaseName = IO.Path.GetFileName(FileName) Header = "Header: " & FileBaseName theUfSession.Std.OpenBinaryStlFile(FileName, False, Header, FileHandle) theUfSession.Ui.SetPrompt("Creating file ... " & FileBaseName & " ...") For Each temp As Body In theObjects If temp.IsSolidBody Then theUfSession.Std.PutSolidInStlFile(FileHandle, Tag.Null, temp.Tag, 0.0, 0.0, triangleTolerance, NumErrors, InfoError) End If Next theUfSession.Std.CloseStlFile(FileHandle) theUfSession.Ui.SetStatus("File ... " & FileBaseName & " generated ...") End Sub '*********************************************************************** Public Function GetUnloadOption(ByVal dummy As String) As Integer 'Unloads the image when the NX session terminates GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination End Function End Modulere: list not defined
This is a namespace issue. The compiler is looking for the type: List and cannot find it. The List type is found in System.Collections.Generic.
Change the 4th line of the journal from:
to:
Alternately, you could add the qualification to the list declaration:
Pick one method or the other, but you don't have to do both.
Brilliant!
Thank you so much.
A++
Can I export XT at the same time?
This code is very helpful. I'm just wondering if someone could tell me how to export an XT file at the same time? I found this http://nxjournaling.com/content/export-parasolid and surely its on a few lines... I just don't know exactly what I'm doing.
For what its worth, there is only 1 solid body in each of my parts that I wish to export as both STL and XT.
Thank you
choosing only the displayed bodies
What is the code for choosing only the displayed bodies
re: displayed bodies
One way is to use the .AskVisibleObjects method which will return all the visible objects in the specified view. You could then sort through the returned objects looking for solid bodies. This method may not return objects that are "off screen" even though they are not hidden and their layer is turned on. If this behavior is not desired, an alternative is to loop through the body collection looking for bodies whose layer is turned on and that is not hidden.
Thank you for the quick response
Thanks for responding so fast, I am new to journals so I have been working on it all day. What would the desired code look like if I ONLY wanted the solids that are visible?
Option Strict Off
Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF
Module Module1
Dim theSession As Session = Session.GetSession()
Dim theUfSession As UFSession = UFSession.GetUFSession()
Dim lw As ListingWindow = theSession.ListingWindow
Sub Main()
If IsNothing(theSession.Parts.BaseWork) Then
'active part required
Return
End If
Dim workPart As Part = theSession.Parts.Work
lw.Open()
'------------------------
' Undo Section
'------------------------
Const undoMarkName As String = "export solids to STL"
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Invisible, undoMarkName)
'------------------------
' Declaring Variables
'------------------------
Dim theSolids As New List(Of Body)
'------------------------
'collect the solid bodies in the work part
'------------------------
For Each temp As Body In workPart.Bodies
If temp.IsSolidBody Then
theSolids.Add(temp)
End If
Next
Try
ExportSTL(workPart.FullPath, theSolids, 0.00127, 0.00127)
Catch ex As NXException
lw.WriteLine("NX Error: " & ex.Message)
Catch ex As Exception
lw.WriteLine("Error: " & ex.Message)
End Try
lw.Close()
End Sub
Sub ExportSTL(ByVal FileName As String, ByVal theObjects As List(Of Body), ByVal triangleTolerance As Double, ByVal adjacencyTolerance As Double)
Dim NumErrors As Integer
Dim FileHandle As IntPtr
Dim InfoError() As UFStd.StlError
Dim Header, FileBaseName As String
'Dim numNegated As Integer
'Dim Negated() As Tag
'Negated = Nothing
InfoError = Nothing
FileName = IO.Path.ChangeExtension(FileName, ".stl")
FileBaseName = IO.Path.GetFileName(FileName)
Header = "Header: " & FileBaseName
theUfSession.Std.OpenBinaryStlFile(FileName, False, Header, FileHandle)
theUfSession.Ui.SetPrompt("Creating file ... " & FileBaseName & " ...")
For Each temp As Body In theObjects
If temp.IsSolidBody Then
theUfSession.Std.PutSolidInStlFile(FileHandle, Tag.Null, temp.Tag, 0.00127, 0.00127, triangleTolerance, NumErrors, InfoError)
End If
Next
theUfSession.Std.CloseStlFile(FileHandle)
theUfSession.Ui.SetStatus("File ... " & FileBaseName & " generated ...")
End Sub
Public Function GetUnloadOption(ByVal dummy As String) As Integer
'Unloads the image immediately after execution within NX
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
End Function
End Module
re: visible solid bodies
Try replacing this for loop:
with this for loop:
WOW THANK YOU!
This worked perfectly! You are the best!
Please Help!
Thank you for this code, it is really good but I only need the bodies that are visible (not the ones that are hidden or on another layer).
Please help?
Re. Export STL
How could this be modified to export each body in a work part to individual .STLs? Another one of our engineers has about 40 bodies in a part that need to be printed. I've been using NX for a while, but have never really needed to automate anything like this, so I'm at a loss. Right now, the need is for NX 8.5, but eventually we'll be doing this in NX 10.
Thanks in advance.
re: export stl files
Try the version below, I modified the export function to export to individual stl files. The code was written and tested in NX 9, but I'm pretty sure it will work with NX 8.5 and 10 as well.
I just realized that I never
I just realized that I never thanked you for this. It worked out really nicely. Thanks again.
re: thanks
Glad to help. When I don't hear back, I assume that "no news is good news"; but a quick "that worked" is encouraging to the code author and it gives other viewers confidence that the code works and is worth downloading.
Want the Program for Sheet Bodies Also
I am a newbie to NX Journaling and this forum has helped me to take baby steps in NX Automation. I found this site very useful and Informative. A Big Thanks to the Contributors for their valuable Suggestions and Contributions. I went through the Code for Exporting Solids to STL, but I wish to have sheet Bodies also to be exported to STL format. I Tried Using theUfSession.Std.PutSheetsInStlFile(---Arguments--),and trying to extract the face information for the particular sheetBodies, but in vain. I am getting a lot of namespace issues and errors. Request anyone to modify the code for exporting sheetbodies also.
Thanks
How to isolate which body
Hey guys. I'm a little new to NX Journaling as well. This code works great, but it grabs all of the bodies that are in the part file. I want to just export the body(bodies) on one specific layer. How do I need to change the code to only get the bodies I'm looking for?
Zachary Buckler
How to isolate which body
Try this to export from layer 1