PlantWise Help

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:
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.
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 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
)