class_04

 

Parametric Objects - Introducing Procedures






The Parametric Building

Creating procedures is like inventing your own language.
The design process becomes a process of inventing your own nomenclature.
In a sense, you become the "composer."
For example, if we want to starting designing a house, we might redifine the word house.








global proc house ( float $width, float $depth, float $height ) {

nurbsCube -p 0 .5 0;
move 0 .5 0;
scale $width $height $depth;
}





Simple Building





The word for house (the procedure) becomes an "interface" to the process.
Any performer can create a house because the designer has articulated his design process in the procedure.

When composing new procedures, you should always make it easy for the end-user or "performer" to use.


Now the "performer" may create different houses:

house ( 30, 40, 40 );

house ( 30, 30, 10 );
move -50 0 0;

house ( 20, 40, 200 );
move 50 0 0;






Clarifying the Defintion of the House

Now the basic concept is in place and the "interface is determined, we can go inside the procedure and articluate our design concepts in MEL.
Our first articulation of the house will be to divide it into something we call "floors".
As we define our new entity "floor," we may consider the interface to be similar to house but also have extended requirements.
Perhaps the floor should have a new parameter called "ledge."








global proc string floor ( float $width, float $depth, float $height, float $ledge ) {

// return group
$floorItems = `group -em`;
// floor deck
$floordeck = `nurbsCube -p 0 .5 0`;
// init vars
$width += $ledge;
$depth += $ledge;
$thickness = 1;

// Transfroms
move 0 .5 0;
scale $width $thickness $depth;

parent $floordeck [0] $floorItems;

return $floorItems;

}


Defining the term "House"





We can try making floors:
floor (80, 40, 60, 1);
floor (20, 40, 60, 1);
floor (20, 40, 60, 20);


We can now make a house and then make floors. But it is better to incorporate floors into
the definition of "house:


First, let's prepare the house to return a group of items rather than just a nurbsCube...







global proc string house ( float $width, float $depth, float $height ) {

// return group
$houseItems = `group -em`;

$glazing = `nurbsCube -p 0 .5 0`;

// Transformations
select $glazing;
move 0 .5 0;
scale $width $height $depth;

parent $glazing[0] $houseItems;

return $houseItems;
}






Now that we can add more items, lets do so...







global proc string house ( float $width, float $depth, float $height ) {

// return group
$houseItems = `group -em`;

// 1. Create
$glazing = `nurbsCube -p 0 .5 0`;

// 2. Transformation
select $glazing;
move 0 .5 0;
scale $width $height $depth;

// 3. Parent
parent $glazing[0] $houseItems;


// floors

// 0. Initialize
$floorHeight = 10.0;
$numFloors = $height / $floorHeight;
$ledge = 2;


$i = 0;
$currentHeight = 0;

while ($i++ < $numFloors ) {

// 1. Create
$floor = floor( $width, $depth, $floorHeight, $ledge);

// 2. Transformation
select $floor;
move 0 $currentHeight 0;

// 3. Parent
parent $floor $houseItems;

$currentHeight += $floorHeight;
}

// Roof
// 0. Initialize
$ledge *= 3;

// 1. Create
$floor = floor( $width, $depth, 1, $ledge);

// 2. Transform
select $floor;
move 0 $currentHeight 0;

// 3. Parent
parent $floor $houseItems;


select $houseItems;
return $houseItems;
}





Now if we make houses, using the exact same interface and input variables we
can see that they are inherently the same but further articulated.

$house = house ( 30, 40, 40 );

$house = house ( 30, 30, 10 );
select $house;
move -50 0 0;

$house = house ( 20, 40, 200 );
select $house;
move 50 0 0;










Now, what is a floor really? It is not just the floor slab.
Lets enhance our concept of floor. Perhaps we will populate the floor with something we will call "column"s

First of all, instead of returning a single nurbsCube, we will be returning a group. Let's set that up first:

Note that we are not returning a string array now.








global proc string floor ( float $width, float $depth, float $height, float $ledge ) {

$floorItems = `group -em`;

// floor deck
$floordeck = `nurbsCube -p 0 .5 0`;
// init vars
$width += $ledge;
$depth += $ledge;
$thickness = 1;

// Transfroms
move 0 .5 0;
scale $width $thickness $depth;

// parent
parent $floordeck[0] $floorItems;


return $floorItems;

}

Columns are added to Floors







Now that we are returning a gropu of items, we can add more items...








