Create points on the faces and get coordinates and normal

Hello

I'm trying create a few points on my body and i wanna get x,y,z and the normal of the face on that point i,j,k. I followed this code NX Journaling but now i have 1 problem, when i click on a face, this create a point behind the face and not on the face, can you see what is wrong with this code? And how can i get the i,j,k of that point?


Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF

Module Module1

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

Sub Main()

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

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

Dim selectedFace As Face
Dim selectedPoint As Point3d
Dim count As Integer

for count = 0 to 15

If SelectAnFace("Select an Face", selectedFace, selectedPoint) = Selection.Response.Cancel Then
exit for
End If

Dim scalar1 As Scalar
scalar1 = workPart.Scalars.CreateScalar( 1, Scalar.DimensionalityType.None, SmartObject.UpdateOption.WithinModeling)

'create point
Dim Point_Face As Point
Point_Face = workPart.Points.CreatePoint(selectedPoint)
Point_Face.SetVisibility(SmartObject.VisibilityOption.Visible)

lw.WriteLine("")
lw.WriteLine("x= " & selectedPoint.x)
lw.WriteLine("y= " & selectedPoint.y)
lw.WriteLine("z= " & selectedPoint.z)
lw.WriteLine("i= ")
lw.WriteLine("j= ")
lw.WriteLine("k= ")

Next

lw.Close()

End Sub

Function SelectAnFace(prompt As String, ByRef selFace As Face, ByRef selPos As Point3d) As Selection.Response

Dim selObj As NXObject
Dim theUI As UI = UI.GetUI
Dim cursor As Point3d
Dim typeArray() As Selection.SelectionType = {Selection.SelectionType.Faces}

Dim resp As Selection.Response = theUI.SelectionManager.SelectObject( prompt, "Select a Point in a Face", _
Selection.SelectionScope.AnyInAssembly, False, typeArray, selObj, cursor)

If resp = Selection.Response.ObjectSelected Or resp = Selection.Response.ObjectSelectedByName Then
selFace = selObj
selPos = cursor
Return Selection.Response.Ok
Else
Return Selection.Response.Cancel
End If

End Function

Public Function GetUnloadOption(ByVal dummy As String) As Integer
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
End Function

End Module

The point returned by the selection function represents the location of the cursor at the time of the pick and is not guaranteed to lie on the selected object. To get a point on the surface, you could use the AskFaceParm method to return a U,V parameter and an X,Y,Z point location on the surface. The U,V parameter returned could then be fed to the AskFaceProps method which will return the unit normal of the surface at that point (among other info).

When you click, your mouse location is really only known in 2D. This 2D location,together with your viewing direction, define a "ray" (an infinite line running normal to the screen). To get a 3D location, you have to intersect this ray with something. In your case, you want to intersect the cursor ray with a surface, to get a 3D point. Then, once you have this 3D point on the surface, you can get the uv coordinates, and then the surface normal.

If you have access to SNAP, this is all pretty easy. And, in fact, there's a section in the "Getting Started with SNAP" guide that talks about using the cursor ray. You call Snap.Compute.IntersectInfo to do the intersection. This returns uv parameter values on the surface (among other things). Then you pass these uv values to Snap.NX.Face.Normal. The SNAP reference guide (the CHM doc) has example code.

If you don't have SNAP, you can follow the suggestions in the previous answer, though reading the SNAP docs might still be useful.

Now it's working fine, i can get the normal of 1 face, but have 1 problem, this return the normal using the absolute csys and not the WCS, when i have the WCS like absolute cys it work fine but i have few bodys that i need to rotate the WCS and in that cases, i get the wrong normal


Dim pt(2) As Double
Dim u1(2) As Double
Dim v1(2) As Double
Dim u2(2) As Double
Dim v2(2) As Double
Dim norm(2) As Double
Dim radii(1) As Double
Dim param(1) As Double
theUfSession.Modl.AskFaceParm(facetag, cp , param, pt)

theUfSession.Modl.AskFaceProps(facetag, param, pt, u1, v1, u2, v2, norm, radii)

I already tried change the wcs only before use AskFaceProps like you can see on the next code, but it use always the absolute csys


