' *********************************************************************************************
' 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