global proc string floor ( float $width, float $depth, float $height, float $ledge ) {

$floorItems = `group -em`;




// floor deck
$floordeck = `nurbsCube -p 0 .5 0`;
// init vars
$width += $ledge;
$depth += $ledge;
$thickness = 1;

// Transfroms
move 0 .5 0;
scale $width $thickness $depth;

// parent
parent $floordeck[0] $floorItems;




// columns
if ( $height > $thickness ) {
// init vars
$colHeight = $height - $thickness;
$bayWidth = 12;
$bayDepth = 8;

int $nbaysWidth = $width / $bayWidth;
int $nbaysDepth = $depth / $bayDepth;

int $colsGroupWidth = $nbaysWidth * $bayWidth;
int $colsGroupDepth = $nbaysDepth * $bayDepth;

float $shiftx = -1 * $colsGroupWidth / 2.0;
float $shiftz = -1 * $colsGroupDepth / 2.0;

float $shifty = $height / 2.0 + $thickness;

// create columns

$columns = `group -em`;

$i = 0;
$posx = 0;
while ($i++ <= $nbaysWidth) {
$row = `group -em`;
$j = 0;
$posz = 0;
while ($j++ <= $nbaysDepth) {
$column = `polyCube`;
select $column;
scale 1 $colHeight 1;
move 0 0 $posz;

parent $column[0] $row;

$posz = $posz + $bayDepth;
}
select $row;
move $posx 0 0;
parent $row $columns;

$posx = $posx + $bayWidth;
}
select $columns;
move $shiftx $shifty $shiftz;

parent $columns $floorItems;

}


return $floorItems;

}




Now our test objects should become another procedure.









global proc string block() {

// Return group for this function
$blockItems = `group -em`;


// 1. Initialize

$lotSize = 100;
$shiftx_r = $lotSize / 2;
$shiftx = $shiftx_r * -1;



// 2. Create

$house1 = house ( 30, 40, 40 );
$house2 = house ( 30, 30, 10 );
$house3 = house ( 20, 40, 200 );



// 3. Transform

select $house2;
move $shiftx 0 0;
$shiftx += $lotSize;

select $house3;
move $shiftx 0 0;



// 4. Parent to return group

parent $house1 $blockItems;
parent $house2 $blockItems;
parent $house3 $blockItems;

return $blockItems;
}

Block






When you start creating variables like $house1, house2, house3, etc., it is often
better to use an array.







global proc string block() {

// Return group for this function
$blockItems = `group -em`;

// 1. Initialize

$lotSize = 100;
$shiftx = $lotSize;

string $house[];

// 2. Create

$house[1] = house ( 30, 40, 40 );
$house[2] = house ( 30, 30, 10 );
$house[3] = house ( 20, 40, 200 );

$i = 0;
while ($house[$i++]) {

// 3. Transform

select $house[$i];
move $shiftx 0 0;

// 4. Parent to return group

parent $house[$i] $blockItems;

}
return $blockItems;
}






Now we can take the block further by creating houses in the loop and changing the interface:









global proc string block(float $blockLength) {

// Return group for this function
$blockItems = `group -em`;

// 1. Initialize

$lotSize = 100;
$numBuildings = $blockLength / $lotSize;
$shiftx = 0;

string $house[];


// Algorithmic Cycle --> Initialize, Create, Transform, Parent
$i = 0;
while ($i++ <= $numBuildings) {

// 1. Initialize

$height = 40;

if ($i == 0 || $i == $numBuildings) {
$height = 80;
} else {
$shiftx += $lotSize;
$height = 40;
}



// 2. Create

$house[$i] = house ( 80, 40, $height );




// 3. Transform

select $house[$i];
move $shiftx 0 0;




// 4. Parent to return group

parent $house[$i] $blockItems;

}
return $blockItems;
}









global proc string block(float $blockLength) {

// Return group for this function
$blockItems = `group -em`;

// 1. Initialize

$lotSize = 100;
$numBuildings = $blockLength / $lotSize;
$shiftx = 0;

string $house[];


// Algorithmic Cycle --> Initialize, Create, Transform, Parent
$i = 0;
while ($i++ < $numBuildings) {

// 1. Initialize

float $height;
$heightCorner = -1 * $blockLength + 700;
$heightMiddle = $heightCorner / 2;

if ($i == 1) {
$height = $heightCorner;
} else if ($i == $numBuildings){
$shiftx += $lotSize;
$height = $heightCorner;
} else {
$shiftx += $lotSize;
$height = $heightMiddle;
}


// 2. Create

$house[$i] = house ( 80, 40, $height );



// 3. Transform

select $house[$i];
move $shiftx 0 0;



// 4. Parent to return group

parent $house[$i] $blockItems;

}
return $blockItems;
}




** Things to note:
1. Reassigning a variable means you loose a handle on the first previous value (orphan).

2. Hide complexity with smart procedure interfaces


3. Lots of upfront work that pays of geometrically later



Make a function called neighborhood using the Initialize, Create, Transform, Parent structure.

Optimize the code for one set of columns running the height of the building












proc t() {


select -all;
delete;

house (20,40,80);

select -all;

};





  • class_04