Dim pt(2) As Double
Dim u1(2) As Double
Dim v1(2) As Double
Dim u2(2) As Double
Dim v2(2) As Double
Dim norm(2) As Double
Dim radii(1) As Double
Dim param(1) As Double
theUfSession.Modl.AskFaceParm(facetag, cp , param, pt)

For Each myFeature As Features.Feature In theSession.Parts.Work.Features.GetFeatures()
If name + "_EL1" = myFeature.name Then

Dim csysTag As Tag
Dim originTag As Tag
Dim daxesTags(2) As Tag
Dim dplanesTags(2) As Tag

theUfSession.Modl.AskDatumCsysComponents(myFeature.Tag, csysTag, originTag, daxesTags, dplanesTags)
Dim theCsys As CoordinateSystem = Utilities.NXObjectManager.Get(csysTag)
displayPart.WCS.SetCoordinateSystemCartesianAtCsys(theCsys)
End If
Next

theUfSession.Modl.AskFaceProps(facetag, param, pt, u1, v1, u2, v2, norm, radii)

There is a way to get the normal using wcs

Almost all of the NXOpen API functions return results with respect to the absolute coordinate system. If you want to see the result in the WCS, you will need to transform the result from the absolute csys to the WCS. The .MapPoint method is one way to transform point coordinates from the absolute csys to the WCS.

The input/output of the .MapPoint method takes a double array that represents the point location and returns an array of the transformed coordinates. One of the outputs of the .AskFaceProps method is an array that represents the normal vector. You can think of the vector information as a point in space; the vector direction runs from (0,0,0) to (x,y,z) of the returned vector array. We can use .MapPoint on this array and the returned value will represent a vector direction in the WCS; from (0,0,0) to the new (x,y,z).

The following link has some code that makes use of the .MapPoint method:
http://nxjournaling.com/comment/261#comment-261

Other methods that may be useful to transform coordinates from one csys to another include:
.CreateCsysMappingMatrix
.CsysToCsys
.MapPosition
.Vec3Multiply
.VecMultiply

To get WCS i use this code, but if i want ACS, what code i need to use?

Dim myStartObject As CoordinateSystem = theSession.Parts.Work.WCS.CoordinateSystem

If you are using the .MapPoint method, it uses some named constants to specify the absolute or WCS. Alternately, you can create a csys object at absolute by using (0,0,0) as the origin, [1,0,0] as the X direction vector, [0,1,0] as the Y direction vector, and [0,0,1] as the Z direction vector.

I tried with .MapPoint but this only return a point and i needed diretions.
I used .Vec3Multiply using first UT_MTX4_rotation(with my ACS and The axis of the body) but noting Works.
I tried too find the angle between each the 2 axis with RotationAngles funtion and after that rotate the normal that angle, but this dont work too because have lot of conditions.
I'm a litle lost now

Can you post the code that you currently have?

This is the code before my attempts to get the normal with the wcs of the body and not the absolute coordinate system


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

Imports NXOpen
Imports NXOpen.UF
Imports NXOpenUI
Imports NXOpen.Features
Imports NXOpen.Utilities

Module Select_Point_on_Face

Dim theSession As Session = Session.GetSession()
Dim theUfSession As UFSession = UFSession.GetUFSession()
Dim ui As UI = UI.GetUI()
Dim workpart As Part = theSession.Parts.Work
Dim lw As ListingWindow = theSession.ListingWindow()

Sub Main()

Dim displayPart As Part = theSession.Parts.Display
Dim response As Selection.Response = Selection.Response.Cancel
Dim prompt As String = "Select Position on Face"
Dim temptag As Tag = Tag.Null
Dim cp(2) As Double
Dim face1 As Face = Nothing
Dim facetag As Tag = Tag.Null
Dim point1 As Point = Nothing
Dim mySelectedObject As NXObject
Dim Name As String =""
Dim test As string
Dim i As integer
Dim j As integer = 1
Dim FGTag As Tag = Tag.Null
Dim FGITag As Tag = Tag.Null
Dim feat_Group As New List(Of Tag)

Dim MyBody As Body = Nothing
Dim a_body As NXOpen.Tag = NXOpen.Tag.Null
Dim endPoint As Point3d
Dim featuresToGroup As Tag() = Nothing

lw.open()
lw.WriteLine("")

Start1:
facetag = select_point_on_face(prompt, cp)
If facetag = Tag.Null Then GoTo End1

