Using VectorArithmetic.Vector3

The NXOpen.VectorArithmetic Namespace has three classes: Matrix3, Quaternion and Vector3. The
example journal below shows the ease that the vector3 object can be created and used. The code
ask the user to select a datum plane and a datum axis and then creates a point on the datum plane
at the intersection point with the datum axis direction. The journal will not work if the datum plane
normal is perpendicular to the datum axis.

The specific example can easily be extended to other cases. For example the plane could be defined
by two axis. The plane normal is then obtained using the cross product of the two axis. Similarly
defining a point not on the plane and a projection vector defined in any of a number of ways can
also be used.

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpenUI
Imports NXOpen.VectorArithmetic

Module ProjectionPoint2
Dim s As Session = Session.GetSession()
Dim ui As UI = ui.GetUI()
Dim ufs As UFSession = UFSession.GetUFSession()
Dim wp As Part = s.Parts.Work

Sub Main()
Dim dPlane1 As DatumPlane = Nothing
Dim dAxis1 As DatumAxis = Nothing
Dim pointTag As Tag = Tag.Null
' select a datum plane
Dim response1 As Selection.Response = select_a_datumPlane(dPlane1)
' select a datum axis
Dim response2 As Selection.Response = select_a_datumAxis(dAxis1)
' get datum plane data
Dim dplaneOrigin1 As Point3d = dPlane1.Origin
Dim dplaneOrigin2 As Vector3 = New Vector3(dplaneOrigin1.X, dplaneOrigin1.Y, dplaneOrigin1.Z)
Dim dplaneNormal1 As Vector3d = dPlane1.Normal
Dim dplaneNormal2 As Vector3 = New Vector3(dplaneNormal1.X, dplaneNormal1.Y, dplaneNormal1.Z)
' get datum axis data
Dim daxisOrigin1 As Point3d = dAxis1.Origin
Dim daxisOrigin2 As Vector3 = New Vector3(daxisOrigin1.X, daxisOrigin1.Y, daxisOrigin1.Z)
Dim daxisDirection1 As Vector3d = dAxis1.Direction
Dim daxisDirection2 As Vector3 = New Vector3(daxisDirection1.X, daxisDirection1.Y, daxisDirection1.Z)
' determine point on dplane
' subtraction of dplaneOrigin - daxisOrigin
Dim subvector1 As Vector3 = dplaneOrigin2 - daxisOrigin2
' dplaneNormal dot subpoint1
Dim sub1 As Double = dplaneNormal2.Dot(subvector1)
' dplaneNormal2 dot daxisDirection2
Dim sub2 As Double = dplaneNormal2.Dot(daxisDirection2)
' w1 is the parameter value of a line from daxisOrigin to the dplane along daxisNormal
Dim w1 As Double = sub1 / sub2
' calculate the point on the dpane
' scale daxisDirection2
Dim scaleddaxis1 As Vector3 = daxisDirection2 * w1
' add daxisorigin2 plus scaleddaxis1
Dim finalvector As Vector3 = daxisOrigin2 + scaleddaxis1
Dim pointOnDplane As Point3d = New Point3d(finalvector.x, finalvector.y, finalvector.z)
' create the point
Dim pointobj1 As Point = wp.Points.CreatePoint(pointOnDplane)
pointobj1.SetVisibility(SmartObject.VisibilityOption.Visible)
End1:
End Sub

Public Function select_a_datumPlane(ByRef dplane As DatumPlane) As Selection.Response
Dim message As String = "Select a datum plane"
Dim selectionMask_array(0) As Selection.MaskTriple
With selectionMask_array(0)
.Type = UFConstants.UF_datum_plane_type
.Subtype = 0
.SolidBodySubtype = 0
End With
Dim cursor As Point3d = Nothing
Dim resp As Selection.Response = _
ui.SelectionManager.SelectTaggedObject("Dplane Selection", message, _
Selection.SelectionScope.WorkPart, _
Selection.SelectionAction.ClearAndEnableSpecific, _
False, False, selectionMask_array, dplane, cursor)
If resp = Selection.Response.ObjectSelected Or _
resp = Selection.Response.ObjectSelectedByName Then
Return Selection.Response.Ok
ElseIf resp = Selection.Response.Back Then
Return Selection.Response.Back
Else
Return Selection.Response.Cancel
End If
End Function

Public Function select_a_datumAxis(ByRef daxis As DatumAxis) As Selection.Response
Dim message As String = "Select a datum axis"
Dim selectionMask_array(0) As Selection.MaskTriple
With selectionMask_array(0)
.Type = UFConstants.UF_datum_axis_type
.Subtype = 0
.SolidBodySubtype = 0
End With
Dim cursor As Point3d = Nothing
Dim resp As Selection.Response = _
ui.SelectionManager.SelectTaggedObject("DAxis Selection", message, _
Selection.SelectionScope.WorkPart, _
Selection.SelectionAction.ClearAndEnableSpecific, _
False, False, selectionMask_array, daxis, cursor)
If resp = Selection.Response.ObjectSelected Or _
resp = Selection.Response.ObjectSelectedByName Then
Return Selection.Response.Ok
ElseIf resp = Selection.Response.Back Then
Return Selection.Response.Back
Else
Return Selection.Response.Cancel
End If
End Function

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

Comments

Seems ridiculous. Why do we need a new VectorArithmetic.Vector3 class; we already have NXOpen.Vector3d. Similarly, why do we need VectorArithmetic.Matrix3 when we already have NXOpen.Matrix3x3. Looks like the people who implemented the VectorArithmetic class didn't know anything about the existing types. And, to make matters worse, the components of a Vector3 are single-precision floats (in NX8.5), not doubles.

The SNAP Position, Vector, and Orientation classes are a far better design. And these classes are available in the free MiniSNAP version, so you can use them even if you don't have a SNAP license.

Here's what the computational part of the code looks like if you use MiniSnap (put Imports MiniSnap at the top of the file):

' Get datum plane data
Dim dplaneOrigin As Position = dPlane.Origin
Dim dplaneNormal As Vector = dPlane.Normal

' Get datum axis data
Dim daxisOrigin As Position = dAxis.Origin
Dim daxisDirection As Vector = dAxis.Direction

' Calculation of point on dplane. Vector math.
Dim subvector As Vector = dplaneOrigin - daxisOrigin
Dim sub1 As Double = dplaneNormal*subvector
Dim sub2 As Double = dplaneNormal*daxisDirection
Dim w1 As Double = sub1 / sub2
Dim pointOnDplane As Position = daxisOrigin + w1*daxisDirection

I have no issue with the comment that Snap is much more simpler to code. If a user does not use Snap then the added VectorArithmetic namespace can be useful for the following reasons.
1. We cannot do add, subtract, divide using the +, -, / operators using vector3d. These operator can be used with vector3 directly
2. We cannot do dot or cross product of Vector3d directly. We have two ways of doing this using Vector3d. One is to use UF_VEC wrapper functions. However one needs to use Double(2) array rather then Vector3d.X, Vector3d.Y and Vector3d.Z values. As I have done, write ones own functions which use Vector3d values

Similar arguments apply to matrix3 versus matrix3x3

Frank Swinkels

I agree that Vector3d and Point3d are brain-dead.

But MiniSNAP is free. Everyone has it. It includes the Position and Vector classes. I don't see why anyone would want to use the VectorArithmetic classes instead.

Another benefit of the Snap/MiniSnap classes ... they are highly interoperable with Point3d and Vector3d, because implicit conversions are performed behind the scenes. In my code above, there are several examples of this.