Using Mask Triples from the SelectObject Routine

As we saw in Beginning Selections, the SelectObject(...) method provides a fairly quick and easy way to allow the user to select one or more objects. However, if you need interactive selection, but the ‘type array’ method could not provide enough control; allow me to introduce you to the selection method using mask triples.

 

Using SelectObject(...)

You may notice that this SelectObject(...) method has the exact same name as the one that filters by type array. Those of keen eye will also notice that the parameter signature shown below of the method is slightly different than the type array version.

Here’s the signature of the SelectObject:


Public Function SelectObject( _
message As String, _
title As String, _
scope As Selection.SelectionScope, _
action As Selection.SelectionAction, _
includeFeatures As Boolean, _
keepHighlighted As Boolean, _
maskArray As Selection.MaskTriple(), _
ByRef object As NXObject, _
ByRef cursor As Point3d _
) As Selection.Response

Overloading is a language feature that lets the programmer reuse the same function name with different parameters. This allows for more flexibility and convenience for the users of the function (such as journal programmers). A good example of this is the VB.NET MessageBox class that has 21 versions of the Show method! http://msdn.microsoft.com/en-us/library/system.windows.forms.messagebox_methods.aspx Suffice it to say there should be a version that does what you need.

The message parameter will show up in the cue line, use this to prompt the user what to pick.

The title parameter will show up in the title of the dialog box. There is not much room here, so keep it short. A simple “Select {main object type}” usually does the job.

The scope parameter limits where the selection is allowed to take place. The following options are available:

  • Selection.SelectionScope.UseDefault
  • Selection.SelectionScope.WorkPart - limit selection to only entities within the work part
  • Selection.SelectionScope.AnyInAssembly - select from pretty much anywhere
  • Selection.SelectionScope.WorkPartAndOccurrence - limit selection to the work part and its components

The action parameter determines what happens with your selected object(s). The available options here are (taken from the net_ref help file):

  • EnableAll - Include objects in the selection
  • EnableSpecific - Include selected objects in selection
  • DisableSpecific - Remove selected objects from selection
  • ClearAndEnableSpecific - Clear selection and include selected objects
  • AllAndDisableSpecific - Select all objects except for selected objects
  • Count - Include count of selected objects

To be honest, I’ve only used the ClearAndEnableSpecific option, it has always met the need. You will probably find good uses for the other options if you have access to the dialog styler (I do not). If you have a short code example using one of the other options, please submit it along with a short explanation.

If you need to allow the selection of features, pass a True value in the includeFeatures parameter, otherwise pass in False.

A False value passed into the keepHighlighted parameter will give control of the object’s highlighting to the selection method. If you want full control over when the highlighting turns off, such as when you are using the dialog styler, pass in a True value.

This brings us to the real meat of this method, the maskArray. The maskArray parameter is an array of maskTriple objects. The maskTriple, in turn, is a three element array of integers representing the objects available through the NXOpen API. The maskTriples act as filters, limiting what is allowed for selection. Each maskTriple added to the maskArray allows a single type of object to be selected; the subtype may allow for all subtypes to be selected (UF_all_subtype), or it may further narrow the selection to a single subtype. A simple selection may only require one maskTriple, more complicated selections may require several.
 

Assinging Values to the maskTriple:
To make your programming life a little bit easier, you can use the maskTriple constructor to assign values. The constructor takes the arguments as below:


Selection.MaskTriple ( _
Type As Integer, _
Subtype As Integer, _
SolidBodySubtype As Integer _
)

All of the objects available through the NXOpen API are divided into types and subtypes.

If you wanted to mask for arcs, the maskTriple would be:

Selection.MaskTriple(5, 0, 0).
 

The maskTriple for circular edges of a solid body would be:

Selection.MaskTriple(70, 0, 3)

