Convert Part Units

Time to change teams

Have you ever needed to convert the units (inches to millimeters or vice versa) of the part you are working on? If so, you probably already know about the utility program, ug_convert_part.exe. For those not yet familiar, ug_convert_part.exe will convert the units of a single part, an entire assembly, or an entire directory of parts (with optional sub-directories), overwriting the originals or creating copies in a folder you specify. Suffice it to say that it has all of your part unit conversion needs covered. But... It is a command line interface (CLI) program. You'll have to type in all the commands you want it to execute, making sure to follow the syntax it expects. Did you make a typo in the argument list? At best, it will give you an error message and won't run; at worst, it will run with an option you didn't intend, possibly overwriting multiple files.

The graphical user interface (GUI) has spoiled us. Even seasoned users tend to be intimidated by CLI programs, especially those used infrequently. But with the power of some journal code, we can tame the CLI program to do our bidding while simultaneously making it user friendly.

The code below will use the utility ug_convert_part.exe to do what is perhaps the most common operation: convert the part units of a given part and overwrite the file. The code operates on the current work part (actually, it works best if the desired part is both the work and displayed part). As a precaution, a copy of the part will be placed in your temp directory (just in case).

The limitations of this version are:

  • only works on a piece part - if the part has one or more components, a message will display and the journal will exit.
  • only works on the native NX filesystem. It will not work with Teamcenter or other PDM/PLM system that stores your files in a database. If Teamcenter is detected, a warning message will appear and the journal will exit.

'NXJournaling.com
'May 13, 2013
'
'journal to convert the units of the work part, native NX filesystem only
'journal closes the work part and calls ug_convert_part, reports success/failure, and reopens the part
'
'changelog:
'  June 5, 2013 - bugfix: target units assigned incorrectly
 
Option Strict Off
Imports System
Imports System.Diagnostics
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies
 
