Export Parasolid

One common operation that is surprisingly not supported by the journal recorder (as of NX 7.5, at least) is exporting geometry to a parasolid file. There is an NX Open function that allows you to export to parasolid files and using it is really easy; it requires only a single call to a function accessible from the UF (User Function) namespace. The only real work required is to gather the tags of the bodies to be exported into an array.

What’s a Tag?

A tag is a data type defined by NXOpen. Each object in your NX file is assigned a unique tag for identification purposes. Many of the .NET functions are ‘wrapped’ and thus the tags are largely hidden, but tags will come into play when a User Function is used.

Barebones Export Parasolid journal

' NX 7.5
' NXJournaling.com
' journal to demonstrate how to export geometry out to a parasolid file

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF

Module NXJournal
Sub Main()

Dim theSession As Session = Session.GetSession()
Dim ufs As UFSession = UFSession.GetUFSession()
Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display
Dim lw As ListingWindow = theSession.ListingWindow
Dim mySelectedObjects() As NXObject
Dim myResponse As Selection.Response

Dim tagList() As NXOpen.Tag
Dim exportFileName As String = Nothing
Dim i As Integer = 0

lw.Open()
myResponse = SelectObjects(mySelectedObjects)
If (myResponse = Selection.Response.Cancel) OrElse (myResponse = Selection.Response.Back) Then
'user canceled selection, exit journal
Exit Sub
End If

ReDim tagList(mySelectedObjects.GetUpperBound(0))
For i = 0 To mySelectedObjects.GetUpperBound(0)
tagList(i) = mySelectedObjects(i).Tag
Next

exportFileName = "C:\temp\myparasolid.x_t"
ufs.Ps.ExportData(tagList, exportFileName)

lw.Close()

End Sub

Function SelectObjects(ByRef selobj() As NXObject) As Selection.Response

'Dim selobj() As NXObject = Nothing
Dim theUI As UI = UI.GetUI
Dim prompt as String = "Select Solid Bodies"
Dim title As String = "Selection"
Dim includeFeatures As Boolean = False
Dim keepHighlighted As Boolean = False
Dim selAction As Selection.SelectionAction = _
Selection.SelectionAction.ClearAndEnableSpecific

Dim scope As Selection.SelectionScope = _
Selection.SelectionScope.AnyInAssembly
Dim selectionMask_array(0) As Selection.MaskTriple

With selectionMask_array(0)
.Type = UFConstants.UF_solid_type
.Subtype = 0
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_SOLID_BODY
End With

Dim resp As Selection.Response = _
theUI.SelectionManager.SelectObjects( _
prompt, title, scope, selAction, _
includeFeatures, keepHighlighted, _
selectionMask_array, selobj)

Return resp

End Function

End Module

The code here is pretty straightforward: it allows the user to select solid objects, reads the tags of the solids into an array, defines a string variable path to our new parasolid file, and finally calls the ExportData function to actually create the new parasolid file.
The function of note here is: ufs.Ps.ExportData(tagList, exportFileName). To successfully call the function, the first argument to pass in is an array of Tag objects (tags from the objects you’d like to export) - notice you don’t pass in the array bounds or even parentheses after the array variable, just the base array variable name. The second argument to pass in is a string (variable or literal value) that specifies the full path to the parasolid file you want to create. Do not use the ByVal or ByRef modifiers, user functions are written in a programming language that doesn’t use them; an error will occur if they are used.
On the second run of this journal you are likely to run into an error condition unless you delete the parasolid file between runs. If a file exists with the name you specified before the command runs; it will not create the file, it errors out instead. Let’s add some features to our journal to avoid the error condition and generate the parasolid file name and location based on the work part.

Improved Export Parasolid

' NX 7.5
' NXJournaling.com
' Journal allows selection of solid objects and
' exports them to a parasolid file.
' This version bases the parasolid file on the work part
' file name and location. If a parasolid file of the same name
' already exists, the journal will delete it before
' creating the new version.

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF

Module NXJournal
Sub Main()

Dim theSession As Session = Session.GetSession()
Dim ufs As UFSession = UFSession.GetUFSession()
Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display
Dim lw As ListingWindow = theSession.ListingWindow
Dim mySelectedObjects() As NXObject
Dim myResponse As Selection.Response

Dim tagList() As NXOpen.Tag
Dim exportFileName As String = Nothing
Dim i As Integer = 0

lw.Open()
myResponse = SelectObjects(mySelectedObjects)
If (myResponse = Selection.Response.Cancel) OrElse (myResponse = Selection.Response.Back) Then
'user canceled selection, exit journal
Exit Sub
End If

ReDim tagList(mySelectedObjects.GetUpperBound(0))
For i = 0 To mySelectedObjects.GetUpperBound(0)
tagList(i) = mySelectedObjects(i).Tag
Next

'return the full path of the work part
exportFileName = workPart.FullPath
'trim off ".prt" and add ".x_t"
exportFileName = exportFileName.Remove(exportFileName.Length - 4, 4) + ".x_t"
'if this file already exists, delete it
If My.Computer.FileSystem.FileExists(exportFileName) Then
My.Computer.FileSystem.DeleteFile(exportFileName)
End If

Try
ufs.Ps.ExportData(tagList, exportFileName)
Catch ex As NXException
lw.WriteLine("*** ERROR ***")
lw.WriteLine(ex.ErrorCode.ToString & " : " & ex.Message)
End Try

lw.Close()

End Sub

Function SelectObjects(ByRef selobj() As NXObject) As Selection.Response

Dim theUI As UI = UI.GetUI
Dim prompt as String = "Select Solid Bodies"
Dim title As String = "Selection"
Dim includeFeatures As Boolean = False
Dim keepHighlighted As Boolean = False
Dim selAction As Selection.SelectionAction = _
Selection.SelectionAction.ClearAndEnableSpecific

Dim scope As Selection.SelectionScope = _
Selection.SelectionScope.AnyInAssembly
Dim selectionMask_array(0) As Selection.MaskTriple

With selectionMask_array(0)
.Type = UFConstants.UF_solid_type
.Subtype = 0
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_SOLID_BODY
End With

Dim resp As Selection.Response = _
theUI.SelectionManager.SelectObjects( _
prompt, title, scope, selAction, _
includeFeatures, keepHighlighted, _
selectionMask_array, selobj)

Return resp

End Function

End Module

Download ExportParasolid.vb
This version uses the FullPath property of the work part, which returns a string indicating the - you guessed it - full path to the part object. The next line of interest does some string manipulation to remove the last 4 characters of the path, the “.prt” extension, and replaces it with the parasolid file extension. The if statement uses the “My” feature of .NET. The “My” feature provides a type of alias shortcut to get to often used resources such as the file system, computer settings, registry, user information, and the form collection among (many) other things. Finally, the ExportData function is wrapped in a Try clause just in case something else goes wrong (trying to write to a network location that you don’t have access to, for example).

Trying Times

If you are running code that errors out a lot, or you suspect it will, wrap it in a Try block. The basic structure of a Try block is:

Try
'code that may error out here
Catch myExceptionObject as Exception
'code to run if an exception occurrs
Finally
'code that runs no matter what
End Try


The catch and finally blocks are optional. Multiple catch blocks are possible and if used they work somewhat like a select case block. Order is important, place the ‘highly likely’ catch blocks first and finish with a generic catch block (like a ‘case else’ at the end of a select case structure). The finally block is a good place to do some cleanup (close open files, destroy objects no longer in use, etc). For a complete discussion of the options available in the Try block see the Microsoft Developer Network (MSDN) entry.

Conclusion

This tutorial describes and demonstrates the function used to export geometry to a new parasolid file. Along the way we used a function that allows the selection of multiple solids, learned a bit about tag objects, found the full path of the work part, did some string manipulation, briefly introduced the “My” feature of the .NET framework, and looked at handling exceptions with a Try...Catch block.

