You are here: Surpac Concepts > Macros > SCL > Object Manipulation > SclIterate First,Last,Next,Prev
GEOVIA Surpac

Scl iterator commands

Overview

Many of the objects created and manipulated with Scl exist in a heirarchy of objects. For example a SWA contains a set of strings, each string contains a set of segments and each segment contains a set of points.

In developing applications with Scl it is often necessary to iterate over the members of a set (visit each child object of a parent object) and perform some operation on them. An example of this might be to iterate over each segment in a string and report the length and number of points in each segment. Similarly it might be necessary to iterate over each point in a segment and add a constant to the Z value. This and other examples of the use of the Scl iterators are included below.

The Scl iterator commands, SclIterateFirst and SclIterateNext operate on any object that is a container of objects. This pair of iterator commands initialise an iterator object and then iterates in a forward direction (starting at the first child and advancing to the next child) over the child objects.

The SclIteratorCommands, SclIterateLast and SclIteratePrev operate on any object that is a container of objects. This pair of iterator commands initialise an iterator object and then iterates in a backwards direction (starting at the last child and regressing to the previous child) over the child objects.

To see how the backwards iterators work, replace SclIterateFirst with SclIterateLast and SclIterateNext with SclIteratePrev in the examples below.

The objects that the iterate commands can operate on, and the type of object returned by the iterators are:

Parent object Child object description
Set of SWAs Swa A set of SWAs exists that contains all the SWAs that exist at any time while the software is in use. It is possible to iterate over this set, by first getting its handle using the sclSwas command, and then by using the iterator commands to find the name of any SWA that has been created by any Surpac application. Be warned though that even though you can access a number of SWAs that are normally hidden from users, manipulating the contents of such hidden SWAs may cause problems for various applications.
Swa Strings table String A Swa contains a set of strings. The handle to this set can be obtained using the SclGetStrings command. Each string in the Swa can be found using the iterator commands
String Segment Each segment in a string can be found using the iterator commands
Segment Point Each point in a segment can be found using the iterator commands
Swa Triobjects table Triobject A Swa contains a set of triobjects. The handle to this set can be obtained using the SclGetTriobjects command. Each triobject in the Swa can be found using the iterator commands
Triobject Trisolation Each trisolation in a triobject can be found using the iterator commands
Trisolation Triangle Each triangle in a trisolation can be found using the iterator commands
Set of Graphics layers Swa Graphics applications use a special set of SWAs (a subset of all SWAs that exist at any point in time) to draw data in a 3D graphics viewport. The handle the set of graphics layers can be obtained using the sclGraphicsLayers command. By applying the iterator commands to the set of graphics layers the names and contents of all graphics layers can be found and manipulated.
Set of graphics viewports Viewport The 3D graphics applications in Surpac operate in an environment that permits data to be displayed in multiple viewports. The sclViewports command returns the handle to the set of viewports. The iterator commands will return the handle to each viewport that exists in the set of viewports. Even though viewports are used in graphics application frames other than the 3D graphics frame, plotting, variogram modeling, etc., the only viewports that are stored in the set of viewports are those viewports that exist in the 3D graphics viewport.

Synopsis

$ParentObjecthandle SclIterateFirst IteratorHandle
$IteratorHandle SclIterateNext ChildObjectHandle

$ParentObjecthandle SclIterateLast IteratorHandle
$IteratorHandle SclIteratePrev ChildObjectHandle

Description

SclIterateFirst and SclIterateLast must be used to create an iterator object that can be used to iterate over all the children in a container object. That is, if you wish to iterate over the segments in a string you must first create an iterator for the string.

SclIterateFirst and SclIterateLast assign the iterator object to the IteratorHandle variable.

SclIterateNext and SclIteratePrev are applied to the iterator object defined by $IteratorHandle and the handle to the child object is returned in the ChildObjectHandle variable. SclIterateNext and SclIteratePrev return $SCL_FALSE if there are no more objects in the parent object (the end of the set has been reached), otherwise it returns $SCL_TRUE.

Arguments

  • ParentObjectHandle
  • The handle of the parent object that is to be iterated over to obtain the handles for the child objects that exist.

  • IteratorHandle
  • Passed by reference to SclIterateFirst and SclIterateLast. An iterator object is created and the handle to this iterator object is returned into this variable name. Note that almost any name for this variable is valid. A verbose form is used here for explanation. Common variable names for iterator objects might be, i, it or perhaps iter.

    Used to iterate forwards or backwards with the SclIterateNext and SclIteratePrev respectively. The variable used here MUST BE one that has been created by a previous call to SclIterateFirst or SclIterateLast.

  • ChildObjectHandle
  • Passed by reference. The handle to the child object is returned into this variable so that operations may be performed on the child object.