So how do you know what numbers to pass in to the maskTriple? All of the available object types and subtypes can be found in the uf_object_types.h file which is in the UGOPEN subdirectory in your NX install path. The available SolidBodySubtypes can be found in the uf_ui_types.h file, which can also be found in the UGOPEN directory. This is a large file, so search for Constants for selection solid_type to find your available options quickly.

The SolidBodySubtype only has an affect when the type is set to UF_solid_type (70); if the type is something other than UF_solid_type, pass in a zero. When UF_solid_type is used, the subtype is ignored (pass in a zero), and the SolidBodySubtype takes over.

Not only do these files list the available types, they also define an enumeration (named constants) so the previous masks would look like this:

Selection.MaskTriple(UFConstants.UF_circle_type, _
            0, _
            0)
Selection.MaskTriple(UFConstants.UF_solid_type, _
            0, _
            UFConstants.UF_UI_SEL_FEATURE_CIRCULAR_EDGE)

Using these named constants helps to make your code self-documenting. When you revisit your code a week, a month, a year later, you will know exactly what the filter was set up to do without searching through the uf_object_types.h and uf_ui_types.h files.

 

Putting it all together: Working journal that selects a single object using SelectObject(...) with SelectionMask.Triple

Here is an example journal that allows for the selection of arcs or circular edges and simply reports the object’s tag and type to the listing window.

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF

Module NXJournal
Sub Main

Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display
Dim lw As ListingWindow = theSession.ListingWindow
Dim mySelectedObject As NXObject

lw.Open
If SelectAnObject("Select arc or circular edge", mySelectedObject) = Selection.Response.Cancel Then
Exit Sub
End if
lw.WriteLine("Object Tag: " & mySelectedObject.Tag)
lw.WriteLine("Object is a: " & mySelectedObject.GetType.ToString)

lw.Close

End Sub

Function SelectAnObject(ByVal prompt As String, byRef selObj as NXObject) As Selection.Response

Dim theUI As UI = UI.GetUI
Dim title As String = "Selection"
Dim includeFeatures As Boolean = False
Dim keepHighlighted As Boolean = False
Dim selAction As Selection.SelectionAction = _
Selection.SelectionAction.ClearAndEnableSpecific
Dim cursor As Point3d
Dim scope As Selection.SelectionScope = Selection.SelectionScope.WorkPart
Dim selectionMask_array(1) As Selection.MaskTriple

With selectionMask_array(0)
.Type = UFConstants.UF_solid_type
.Subtype = 0
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_CIRCULAR_EDGE
End With
With selectionMask_array(1)
.Type = UFConstants.UF_circle_type
.Subtype = 0
.SolidBodySubtype = 0
End With

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

If resp = Selection.Response.ObjectSelected OrElse _
resp = Selection.Response.ObjectSelectedByName Then
Return Selection.Response.Ok
Else
Return Selection.Response.Cancel
End If

End Function

End Module

 

Using SelectObjects(...)

To select multiple objects, use the SelectObjects(...) method is very similar to the SelectObject(...) method described above. However the Select Objects(...) does require an array variable of NXObjects as a parameter and it does not require (or return) a Point3d object parameter (cursor position). The parameter signature of this method is shown below:

Public Function SelectObjects( _
message As String, _
title As String, _
scope As Selection.SelectionScope, _
action As Selection.SelectionAction, _
includeFeatures As Boolean, _
keepHighlighted As Boolean, _
maskArray As Selection.MaskTriple(), _
ByRef objectArray As NXObject() _
) As Selection.Response

 

Below is an example journal that allows for multiple selection of arcs and/or circular edges.

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF

Module NXJournal
Sub Main

Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display
Dim lw As ListingWindow = theSession.ListingWindow
Dim mySelectedObjects() As NXObject

lw.Open
If SelectObjects("Select objects", mySelectedObjects) = Selection.Response.Cancel Then
Exit Sub
End if
For each obj as NXObject in mySelectedObjects
lw.WriteLine("Object Tag: " & obj.Tag)
lw.WriteLine("Object is a: " & obj.GetType.ToString)
lw.WriteLine("")
Next

