# Tutorial Notes 08: Mass Modeling, Part 2 – Recursive Shape Generation

In Tutorial 8, we use a kind of looping procedure to randomly generate building shapes of the same relative design, but with different proportions: we are “telescoping” shapes whose total heights, total numbers of tiers and the heights and narrowness of those tiers will vary based on the parameters we set.

Let’s look at the code:

```// A height per floor is set; this will help determine
// the overall number of recursive tiers generated.

attr floorheight = 5

// Random heights are based on the size of the lot.
// The tallest shapes will appear on the largest lots.

height =
case geometry.area > 1000: rand(50, 200)
else: rand(20, 50)

// Half (50%) of the lower tiers generated in each
// iteration will have heights of 40 percent (0.4)
// of the overall building height; the rest will
// have 60 percent heights.

lowHeight = 50% : 0.4
else: 0.6

// The scale of setbacks will vary between 70 and 95
// percent of the building's width

attr scale = rand(0.7, 0.95)

// Random extrude heights are generated for each
// building lot where this rule file applies.
// Extrude heights represent a building's total height.
attr extrudeHeight = rand(20, 120)

// ESRI uses the "Lot" starting rule name
// for consistency.
Lot --> Tower

// The lot shape is extruded
Tower --> extrude(extrudeHeight) Envelope

Envelope --> RecursiveSetbacks

// If the height of the extrusion is greater than
// twicethe floorheight parameter, the shape is split
// into two sections: a Mass, with a lower tier
// having a heightof either 40 or 60 percent of the
// total, and a Setback section above

RecursiveSetbacks -->
case scope.sy > 2 * floorheight :
split(y){ 'lowHeight : Mass | ~1: Setback }
else:
s('1, floorheight, '1) Mass

// The x and z values of the setback are between
// 70 and 95 percent of the tier immediately below.
// and run the RecursiveSetbacks rule again.

// Note that we are coloring Setback shapes green and
// coloring Mass shapes red.
Setback -->
s('scale, '1, 'scale) center(xz)
color("#00FF00")
RecursiveSetbacks

Mass -->
color("#FF0000")
```

So, how does this all work? What determines how many setbacks are created and a total height of a generated building is? In the slide show below, we apply the code to a single building whose height (extrudeHeight) is 50 meters. For reference, we have created a neighboring shape with alternating color bands calibrated at 5 meters each.

• Each generated building will have an initial base tier that is either 40 percent or 60 percent of extrudeHeight.  In this case, it is either 20 or 30 meters.
.
• Each time a base is generated, the total height of all bases is subtracted from extrudeHeight. This will leave a remainder of vertical space in which to build subsequent tiers.
.
• In the first line of the RecursiveSetbacks rule, note that Setback tiers will be added as long as the remainder of vertical space in the scope of a shape is greater than twice the floorheight of 5 meters. Floor height is one of the parameters that controls recursive setbacks.
.
• The setback tiers generated will be either 40 or 60 percent the value of the remaining height.  This is the other value that controls the number of recursive setbacks.
.
• In the slide series below, 40-percent tiers are labeled S (small) and 60-percent tiers are labeled B (big). Recursive tiers are colored red. The final possible tiers are colored green.
.
• Obsessive-compulsive types: look at and deeply contemplate the Small-Big combinations in the slide show.

Here is the code used to generate the variations in the slide show. See what happens when you adjust parameters and regenerate shapes.

```/**
* File: TierExperiment.cga
* Created: 03 April 2017 10:43:55 GMT
* Author: Jeffrey K. Herzer | jeffherzer.com
*/

version "2016.1"

attr floorheight = 5

lowHeight = 50% : 0.4
else: 0.6

attr scale = 0.8

attr extrudeHeight = 50

Lot --> extrude(extrudeHeight) RecursiveSetbacks

RecursiveSetbacks -->
# How high must the building be before we see setbacks?
case scope.sy > 2 * floorheight :
# The lower lowheight percentage will be MASS
# The rest (relative to 1) will be SETBACK
split(y){ 'lowHeight : Mass | '1: Setback }
# If the minimum height is not met
else:
s('1, floorheight, '1)

Mass -->
color("#FF0000")

Setback -->
s('scale, '1, 'scale) center(xz)
color("#00ff00")
RecursiveSetbacks

// Generate the calibrated reference shape

Lot2 -->
extrude(50)
split(y){ 5 : Next | 5 : After }*

Next -->
color("#00ffff")

After-->
color("#ffff00")```