Returns

SclIterateNext and SclIteratePrev return $SCL_FALSE as soon as there are no more children in the parent set of object otherwise they return $SCL_TRUE. For example, if iterating over a segment that contains 5 points, SclIterateNext will return $SCL_TRUE for the first 5 calls and it will return $SCL_FALSE on the 6th call. the examples below show how to terminate simple while loops as soon as this condition occurs.

Examples

#
# This example iterates over all SWAs that exist and displays their
# names and handles in the message window. If you execute this script after
# a number of graphics layers have been created by recalling some
# DTM files you will see that there are some SWAs that have a name
# with a ".boundary" suffix. These SWAs are not graphics layers but
# they exist. This shows how the set of SWAs is not the same as the
# set of graphics layers.
#
puts "List of all SWAs that exist"
sclSwas SclIterateFirst Iterator
while {[$Iterator SclIterateNext SwaHandle] == $SCL_TRUE} {
  puts "Swa handle = $SwaHandle, swa name = [$SwaHandle SclGetId]"
}

 

#
# This example iterates over all SWAs that exist as Graphics layers 
# and displays their names and handles in the message window.
#
puts "List of all Graphics layers that exist"
sclGraphicsLayers SclIterateFirst Iterator
while {[$Iterator SclIterateNext SwaHandle] == $SCL_TRUE} {
  puts "Swa handle = $SwaHandle, swa name = [$SwaHandle SclGetId]"
}

 

#
# This example iterates over all viewports that exist and displays 
# the viewport name and the name of the active layer for the
# viewport. Run this script after loading a number of files into
# different layers and creating a number of viewports each with a
# different, or the same if you like, active layer
#
puts "List of all viewports and the active layer in each viewport"
sclViewports SclIterateFirst Iterator
while {[$Iterator SclIterateNext ViewportHandle] == $SCL_TRUE} {
  $ViewportHandle SclGetActiveLayer SwaHandle
  puts "Viewport handle = $ViewportHandle, Viewport name = [$ViewportHandle SclGetId], \
  Active layer name = [$SwaHandle SclGetId]"
}

 

# This example shows how to iterate over all of the data in the SWA
# that is the active layer for the active viewport. Don't run this
# script with large data sets as it displays data in the message
# window for each point that exists. A small data set is preferable
# for this example. 
# 
SclGetActiveViewport ViewportHandle
$ViewportHandle SclGetActiveLayer SwaHandle
puts "Viewport handle = $ViewportHandle, Viewport name = [$ViewportHandle SclGetId], \
Active layer name = [$SwaHandle SclGetId]" 
$SwaHandle SclGetStrings StringsHandle
$StringsHandle SclIterateFirst StringsIterator
while {[$StringsIterator SclIterateNext StringHandle] == $SCL_TRUE} {
  puts "String number = [$StringHandle SclGetId]"
  $StringHandle SclIterateFirst StringIterator
  while {[$StringIterator SclIterateNext SegmentHandle] ==  $SCL_TRUE} {
    puts "Segment number = [$SegmentHandle SclGetId]"
    $SegmentHandle SclIterateFirst SegmentIterator
    set PointCount 0
    while {[$SegmentIterator SclIterateNext PointHandle] == $SCL_TRUE} {
      set x [$PointHandle SclGetValueByName x]
      set y [$PointHandle SclGetValueByName y]
      set z [$PointHandle SclGetValueByName z]
      puts "Point $PointCount X = $x, Y = $y, Z = $z"
      incr PointCount
    }
  }
}
$SwaHandle SclGetTriobjects TriobjectsHandle
$TriobjectsHandle SclIterateFirst TriobjectsIterator
while {[$TriobjectsIterator SclIterateNext TriobjectHandle] == $SCL_TRUE} {
  puts "Triobject number = [$TriobjectHandle SclGetId]"
  $TriobjectHandle SclIterateFirst TriobjectIterator
  while {[$TriobjectIterator SclIterateNext TrisolationHandle] ==  $SCL_TRUE} {
    puts "Trisolation number = [$TrisolationHandle SclGetId]"
    $TrisolationHandle SclIterateFirst TrisolationIterator
    while {[$TrisolationIterator SclIterateNext TriangleHandle] == $SCL_TRUE} {
      set v0 [$TriangleHandle SclGetValueByName v0 vh0]
      set v1 [$TriangleHandle SclGetValueByName v1 vh1]
      set v2 [$TriangleHandle SclGetValueByName v2 vh2]
      puts "Triangle = [$TriangleHandle SclGetId] vertex0 = {$vh0}, vertex1 = {$vh1}, vertex2 = {$vh2}"
    }
  }
}