face1 = NXObjectManager.Get(facetag)
Dim pnt3d As Point3d = New Point3d(cp(0), cp(1), cp(2))
point1 = PointFeatureOnFace(pnt3d)

i += 1

Dim pt(2) As Double
Dim u1(2) As Double
Dim v1(2) As Double
Dim u2(2) As Double
Dim v2(2) As Double
Dim norm(2) As Double
Dim radii(1) As Double
Dim param(1) As Double
theUfSession.Modl.AskFaceParm(facetag, cp , param, pt)
theUfSession.Modl.AskFaceProps(facetag, param, pt, u1, v1, u2, v2, norm, radii)

lw.WriteLine("X:" & formatnumber(norm(0),2).ToString & " Y:" & _
formatnumber(norm(1),2).ToString & " Z:" & _
formatnumber(norm(2),2).ToString)

GoTo Start1
End1:

End Sub

Public Function select_point_on_face(ByVal prompt As String, _
ByRef cp() As Double) As NXOpen.Tag
Dim resp As Integer = 0
Dim face1 As Face = Nothing
Dim theView As NXOpen.Tag = NXOpen.Tag.Null
Dim mask_face As UFUi.SelInitFnT = AddressOf mask_for_face
Dim facetag As Tag = Tag.Null
theUfSession.Ui.LockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
theUfSession.Ui.SelectWithSingleDialog("Select a face", prompt, UFConstants.UF_UI_SEL_SCOPE_ANY_IN_ASSEMBLY, _
mask_face, Nothing, resp, facetag, cp, theView)
theUfSession.Ui.UnlockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)

If resp = UFConstants.UF_UI_OBJECT_SELECTED Or resp = UFConstants.UF_UI_OBJECT_SELECTED_BY_NAME Then
ask_pos_on_obj(facetag, cp)
theUfSession.Disp.SetHighlight(facetag, 0)
Return facetag
End If
Return Tag.Null
End Function

Public Sub map_view2abs(ByRef c() As Double)
Dim vname As String = ""
Dim abs_mx() As Double = {0, 0, 0, 1, 0, 0, 0, 1, 0}
Dim vw() As Double = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
Dim mx() As Double = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
Dim irc As Integer = 0
theUfSession.Ui.AskLastPickedView(vname)
Dim wp As Part = theSession.Parts.Work
Dim lastViewPicked As View = CType(wp.ModelingViews.FindObject(vname), ModelingView)
Dim vmx As Matrix3x3 = lastViewPicked.Matrix()
vw(3) = vmx.Xx
vw(4) = vmx.Xy
vw(5) = vmx.Xz
vw(6) = vmx.Yx
vw(7) = vmx.Yy
vw(8) = vmx.Yz
vw(9) = vmx.Zx
vw(10) = vmx.Zy
vw(11) = vmx.Zz
theUfSession.Trns.CreateCsysMappingMatrix(vw, abs_mx, mx, irc)
theUfSession.Trns.MapPosition(c, mx)
End Sub

Public Sub map_abs2view(ByRef c() As Double)
Dim vname As String = ""
Dim abs_mx() As Double = {0, 0, 0, 1, 0, 0, 0, 1, 0}
Dim vw() As Double = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
Dim mx() As Double = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
Dim irc As Integer = 0
theUfSession.Ui.AskLastPickedView(vname)
Dim wp As Part = theSession.Parts.Work
Dim lastViewPicked As View = _
CType(wp.ModelingViews.FindObject(vname), ModelingView)
Dim vmx As Matrix3x3 = lastViewPicked.Matrix()
vw(3) = vmx.Xx
vw(4) = vmx.Xy
vw(5) = vmx.Xz
vw(6) = vmx.Yx
vw(7) = vmx.Yy
vw(8) = vmx.Yz
vw(9) = vmx.Zx
vw(10) = vmx.Zy
vw(11) = vmx.Zz
theUfSession.Trns.CreateCsysMappingMatrix(abs_mx, vw, mx, irc)
theUfSession.Trns.MapPosition(c, mx)
End Sub

