Simple Building

Week 5

 
Procedures and Data Structures

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 ) {
	
	// 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;

	return $floordeck;

}

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 $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 $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 $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 $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 $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; };
  • Week 5