lw.Close

End Sub

Function SelectObjects(ByVal prompt As String, byRef selObj() as NXObject) As Selection.Response

Dim theUI As UI = UI.GetUI
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.WorkPart
Dim selectionMask_array(1) As Selection.MaskTriple

With selectionMask_array(0)
.Type = UFConstants.UF_solid_type
.Subtype = 0
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_CIRCULAR_EDGE
End With
With selectionMask_array(1)
.Type = UFConstants.UF_circle_type
.Subtype = 0
.SolidBodySubtype = 0
End With

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

If resp = Selection.Response.Ok
Return Selection.Response.Ok
Else
Return Selection.Response.Cancel
End If

End Function

End Module

Recap:

Althought the SelectObjectMaskTriple() is more difficult to set up you can see how it will allow the user more options in the selection process. By setting up the MaskTriple() then understanding and defining what parameters you need, you can create a selection process that will be as selective as you need.

 

Objectives:

In this tutorial, we have learned how to use maskTriples in both the SelectObject and SelectObjects methods to create a finely tuned selection process.

Comments

Hello
I am very new to journalling and NX.  I appreciate the information on selecting objects.  It is very useful.  How do I  run an action on a line that I have now selected?  For instance, once I select the line, if it is a yellow centerline, I need to create .050 circles at .150 from each end.  If it is a magenta centerline, I need to create .050 squares at .150 from each end, with the squares remaining at zero degrees no matter what angle the centerline is at.  If the line I select isn't a centerline at all, then I need to have a warning message pop up stating this, but no action taking place.  After I am done selecting lines, then I need a way to exit out of the journal like an "OK" or "Cancel" button.  Any help in accomplishing this would be appreciated.
Thanks

hppianoman

Hi,

When I use the example ''Using SelectObjects (...)'', I get this error message bellow in VS2013. You know how to fix this error?

Also, in the example of ''Using SelectObjects (...)'' the scope is on ''UF_circle_type'' and ''UF_UI_SEL_FEATURE_CIRCULAR_EDGE''. How i can set the scope on radial dimensions or diametric dimension? You can write an exemple ?

Eror on VS2013:
_________________________________________________________________________
Warning 1 'Public Function SelectObjects(message As String, title As String, scope As NXOpen.Selection.SelectionScope, action As NXOpen.Selection.SelectionAction, includeFeatures As Boolean, keepHighlighted As Boolean, maskArray() As NXOpen.Selection.MaskTriple, ByRef objectArray() As NXOpen.NXObject) As NXOpen.Selection.Response' is obsolete: 'Deprecated in NX8.0.0. Use Selection.SelectTaggedObject instead'. C:\temp\DimSetting VS2013\DimSetting\DimSetting\Module1.vb 66 42 DimSetting
__________________________________________________________________

Tank you!

Pat

