Attributes to variables

Hello,

Does anyone have a vb script that gets the area, volume and mass of a part without having to select the part? I would like to get that information and pass it to my own variables,that I have declared, so that I can do other things with that info. So I would like to get the area of the part and pass it to x and the volume of the part and pass it to y and the mass and pass it to z.

What version of NX?

You have the mass, volume, and surface area saved as part attributes and you want to pass the values to your variables? Or do you need to calculate these values for the part?

I need to calculate the information for the part. I would like to set up a button to calculate that info and then pass it to the x,y,z variables. I know that i can do something like button1.click to run an action I just don't know how to make the vb script select the entire part , without having to use the UI to make the user select the part, and then pass the variables to to x,y and z.

Hello World

The part's .Bodies collection contains all the bodies (sheet and solid) in the given part. If the part has only one solid body in the file, it would be very easy to automatically select the correct one. However, many parts contain multiple solid and sheet bodies (the model body and tool bodies); you need some sort of strategy to select the correct one(s) for evaluation. For instance, if the solid body you want to measure is always the only solid body on layer 1, or the only solid body in reference set "SOLID", you can use this as an indication that you have the correct solid.

Is there some way in your files to uniquely identify which bodies should be measured?

I am fairly new at using this software but from what I have seen the parts that are created here are only solids and only one part per file. They will model something like this http://i.ytimg.com/vi/moYvcO-i574/maxresdefault.jpg They end up building that in one file so the history tree is filled with extrudes,rounds, chamfers. Is there a way to control select all in order to get the mass,volume and area?

Hello World

What version of NX?

We are currently using NX Version 9.0.3.4 , NX Phase 4.

Hello World

The following journal will measure the first solid body found in the current work part. If there are multiple solid bodies in the file, the results may not be what you expect/desire. If this is the case, you will need to find a way to differentiate between the solids in the file to programmatically choose the desired one.

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF

Module Module1

Public Enum units
PoundsInches = 1
PoundsFeet = 2
GramsCentimeters = 3
KilogramsMeters = 4
End Enum

Sub Main()

Dim theSession As Session = Session.GetSession()
Dim theUfSession As UFSession = UFSession.GetUFSession()
If IsNothing(theSession.Parts.BaseWork) Then
'active part required
Return
End If

Dim workPart As Part = theSession.Parts.Work
Dim lw As ListingWindow = theSession.ListingWindow
lw.Open()

Const undoMarkName As String = "measure body"
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

Dim theSolid As Body = Nothing
Dim found As Boolean = False

'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
'$ change desired units here
Const analysisUnits As units = units.KilogramsMeters
'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

'iterate through the bodies collection, measure first solid body found
For Each temp As Body In workPart.Bodies
If temp.IsSolidBody Then
found = True
theSolid = temp
End If
Next

If Not found Then
lw.WriteLine("no solid body found in file")
Return
End If

Dim accuracyValues(10) As Double
accuracyValues(0) = 0.99
Dim massProps(46) As Double
Dim stats(12) As Double
theUfSession.Modl.AskMassProps3d({theSolid.Tag}, 1, 1, analysisUnits, 1, 1, accuracyValues, massProps, stats)

Dim surfaceArea As Double = massProps(0)
Dim volume As Double = massProps(1)
Dim mass As Double = massProps(2)

lw.WriteLine("units used: " & analysisUnits.ToString)
lw.WriteLine("mass: " & mass.ToString)
lw.WriteLine("volume: " & volume.ToString)
lw.WriteLine("surface area: " & surfaceArea.ToString)

lw.Close()

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

I was researching a way to copy the measured value of the user selected faces into a attribute / expressions (maybe) and then using that attribute into a drafting note of that part. Using NX 12 with Teamcenter. Please advice.

Regards,
MFJ

Here is a quick overview of what I'd try:
Create an associative measure on the desired faces. This will create expressions, one of which will be the area. The expression can be used in the drafting note, but it might be easier to create a part attribute that references the expression and use the new part attribute in the drawing note.

Recording a journal while creating an associative measurement would be a good starting point.

I have already recorded a journal for the measuring area part, still working on it to let user select the desired faces. Once I do that, I still need to know how to reference that expression into attribute. I didn't have luck finding that in internet. Can you please direct me?

If I know how to, I can probably automate that part and also a separate one for drafting note.

Regards,
MFJ

I figured the way to call the expression directly into the drafting note. But how can I rename this expression (the last expression, since assuming there are many other expressions in the part file) to a specific name programmatically so that it can be used for automating drafting note? Please advice.

