In today's bite size piece of code, we explore the SclSelectPoint functionality and how we can use it to access the hierarchy of data attached to any selected point.
The Surpac data hierarchy goes something like this; Point->Segment->String->Layer->Viewport. To put it another way, One or more points make a segment. One or more segments make a string. One or more strings make up a layer and a viewport can contain multiple layers however, at least one layer must always be present. By default, this is the "main graphics layer."
Just by selecting a single point in graphics with the SclSelectPoint command, I'm able to access all parts of the hierarchy attached to that point using the SclGetParent function. I'm then able to find out information like;
- Area
- Length
- Direction (Clockwise or Anti-Clockwise or open)
- Closure
- Coordinates
A few special points of interest in the macro;
- The use of NINT to round a number to the nearest integer
- FORMAT to trim up the amount of decimal places in a number
- SclGetValueByName to extract information from a point, segment, string or layer
- SclSetValueByName to add information to a point
- SclCountItems to count the number of points in a segment
- SclErase to hide a segment
- SclDraw to display a segment
If you have any questions or comments, please add them in the comments section below. If you have success running the macro on some simple data, why don't you try to;
- Put the macro in a loop so you can select more than one point
- See if you can modify the coordinates of a point (SclSetValueByName - See Surpac Help)
- Calculate the centroid of a selected polygon and create a point
- For a more advanced challenge, add information like area, length etc to the d1, d2 field of the created centroid
As always, I've added my notes in Bold and Italics but download the macro at the bottom of the page to try it out firsthand.
#The Surpac hierarchy is Point, Segment, String, Layer, Viewport. We can select a point and get each "Parent" item using SclGetParent set status [SclSelectPoint userPnt "Select any point on a segment to see its properties" layer strNum segNum pntNum x y z desc] \$userPnt SclGetParent userSeg;# From the point selected, get a handle to the segment \$userSeg SclGetParent userStr;# From the segment, get a handle to the string \$userStr SclGetParent userLayer;# From the string, get a handle to the layer #What can we do now that we have a "handle" to this data. Surpac provides other key SCL commands. Note these are operating on the segment "\$userSeg" set area [SclExpr NINT([\$userSeg SclGetValueByName area])];# using NINT - nearest integer, to remove decimal places. set length [SclExpr FORMAT([\$userSeg SclGetValueByName 2dlength],2)];# using FORMAT to trim up the amount fo decimal places to 2. set closure [\$userSeg SclGetValueByName closure] set direction [\$userSeg SclGetValueByName direction] set shape [\$userSeg SclGetValueByName shapetype] puts "The area is \$area with length \$length. It is a \$closure segment of \$direction direction. The shape is \$shape." #Want to get the Min and Max z value of an entire layer, that can be done too. Note these are operating on the layer "userLayer" set zmin [\$userLayer SclGetValueByName zmin] set zmax [\$userLayer SclGetValueByName zmax] puts "The Min Z value of \$layer layer is \$zmin, the max value is \$zmax." #Want to store some of this information into the first point of a segment, That can be done too. \$userSeg SclGetItem firstPnt 0;# 0 is the first point as it works on an index position which starts at zero. \$firstPnt SclSetValueByName d1 \$area \$firstPnt SclSetValueByName d2 \$length #Delete the information from the last point in the chosen segment. \$userSeg SclGetItem lastPnt [expr [\$userSeg SclCountItems]-1];# This provides access to the last point. \$lastPnt SclSetValueByName d1 "" \$lastPnt SclSetValueByName d2 "" #Now we have a handle to the first point of the selected segment "\$firstPnt" lets extract the X and Y values for it. set x [SclExpr FORMAT([\$firstPnt SclGetValueByName x],3)] set y [SclExpr FORMAT([\$firstPnt SclGetValueByName y],3)] puts "The first point coordinates are X = \$x and Y = \$y" #Want to hide the selected segment \$userSeg SclErase SclPause 3;#Pause the macro for 3 seconds #Let's display it again \$userSeg SclDraw puts "Macro Finished"