Change Expression Units

The expression system in NX is "'unit aware" and can correctly handle a wide variety of unit types. This can make life easier since the designer no longer has to worry about unit conversions when creating expressions. Create a new length expression using units of centimeters, add an existing expression defined in inches to another defined in millimeters and you get the correct length expressed in centimeters.




This feature is a great way to reduce mistakes and capture design intent; however, it can also cause a few headaches. The company I work for recently contracted out some modeling work and we forgot to specify that we like to work in imperial units. We used ug_convert_part.exe to convert the part's base units so the files would play nice in our assemblies. Editing existing sketches prompted for dimensions in mm. I was a bit surprised to learn that interactive NX would not allow you to change an existing expression's units. As an alternative, I showed my coworker how to enter values such as "2.5in" so the input would be interpreted as inches, but this wasn't to his liking and he ended up remodeling the entire part. This struck me as a colossal waste of time and I started looking for ways to use NXOpen to convert the units of expressions. The result is the journal below.



Usage Notes

The journal, in its current form, will only convert length expressions from inch to mm (or vice-versa). If you need to convert expressions defined in other units such as feet or centimeters or if you need to convert expressions of area or volume; the journal will need to be modified for your requirements.

The journal will attempt to convert all length expressions defined as inch or mm. If you want to selectively convert certain expressions, again, the journal will need to be modified for your use.

There are several "writeline" statements that I used during testing to examine the output. Uncomment some or all of these if you would like to see a "report" of sorts.

The code was tested with NX 7.5 and should run on newer versions. It may even run on older versions, but I have not tested this.



WARNING

Use the code at your own risk. Create a back up of your file before running the code. Nothing bad has happened during my testing, but I cannot claim to have tested every possibility. Should you find a bug, please contact me with a test file or procedure to reproduce it; email to info@nxjournaling.com





'NXJournaling.com
'January 14, 2014
'convert expressions with length units to part base units
'operates on the current work part

Option Strict Off
Imports System
Imports NXOpen

Module Module1

Sub Main()

Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work

If IsNothing(workPart) Then
'active part required
Return
End If

Dim lw As ListingWindow = theSession.ListingWindow
lw.Open()

Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Convert Expression Units")

Dim myUnit As Unit
myUnit = workPart.UnitCollection.GetBase("length")

'lw.WriteLine("part base length unit: " & myUnit.Abbreviation)
'lw.WriteLine("")

Dim unitsToConvert As String = ""
If workPart.PartUnits = BasePart.Units.Inches Then
unitsToConvert = "mm"
Else
unitsToConvert = "in"
End If

'lw.WriteLine("expression units to convert: " & unitsToConvert)
'lw.WriteLine("")

For Each myExp As Expression In workPart.Expressions
'lw.WriteLine("name: " & myExp.Name)
'lw.WriteLine("equation: " & myExp.Equation)
'lw.WriteLine("rhs: " & myExp.RightHandSide)
'lw.WriteLine("type: " & myExp.Type)
'Try
' If Not IsNothing(myExp.Units) Then
' lw.WriteLine("units: " & myExp.Units.Abbreviation)
' lw.WriteLine("value (in base units): " & myExp.Value)
' End If

'Catch ex As NXException
' lw.WriteLine(ex.ErrorCode & ": " & ex.Message)
'End Try

'lw.WriteLine("interpart expression: " & myExp.RightHandSide.Contains("::").ToString)

'the .value property returns the value in terms of the part's base units

If myExp.Type.ToLower <> "number" Then
'current expression is not a number (point, list, string, etc)
'move to next expression
Continue For
End If

If IsNothing(myExp.Units) Then
'unitless (constant) expression
Continue For
End If

If myExp.Units.Abbreviation = unitsToConvert Then

'if we can parse the right hand side of the expression to a
'double value, the expression "formula" is a simple numeric entry
Dim theValue As Double
If Double.TryParse(myExp.RightHandSide, theValue) Then
'the "formula" is a numeric entry
'lw.WriteLine(" parse success")
'lw.WriteLine(" parse value: " & theValue.ToString)

'the expression .Value will be returned in base units i.e. it will be converted for us
'set the .RightHandSide to the .Value and set the new units
myExp.RightHandSide = myExp.Value.ToString
myExp.Units = myUnit

Else
'the "formula" is more complex than a simple numeric entry
'just convert units
myExp.Units = myUnit
End If

End If

'lw.WriteLine("")

Next

lw.Close()

End Sub

Public Function GetUnloadOption(ByVal dummy As String) As Integer

'Unloads the image when the NX session terminates
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination

'----Other unload options-------
'Unloads the image immediately after execution within NX
'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately

'Unloads the image explicitly, via an unload dialog
'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Explicitly
'-------------------------------

End Function

End Module

Comments

Firstly thank you for the code. The code throws error message for locked expressions like Threaded holes and Values linked expressions. Can you please help to develop the code to skip those exceptions and run. we use NX 12 and 1855 versions.