Module Module1
 
    Sub Main()
 
        Dim theSession As Session = Session.GetSession()
        Dim ufs As UFSession = UFSession.GetUFSession
        Dim theUISession As UI = UI.GetUI
        Dim workPart As Part = theSession.Parts.Work
        Dim partPath As String = workPart.FullPath
        Dim partName As String = System.IO.Path.GetFileName(partPath)
        Dim copyPart As String = System.IO.Path.Combine(System.IO.Path.GetTempPath, partName)
 
        Dim lw As ListingWindow = theSession.ListingWindow
        lw.Open()
 
        Dim IsTcEng As Boolean = False
        ufs.UF.IsUgmanagerActive(IsTcEng)
        If IsTcEng Then
            theUISession.NXMessageBox.Show("Native NX only", NXMessageBox.DialogType.Information, "This journal only works in native NX")
            Exit Sub
        End If
 
        'lw.WriteLine("user: " & Environment.UserName)
        'lw.WriteLine("part path: " & partPath)
        lw.WriteLine("part name: " & partName)
        'lw.WriteLine("copy destination: " & copyPart)
        lw.WriteLine("current part units: " & workPart.PartUnits.ToString)
 
        Dim targetUnits As String = ""
        Dim unitArg As String = ""
        If workPart.PartUnits = BasePart.Units.Millimeters Then
	    targetUnits = "inch"
            unitArg = " -in "
        Else
            targetUnits = "metric"
            unitArg = " -mm "
        End If
 
        Dim rm As RemoteUtilities = RemoteUtilities.GetRemoteUtilities()
        Dim convertPath As String = rm.GetEnvironmentVariable("UGII_ROOT_DIR") & "ug_convert_part.exe"
        'lw.WriteLine("UGII_ROOT_DIR: " & convertPath)
 
        Dim c As ComponentAssembly = workPart.ComponentAssembly
        If Not IsNothing(c.RootComponent) Then
            lw.WriteLine("Assemblies not supported in this version, journal exiting")
            Return
        Else
            lw.WriteLine("Part has no components, units will be converted")
        End If
 
        Dim response As Integer
        response = theUISession.NXMessageBox.Show("Convert Units?", NXMessageBox.DialogType.Question, "Convert part to " & targetUnits & " units?")
        '1 = Yes
        '2 = No
 
        If response = 2 Then
            Return
        End If
 
        If ufs.Part.IsModified(workPart.Tag) Then
            response = theUISession.NXMessageBox.Show("Save?", NXMessageBox.DialogType.Question, "Save part before closing?")
 
            If response = 1 Then
                'save and close
                Dim partSaveStatus1 As PartSaveStatus
                partSaveStatus1 = workPart.Save(BasePart.SaveComponents.True, BasePart.CloseAfterSave.False)
                partSaveStatus1.Dispose()
                workPart.Close(BasePart.CloseWholeTree.True, BasePart.CloseModified.UseResponses, Nothing)
                workPart = Nothing
 
            Else
                'just close
                Dim markId1 As Session.UndoMarkId
                markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Close Part")
                workPart.Close(BasePart.CloseWholeTree.True, BasePart.CloseModified.UseResponses, Nothing)
                workPart = Nothing
                'UF_UNDO_delete_all_marks
            End If
 
        Else
            'just close
            Dim markId1 As Session.UndoMarkId
            markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Close Part")
            workPart.Close(BasePart.CloseWholeTree.True, BasePart.CloseModified.UseResponses, Nothing)
            workPart = Nothing
            'UF_UNDO_delete_all_marks
        End If
 
        'save backup copy to temp folder before conversion
        Dim tempPath As String = System.IO.Path.GetTempPath
        My.Computer.FileSystem.CopyFile(partPath, copyPart, True)
 
        'tell user about backup copy
        theUISession.NXMessageBox.Show("Backup Created", NXMessageBox.DialogType.Information, "A backup file has been saved to: " & copyPart)
 
        Dim conversionSuccess As Boolean = False
 
        Try
 
            Dim convertProcess As New Process
 
            Dim myStartInfo As New ProcessStartInfo
            myStartInfo.UseShellExecute = False
            myStartInfo.CreateNoWindow = True
            myStartInfo.FileName = """" & convertPath & """" & unitArg & """" & partPath & """"
            myStartInfo.RedirectStandardOutput = True
            myStartInfo.RedirectStandardError = True
 
            convertProcess.StartInfo = myStartInfo
            convertProcess.Start()
 
            Dim std_out As IO.StreamReader = convertProcess.StandardOutput()
            Dim std_err As IO.StreamReader = convertProcess.StandardError()
 
            Dim stdOutput As String = std_out.ReadToEnd
            Dim stdLines() As String = stdOutput.Split(ControlChars.CrLf)
 
            For Each Line As String In stdLines
                If Line.ToUpper.Contains("SUCCESS") Then
                    conversionSuccess = True
                End If
                'lw.WriteLine(Line)
            Next
 
            Dim stdError As String = std_err.ReadToEnd
            If Not String.IsNullOrEmpty(stdError) Then
                lw.WriteLine("")
                lw.WriteLine("stdErr:")
                For Each Line As String In stdError
                    lw.WriteLine(Line)
                Next
            End If
 
            std_out.Close()
            std_err.Close()
            convertProcess.Close()
 
        Catch ex As Exception
 
            lw.WriteLine("Error with ug_convert_part.exe")
            lw.WriteLine(ex.GetType.ToString & " : " & ex.Message)
 
        End Try
 
        If conversionSuccess Then
            theUISession.NXMessageBox.Show("Success", NXMessageBox.DialogType.Information, "File converted successfully, reopening file")
        Else
            theUISession.NXMessageBox.Show("Failure", NXMessageBox.DialogType.Information, "File failed to convert, reopening file")
        End If
 
        Dim basePart1 As BasePart
        Dim partLoadStatus1 As PartLoadStatus
        basePart1 = theSession.Parts.OpenBaseDisplay(partPath, partLoadStatus1)
 
        workPart = theSession.Parts.Work
        partLoadStatus1.Dispose()
 
    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 Module

Conclusion

You can create a custom menu item and/or toolbar button to give your users one click access to part conversion. Or, if you need to convert entire assemblies or directories of parts, use the code as a guide and add in your desired options.

Happy coding!

Comments

I found and fixed a bug today. The target units were being assigned incorrectly (the journal would have tried to convert a metric part to metric units instead of inch units). If you have downloaded the previous code, please delete it and download this updated journal.

This code no longer works in NX 11.0

I get this error message;

Part name: BC14_BC-14.step_2017-01-10_HG.prt
Current part units: Millimeters
Part has no components, units will be converted
Error with ug_convert_part.exe
System.ComponentModel.Win32Exception: The specified file could not be found (The specified file can not be found)

I believe the error occurs on line 114 and the following

I thought the error could come from framemework, so I installed the 4.6.1 framework and the error still occurs.

You can help me ?

Sorry for my English, I'm French

Patrick

Pat

