FOR-NEXT Loops and WHEN Clauses
The equipment geometry description language has two additional features for a BASIC style FOR-NEXT loop to supported repeated elements and a WHEN clause similar to the nozzle and vicinity routing languages to support conditional elements.
FOR-NEXT Loop in Equipment Geometry Description
The FOR-NEXT loop feature has been adapted from the BASIC programming
language to allow
PlantWise users to define equipment
geometry descriptions that have variable numbers of repeated elements. The
FOR-NEXT construct from BASIC was used to keep the language simple and add
something familiar to at least some
PlantWise users. The syntax is:
The FOR-NEXT loop repeats the element description(s) as many times as
the range from the initial value to the final value. If the final value is less
than the initial value, the included element descriptions are omitted
altogether. During the expansion, any occurrences of the variable between the
final value and the NEXT keyword are replaced by the incriminated loop value in
each repetition. Also, any element names are suffixed with a hyphen and
variable value (e.g., box-1, box-2, etc.). FOR-NEXT loops may be nested to an
arbitrary depth as long as they use different variable names.
FOR <variable> = <initial value> to <final value> {<element description>}* NEXT <variable>where <variable> is any symbol that is not already a reserved word in the equipment geometry language or the name of an equipment attribute.
<initial value> ::= <arithmetic expression> <final value> ::= <arithmetic expression>If the initial value or final value is an expression instead of just a number, it must be parenthesized.
For example, the geometry rule for the ladder follows. The new
keywords FOR, TO, and NEXT are capitalized for emphasis.
(The LADDER is composed of element LEFT-RAIL with geometry = box x-dimension = equipment.width / 10 y-dimension = equipment.length z-dimension = equipment.height local-x-origin = equipment.width / -2.0 local-y-origin = equipment.length / -2.0 local-x-rotation = equipment.angle element RIGHT-RAIL geometry = box x-dimension = left-rail.x-dimension y-dimension = left-rail.y-dimension z-dimension = left-rail.z-dimension local-x-origin = (equipment.width / 2.0) - right-rail.x-dimension local-y-origin = left-rail.local-y-origin local-x-rotation = left-rail.local-x-rotation FOR i = 1 TO ((equipment.height / inches-or-mm(12.0 300.0)) - 1) ; 1' spacing element RUNG geometry = cylinder diameter = inches-or-mm(1.0 25.0) length = equipment.width - (left-rail.x-dimension + right-rail.x-dimension) local-x-origin = - rung-1.length / -2 local-y-origin = - ((i * inches-or-mm(12.0 300.0)) * (lisp-function (sin-degrees equipment.angle))) local-z-origin = (i * inches-or-mm(12.0 300.0)) * (lisp-function (cos-degrees equipment.angle)) local-y-rotation = -90 NEXT i element OBSTACLE with type = obstacle geometry = box x-dimension = width y-dimension = length z-dimension = height local-x-origin = width / -2.0 local-y-origin = length / -2.0 local-x-rotation = left-rail.local-x-rotation element LABEL with geometry = text width = 0.9 * width string = display_name rotation = east-west local-y-origin = - (equipment.height * (lisp-function (sin-degrees equipment.angle))) local-z-origin = 1.1 * (equipment.height * (lisp-function (cos-degrees equipment.angle))) )
WHEN Conditional in Equipment Geometry Description
Equipment elements may be included or excluded based on logical expressions just as in nozzle placement and vicinity routing rules.
The syntax is:
WHEN <expression> <element description>where the expression may be any infix expression that evaluates to a true (non-nil) or false (nil) value. Here is an example that places different kinds of heads on a cylinder based on a user selected value for the cylinder's head_type attribute:
(The CYLINDRICAL_EQUIPMENT is composed of element BODY with geometry = cylinder diameter = diameter length = length WHEN (equipment.head_type is "elliptical") element HEAD with geometry = elliptical-head radius = diameter / 2.0 height = equipment.head_height or diameter / 4.0 local-z-origin = length WHEN (equipment.head_type is "conical") element HEAD with geometry = cylindrical-transition diameter1 = diameter diameter2 = diameter / 2.0 length = equipment.head_height or diameter / 4.0 local-z-origin = length element LABEL with geometry = text width = 0.8 * diameter string = display_name rotation = east-west local-z-origin = 1.1 * length element OBSTACLE with type = obstacle geometry = box x-dimension = diameter y-dimension = diameter z-dimension = length + equipment.head_height or diameter / 4.0 local-x-origin = diameter / -2.0 local-y-origin = diameter / -2.0 )