Other ideas for the export parasolid journal

  • Change the select object function to allow for selection of solid AND sheet bodies
  • Add a date/time stamp to the export file name
  • Eliminate the interactive selection and instead export all the solid bodies from layer 1
  • Read up on the .NET FolderBrowserDialog class and add a GUI interface to select the export file name and location
  • In short, take it and modify it to your workflow

Comments

Hy guys,
I found a code on eng-tips using winforms look below. The problem I do not understand because it runs into a server bussy error-any ideas
thanks in advance
' *********************************************************************************************
' Parasolid batch exporter written for NX6
' V0.02 - 2010-05
' Petulf
' *********************************************************************************************
' Uses windows forms to create a UI and the ufs.Ps.ExportData(tags, filename) function to create the parasolid file
' The ASM parsing text field is used to filter the part files ex)
' typing cylinder in the text field will convert all .prt files with cylinder in their name.
' *********************************************************************************************
' Can be run from within NX as a journal or started from the command line
' c:\NX6\UGII\run_journal.exe psBatchExport.vb
' *********************************************************************************************

Imports System
Imports System.Windows.Forms
Imports System.IO
Imports System.Collections.Generic
Imports System.Drawing
Imports System.Threading

Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies

Public Class psBatchExport
    Public Shared thePsBatchExport As psBatchExport = Nothing
    Public Sub New()
    End Sub

    Public Shared Sub Main(ByVal args As String())
        ' Singleton
        thePsBatchExport = New psBatchExport

        ' Launch the windows form class
        Dim f As New BatchExportForm
        Application.Run(f)
    End Sub
End Class

#Region "Parasolid and File management"
Public Class ExportParasolid
    Dim theSession As Session = Session.GetSession
    Dim ufs As UFSession = UFSession.GetUFSession

    Public Function Export(ByVal file As String) As Boolean

        Dim loadStatus As PartLoadStatus = Nothing
        Dim currentPart As Part = Nothing
        Dim bodyTags As List(Of Tag) = Nothing
        Dim tags(-1) As NXOpen.Tag
        Dim exportFileName As String = Nothing

        ' Open the part, if all ready open set as displaypart
        Try
            currentPart = theSession.Parts.OpenDisplay(file, loadStatus)
        Catch ex As Exception
            If ex.Message = "File already exists" Then
                For Each partItem As Part In theSession.Parts
                    If partItem.FullPath = file Then
                        currentPart = partItem
                        theSession.Parts.SetDisplay(currentPart, False, False, loadStatus)
                        Exit For
                    End If
                Next
            End If
        End Try

        ' Fetch the sheet and solidbody tags from the part file.
        Try
            Dim tagsList As List(Of Tag) = GetBodyTagsInPart(currentPart)
            tagsList.AddRange(GetBodyTagsInAsm(currentPart.ComponentAssembly.RootComponent))
            tags = tagsList.ToArray()
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

        ' Export the bodies
        Try
            If tags.Length > 0 Then
                exportFileName = file.Remove(file.Length - 4, 4) + ".x_t"
                If IO.File.Exists(exportFileName) Then
                    IO.File.Delete(exportFileName)
                End If
                ufs.Ps.ExportData(tags, exportFileName)
                currentPart.Close(BasePart.CloseWholeTree.True, BasePart.CloseModified.UseResponses, Nothing)
                Return True
            End If
            currentPart.Close(BasePart.CloseWholeTree.True, BasePart.CloseModified.UseResponses, Nothing)
        Catch ex As Exception
        End Try
        Return False
    End Function

    ' Recursive function to retrive all components occurence body tags.
    Private Function GetBodyTagsInAsm(ByVal c As Component) As List(Of Tag)
        Dim componentTagList As New List(Of Tag)
        If c Is Nothing Then
            Return componentTagList
        End If

        Dim children As Component() = c.GetChildren()
        For Each child As Component In children
            If Not child.IsSuppressed Then
                For Each bodyItem As Body In CType(child.Prototype, Part).Bodies
                    Dim tmpNXObject As NXObject = child.FindOccurrence(bodyItem)
                    If Not tmpNXObject Is Nothing Then
                        componentTagList.Add(CType(tmpNXObject, Body).Tag)
                    End If
                Next
                componentTagList.AddRange(GetBodyTagsInAsm(child))
            End If
        Next
        Return componentTagList
    End Function

    Private Function GetBodyTagsInPart(ByRef thePart As Part) As List(Of Tag)
        Dim bodyTags As New List(Of Tag)
        For Each bodyItem As Body In thePart.Bodies
            bodyTags.Add(bodyItem.Tag)
        Next
        Return bodyTags
    End Function