I do not have NX 11 fully up and running (yet), but I have heard that they moved many of the utilities into a subfolder named "NXBIN". The easy way to get this journal working again would be to find the "ug_convert_part.exe" file in the NX 11 install directory then change the following line of code to point to the new location.

change this:

Dim convertPath As String = rm.GetEnvironmentVariable("UGII_ROOT_DIR") & "ug_convert_part.exe"

to point to your NX 11 location; something like:

Dim convertPath As String =  "C:\Program Files\Siemens\NX 11.0\NXBIN\ug_convert_part.exe"

I'll post updated code when I get NX 11 installed and running.

Thanks for your help, it works!

Has anyone made a code to convert a complete assembly? It would be super useful !!!

Pat

If you are a member of the Siemens community site, the following thread has some utilities (near the end of the thread) that make using "ug_convert_part" easier.

https://community.plm.automation.siemens.com/t5/NX-Design-Forum/Easier-u...

I'm looking for a command (.exe) that I can use to know what is the measurement unit of an nx (.prt) component...a command like ug_inspect.exe. I want to know from the Windows explorer if a component is IN or MM without starting NX.

I want to add a key in the registry (REGEDIT) to add a shortcut in my right button menu when I click on a .prt file in Windows explorer.

Example similar to what I want to do (NX11.0 not NX10.0);

******************************************************************
reg.exe add "HKEY_CLASSES_ROOT\UGpartfile\shell\NX Part Version\command" /t reg_sz /d "cmd.exe /s/c \" @\"%UGII_BASE_DIR%\nxbin\ug_inspect.exe\" -release \"%%1\" ^& pause \" " /f

REG ADD "HKCR\UGpartfile\shell\NX Convert to mm\command" /t reg_sz /d "cmd.exe /s/c \" @\"%UGII_BASE_DIR%\nxbin\ug_convert_part.exe\" -mm \"%%1\" ^& pause \" " /f

REG ADD "HKCR\UGpartfile\shell\NX Convert to Inches\command" /t reg_sz /d "cmd.exe /s/c \" @\"%UGII_BASE_DIR%\nxbin\ug_convert_part.exe\" -in \"%%1\" ^& pause \" " /f
******************************************************************

But, this command should be able to be used from the command prompt of nx (DOS).

Pat

Below is a VBScript that uses ug_inspect to find the units of the specified part file. You should be able to adapt it to your needs. I tested it with NX 9; it does not reference the "NXBIN" folder. Copy & paste the code into a plain text file and name it with the extension ".vbs". You can call the script from the command line {script name}.vbs "path to your part file", or drag & drop a part file onto the script file to process it (report the units in a message box).

'NX part file version
 
Set objFSO = CreateObject("Scripting.FileSystemObject")
 
If Not objFSO.FileExists(WScript.Arguments(0)) Then
	wscript.echo("Invalid file")
	wscript.quit
End If
 
 
Set objShell = CreateObject( "WScript.Shell" )
Set objEnv = objShell.Environment("Process")
 
	strProgramPath = objEnv("UGII_ROOT_DIR") & "ug_inspect.exe"
 
	Set objWshScriptExec = objShell.Exec(strProgramPath & " " & chr(34) & WScript.Arguments(0) & chr(34))
 
	lineTest = "Part units: "
	'create object to catch external program's output
	Set objStdOut = objWshScriptExec.StdOut
	Do While Not objStdOut.AtEndOfStream
		strLineTest = objStdOut.ReadLine
		pos = instr(strLineTest, lineTest)
		if pos > 0 then
			units = Right(strLineTest, Len(strLineTest) - Len(lineTest))
		end if
	Loop
	wscript.echo("units: " & units)

To add commands to the right mouse button for windows explorer ... You dont need to start nx to use these commands !!!

Procedure.....

First;
Create a "AddToRightClicMenu.bat" file, that will add to the Windows registry database the information needed to add commands to the right mouse button from windows explorer for a .prt file only.
- Convert part Inches to Metric.
- Convert part Metric to Inches.
- Infos Units (Inches or Metric).
- NX version... In which version of nx the file was saved.

In the "AddToRightClicMenu.bat" file, you will need to adjust the "Info_Units.vbs" path... for me it's (C:\Temp_NX\SettingNX\NX11.0\Start_NX11.0\Info_Units.vbs\).

You need to adjust the following line code in "AddToRightClicMenu.bat"... adjust the path: REG ADD "HKCR\UGpartfile\shell\NX Info Units\command" /t reg_sz /d "cmd.exe /s/c \" @\"C:\Temp_NX\SettingNX\NX11.0\Start_NX11.0\Info_Units.vbs\" \"%%1\"