Public Sub ask_pos_on_obj(ByVal obj As NXOpen.Tag, ByVal loc() As Double)
Dim aLine As NXOpen.Tag = NXOpen.Tag.Null
Dim cp() As Double = {0, 0, 0}
Dim dist As Double = 0
Dim lp As UFCurve.Line
Dim sp(2) As Double
Dim ep(2) As Double
lp.start_point = sp
lp.end_point = ep
map_abs2view(loc)
lp.start_point(0) = loc(0)
lp.start_point(1) = loc(1)
lp.start_point(2) = loc(2) + 10000
lp.end_point(0) = loc(0)
lp.end_point(1) = loc(1)
lp.end_point(2) = loc(2) - 10000
map_view2abs(lp.start_point)
map_view2abs(lp.end_point)
theUfSession.Curve.CreateLine(lp, aLine)
theUfSession.Modl.AskMinimumDist(obj, aLine, 0, cp, 0, cp, dist, loc, cp)
theUfSession.Obj.DeleteObject(aLine)
End Sub

Public Function mask_for_face(ByVal select_ As IntPtr, ByVal userdata As IntPtr) As Integer

Dim num_triples As Integer = 1
Dim mask_triples(0) As UFUi.Mask
mask_triples(0).object_type = UFConstants.UF_solid_type
mask_triples(0).object_subtype = 0
mask_triples(0).solid_type = UFConstants.UF_UI_SEL_FEATURE_ANY_FACE
theUfSession.Ui.SetSelMask(select_, _
UFUi.SelMaskAction.SelMaskClearAndEnableSpecific, _
num_triples, mask_triples)
Return UFConstants.UF_UI_SEL_SUCCESS
End Function

Public Function PointFeatureOnFace(ByVal where As Point3d) As Point
Dim markId1 As Session.UndoMarkId = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Create Point")
Dim point1 As Point
point1 = workpart.Points.CreatePoint(where)
Dim nullFeatures_Feature As Features.Feature = Nothing
Dim pointFeatureBuilder1 As Features.PointFeatureBuilder
pointFeatureBuilder1 = workPart.BaseFeatures.CreatePointFeatureBuilder(nullFeatures_Feature)
pointFeatureBuilder1 .Point = point1
Dim nXObject1 As NXObject = pointFeatureBuilder1.Commit()
pointFeatureBuilder1.Destroy()
Return point1
End Function

Public Function GetUnloadOption(ByVal dummy As String) As Integer
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
End Function
End Module

Here's a version that uses .MapPoint.

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

Imports NXOpen
Imports NXOpen.UF
Imports NXOpenUI
Imports NXOpen.Features
Imports NXOpen.Utilities

Module Module1

Dim theSession As Session = Session.GetSession()
Dim theUfSession As UFSession = UFSession.GetUFSession()
Dim ui As UI = UI.GetUI()
Dim workpart As Part = theSession.Parts.Work
Dim lw As ListingWindow = theSession.ListingWindow()

Sub Main()

Dim displayPart As Part = theSession.Parts.Display
Dim response As Selection.Response = Selection.Response.Cancel
Dim prompt As String = "Select Position on Face"
Dim temptag As Tag = Tag.Null
Dim cp(2) As Double
Dim face1 As Face = Nothing
Dim facetag As Tag = Tag.Null
Dim point1 As Point = Nothing
Dim mySelectedObject As NXObject
Dim Name As String = ""
Dim test As String
Dim i As Integer
Dim j As Integer = 1
Dim FGTag As Tag = Tag.Null
Dim FGITag As Tag = Tag.Null
Dim feat_Group As New List(Of Tag)

Dim MyBody As Body = Nothing
Dim a_body As NXOpen.Tag = NXOpen.Tag.Null
Dim endPoint As Point3d
Dim featuresToGroup As Tag() = Nothing

lw.Open()
lw.WriteLine("")

Start1:
facetag = select_point_on_face(prompt, cp)
If facetag = Tag.Null Then GoTo End1

face1 = NXObjectManager.Get(facetag)
Dim pnt3d As Point3d = New Point3d(cp(0), cp(1), cp(2))
point1 = PointFeatureOnFace(pnt3d)

i += 1

Dim pt(2) As Double
Dim u1(2) As Double
Dim v1(2) As Double
Dim u2(2) As Double
Dim v2(2) As Double
Dim norm(2) As Double
Dim radii(1) As Double
Dim param(1) As Double
theUfSession.Modl.AskFaceParm(facetag, cp, param, pt)
theUfSession.Modl.AskFaceProps(facetag, param, pt, u1, v1, u2, v2, norm, radii)