End Class

Public Class FilesManager
    Private _directoryPath As String = ""
    Private _files As String()

    Public Property DirectoryPath() As String
        Get
            Return _directoryPath
        End Get
        Set(ByVal value As String)
            If IO.Directory.Exists(value) Then
                _directoryPath = value
            End If
        End Set
    End Property

    Private _filterString As String = "*.prt"

    Public Property FilterString() As String
        Get
            Return _filterString
        End Get
        Set(ByVal value As String)
            If value <> "" Then
                _filterString = "*" + value + "*.prt"
            Else
                _filterString = "*.prt"
            End If

        End Set
    End Property

    Public ReadOnly Property Files() As String()
        Get
            If DirectoryPath <> "" Then
                _files = System.IO.Directory.GetFiles(DirectoryPath, FilterString)
                Return _files
            Else
                Return Nothing
            End If
        End Get
    End Property
End Class

#End Region

Public Class BatchExportForm
    Inherits System.Windows.Forms.Form

    Dim theFilesManager As New FilesManager
    Dim theExporter As New ExportParasolid

#Region "Threaded openFolderBrowser"
    ' This class is needed to ensure the folderbrowser is a STA thread, as a work around from running
    ' the jorunal in batch mode.
    Private Class OpenFolderBrowserHelper
        Private Shared _selectedFolder As String = ""

        Public Shared Function OpenFolderBrowser() As String
            Dim newThread As New Thread(New ThreadStart(AddressOf ThreadedFolderBrowser))
            newThread.SetApartmentState(ApartmentState.STA)
            newThread.Start()
            newThread.Join()
            newThread.Abort()
            Return _selectedFolder
        End Function

        Private Shared Sub ThreadedFolderBrowser()
            Dim folderBrowserDialog As New FolderBrowserDialog
            folderBrowserDialog.Description = "Select Part File Directory"
            folderBrowserDialog.ShowNewFolderButton = False
            folderBrowserDialog.RootFolder = Environment.SpecialFolder.MyComputer
            If folderBrowserDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
                _selectedFolder = folderBrowserDialog.SelectedPath
            End If
            folderBrowserDialog.Dispose()
            folderBrowserDialog = Nothing
        End Sub
    End Class