The code above was written for NX 7.5; in NX 8 the SelectObject and SelectObjects functions were deprecated (as you can see in the warning message that you posted). "Deprecated" means this function is being retired, there is a new one to take its place. You can still use the function, for now at least, but it may be removed in a future version. SelectObject(s) still works in NX 8, 8.5, and 9 (I've not yet tested it in 10), but it is recommended that you use SelectTaggedObject or SelectTaggedObjects instead. Also to use the new functions, change the object references from type "NXObject" to "TaggedObject".

I've tried all of the techniques listed in the two selections tutorials, but I cannot find a way to allow my users to select edges of a component on a drawing.

If I change to modelling mode, it works as intended, but does not work in drawing mode.

Am I missing something?

Cheers,
Ian

When writing selection functions, I will often use the following code from GTAC to help determine what type of object(s) I am dealing with. Select the object of interest then run the code, something must be selected before the code is run.

'Amy Webster
'Date: 03/28/2011
'Subject: Sample NX Open .NET Visual Basic program : report type and subtype of preselected objects
'
'Note: GTAC provides programming examples for illustration only, and
'assumes that you are familiar with the programming language being
'demonstrated and the tools used to create and debug procedures. GTAC
'support professionals can help explain the functionality of a particular
'procedure, but we will not modify these examples to provide added
'functionality or construct procedures to meet your specific needs.

Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpenUI

Module journal

Sub Main
Dim s As Session = Session.GetSession()
Dim ufs As NXOpen.UF.UFSession = NXOpen.UF.UFSession.GetUFSession()
Dim selobj As NXObject
Dim type As Integer
Dim subtype As Integer
Dim lw As ListingWindow = s.ListingWindow

Dim theUI As UI = ui.GetUI
Dim numsel As Integer = theUI.SelectionManager.GetNumSelectedObjects()
lw.Open()
lw.WriteLine("Selected Objects: " & numsel.ToString())

For inx As Integer = 0 To numsel-1
selobj = theUI.SelectionManager.GetSelectedObject(inx)

ufs.Obj.AskTypeAndSubtype(selobj.Tag, type, subtype)
lw.WriteLine("Object: " & selobj.ToString())
lw.WriteLine(" Tag: " & selobj.Tag.ToString())
lw.WriteLine(" Type: " & type.ToString())
lw.WriteLine(" Subtype: " & subtype.ToString())
lw.WriteLine("")
Next

End Sub

End Module

After I know the type and subtype numbers, I can look in the file: uf_object_types.h to find the desired UF constants.

From experience, I'll say that the filters you use for selecting an edge of a component in a drawing view will probably look something like this:

mask_triples(0).object_type = UFConstants.UF_solid_type
mask_triples(0).object_subtype = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE
mask_triples(0).solid_type = UFConstants.UF_UI_SEL_FEATURE_ANY_EDGE

mask_triples(1).object_type = UFConstants.UF_line_type
mask_triples(1).object_subtype = UFConstants.UF_all_subtype

mask_triples(2).object_type = UFConstants.UF_circle_type
mask_triples(2).object_subtype = UFConstants.UF_all_subtype

mask_triples(3).object_type = UFConstants.UF_conic_type
mask_triples(3).object_subtype = UFConstants.UF_all_subtype

mask_triples(4).object_type = UFConstants.UF_spline_type
mask_triples(4).object_subtype = UFConstants.UF_all_subtype

mask_triples(5).object_type = UFConstants.UF_solid_silhouette_type
mask_triples(5).object_subtype = UFConstants.UF_all_subtype

mask_triples(6).object_type = UFConstants.UF_section_edge_type
mask_triples(6).object_subtype = UFConstants.UF_all_subtype

Thanks for this code snippet. That will be very useful.

However, I can't select the edge of the component on the drawing to be able to run this code. All I can select are the components themselves.

If I'm on a piece part drawing, I cannot select any geometry until I click on a button (like 'Inferred Dimension' or 'Object Information').

I feel there must be a setting somewhere that I'm missing that allows me to select more stuff in a drawing.

Cheers,

In your selection function, before the call to the .SelectObject(s) method, use the .SetCursorView function.

theUfSession.Ui.SetCursorView(0)

When you are in drafting, the selection defaults to the work view, using .SetCursorView(0) allows you to select from any view.

Perfect! You are a legend!

Thank you so much.

Hi,

During measure length function I have possibility to choice e.g. "Connected Curves" or "Tangent Curves" in selection bar. How to modify above journal code to make do it?

I use NX 10
Thanks
Marcin

If you have a UI styler license, I believe that there is a filter that you can set in your dialog to allow various curve selection rules to be used.

If you are using a bare-bones journal, you can write code to use a particular curve collection rule, but I don't know of any way to enable the curve selection intent options while your code is running.

Hi,
I'm trying to get the user to be able to select only conical edges. The thing is - all the entities of the CAEEdge type are of the same type and subtype (both conical and straight). Is there a way to do that?
I know that it is possible internally because this is exactly the case in the Bolt Connection/ Hole Edge interactive menu.
I use NX9.
Thanks!