Dim WcsNorm(2) As Double
theUfSession.Csys.MapPoint(UFConstants.UF_CSYS_ROOT_COORDS, norm, UFConstants.UF_CSYS_ROOT_WCS_COORDS, WcsNorm)

lw.WriteLine("X:" & (norm(0)).ToString & " Y:" &
(norm(1)).ToString & " Z:" &
(norm(2)).ToString)

lw.WriteLine("XC: " & WcsNorm(0).ToString & " YC: " & WcsNorm(1).ToString & " ZC: " & WcsNorm(2).ToString)

GoTo Start1
End1:

End Sub

Public Function select_point_on_face(ByVal prompt As String,
ByRef cp() As Double) As NXOpen.Tag
Dim resp As Integer = 0
Dim face1 As Face = Nothing
Dim theView As NXOpen.Tag = NXOpen.Tag.Null
Dim mask_face As UFUi.SelInitFnT = AddressOf mask_for_face
Dim facetag As Tag = Tag.Null
theUfSession.Ui.LockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
theUfSession.Ui.SelectWithSingleDialog("Select a face", prompt, UFConstants.UF_UI_SEL_SCOPE_ANY_IN_ASSEMBLY,
mask_face, Nothing, resp, facetag, cp, theView)
theUfSession.Ui.UnlockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)

If resp = UFConstants.UF_UI_OBJECT_SELECTED Or resp = UFConstants.UF_UI_OBJECT_SELECTED_BY_NAME Then
ask_pos_on_obj(facetag, cp)
theUfSession.Disp.SetHighlight(facetag, 0)
Return facetag
End If
Return Tag.Null
End Function

Public Sub map_view2abs(ByRef c() As Double)
Dim vname As String = ""
Dim abs_mx() As Double = {0, 0, 0, 1, 0, 0, 0, 1, 0}
Dim vw() As Double = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
Dim mx() As Double = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
Dim irc As Integer = 0
theUfSession.Ui.AskLastPickedView(vname)
Dim wp As Part = theSession.Parts.Work
Dim lastViewPicked As View = CType(wp.ModelingViews.FindObject(vname), ModelingView)
Dim vmx As Matrix3x3 = lastViewPicked.Matrix()
vw(3) = vmx.Xx
vw(4) = vmx.Xy
vw(5) = vmx.Xz
vw(6) = vmx.Yx
vw(7) = vmx.Yy
vw(8) = vmx.Yz
vw(9) = vmx.Zx
vw(10) = vmx.Zy
vw(11) = vmx.Zz
theUfSession.Trns.CreateCsysMappingMatrix(vw, abs_mx, mx, irc)
theUfSession.Trns.MapPosition(c, mx)
End Sub

Public Sub map_abs2view(ByRef c() As Double)
Dim vname As String = ""
Dim abs_mx() As Double = {0, 0, 0, 1, 0, 0, 0, 1, 0}
Dim vw() As Double = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
Dim mx() As Double = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
Dim irc As Integer = 0
theUfSession.Ui.AskLastPickedView(vname)
Dim wp As Part = theSession.Parts.Work
Dim lastViewPicked As View =
CType(wp.ModelingViews.FindObject(vname), ModelingView)
Dim vmx As Matrix3x3 = lastViewPicked.Matrix()
vw(3) = vmx.Xx
vw(4) = vmx.Xy
vw(5) = vmx.Xz
vw(6) = vmx.Yx
vw(7) = vmx.Yy
vw(8) = vmx.Yz
vw(9) = vmx.Zx
vw(10) = vmx.Zy
vw(11) = vmx.Zz
theUfSession.Trns.CreateCsysMappingMatrix(abs_mx, vw, mx, irc)
theUfSession.Trns.MapPosition(c, mx)
End Sub

