NX8 Journaling: Creation of a datum CSYS from plane and point data imported from a journal
NX8 Journaling: Creation of a datum CSYS from plane and point data imported from a journal
(OP)
I am looking to add to a journal to create some datum CSYS.
Currently, the journal will path to and import two text files. The first text file contains coordinates for three sets of points that are used to create a plane. Big shoutout to FrankSwinks for helping me with that task in this thread: thread561-317741: Creation of Datum Plane from 3 points in a Text File. That code looks like this:
The second text file contains coordinates for sets of three points. Each set will correspond to one of the planes imported from the previous file, and the third point in each group will intersect with the corresponding datum plane previously created (so point 3 will intersect with plane 1, point 6 will intersect with plane 2, and so on) These points are imported as below (Big ups to cowski in this thread: thread561-284673: Grip code that reads in a CSV text file of points? for the assist here):
The previous code also saved the coordinates of the first and last point that intersected with the created planes. I use these points to create a line and find the midpoint of that line in the following code (Big ups to cowski again here as I got this info from his excellent site http://www.nxjournaling.com):
So now that we've talked about what I can do, now I want to shift gears to what I want to do. I would like this journal to use the created points, planes, and lines to create a datum CSYS that will be oriented such that the X-axis is normal the the created datum plane, the Y-axis is pointing back toward the midpoint of the line we previously created, and its origin is at the point that intersects with the datum plane. I'm sure I worded this poorly, so I have attached a picture.
Any help would be greatly appreciated. Thanks in advance for your time and thanks for reading all this.
Currently, the journal will path to and import two text files. The first text file contains coordinates for three sets of points that are used to create a plane. Big shoutout to FrankSwinks for helping me with that task in this thread: thread561-317741: Creation of Datum Plane from 3 points in a Text File. That code looks like this:
CODE -->
Dim planesFile As String
Dim linestring As String = Nothing
Dim testArray() As String
Dim pnt1(2) As Double
Dim pnt2(2) As Double
Dim pnt3(2) As Double
Dim temptag As Tag = Tag.Null
Dim name1 As String = Nothing
planesFile = FILE PATH DATA GOES HERE
' read data and create datum planes
Dim sr As StreamReader = File.OpenText(planesFile)
Try
Do While sr.Peek >= 0
linestring = sr.ReadLine
testArray = Split(linestring, ",", 10)
pnt1(0) = CType(testArray(0), Double)
pnt1(1) = CType(testArray(1), Double)
pnt1(2) = CType(testArray(2), Double)
pnt2(0) = CType(testArray(3), Double)
pnt2(1) = CType(testArray(4), Double)
pnt2(2) = CType(testArray(5), Double)
pnt3(0) = CType(testArray(6), Double)
pnt3(1) = CType(testArray(7), Double)
pnt3(2) = CType(testArray(8), Double)
name1 = testArray(9)
CreateDatumPlane(pnt1, pnt2, pnt3, name1)
Loop
Catch ex As Exception
MsgBox("Wrong data format")
End Try
sr.Close()
sr.Dispose() The second text file contains coordinates for sets of three points. Each set will correspond to one of the planes imported from the previous file, and the third point in each group will intersect with the corresponding datum plane previously created (so point 3 will intersect with plane 1, point 6 will intersect with plane 2, and so on) These points are imported as below (Big ups to cowski in this thread: thread561-284673: Grip code that reads in a CSV text file of points? for the assist here):
CODE -->
Dim pointsFile as String
Dim num_points As Long
Dim x As Double
Dim y As Double
Dim z As Double
Dim strlines() As String
Dim strline() As String
'initializing variables for the alignment line on layer 62
Dim AlignLinePoint1 as Point3d
Dim AlignLinePoint2 as Point3d
pointsFile = FILE PATH DATA GOES HERE
Dim tmpstream As StreamReader = File.OpenText(pointsFile)
'read the points into an array
'Load content of file to strLines array
strlines = tmpstream.ReadToEnd().Split(Environment.NewLine)
' Count number of points
num_points = UBound(strlines)
Dim i As Integer
for i = 0 to num_points - 1
strline = strlines(i).Split(",")
x = CDbl(strline(0))
y = CDbl(strline(1))
z = CDbl(strline(2))
Dim coordinates1 As Point3d = New Point3d(x, y, z)
Dim point1 As Point
point1 = workPart.Points.CreatePoint(coordinates1)
point1.SetVisibility(SmartObject.VisibilityOption.Visible)
point1.RedisplayObject()
coordinates1 = nothing
point1 = nothing
'Saves x,y,and z coordinates for the Alignment Line Point 1
If i = 2 Then
AlignLinePoint1.x = x
AlignLinePoint1.y = y
AlignLinePoint1.z = z
End If
'Saves x,y,and z coordinates for the Alignment Line Point 2
If i = num_points - 1 Then
AlignLinePoint2.x = x
AlignLinePoint2.y = y
AlignLinePoint2.z = z
End If
next The previous code also saved the coordinates of the first and last point that intersected with the created planes. I use these points to create a line and find the midpoint of that line in the following code (Big ups to cowski again here as I got this info from his excellent site http://www.nxjournaling.com):
CODE -->
workPart.Curves.CreateLine(AlignLinePoint1, AlignLinePoint2) 'create scalar representing the 50% distance between two points (midpoint) Dim distanceScalar As Scalar distanceScalar = workPart.Scalars.CreateScalar(0.5, Scalar.DimensionalityType.None, SmartObject.UpdateOption.WithinModeling) 'create midpoint between Import Points of DPF1 and the last DPF 'Next lines basically shift the point types to 'Point' instead of 'Point3d' due to the incompatibility of the distance scalar 'function for use with the point creation at the midline between two points. Dim ToeLinePoint1 as Point = workPart.Points.CreatePoint(AlignLinePoint1) Dim ToeLinePoint2 as Point = workPart.Points.CreatePoint(AlignLinePoint2) Dim AlignMidPoint As Point AlignMidPoint = workPart.Points.CreatePoint(ToeLinePoint1, ToeLinePoint2, distanceScalar, SmartObject.UpdateOption.WithinModeling) AlignMidPoint.RemoveParameters() AlignMidPoint.SetVisibility(SmartObject.VisibilityOption.Visible)
So now that we've talked about what I can do, now I want to shift gears to what I want to do. I would like this journal to use the created points, planes, and lines to create a datum CSYS that will be oriented such that the X-axis is normal the the created datum plane, the Y-axis is pointing back toward the midpoint of the line we previously created, and its origin is at the point that intersects with the datum plane. I'm sure I worded this poorly, so I have attached a picture.
Any help would be greatly appreciated. Thanks in advance for your time and thanks for reading all this.





RE: NX8 Journaling: Creation of a datum CSYS from plane and point data imported from a journal
Given three point data defining plane corner point P1, plane X direction point P2, and plane Y direction point P3 and two data point for a line P3 - P4 then using these five point coordinates we can determine the CSYS origin from the mathematical intersection of the line P1-P2 with the plane defined by P1,P2 and P3. The CSYS orientation is defined from the plane points P1, P2 and P3.
Before I write the code is this what you want?
Frank Swinkels
RE: NX8 Journaling: Creation of a datum CSYS from plane and point data imported from a journal
RE: NX8 Journaling: Creation of a datum CSYS from plane and point data imported from a journal
CODE -->
Option Strict Off Imports System Imports NXOpen Imports NXOpen.Features Imports NXOpen.UF Module DatumCSYS Dim s As Session = Session.GetSession() Dim ufs As UFSession = UFSession.GetUFSession() Dim workPart As Part = s.Parts.Work Sub Main() Dim response As Selection.Response = Nothing Dim response2 As Selection.Response = Nothing Dim dplane1 As DatumPlane = Nothing Dim line1 As Line = Nothing Start1: response = select_a_Dplane(dplane1) If response = Selection.Response.Back Then GoTo End1 If response = Selection.Response.Cancel Then GoTo End1 response2 = select_a_Line(line1) If response2 = Selection.Response.Back Then GoTo Start1 ' Select a new face If response2 = Selection.Response.Cancel Then GoTo End1 Dim originonplane As Point3d = GetLinePlaneIntersectionPoint(dplane1, line1) CreateDatumCSYS(dplane1, line1, originonplane) End1: End Sub Function select_a_Dplane(ByRef obj As DatumPlane) As Selection.Response Dim ui As UI = ui.GetUI() Dim selectionMask_array(1) 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.SelectObject("Select a Datum Plane", "Select a Datum Plane", _ Selection.SelectionScope.WorkPart, _ Selection.SelectionAction.ClearAndEnableSpecific, _ False, False, selectionMask_array, obj, 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 Function select_a_Line(ByRef ln1 As Line) Dim ui As UI = ui.GetUI() Dim mask(0) As Selection.MaskTriple With mask(0) .Type = UFConstants.UF_line_type .Subtype = 0 .SolidBodySubtype = 0 End With Dim cursor As Point3d = Nothing Dim resp As Selection.Response = _ ui.SelectionManager.SelectObject("Select a Line", "Select a Line", _ Selection.SelectionScope.AnyInAssembly, _ Selection.SelectionAction.ClearAndEnableSpecific, _ False, False, mask, ln1, 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 GetLinePlaneIntersectionPoint(ByVal dplane1 As DatumPlane, ByVal line1 As Line) As Point3d ' get intersection pt of line on datum plane ' datum plane data Dim dplaneOrigin(2) As Double Dim dplaneNormal(2) As Double ufs.Modl.AskDatumPlane(dplane1.Tag, dplaneOrigin, dplaneNormal) ' line data for line pnt and line vector Dim startpnt As Point3d = line1.StartPoint Dim endpnt As Point3d = line1.EndPoint Dim pnt1() As Double = {startpnt.X, startpnt.Y, startpnt.Z} Dim pnt2() As Double = {endpnt.X, endpnt.Y, endpnt.Z} Dim distance1 As Double = Nothing Dim distance2 As Double = Nothing Dim linevec(2) As Double Dim tol1 As Double = 0.001 Dim mag1 As Double = Nothing ufs.Vec3.Distance(dplaneOrigin, pnt1, distance1) ufs.Vec3.Distance(dplaneOrigin, pnt2, distance2) Dim point1(2) As Double Dim sub1 As Double = Nothing Dim sub2 As Double = Nothing Dim w As Double = Nothing If distance1 > distance2 Then ' use startpnt and pnt1 ufs.Vec3.Sub(pnt1, pnt2, linevec) ufs.Vec3.Unitize(linevec, tol1, mag1, linevec) ' dplaneOrigin - line origin point1(0) = dplaneOrigin(0) - pnt1(0) point1(1) = dplaneOrigin(1) - pnt1(1) point1(2) = dplaneOrigin(2) - pnt1(2) ' dplaneNormal dot point1 ufs.Vec3.Dot(dplaneNormal, point1, sub1) ' dplaneNormal dot linevec ufs.Vec3.Dot(dplaneNormal, linevec, sub2) ' w is the parameter value of a line from the line point to the dplane along line vector w = sub1 / sub2 ' calculate the point on the dpane point1(0) = pnt1(0) + w * linevec(0) point1(1) = pnt1(1) + w * linevec(1) point1(2) = pnt1(2) + w * linevec(2) Else ' use endpnt and pnt2 ufs.Vec3.Sub(pnt2, pnt1, linevec) ufs.Vec3.Unitize(linevec, tol1, mag1, linevec) ' dplaneOrigin - line origin point1(0) = dplaneOrigin(0) - pnt2(0) point1(1) = dplaneOrigin(1) - pnt2(1) point1(2) = dplaneOrigin(2) - pnt2(2) ' dplaneNormal dot point1 ufs.Vec3.Dot(dplaneNormal, point1, sub1) ' dplaneNormal dot linevec ufs.Vec3.Dot(dplaneNormal, linevec, sub2) ' w is the parameter value of a line from the line point to the dplane along line vector w = sub1 / sub2 ' calculate the point on the dpane point1(0) = pnt2(0) + w * linevec(0) point1(1) = pnt2(1) + w * linevec(1) point1(2) = pnt2(2) + w * linevec(2) End If ' create the point Dim pointTag As Tag = Tag.Null ufs.Curve.CreatePoint(point1, pointTag) Dim pnt3d As Point3d = New Point3d(point1(0), point1(1), point1(2)) Return pnt3d End Function Public Sub CreateDatumCSYS(ByVal dplane1 As DatumPlane, ByVal line1 As Line, ByVal originpt As Point3d) ' datum plane data Dim dplaneOrigin(2) As Double Dim xvec(2) As Double ufs.Modl.AskDatumPlane(dplane1.Tag, dplaneOrigin, xvec) Dim startpnt As Point3d = line1.StartPoint Dim endpnt As Point3d = line1.EndPoint Dim linevec(2) As Double ' get midpoint of line Dim midpnt(2) As Double midpnt(0) = (startpnt.X + endpnt.X) / 2.0 midpnt(1) = (startpnt.Y + endpnt.Y) / 2.0 midpnt(2) = (startpnt.Z + endpnt.Z) / 2.0 Dim yvec(2) As Double Dim zvec(2) As Double Dim originpt1() As Double = {originpt.X, originpt.Y, originpt.Z} ufs.Vec3.Sub(midpnt, originpt1, yvec) ufs.Vec3.Cross(xvec, yvec, zvec) If xvec(2) > 0.0 Then If yvec(2) > 0.0 Then ufs.Vec3.Cross(zvec, xvec, yvec) Else ufs.Vec3.Cross(xvec, zvec, yvec) End If Else If yvec(2) < 0.0 Then ufs.Vec3.Cross(zvec, xvec, yvec) Else ufs.Vec3.Cross(xvec, zvec, yvec) End If End If Dim coordsx As Point3d = New Point3d(originpt.X + xvec(0), originpt.Y + xvec(1), originpt.Z + xvec(2)) Dim coordsy As Point3d = New Point3d(originpt.X + yvec(0), originpt.Y + yvec(1), originpt.Z + yvec(2)) Dim nullFeatures_Feature As Features.Feature = Nothing Dim datumCsysBuilder1 As Features.DatumCsysBuilder datumCsysBuilder1 = workPart.Features.CreateDatumCsysBuilder(nullFeatures_Feature) Dim point1 As Point point1 = workPart.Points.CreatePoint(originpt) Dim point2 As Point point2 = workPart.Points.CreatePoint(coordsx) Dim point3 As Point point3 = workPart.Points.CreatePoint(coordsy) Dim xform1 As Xform xform1 = workPart.Xforms.CreateXform(point1, point2, point3, SmartObject.UpdateOption.WithinModeling, 1.0) Dim cartesianCoordinateSystem1 As CartesianCoordinateSystem cartesianCoordinateSystem1 = workPart.CoordinateSystems.CreateCoordinateSystem(xform1, SmartObject.UpdateOption.WithinModeling) datumCsysBuilder1.Csys = cartesianCoordinateSystem1 datumCsysBuilder1.DisplayScaleFactor = 1.25 Dim nXObject1 As NXObject nXObject1 = datumCsysBuilder1.Commit() datumCsysBuilder1.Destroy() 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 ModuleRegards
Frank Swinkels
RE: NX8 Journaling: Creation of a datum CSYS from plane and point data imported from a journal
Again, thanks for taking the time.
RE: NX8 Journaling: Creation of a datum CSYS from plane and point data imported from a journal
In Frank's code, the user specifies the plane normal of the X-axis, the line for the direction of the Y-axis, and the origin point of the datum CSYS. From the previous code I had done, the journal reads in a file with three points and creates a plane. I save these planes in an array to call later to pass to the CreateDatumCSYS() function in Frank's code. The origin point of the CSYS is established by every third point in the text file that is imported by the journal in the second bit of code I posted, and this point location is passed to the CreateDatumCSYS() function at each location.
The problem appears to be the line that is passed as the second variable in the CreateDatumCSYS() function. This line will always have a starting point that is the same as the desired origin point of the CSYS at that location (a known value as previously stated). The ending point of the line will always be the AlignMidPoint variable, which is a point I establish in the third bit of code in the original post. I use these two points to create the line that is passed as the second variable in the CreateDatumCSYS() function. When I do this, there is an inconsistency in the direction of the resulting Y-axis of the CSYS that is created, and it seems to not matter the order of the points that are used to create the line passed in the CreateDatumCSYS() function.
I'm not sure how clear that last paragraph is, but I always want the Y-axis of the created datum CSYS to be pointing back toward the AlignMidPoint defined earlier (third bit of code in the original post).
________________________________________________________________________________________________________________________________________
On a separate note but something I touched on in the last post, how difficult would it be to take all points, lines, bodies, everything from all layers and move them from a defined CSYS to the part's absolute coordinate system? This would essentially automate the process of doing a 'Move Object' function of the 'CSYS to CSYS' variety and selecting everything in the part.
Thanks to Frank for the help he has given already and thanks to anyone else who might be able to lend a hand.
RE: NX8 Journaling: Creation of a datum CSYS from plane and point data imported from a journal
Frank Swinkels