AddToRightClicMenu.bat ----------you need to create this file.... with the note pad ----------------------------------
@echo off
:: (c) 2017 Patrick
::
:: Ce script ajoute des commandes de conversion de fichiers NX dans le menu contextuel ainsi
:: que la version de NX installé et les informations d'un assemblage.
::
setlocal ENABLEDELAYEDEXPANSION
echo;
echo Ajout de la commande "NX Assy Info"
echo;
REG ADD "HKEY_CLASSES_ROOT\UGpartfile\shell\NX Assy Info\command" /t reg_sz /d "cmd.exe /s/c \" @\"%UGII_BASE_DIR%\nxbin\ugpc.exe\" -s -a \"%%1\" ^& pause \" " /f
echo;
echo Ajout de la commande "NX Version"
echo;
REG ADD "HKEY_CLASSES_ROOT\UGpartfile\shell\NX Part Version\command" /t reg_sz /d "cmd.exe /s/c \" @\"%UGII_BASE_DIR%\nxbin\ug_inspect.exe\" -release \"%%1\" ^& pause \" " /f
echo;
echo Ajout de la commande "NX Convert Units - Metric"
echo;
REG ADD "HKCR\UGpartfile\shell\NX Convert to Metric\command" /t reg_sz /d "cmd.exe /s/c \" @\"%UGII_BASE_DIR%\nxbin\ug_convert_part.exe\" -mm \"%%1\" ^& pause \" " /f
echo;
echo Ajout de la commande "NX Convert Units - Inches"
echo;
REG ADD "HKCR\UGpartfile\shell\NX Convert to Inches\command" /t reg_sz /d "cmd.exe /s/c \" @\"%UGII_BASE_DIR%\nxbin\ug_convert_part.exe\" -in \"%%1\" ^& pause \" " /f
echo;
echo Ajout d'un racoucci de pour connaitre si une composante NX est corrompu
echo;
REG ADD "HKCR\UGpartfile\shell\NX Corrupted Part\command" /t reg_sz /d "cmd.exe /s/c \" @\"%UGII_BASE_DIR%\nxbin\ug_inspect.exe\" -scan \"%%1\" ^& pause \" " /f
echo;
echo Ajout d'un racoucci pour connaitre l'unitee de mesure d'une composante NX
echo;
REG ADD "HKCR\UGpartfile\shell\NX Info Units\command" /t reg_sz /d "cmd.exe /s/c \" @\"C:\Temp_NX\SettingNX\NX11.0\Start_NX11.0\Info_Units.vbs\" \"%%1\"
echo;
:EOF
pause
---------------------------------------------------------------------------------------------------

Secondly;
Create a "Info_Units.vbs" file that you will save to your computer.

In the Info_Units.vbs file, you will need to adjust the following line to specify where is saved "ug_inspect.exe"... for me it's(C:\Siemens\NX11.0\NXBIN\ug_inspect.exe)
In NX10 and lower = ug_inspect.exe it's in UGII
In NX11 = ug_inspect.exe it's in NXBIN

You need to adjust the following line code in "Info_Units.vbs"... adjust the path: strProgramPath = "C:\Siemens\NX11.0\NXBIN\ug_inspect.exe"

Info_Units.vbs ----------you need to create this file.... with the note pad ----------------------------------
'NX part file version

Set objFSO = CreateObject("Scripting.FileSystemObject")

If Not objFSO.FileExists(WScript.Arguments(0)) Then
wscript.echo("Invalid file")
wscript.quit
End If

Set objShell = CreateObject( "WScript.Shell" )
Set objEnv = objShell.Environment("Process")

strProgramPath = "C:\Siemens\NX11.0\NXBIN\ug_inspect.exe"

Set objWshScriptExec = objShell.Exec(strProgramPath & " " & chr(34) & WScript.Arguments(0) & chr(34))

lineTest = "Part units: "
'create object to catch external program's output
Set objStdOut = objWshScriptExec.StdOut
Do While Not objStdOut.AtEndOfStream
strLineTest = objStdOut.ReadLine
pos = instr(strLineTest, lineTest)
if pos > 0 then
units = Right(strLineTest, Len(strLineTest) - Len(lineTest))
end if
Loop
wscript.echo ("Unité: " & units)
WScript.Quit
---------------------------------------------------------------------------------------------------

Enjoy !!!

Pat