Public Sub ask_pos_on_obj(ByVal obj As NXOpen.Tag, ByVal loc() As Double)
Dim aLine As NXOpen.Tag = NXOpen.Tag.Null
Dim cp() As Double = {0, 0, 0}
Dim dist As Double = 0
Dim lp As UFCurve.Line
Dim sp(2) As Double
Dim ep(2) As Double
lp.start_point = sp
lp.end_point = ep
map_abs2view(loc)
lp.start_point(0) = loc(0)
lp.start_point(1) = loc(1)
lp.start_point(2) = loc(2) + 10000
lp.end_point(0) = loc(0)
lp.end_point(1) = loc(1)
lp.end_point(2) = loc(2) - 10000
map_view2abs(lp.start_point)
map_view2abs(lp.end_point)
theUfSession.Curve.CreateLine(lp, aLine)
theUfSession.Modl.AskMinimumDist(obj, aLine, 0, cp, 0, cp, dist, loc, cp)
theUfSession.Obj.DeleteObject(aLine)
End Sub

Public Function mask_for_face(ByVal select_ As IntPtr, ByVal userdata As IntPtr) As Integer

Dim num_triples As Integer = 1
Dim mask_triples(0) As UFUi.Mask
mask_triples(0).object_type = UFConstants.UF_solid_type
mask_triples(0).object_subtype = 0
mask_triples(0).solid_type = UFConstants.UF_UI_SEL_FEATURE_ANY_FACE
theUfSession.Ui.SetSelMask(select_,
UFUi.SelMaskAction.SelMaskClearAndEnableSpecific,
num_triples, mask_triples)
Return UFConstants.UF_UI_SEL_SUCCESS
End Function

Public Function PointFeatureOnFace(ByVal where As Point3d) As Point
Dim markId1 As Session.UndoMarkId = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Create Point")
Dim point1 As Point
point1 = workpart.Points.CreatePoint(where)
Dim nullFeatures_Feature As Features.Feature = Nothing
Dim pointFeatureBuilder1 As Features.PointFeatureBuilder
pointFeatureBuilder1 = workpart.BaseFeatures.CreatePointFeatureBuilder(nullFeatures_Feature)
pointFeatureBuilder1.Point = point1
Dim nXObject1 As NXObject = pointFeatureBuilder1.Commit()
pointFeatureBuilder1.Destroy()
Return point1
End Function

Public Function GetUnloadOption(ByVal dummy As String) As Integer
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
End Function
End Module

but with .MapPoint, rotate the normal like if was a point, so after that, i get huge values for normal, but the normal need to be between -1 and 1

Normalize the values.

how i do that?

Divide each component value by the magnitude of the vector. You can write your own routine for this or you can use one of the built-in NXOpen commands. The .Unitize method is one approach; alternately, you can convert the values to a Vector3 object then use its .Normalize method.

Hello all,
I referred to the codes from NXJournaling and eskourense, and the normal vector of the point/face is exactly what I need.

However, the FaceTag for UF_MODL_ask_face_props should be accessed by object selecting functions which return NXOpen.Tag. In my codes I already defined a selecting function to return Face. When I combined two selecting functions, the problem with identical signatures pops up.

If NX doesn't allow this kind of double return, is there any possibility to get a facetag through a face?

Best regards,
Ray

My current codes:

Public Function SelectFace() As Face
Dim dispObj1 As Face = Nothing
' Variablen fuer Auswahl-Dialoge (Selection Dialogs)

Dim selManager = theUI.SelectionManager
Dim selectedObject As TaggedObject
Dim cursor As Point3d
Dim cue = "Bitte wähle eine Fläche aus."
Dim title = "Kosten- und CO2-Rechner"
Dim scope = Selection.SelectionScope.AnyInAssembly
Dim action = Selection.SelectionAction.ClearAndEnableSpecific
Dim keepHighlighted = False
Dim typeArray As NXOpen.Selection.SelectionType() = {SelectionType.Faces}
Dim response = selManager.SelectTaggedObject(cue, title, scope, keepHighlighted, typeArray, selectedObject, cursor)

If response <> NXOpen.Selection.response.Cancel And response <> NXOpen.Selection.response.Back Then
If TypeOf selectedObject Is Face Then
dispObj1 = CType(selectedObject, Face)
End If
End If

Return dispObj1

End Function

Almost all of the objects in the NXOpen .net API have a .Tag property that you can use to get the tag from the object.

dim myFaceObj as Face = SeletFace()
FunctionThatRequiresFaceTag(myFaceObj.Tag)