' This allows you to select a planar face.
'
' The program will then find the longest LINEAR edge of that face.
' It will find the start and end points of that edge.
'
' Then it will find the LINEAR edge of the face that intersects
' the longest edge at the start point of the long edge.
'
' It creates vectors based on those two edges, and then creates
' a matrix from those vectors.
'
' It creates a CSYS entity whose origin is at the start point of
' the long edge, and which is aligned to the matrix.
'
' Then it moves the WCS to the newly-created CSYS.
'
' There is very little error-checking, so it may not behave nicely if
' one of the expected prerequisites mentioned above is not met.
'
' Also, you might want to modify it to allow the user to
' reverse the X-vector and put the origin at the other end
' of the longest edge, because it is hard-coded to use the start
' point of that edge, which will sometimes be wrong.
Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.UI
Imports NXOpen.Utilities
Module wcs_from_face_and_longest_edge
Dim s As Session = Session.GetSession()
Dim ufs As UFSession = UFSession.GetUFSession()
Dim lw As ListingWindow = s.ListingWindow
Sub Main()
Dim planarFace As NXOpen.Tag = NXOpen.Tag.Null
Dim longEdge As NXOpen.Tag = NXOpen.Tag.Null
Dim otherEdge As NXOpen.Tag = NXOpen.Tag.Null
Dim origin() As Double = {0, 0, 0}
Dim xVector(2) As Double
Dim yVector(2) As Double
If select_a_planar_face(planarFace) = Selection.Response.Ok Then
ufs.Disp.SetHighlight(planarFace, 0)
End If
Dim faceObject As Face = NXObjectManager.Get(planarFace)
Dim edges() As Edge = faceObject.GetEdges()
longEdge = get_longest_edge(edges)
Dim sp(2) As Double
Dim ep(2) As Double
Dim lineData As UFCurve.Line
lineData.start_point = sp
lineData.end_point = ep
ufs.Curve.AskLineData(longEdge, lineData)
sp = lineData.start_point
ep = lineData.end_point
ufs.Vec3.Sub(ep, sp, xVector)
ufs.Vec3.Copy(sp, origin)
Dim sp2(2) As Double
Dim ep2(2) As Double
otherEdge = find_edge_adjacent_to_start_point(edges, sp, longEdge)
ufs.Curve.AskLineData(otherEdge, lineData)
sp2 = lineData.start_point
ep2 = lineData.end_point
If sp2(0) = sp(0) And sp2(1) = sp(1) And sp2(2) = sp(2) Then
ufs.Vec3.Sub(ep2, sp2, yVector)
Else
ufs.Vec3.Sub(sp2, ep2, yVector)
End If
Dim mtx As NXOpen.Tag = NXOpen.Tag.Null
Dim new_csys As NXOpen.Tag = NXOpen.Tag.Null
Dim mtx_vals(8) As Double
ufs.Mtx3.Initialize(xVector, yVector, mtx_vals)
ufs.Csys.CreateMatrix(mtx_vals, mtx)
ufs.Csys.CreateCsys(origin, mtx, new_csys)
If new_csys <> NXOpen.Tag.Null Then
ufs.Csys.SetWcs(new_csys)
End If
End Sub
Function find_edge_adjacent_to_start_point(ByVal edges() As Edge, _
ByVal org() As Double, ByVal longEdge As NXOpen.Tag) As NXOpen.Tag
Dim thisEdge As NXOpen.Tag = NXOpen.Tag.Null
Dim inx As Integer = 0
For inx = 0 To edges.GetUpperBound(0)
thisEdge = edges(inx).Tag
If thisEdge <> longEdge Then ' to make sure we skip the xVector edge
Dim edgeType As Integer = 0
ufs.Modl.AskEdgeType(thisEdge, edgeType)
If edgeType = UFConstants.UF_MODL_LINEAR_EDGE Then
Dim sp(2) As Double
Dim ep(2) As Double
Dim lineData As UFCurve.Line
lineData.start_point = sp
lineData.end_point = ep
ufs.Curve.AskLineData(thisEdge, lineData)
sp = lineData.start_point
ep = lineData.end_point
If sp(0) = org(0) And sp(1) = org(1) And sp(2) = org(2) Then
Return thisEdge
End If
If ep(0) = org(0) And ep(1) = org(1) And ep(2) = org(2) Then
Return thisEdge
End If
End If
End If
Next
End Function
Function get_longest_edge(ByVal edges() As Edge) As NXOpen.Tag
Dim lgth As Double = 0
Dim inx As Integer = 0
Dim thisEdge As NXOpen.Tag = NXOpen.Tag.Null
Dim longestNumber As Double = 0
Dim longestEdge As NXOpen.Tag = NXOpen.Tag.Null
For inx = 0 To edges.GetUpperBound(0)
thisEdge = edges(inx).Tag
Dim edgeType As Integer = 0
ufs.Modl.AskEdgeType(thisEdge, edgeType)
If edgeType = UFConstants.UF_MODL_LINEAR_EDGE Then
ufs.Curve.AskArcLength(thisEdge, 0, 1, ModlUnits.ModlUnitsPart, lgth)
If lgth > longestNumber Then
longestEdge = thisEdge
longestNumber = lgth
End If
End If
Next inx
Return longestEdge
End Function
Function select_a_planar_face(ByRef face As NXOpen.Tag) As Selection.Response
Dim message As String = "Planar Face:"
Dim title As String = "Select a PLANAR FACE"
Dim scope As Integer = UFConstants.UF_UI_SEL_SCOPE_ANY_IN_ASSEMBLY
Dim response As Integer
Dim view As NXOpen.Tag
Dim cursor(2) As Double
Dim mask_face As UFUi.SelInitFnT = AddressOf mask_for_planar_faces
ufs.Ui.LockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
Try
ufs.Ui.SelectWithSingleDialog(message, title, scope, mask_face, _
Nothing, response, face, cursor, view)
Finally
ufs.Ui.UnlockUgAccess(UFConstants.UF_UI_FROM_CUSTOM)
End Try
If response <> UFConstants.UF_UI_OBJECT_SELECTED And _
response <> UFConstants.UF_UI_OBJECT_SELECTED_BY_NAME Then
Return Selection.Response.Cancel
Else
Return Selection.Response.Ok
End If
End Function
Function mask_for_planar_faces(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 = UFConstants.UF_solid_face_subtype
mask_triples(0).solid_type = UFConstants.UF_UI_SEL_FEATURE_PLANAR_FACE
ufs.Ui.SetSelMask(select_, _
UFUi.SelMaskAction.SelMaskClearAndEnableSpecific, _
num_triples, mask_triples)
Return UFConstants.UF_UI_SEL_SUCCESS
End Function
Public Function GetUnloadOption(ByVal dummy As String) As Integer
Return Session.LibraryUnloadOption.Immediately
End Function
End Module