#End Region

    Private Sub BrowseButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BrowseButton.Click
        PathTextBox.Text = OpenFolderBrowserHelper.OpenFolderBrowser()
        ValidateTextBoxPath()
    End Sub

    '' <summary>
    '' Main form loop, handles part conversion and updating of the exportlog textlist.
    '' </summary>
    '' <param name="sender"></param>
    '' <param name="e"></param>
    '' <remarks></remarks>
    Private Sub ExportButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExportButton.Click
        theFilesManager.FilterString = FilterTextBox.Text

        If ValidateTextBoxPath() Then

            For Each file As String In theFilesManager.Files
                If theExporter.Export(file) Then
                    ExportLog.Items.Add("Succesfully exported " + file)
                Else
                    ExportLog.Items.Add("Failed to export " + file)
                End If
                LogDown()
            Next
            ExportLog.Items.Add("Export finished")
            LogDown()
        End If

    End Sub

    Private Sub PathTextBox_Validating(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles PathTextBox.Validating
        ValidateTextBoxPath()
    End Sub

    Private Sub PathTextBox_KeyDown(ByVal sender As System.Object, ByVal e As KeyEventArgs) Handles PathTextBox.KeyDown
        If e.KeyCode = Keys.Enter Then
            ValidateTextBoxPath()
        End If
    End Sub

    Private Function ValidateTextBoxPath() As Boolean
        theFilesManager.DirectoryPath = PathTextBox.Text
        If theFilesManager.DirectoryPath = "" Then
            ErrorProvider1.SetError(PathTextBox, "Path is not valid")
            Return False
        Else
            ErrorProvider1.SetError(PathTextBox, "")
            Return True
        End If
    End Function

    ' Method that scrolls down the listbox
    Private Sub LogDown()
        ExportLog.SelectedIndex = ExportLog.Items.Count - 1
        ExportLog.SelectedIndex = -1
    End Sub

    ' Enables copying from the listbox to the clipboard
    Private Sub ExportLog_Copy(ByVal sender As System.Object, ByVal e As KeyEventArgs) Handles ExportLog.KeyDown
        If e.Control And e.KeyCode = Keys.C Then
            Try
                Dim clipBoardString As String = ""
                For Each selectedItem As String In ExportLog.SelectedItems
                    clipBoardString += selectedItem + vbCrLf
                Next
                Clipboard.SetText(clipBoardString)
            Catch ex As Exception
            End Try
        End If
    End Sub

    Public Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()
    End Sub

#Region "Windows Form"

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container
        Me.ExportButton = New System.Windows.Forms.Button
        Me.BrowseButton = New System.Windows.Forms.Button
        Me.FilterTextBox = New System.Windows.Forms.TextBox
        Me.PathTextBox = New System.Windows.Forms.TextBox
        Me.Label1 = New System.Windows.Forms.Label
        Me.Label2 = New System.Windows.Forms.Label
        Me.ErrorProvider1 = New System.Windows.Forms.ErrorProvider(Me.components)
        Me.ExportLog = New System.Windows.Forms.ListBox
        CType(Me.ErrorProvider1, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'ExportButton
        '
        Me.ExportButton.Location = New System.Drawing.Point(536, 274)
        Me.ExportButton.Name = "ExportButton"
        Me.ExportButton.Size = New System.Drawing.Size(76, 23)
        Me.ExportButton.TabIndex = 0
        Me.ExportButton.Text = "Export"
        Me.ExportButton.UseVisualStyleBackColor = True
        '
        'BrowseButton
        '
        Me.BrowseButton.Location = New System.Drawing.Point(536, 70)
        Me.BrowseButton.Name = "BrowseButton"
        Me.BrowseButton.Size = New System.Drawing.Size(75, 23)
        Me.BrowseButton.TabIndex = 1
        Me.BrowseButton.Text = "Browse"
        Me.BrowseButton.UseVisualStyleBackColor = True
        '
        'FilterTextBox
        '
        Me.FilterTextBox.Location = New System.Drawing.Point(12, 25)
        Me.FilterTextBox.Name = "FilterTextBox"
        Me.FilterTextBox.Size = New System.Drawing.Size(495, 20)
        Me.FilterTextBox.TabIndex = 2
        Me.FilterTextBox.Text = "ASM"
        '
        'PathTextBox
        '
        Me.PathTextBox.Location = New System.Drawing.Point(12, 72)
        Me.PathTextBox.Name = "PathTextBox"
        Me.PathTextBox.Size = New System.Drawing.Size(495, 20)
        Me.PathTextBox.TabIndex = 3
        Me.PathTextBox.Text = "c:\"
        '
        'Label1
        '
        Me.Label1.AutoSize = True
        Me.Label1.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Label1.Location = New System.Drawing.Point(9, 9)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(139, 13)
        Me.Label1.TabIndex = 4
        Me.Label1.Text = "Assembly parsing string"
        '
        'Label2
        '
        Me.Label2.AutoSize = True
        Me.Label2.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Label2.Location = New System.Drawing.Point(9, 56)
        Me.Label2.Name = "Label2"
        Me.Label2.Size = New System.Drawing.Size(58, 13)
        Me.Label2.TabIndex = 5
        Me.Label2.Text = "Directory"
        '
        'ErrorProvider1
        '
        Me.ErrorProvider1.ContainerControl = Me
        '
        'ExportLog
        '
        Me.ExportLog.FormattingEnabled = True
        Me.ExportLog.Location = New System.Drawing.Point(12, 98)
        Me.ExportLog.Name = "ExportLog"
        Me.ExportLog.ScrollAlwaysVisible = True
        Me.ExportLog.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended
        Me.ExportLog.Size = New System.Drawing.Size(495, 199)
        Me.ExportLog.TabIndex = 6
        '
        'BatchExport
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(623, 309)
        Me.Controls.Add(Me.ExportLog)
        Me.Controls.Add(Me.Label2)
        Me.Controls.Add(Me.Label1)
        Me.Controls.Add(Me.PathTextBox)
        Me.Controls.Add(Me.FilterTextBox)
        Me.Controls.Add(Me.BrowseButton)
        Me.Controls.Add(Me.ExportButton)
        Me.Name = "BatchExport"
        Me.Text = "NX - Batch Export Parasolid"
        CType(Me.ErrorProvider1, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)
        Me.PerformLayout()

    End Sub

    Friend WithEvents ExportButton As System.Windows.Forms.Button
    Friend WithEvents BrowseButton As System.Windows.Forms.Button
    Friend WithEvents FilterTextBox As System.Windows.Forms.TextBox
    Friend WithEvents PathTextBox As System.Windows.Forms.TextBox
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents Label2 As System.Windows.Forms.Label
    Friend WithEvents ErrorProvider1 As System.Windows.Forms.ErrorProvider
    Friend WithEvents ExportLog As System.Windows.Forms.ListBox

#End Region

End Class
 
 

That journal makes use of "threading" for the folder selection box. If/when that "error" message box pops up, press "retry" and activate the form for the journal (it appears as "NX - Batch Export Parasolid" in your taskbar), it will allow you to continue using it to finish the export.
 
I don't know enough about threading to fix this hiccup, but it appears that it is not a show-stopper.

How can i add the option to choose specific folder during export and to use DB_PART_NO and DB_PART_REV as the part names when NX is integrated with TC?

NXJournaling
During Export Parasolid files ( using File->Export->Parasolid) you can choice version which parasolid have to be save e.g. 27.0 - NX 10.0; 26.0 - NX 9; ...; 16.0 - NX3.0 ....
For which version is Exporting in the above journal? I guess that to version which journal is running. It's mean that when journal is run in e.g. NX10 than exporting parasolid file will be in the same version. Is it? I bring this up because I need to send parasolid files in older version (16.0 - NX 3). Is it possible to add export parasolid version to journal?
Thanks
Marcin

Below is a simple subroutine to export a parasolid file to a specific parasolid version. The "PsVersion" argument is an integer; to export a version 27.0, pass in 270 (26.0 -> 260, 16.0 -> 160, etc etc).

Sub PsExport(ByVal theBodies As List(Of Body), ByVal PsVersion As Integer, ByVal exportFileName As String)

'parasolid export
Dim exportTags(theBodies.Count - 1) As NXOpen.Tag
For i As Integer = 0 To theBodies.Count - 1
exportTags(i) = theBodies.Item(i).Tag
Next

Dim numUnexported As Integer

Try
theUfSession.Ps.ExportLinkedData(exportTags, exportTags.Length, exportFileName, PsVersion, Nothing, numUnexported, Nothing)

Catch ex As NXException
MsgBox(ex.Message)

End Try

End Sub

Thanks. I would like to paste it in your "Improved Export Parasolid" journal - your second journal of this post. (it is my mistake because I not defined which journal I mean). Is this subroutine fit to this journal?

For Your code I added"

Imports System.Collections.Generic
Sub PsExport(ByVal theBodies As List(Of Body), ByVal PsVersion As Integer, ByVal exportFileName As String)

Dim theUfSession As UFSession = UFSession.GetUFSession()

'parasolid export
Dim exportTags(theBodies.Count - 1) As NXOpen.Tag
PsVersion = 160
For i As Integer = 0 To theBodies.Count - 1
exportTags(i) = theBodies.Item(i).Tag
Next

Dim numUnexported As Integer

Try
theUfSession.Ps.ExportLinkedData(exportTags, exportTags.Length, exportFileName, PsVersion, Nothing, numUnexported, Nothing)

Catch ex As NXException
MsgBox(ex.Message)

End Try

End Sub

So when I paste this code to your "Improved Export Parasolid" journal - your second journal of this post, I receive export parasolid file in 16.0 - NX 3.0 version. Correct?

Thanks for advice.

The subroutine in my previous post was taken from a different, unpublished journal that I have. It can be made to work with the journal in the article above, but it will require more than a "copy & paste" job.

The code below integrates the subroutine with the main code.

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF

Module Module2
Sub Main()

Dim theSession As Session = Session.GetSession()
Dim ufs As UFSession = UFSession.GetUFSession()
Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display
Dim lw As ListingWindow = theSession.ListingWindow
Dim mySelectedObjects() As NXObject
Dim myResponse As Selection.Response

Dim tagList() As NXOpen.Tag
Dim exportFileName As String = Nothing
Dim i As Integer = 0

lw.Open()
myResponse = SelectObjects(mySelectedObjects)
If (myResponse = Selection.Response.Cancel) OrElse (myResponse = Selection.Response.Back) Then
'user canceled selection, exit journal
Exit Sub
End If

ReDim tagList(mySelectedObjects.GetUpperBound(0))
For i = 0 To mySelectedObjects.GetUpperBound(0)
tagList(i) = mySelectedObjects(i).Tag
Next

'return the full path of the work part
exportFileName = workPart.FullPath
'trim off ".prt" and add ".x_t"
exportFileName = exportFileName.Remove(exportFileName.Length - 4, 4) & ".x_t"
'if this file already exists, delete it
If My.Computer.FileSystem.FileExists(exportFileName) Then
My.Computer.FileSystem.DeleteFile(exportFileName)
End If

Try
PsExport(tagList, 160, exportFileName)
Catch ex As NXException
lw.WriteLine("*** ERROR ***")
lw.WriteLine(ex.ErrorCode.ToString & " : " & ex.Message)
End Try

lw.Close()

End Sub

Sub PsExport(ByVal bodyTags() As Tag, ByVal PsVersion As Integer, ByVal exportFileName As String)

Dim theUfSession As UFSession = UFSession.GetUFSession()

'parasolid export

Dim numUnexported As Integer

Try
theUfSession.Ps.ExportLinkedData(bodyTags, bodyTags.Length, exportFileName, PsVersion, Nothing, numUnexported, Nothing)

Catch ex As NXException
MsgBox(ex.Message)

End Try

End Sub

Function SelectObjects(ByRef selobj() As NXObject) As Selection.Response

Dim theUI As UI = UI.GetUI
Dim prompt As String = "Select Solid Bodies"
Dim title As String = "Selection"
Dim includeFeatures As Boolean = False
Dim keepHighlighted As Boolean = False
Dim selAction As Selection.SelectionAction = _
Selection.SelectionAction.ClearAndEnableSpecific

Dim scope As Selection.SelectionScope = _
Selection.SelectionScope.AnyInAssembly
Dim selectionMask_array(0) As Selection.MaskTriple

With selectionMask_array(0)
.Type = UFConstants.UF_solid_type
.Subtype = 0
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_SOLID_BODY
End With

Dim resp As Selection.Response = _
theUI.SelectionManager.SelectObjects( _
prompt, title, scope, selAction, _
includeFeatures, keepHighlighted, _
selectionMask_array, selobj)

Return resp

End Function

End Module