The point is a fundamental object for 3D modeling. It is a simple object, so will serve well for learning purposes; but they are also useful because they are often required when creating more complex entities (lines, arcs, splines, etc).
Even more fundamental than a point object is the Point3d structure, the NXOpen representation of a 3D coordinate. The Point3d is a three element array of doubles which provides the programmer (that’s us) a convenient way to access the X, Y, and Z coordinate values along with a few useful methods. A Point3d is simply variable data in your journal; by itself it does not create a visible point object. It does not appear in the NX graphics window or as an object anywhere in the interactive display, for that matter.
The Point3d structure provides a constructor which allows you to assign values at the time the variable is declared.
'create Point3d using the constructor
Dim myPt1 As New Point3d(0, 0, 0)
Alternatively, you can declare the variable and assign values later.
'create Point3d, then assign values
Dim myPt2 As Point3d
myPt2.X = 0
myPt2.Y = 0
myPt2.Z = 0
Like many NXOpen objects, the Point3d structure has a .ToString method. This method will return a string representation of the object. In the case of a Point3d, it will return labeled coordinate information.
The .Equals method allows you to test if one object equals another; a boolean value of True or False is returned.
The .GetType method will return the type of the object it is used on. This is useful when you are cycling through objects in the file looking for a particular type. If you use .GetType.ToString() on a Point3d variable, the string value “NXOpen.Point3d” will be returned.
The .X, .Y, and .Z members can be used to get or set the respective coordinate data. In the myPt2 example above, the XYZ members were used to assign values to the Point3d. We can assign new values in the same way.
myPt2.X = 2.71
myPt2.Y = 3.14
myPt2.Z = myPt2.Y * 2
Once a value is assigned, it can be used just like any other variable. You will notice the Z value above uses the Y value in its assignment.
Finally, the Point3d also provides the .GetHashCode() method. Hash codes are beyond the scope of this tutorial; but if you are interested,
Wikipedia has a decent introductory article.
There is also a Point2d structure with all the methods and members of the Point3d structure, with the exception of the .Z member. As you may guess, this structure comes in handy for dealing with coordinates on the X-Y plane.
Below is a very short journal illustrating the use of the Point3d structure.
Option Strict Off
Imports System
Imports NXOpen
Module Points_01a
Sub Main()
Dim theSession As Session = Session.GetSession()
Dim rnd1 As New Random()
Dim lw As ListingWindow = theSession.ListingWindow
lw.Open()
'create Point3d using the constructor
Dim myPt1 As New Point3d(0, 0, 0)
'create Point3d, then assign values
Dim myPt2 As Point3d
myPt2.X = 0
myPt2.Y = 0
myPt2.Z = 0
'output point information
lw.WriteLine("myPt1: " & myPt1.ToString)
lw.WriteLine("myPt2: " & myPt2.ToString)
lw.WriteLine("myPt1 = myPt2 : " & myPt1.Equals(myPt2).ToString)
lw.WriteLine("myPt1.GetType.ToString: " & myPt1.GetType.ToString)
lw.WriteLine("")
'change values of myPt1 using random numbers
myPt1.X = rnd1.Next(-10, 10) + rnd1.NextDouble
myPt1.Y = rnd1.Next(-10, 10) + rnd1.NextDouble
myPt1.Z = rnd1.Next(-10, 10) + rnd1.NextDouble
'output new point information
lw.WriteLine("myPt1: " & myPt1.ToString)
lw.WriteLine("myPt2: " & myPt2.ToString)
lw.WriteLine("myPt1 = myPt2 : " & myPt1.Equals(myPt2).ToString)
lw.WriteLine("")
'show values of myPt1 rounded to 3 decimal places
lw.WriteLine(myPt1.X.ToString("[X=0.###;[X=-0.###") & "," & myPt1.Y.ToString("Y=0.###;Y=-0.###") & "," & myPt1.Z.ToString("Z=0.###];Z=-0.###]"))
lw.Close()
End Sub
Public Function GetUnloadOption(ByVal dummy As String) As Integer
'Unloads the image when the NX session terminates
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination
End Function
End Module
The NXOpen .NET API help file lists no less than 20 ways to create a point, considering that most of these methods can be used for creating a dumb point or an associative point feature, you’ll see that there is simply too much ground to cover in one tutorial. We’ll look at a basic method for creating dumb points and build on that in later tutorial(s).
Creating a dumb point with CreatePoint(Point3d)
Option Strict Off
Imports System
Imports NXOpen
Module Points_01b
Sub Main()
Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim rnd1 As New Random()
Dim lw As ListingWindow = theSession.ListingWindow
Dim newPt(1000) As Point
Dim max As Integer
lw.Open()
'lw.WriteLine(workPart.PartUnits.ToString)
If workPart.PartUnits = Part.Units.Inches Then
max = 10
Else 'metric file
max = 250
End If
'create Point3d using the constructor
Dim myPt1 As New Point3d(0, 0, 0)
'lw.WriteLine("max = " & max)
For i As Integer = 0 To 1000
'change values of myPt1 using random numbers
myPt1.X = rnd1.Next(-max, max) + rnd1.NextDouble
myPt1.Y = rnd1.Next(-max, max) + rnd1.NextDouble
myPt1.Z = rnd1.Next(-max, max) + rnd1.NextDouble
newPt(i) = workPart.Points.CreatePoint(myPt1)
newPt(i).SetVisibility(SmartObject.VisibilityOption.Visible)
newPt(i).Layer = rnd1.Next(1, 257)
Next
lw.Close()
End Sub
Public Function GetUnloadOption(ByVal dummy As String) As Integer
'Unloads the image when the NX session terminates
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination
End Function
End Module
The journal starts off by declaring some variables; all of the code is contained within Sub Main() so there are no module level variables declared. The notable declarations here are:
Dim rnd1 As New Random()
Random is a class in the .NET framework used to generate random numbers. We'll use it to generate point coordinate data.
Dim newPt(1000) As Point
Point is a class in the NXOpen API used to represent point objects.
The next section of code checks the part units (inch or millimeter) and sets the value of a variable named max accordingly. The max variable will be used to define a bounding cube for the points we generate.
The for loop creates the points. Coordinate data is generated by random numbers.
myPt1.X = rnd1.Next(-max, max) + rnd1.NextDouble
rnd1.Next(-max, max) returns a random integer in the range -max (inclusive) to max (exclusive); rnd1.NextDouble returns a random number between 0 (inclusive) and 1 (exclusive). The X, Y, and Z coordinate data for each point can then range anywhere within -max to max.
Each part file has a PointCollection object associated to it. It is through this object that we can query existing points and create new ones. CreatePoint(point3d) is a method of the PointCollection object, the following line of code accesses the point collection of the work part and creates the point... mostly
newPt(i) = workPart.Points.CreatePoint(myPt1)
The default visibility option for new points is "Invisible", not what we need for this journal. So...
newPt(i).SetVisibility(SmartObject.VisibilityOption.Visible)
makes our new point visible.
The following line assigns the point object to a random layer (1-256). If you don't specify properties such as color, layer, lineweight (not very useful for points), etc. they will be assigned the current default. All the points will be created in your current color (or default color for points if you have one specified) and if you comment out the layer assignment all the points will be created on your work layer. I assign the point to a random layer so that in the next journal we can see how to access and modify property values such as layer, color, etc.
Working with existing points
The following journal demonstrates how to work with existing points in a file. Run the previous journal that creates points before running this one.
Option Strict Off
Imports System
Imports NXOpen
Module Points_01c
Sub Main()
Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work
Dim lw As ListingWindow = theSession.ListingWindow
Dim max As Double
Dim myPoints() As Point
Dim pointsOnLayer(256) As Integer
Dim maxPoints As Integer
Dim maxLayer As Integer
Dim ptXYZ As Point3d
lw.Open()
'lw.WriteLine(workPart.PartUnits.ToString)
If workPart.PartUnits = Part.Units.Inches Then
max = 10
Else 'metric file
max = 250
End If
myPoints = workPart.Points.ToArray
For Each tempPoint As Point In myPoints
'if the layer number is odd, move point to next even numbered layer
If tempPoint.Layer Mod 2 > 0 Then
tempPoint.Layer += 1
End If
'keep track of how many points are on each layer
pointsOnLayer(tempPoint.Layer) += 1
'keep track of which layer has the most point objects
If pointsOnLayer(tempPoint.Layer) > maxPoints Then
maxPoints = pointsOnLayer(tempPoint.Layer)
maxLayer = tempPoint.Layer
End If
Next
'move first 2 points to opposite corners of bounding cube
ptXYZ = New Point3d(-max, -max, -max)
myPoints(0).SetCoordinates(ptXYZ)
myPoints(0).SetName("-max, -max, -max")
myPoints(0).Color = 1
myPoints(0).RedisplayObject()
ptXYZ = New Point3d(max, max, max)
myPoints(1).SetCoordinates(ptXYZ)
myPoints(1).SetName("max, max, max")
myPoints(1).Color = 1
myPoints(1).RedisplayObject()
'turn on name display for the work view
workPart.Preferences.NamesBorderVisualization.ObjectNameDisplay = Preferences.PartVisualizationNamesBorders.NameDisplay.WorkView
'move point to closest face of bounding cube
For i As Integer = 2 To myPoints.GetUpperBound(0)
ptXYZ = myPoints(i).Coordinates
If Math.Abs(ptXYZ.X) > Math.Abs(ptXYZ.Y) Then
'x is bigger
If Math.Abs(ptXYZ.X) > Math.Abs(ptXYZ.Z) Then
'x is bigger
myPoints(i).SetCoordinates(New Point3d(Math.Sign(ptXYZ.X) * max, ptXYZ.Y, ptXYZ.Z))
Else
'z is bigger
myPoints(i).SetCoordinates(New Point3d(ptXYZ.X, ptXYZ.Y, Math.Sign(ptXYZ.Z) * max))
End If
Else
'y is bigger
If Math.Abs(ptXYZ.Y) > Math.Abs(ptXYZ.Z) Then
'y is bigger
myPoints(i).SetCoordinates(New Point3d(ptXYZ.X, Math.Sign(ptXYZ.Y) * max, ptXYZ.Z))
Else
'z is bigger
myPoints(i).SetCoordinates(New Point3d(ptXYZ.X, ptXYZ.Y, Math.Sign(ptXYZ.Z) * max))
End If
End If
myPoints(i).RedisplayObject()
Next
'report the number of points on each even numbered layer
For i As Integer = 2 To 256 Step 2
lw.WriteLine("Points on Layer: " & i & " = " & pointsOnLayer(i).ToString)
Next
lw.WriteLine("")
'report which layer has the most point objects
lw.WriteLine("Max point count = " & maxPoints & " on layer: " & maxLayer)
lw.Close()
End Sub
Public Function GetUnloadOption(ByVal dummy As String) As Integer
'Unloads the image when the NX session terminates
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination
End Function
End Module
At the start of this journal, an empty array of point objects was created. The line:
myPoints = workPart.Points.ToArray
converts the point collection of the work part to an array of Point objects and assigns it to our array variable. We now have access to all the point objects in the current work part.
The For loop checks each point in the array. If the point object is on an odd numbered layer; the journal increases the layer number by one, moving it to the next higher even numbered layer. After the layer check the journal increments an array variable that keeps track of how many points are on each layer and it increments an integer variable that keeps track of the layer number that holds the most point objects.
The next group of statements demonstrates how to change the coordinates of an existing point, set the name property, and change the color. The .RedisplayObject() method forces an update so the changes can be seen, otherwise the changes may not be apparent until the system (or user) refreshed the display.
The following statment turns on the name display in the work view so you can see which points we have assigned names to.
The next For loop moves the point to the closest face of the bounding cube. The .SetCoordinates() method is used to change the existing points and the absolute value (.Abs) and sign (.Sign) methods of the .NET Math class are used.
Finally, some information on the point objects is output to the listing window.
Conclusion
In this tutorial we learned about the Point3d structure and how it can be used to create point objects. Along the way we learned a little about the PointCollection and part units of the work part, .NET random numbers, and a couple of .NET Math functions (.Abs and .Sign). I hope you learned something that will be useful in your future journals. If you have any specific questions, find any bugs, or have any comments please email them to info@nxjournaling.com or leave them in the comments section below.
Comments
How to select snap points using a Selection dialog
can any one help me in creating a selection dialog for selection of snap points i.e., points on objects like end point,centre etc...please help me..its so urgent
point constructor
Thank you very much.
Wow..dats great support...Thanks for your timely help..this is what exactly i've been trying to do..i'm glad that i didn't hesitated to join NX journalling.
How to find and display the Sketch status ?
We have a provision in NX for checking the status of a sketch by unhiding the Column Status.It then gives status results like fully constrained,fully constrained with auto dimensioning,underconstrained etc..I want all that info into my listing window.i.e.,sketches status to be displayed exactly what it looks like in column Status.
I have identified using activateSketch,GetStatus and Deactivate sketch methods.But the problem is, it is taking much time when my part has more number of sketches.So i need an alternate method to find status of sketch.Can this be done?..Please reply immidiately.
sketch status
I know of no way to get the sketch status without first activating the sketch.
If you are simply checking the part to your site standards, I know there are some Knowledge Fusion (KF) part checks - checks for constrained sketches included. If you have access to a KF license (I do not) you might want to look into these part checks.
Thanks
I don't have KF license but still thanks for the information.
Routing Spline Segment
Hello,
I am trying to figure out how to get information for all the Routing Segments in the 3D.
I edited the code of "Working with existing points" , but it doesnt work.
Please help.
Thanks
Dim mySplines() As NXOpen.Routing.SplineSegment
lw.Open()
mySplines = workPart.NXOpen.Routing.SplineSegment.ToArray
For Each tempSpline As NXOpen.Routing.SplineSegment In mySplines
lw.WriteLine("length:" & tempSpline.Getlength() )
Next
lw.Close
REPLY: Routing Spline Segment
Forget it.
I figured it out.
MOUSE PICKING COORDINATE
Hello,
Is it possible to find the location (x,y) of mouse picking on drafting?
re: mouse picking
great! thanks!
great! thanks!
focusing on defined location
is it possible to focus on a location with given x,y coordinate in drafting?
re: focus
Can you be more specific on what you mean by "focus on a location"?
Is there an interactive NX command that has the desired behavior so we can see an example?