SCL provides a number of great functions to create, add, import and manipulate layers. There is great reference material in the Surpac->Help menu so my aim is to introduce some of these features in more layman’s terms. Some knowledge of how macro’s work with variables and commands will certainly be helpful but not essential.
In the following tip;
- My comments in the code blocks will have a # in front of them. They are also in bold and italicized.
- If you would like to test this code in Surpac, the entire code block has been added to the end of the tip. Copy it into any text editor and save it with a .tcl extension to use it in Surpac. The final result will look similar (but not the same due to styles) as the screen capture below.
Let’s start by working out what the active layer is and print the name to the message window.
# Get a reference to the active viewport (You can have more than one) store it in reference variable "vh" SclGetActiveViewport vh # Using the "vh" reference, get the active layer and store the reference in the "initialSwa" variable $vh SclGetActiveLayer initialSwa # Extract the layer name into the layerName variable using the SCL command "SclGetId" set layerName [$initialSwa SclGetId] # Print the layer name to the message window puts "Layer name is $layerName"
Now let’s create an empty layer that we can use.
# Create a layer called design that can be manipulated/inquired with the "designSwa" reference variable SclCreateSwa designSwa "design" # Use the SclAdd function to add the layer into the layer panel sclGraphicsLayers SclAdd $designSwa $vh
Now let’s create a string using string number 8.
# Using the reference to "designSwa", create a reference variable "designStr" and make the string number 8 $designSwa SclCreateString designStr 8 # Using the reference to the "designStr" create a reference variable "designSeg" and count how many items (i.e. segments) already # exist for string 8. If there are 5 existing segments in string number 8, [$designStr SclCountItems] will return a value of 5. # 5 will become the new segment number. Now, why doesn't this clash with the existing segments if there are already 5 of them? # This is because the segments are stored as an index position which starts at zero. i.e. segment 1 = index 0, segment 2 = index 1 # ... segment 5 = index 4 and so on. # All of this to say that when we count how many items are in string 8, the number returned will work as the next index position # which is what the "SclCreateSegment" function requires. So if I write it manually it becomes # $designStr SclCreateSegment designSeg 5 $designStr SclCreateSegment designSeg [$designStr SclCountItems]
Now if I stopped the macro here, you wouldn’t actually be able to see string 8 as there is no data associated with it so let’s add some points. Note that we are also adding data to the d1 field.
# Using the reference variable "designSeg" count how many points there are and add this one to the end $designSeg SclCreatePoint designPnt [$designSeg SclCountItems] $designPnt SclSetValueByName X 10 $designPnt SclSetValueByName Y 10 $designPnt SclSetValueByName Z 10 $designPnt SclSetValueByName d1 "Testing SCL layer commands"
Now create a second point in string 8 segment 1.
# Using the reference variable "designSeg" count how many points there are and add this one to the end $designSeg SclCreatePoint designPnt [$designSeg SclCountItems] $designPnt SclSetValueByName X 10 $designPnt SclSetValueByName Y 20 $designPnt SclSetValueByName Z 10
Add a third point. Note that the coordinates are changing for each point.
# Using the reference variable "designSeg" count how many points there are and add this one to the end $designSeg SclCreatePoint designPnt [$designSeg SclCountItems] $designPnt SclSetValueByName X 20 $designPnt SclSetValueByName Y 20 $designPnt SclSetValueByName Z 10
Add a fourth point.
# Using the reference variable "designSeg" count how many points there are and add this one to the end $designSeg SclCreatePoint designPnt [$designSeg SclCountItems] $designPnt SclSetValueByName X 20 $designPnt SclSetValueByName Y 10 $designPnt SclSetValueByName Z 10
Now we will close string 8 segment 1. This is done by making the first and last points have the same coordinates.
# To close the shape, make the x,y and z the same as the first point. $designSeg SclCreatePoint designPnt [$designSeg SclCountItems] $designPnt SclSetValueByName X 10 $designPnt SclSetValueByName Y 10 $designPnt SclSetValueByName Z 10
All the points we require have now been added so let’s draw them on the screen so they are visible.
# Using the reference to the design layer (designSwa), use the command "SclDraw" to draw everything in the design layer. $designSwa SclDraw SclFunction "ZOOM ALL" {}
Make the design layer the active layer in Surpac.
# Now, the active layer is still the initial layer that was active when the macro was first run. Let's make it the design layer $vh SclSetActiveLayer $designSwa
This is the end of part 1 in the TCL/SCL series. Lookout for part 2 coming in May where we will look at further layer manipulation and adding more data using procedures to simplify our code.
Entire Code Block that can be copied into a text editor and saved with a .tcl extension for testing in Surpac
# Get a reference to the active viewport (You can have more than one) store it in reference variable "vh" SclGetActiveViewport vh # Using the "vh" reference, get the active layer and store the reference in the "initialSwa" variable $vh SclGetActiveLayer initialSwa # Extract the layer name into the layerName variable using the SCL command "SclGetId" set layerName [$initialSwa SclGetId] # Print the layer name to the message window puts "Layer name is $layerName" # Create a layer called design that can be manipulated/inquired with the "designSwa" reference variable SclCreateSwa designSwa "design" # Use the SclAdd function to add the layer into the layer panel sclGraphicsLayers SclAdd $designSwa $vh # Using the reference to "designSwa", create a reference variable "designStr" and make the string number 8 $designSwa SclCreateString designStr 8 # Using the reference to the "designStr" create a reference variable "designSeg" and count how many items (i.e. segments) already # exist for string 8. If there are 5 existing segments in string number 8, [$designStr SclCountItems] will return a value of 5. # 5 will become the new segment number. Now, why doesn't this clash with the existing segments if there are already 5 of them? # This is because the segments are stored as an index position which starts at zero. i.e. segment 1 = index 0, segment 2 = index 1 # ... segment 5 = index 4 and so on. # All of this to say that when we count how many items are in string 8, the number returned will work as the next index position # which is what the "SclCreateSegment" function requires. So if I write it manually it becomes # $designStr SclCreateSegment designSeg 5 $designStr SclCreateSegment designSeg [$designStr SclCountItems] # Using the reference variable "designSeg" count how many points there are and add this one to the end $designSeg SclCreatePoint designPnt [$designSeg SclCountItems] $designPnt SclSetValueByName X 10 $designPnt SclSetValueByName Y 10 $designPnt SclSetValueByName Z 10 $designPnt SclSetValueByName d1 "Testing SCL layer commands" # Using the reference variable "designSeg" count how many points there are and add this one to the end $designSeg SclCreatePoint designPnt [$designSeg SclCountItems] $designPnt SclSetValueByName X 10 $designPnt SclSetValueByName Y 20 $designPnt SclSetValueByName Z 10 # Using the reference variable "designSeg" count how many points there are and add this one to the end $designSeg SclCreatePoint designPnt [$designSeg SclCountItems] $designPnt SclSetValueByName X 20 $designPnt SclSetValueByName Y 20 $designPnt SclSetValueByName Z 10 # Using the reference variable "designSeg" count how many points there are and add this one to the end $designSeg SclCreatePoint designPnt [$designSeg SclCountItems] $designPnt SclSetValueByName X 20 $designPnt SclSetValueByName Y 10 $designPnt SclSetValueByName Z 10 # To close the shape, make the x,y and z the same as the first point. $designSeg SclCreatePoint designPnt [$designSeg SclCountItems] $designPnt SclSetValueByName X 10 $designPnt SclSetValueByName Y 10 $designPnt SclSetValueByName Z 10 # Using the reference to the design layer (designSwa), use the command "SclDraw" to draw everything in the design layer. $designSwa SclDraw SclFunction "ZOOM ALL" {} # Now, the active layer is still the initial layer that was active when the macro was first run. Let's make it the design layer $vh SclSetActiveLayer $designSwa