Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

Exporting Object to STL file; Journal

Status
Not open for further replies.

pittbuck

Computer
May 1, 2017
31
0
0
US
I am trying to write a journal that will export a single object from a specified layer to a .stl file. I've tried to "rewrite" the journal that is on the following website, but it doesn't seem to help. Maybe I am re-writing the code wrong (very likely).


This file needs to go to a specified place and needs a specified name, but I'll worry about that later. If this file goes into the TEMP folder on my computer for now, that's fine. When export the object to an STL file, the following has to be in the "rapid prototyping" window:

Capture_zh9lt1.jpg
.

Thanks in advance for any advice.
 
Replies continue below

Recommended for you

The journal in the link finds all the solid bodies in the work part and adds them to a list, it later uses the list to export those objects. Instead of adding all the bodies, only add the one that you are interested in (I'm assuming the object you want to export is a solid body).

Code:
'collect the solid bodies in the work part
[s]For Each temp As Body In workPart.Bodies
    If temp.IsSolidBody Then
        theSolids.Add(temp)
    End If
Next[/s]
theSolids.Add([highlight #FCE94F]{your body object}[/highlight])

The code, as-is, creates the STL file in the same folder as the work part; but you can pass in the desired file path:
Code:
ExportSTL([highlight #FCE94F]{your file path here}[/highlight], theSolids, [highlight #8AE234]0.003[/highlight], [highlight #8AE234]0.003[/highlight])
Also, you can adjust the triangle tolerance and adjacency tolerance here.

www.nxjournaling.com
 
Cowski,

Something still isn't working. It keeps giving me the "declaration expected" error in a variety of places. Here is the code currently.

Code:
Option Strict Off
Imports System
Imports System.IO
Imports System.Collections.Generic  
Imports NXOpen
Imports NXOpen.UI
Imports NXOpen.UF

Module NXJournal

Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display
Dim theUFSession As UFSession = UFSession.GetUFSession

Const undoMarkName As String = "export solids to STL"
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Invisible, undoMarkName)

Dim layerExport as NXObject()
Dim myExportObjects as DisplayableObject()
Dim l as Integer = 0

layerExport = workPart.Layers.GetAllObjectsOnLayer(195)

for each someObject as NXObject in layerExport
    if someObject.GetType.ToString = "NXOpen.Body" then
        redim preserve myExportObjects(l)
        myExportObjects(l) = someObject
        l += 1
    end if
	
'*******************************************
'Following code is used to get the current file name and path for approval file

Dim currentPath as string
Dim currentFile as string

'currentFile = GetFilePath() & GetFileName() & ".prt"
currentPath = GetFilePath()
currentFile = GetFileName()

Try
    ExportSTL(currentPath & "\" & currentFile & " Overlay", myExportObjects, 0.01, 0.01)
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.0, 0.0, triangleTolerance, NumErrors, InfoError)
    End If
Next

theUfSession.Std.CloseStlFile(FileHandle)

theUfSession.Ui.SetStatus("File ... " & FileBaseName & " generated ...")

End Sub

Function GetFilePath()
	Dim strPath as String
	Dim strPart as String
	Dim pos as Integer
	Dim pos2 as Integer
	
	'get the full file path
	strPath = displayPart.fullpath
	'get the part file name
	pos = InStrRev(strPath, "\")
	strPart = Mid(strPath, pos + 1)
	
	strPath = Left(strPath, pos - 1)
	'strip off the ".prt" extension
	strPart = Left(strPart, Len(strPart) - 4)

	'pos2 = InStrRev(strPath, "\")
	'strPath = Left(strPath, pos2)

	
	GetFilePath = strPath
End Function

Function GetFileName()
	Dim strPath as String
	Dim strPart as String
	Dim pos as Integer
	
	'get the full file path
	strPath = displayPart.fullpath
	'get the part file name
	pos = InStrRev(strPath, "\")
	strPart = Mid(strPath, pos + 1)
	
	strPath = Left(strPath, pos)
	'strip off the ".prt" extension
	strPart = Left(strPart, Len(strPart) - 4)
	
	GetFileName = strPart
End Function

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
 
You are passing in an array of DisplayableObject where the ExportSTL sub is expecting a list of bodies. You'll need to pass in a list of bodies or change the ExportSTL sub to work with an array of DisplayableObject. Of these 2 choices, I'd suggest using a list object to hold the bodies that you want to export. I prefer lists as they will resize themselves as needed (no need for reDim preserve) and can be used as an array where the NXOpen API expects array input (with the use of the .ToArray method).

www.nxjournaling.com
 
Alright. Getting somewhere. Less errors. Right now, the biggest problem seems to be something in line 56 (the Sub ExportSTL line). "theObjects" does not have a parameter, so I'm guessing that "theObjects needs to be replaced with something.

Code:
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

There are a couple of small errors that come up, but I think I can figure those out. I'll post something here otherwise.
 
Hey Cowski,

First, I wanted to thank you for all the help you have given me. Things got a bit busy over here and I haven't been able to adjust the journal until recently. So because I had made so many adjustments to the code and wasn't getting anywhere, I started over. Now I'm on the right track again. With the code the way it is now, it takes all bodies that are in a particular part file and makes separate STL files for all of them. How do I get the journal select just the bodies on a particular layer?

Code:
Option Strict Off
Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF
 
Module Module2
 
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
 
    lw.Open()
 
    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
        ExportSTLFiles(workPart.FullPath, theSolids, 0.01, 0.01)
    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.0, 0.0, triangleTolerance, NumErrors, InfoError)
        End If
    Next
 
    theUfSession.Std.CloseStlFile(FileHandle)
 
    theUfSession.Ui.SetStatus("File ... " & FileBaseName & " generated ...")
 
End Sub
 
Sub ExportSTLFiles(ByVal FileName As String, ByVal theObjects As List(Of Body), ByVal triangleTolerance As Double, ByVal adjacencyTolerance As Double)
 
    Dim NumErrors As Integer
    Dim InfoError() As UFStd.StlError
    Dim Header, FileBaseName As String
    'Dim numNegated As Integer
    'Dim Negated() As Tag
 
    'Negated = Nothing
    InfoError = Nothing
 
    Dim parentFolder As String = IO.Path.GetDirectoryName(FileName)
    Dim fileNameNoExt As String = IO.Path.GetFileNameWithoutExtension(FileName)
 
    'FileName = IO.Path.ChangeExtension(FileName, ".stl")
    Dim suffix As Integer = 1
    For Each temp As Body In theObjects
 
        Dim FileHandle As IntPtr
 
        Dim fileNameWithSuffix As String = fileNameNoExt & "_" & suffix.ToString & ".stl"
 
        FileBaseName = IO.Path.GetFileName(FileName)
        Header = "Header: " & FileBaseName
 
        theUfSession.Std.OpenBinaryStlFile(IO.Path.Combine(parentFolder, fileNameWithSuffix), False, Header, FileHandle)
 
        theUfSession.Ui.SetPrompt("Creating file ... " & FileBaseName & " ...")
 
        theUfSession.Std.PutSolidInStlFile(FileHandle, Tag.Null, temp.Tag, 0.0, 0.0, triangleTolerance, NumErrors, InfoError)
 
        theUfSession.Std.CloseStlFile(FileHandle)
 
        theUfSession.Ui.SetStatus("File ... " & FileBaseName & " generated ...")
 
        suffix += 1
 
    Next
 
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

Thanks again!!
 
Change the code that finds the solid bodies to:
Code:
If temp.IsSolidBody andAlso temp.Layer = 1 Then
    theSolids.Add(temp)
End If

Change the layer number as needed for your situation.

The above works well if you are interested in a single layer. If you need to get the solids from several layers, one strategy is to create a list(of integer) to keep track of the layers you want to process; then in the "If" block, check to see if the body's layer is contained in the list.
Code:
dim layersToProcess as new list(of integer)
layersToProcess.Add(1)
layersToProcess.Add(2)
layersToProcess.Add(7)
layersToProcess.Add(11)
layersToProcess.Add(97)
.
.
.
If temp.IsSolidBody andAlso layersToProcess.Contains(temp.Layer) Then
    theSolids.Add(temp)
End If

www.nxjournaling.com
 
Cowski,

The first one is exactly what I needed. Thanks! As I mentioned before, I am still new to Journaling and just didn't know how to do something that is clearly a simple change.

Now onto a question that may be a lot more complicated. How do I move the new STL file as follows:

Folder A
-->Folder B
----->Folder C
"new STL file"

The goal is to not only move new STL file outside of Folder C and Folder B to inside Folder A and create a new folder labeled as "Folder D". so it is more like this:

Folder A
-->Folder D
"new STL file"

Now, if creating a folder is something that isn't exactly something that can be created with a journal, that is ok. If I need to create folder D before running the journal, that is fine.

Hope all of this makes sense. Thanks in advance!
 
It's been a while. Just wanted to first say thanks to cowski! This journal has been a HUGE help.

Now it's time to start another little project that involves exporting more STL files.

I have multiple bodies that need to be exported to STL files and have each of these files have a different specific name as mentioned previously. I want this to be done with as little work to be done by the operator as possible. Presently, all the bodies are on the same layer (195). I think that the start to this is to put each body on their own, separate layer (for ease of the user, we will say layers 218-231). Is there a way to have this journal export each of these bodies with their specific names without having TONS of lines of code? ("Layer 218" to be named "ITEM #1, "Layer 219" to be named "ITEM #2", etc.)

There is one more idea I wish to add to this, but it may be dependent upon what is presented.

Thanks in advance for the help.
 
The first strategy that I'd try would be to create a list (of Body) for each layer of interest, iterate through the body collection and place the bodies found on each layer in the appropriate list. Then call the export stl subroutine with the desired list of bodies and file name. You'll need to modify the code to create multiple lists for the layers and to process the resulting lists, but I think the rest of what you need is already in the code above.

www.nxjournaling.com
 
Status
Not open for further replies.
Back
Top