Regards,
MFJ

If you have a reference to the expression object, you can use the .SetName method to change its name (assuming it is not locked).

Thanks. I will try that.

Regards,
MFJ

Is there any way I can select the faces with certain color (i.e. color ID :17), and measure total area? And then copy the result in clipboard ? Have someone done that before?

Regards,
MFJ

I don't have any code that does exactly that, but it sounds possible.

Are you working in the context of an assembly or a single piece part?

I am working on single Piece part.

Regards,
MFJ

Try the following code, it will look for faces with the color index 17, measure the area in square inches (you can edit the journal to change units), rename the expression to "SA" (unless an expression with this name already exists), and will copy the value to the clipboard.

Option Strict Off
Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF

Module Module1

Dim theSession As Session = Session.GetSession()
Dim theUfSession As UFSession = UFSession.GetUFSession()

Dim theUI As UI = UI.GetUI()
Dim lw As ListingWindow = theSession.ListingWindow

Sub Main()

Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "NXJ")

'***************************************************
'change next line to find faces of the desired color
Const findColor As Integer = 17
'***************************************************

Dim theFaces As New List(Of Face)
lw.Open()

'process faces in the work part
For Each tempBody As Body In theSession.Parts.Work.Bodies
For Each tempFace As Face In tempBody.GetFaces
If tempFace.Color = findColor Then
theFaces.Add(tempFace)
End If
Next
Next

Dim surfaceAreaExpression As Expression = SurfaceArea(theFaces)

'lw.WriteLine(surfaceAreaExpression.Name)
Try
surfaceAreaExpression.SetName("SA")
Catch ex As NXException
lw.WriteLine(ex.Message)
End Try

lw.WriteLine("surface area expression name: " & surfaceAreaExpression.Name)

System.Windows.forms.Clipboard.SetText(surfaceAreaExpression.Value.ToString)

lw.Close()

End Sub

Function SurfaceArea(ByVal faceList As List(Of Face)) As Expression

Dim currentExpressions As New List(Of Expression)
currentExpressions.AddRange(theSession.Parts.Work.Expressions.ToArray)

Dim surfaceAreaExpression As Expression = Nothing

Dim markId1 As NXOpen.Session.UndoMarkId = Nothing
markId1 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Visible, "Measure")

Dim scCollector1 As NXOpen.ScCollector = Nothing
scCollector1 = theSession.Parts.Work.ScCollectors.CreateCollector()

scCollector1.SetMultiComponent()

Dim faceDumbRule1 As NXOpen.FaceDumbRule = Nothing
faceDumbRule1 = theSession.Parts.Work.ScRuleFactory.CreateRuleFaceDumb(faceList.ToArray)

Dim rules1(0) As NXOpen.SelectionIntentRule
rules1(0) = faceDumbRule1
scCollector1.ReplaceRules(rules1, False)

Dim markId3 As NXOpen.Session.UndoMarkId = Nothing
markId3 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Invisible, "Measure")

Dim markId4 As NXOpen.Session.UndoMarkId = Nothing
markId4 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Invisible, "Measurement Apply")

Dim measureMaster1 As NXOpen.MeasureMaster = Nothing
measureMaster1 = theSession.Parts.Work.MeasureManager.MasterMeasurement()

measureMaster1.SequenceType = NXOpen.MeasureMaster.Sequence.Free

measureMaster1.SetNameSuffix("Face")

Dim faceUnits1(4) As NXOpen.Unit
Dim unit1 As NXOpen.Unit = CType(theSession.Parts.Work.UnitCollection.FindObject("SquareInch"), NXOpen.Unit)

faceUnits1(0) = unit1
Dim unit2 As NXOpen.Unit = CType(theSession.Parts.Work.UnitCollection.FindObject("Inch"), NXOpen.Unit)

faceUnits1(1) = unit2
faceUnits1(2) = unit2
faceUnits1(3) = unit2
faceUnits1(4) = unit2
Dim measureElement1 As NXOpen.MeasureElement = Nothing
measureElement1 = theSession.Parts.Work.MeasureManager.FacePropertiesElement(measureMaster1, faceUnits1, 0, True, 0.99, scCollector1)

measureElement1.MeasureObject1 = NXOpen.MeasureElement.Measure.Object

measureElement1.SingleSelect1 = False

measureElement1.SetExpressionState(0, True)
measureElement1.SetGeometryState(0, False)
measureElement1.SetAnnotationState(0, False)
measureElement1.SetApproximateState(0, False)

measureElement1.SetExpressionState(1, False)
measureElement1.SetGeometryState(1, False)
measureElement1.SetAnnotationState(1, False)
measureElement1.SetApproximateState(1, False)

measureElement1.SetExpressionState(2, False)
measureElement1.SetGeometryState(2, False)
measureElement1.SetAnnotationState(2, False)
measureElement1.SetApproximateState(2, False)

measureElement1.SetExpressionState(3, False)
measureElement1.SetGeometryState(3, False)
measureElement1.SetAnnotationState(3, False)
measureElement1.SetApproximateState(3, False)

measureElement1.SetExpressionState(4, False)
measureElement1.SetGeometryState(4, False)
measureElement1.SetAnnotationState(4, False)
measureElement1.SetApproximateState(4, False)

measureElement1.SetExpressionState(5, False)
measureElement1.SetGeometryState(5, False)
measureElement1.SetAnnotationState(5, False)
measureElement1.SetApproximateState(5, False)

Dim markId5 As NXOpen.Session.UndoMarkId = Nothing
markId5 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Invisible, "Measurement Update")

Dim nErrs1 As Integer = Nothing
nErrs1 = theSession.UpdateManager.DoUpdate(markId5)

theSession.DeleteUndoMark(markId5, "Measurement Update")

theSession.DeleteUndoMark(markId4, "Measurement Apply")

Dim datadeleted1 As Boolean = Nothing
datadeleted1 = theSession.DeleteTransientDynamicSectionCutData()

theSession.DeleteUndoMark(markId3, Nothing)

For Each tempExp As Expression In theSession.Parts.Work.Expressions
If Not currentExpressions.Contains(tempExp) Then
'lw.WriteLine(tempExp.Name)
'lw.WriteLine(tempExp.Description)
If tempExp.Description.Contains("area") Then
surfaceAreaExpression = tempExp
End If
End If
Next

Return surfaceAreaExpression

End Function

Public Function GetUnloadOption(ByVal dummy As String) As Integer

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

'----Other unload options-------
'Unloads the image when the NX session terminates
'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination

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

End Function

End Module

Thanks! It works great. I can also add a if condition to handle error or if the color doesn't exists, which I can go from here.

Regards,
MFJ

I tried to change the unit to millimeter with the following synax:


Dim unit1 As NXOpen.Unit = CType(theSession.Parts.Work.UnitCollection.FindObject("SquareMilliMeter"), NXOpen.Unit)

Don't know why, but it still shows me the result in in2

Regards,
MFJ

Also, change "unit2" from "Inch" to "Millimeter".

I forgot to mention that I actually changed that too, but still showing in in2, although the list of expressions shows there is one in mm2 for the same area measurement.

Regards,
MFJ

The change that I mentioned previously works for me (NX 12.0.2.9). Note that the journal will create a new expression each time it is run, it does not check for the existence of a previous measurement. Are you seeing something different?

I've used .convert method to convert the unit. And that will work for me. The code is below:


Dim faceUnits1(4) As NXOpen.Unit
Dim unit1 As NXOpen.Unit = CType(theSession.Parts.Work.UnitCollection.FindObject("SquareInch"), NXOpen.Unit)

faceUnits1(0) = unit1
Dim unit2 As NXOpen.Unit = CType(theSession.Parts.Work.UnitCollection.FindObject("Inch"), NXOpen.Unit)

faceUnits1(1) = unit2
faceUnits1(2) = unit2
faceUnits1(3) = unit2
faceUnits1(4) = unit2
Dim surfaceAreaExpression As Expression = SurfaceArea(theFaces)

Dim lengthInInches As Double = surfaceAreaExpression.value
Dim lengthInCm As Double

'lw.WriteLine(surfaceAreaExpression.Name)
Try
surfaceAreaExpression.SetName("SA")
Catch ex As NXException
lw.WriteLine(ex.Message)
End Try

'convert value from inches to centimeters
Dim millimeterUnit As Unit = theSession.Parts.Work.UnitCollection.FindObject("MilliMeter")

'{part ref}.UnitCollection.Convert(initialUnits, targetUnits, initialValue)
'returns Double value representing the equivalent value in the target units
lengthInCm = theSession.Parts.Work.UnitCollection.Convert(unit1, millimeterUnit, lengthInInches)
lw.WriteLine(lengthInInches.ToString & " in2 = " & lengthInCm.ToString & " mm2")

Regards,
MFJ