Lessons learnt
As a result of this project I had learnt a number of things regarding rule file creation:
- How to structure the rule file
- How to create attributes and give them additional information such as a range
- How to create functions and loops within the rule file
- How to create a conditional (case) statement
Within the rule file I also was able to understand and use a number of CityEngine operations including:
- Split
- Extrude
- Comp
- Align
- Set
- Report
- Setback
- Roof operations
- Translate
Looking back at what I intended to achieve a result of the project, I think I covered everything pretty well. I created a basic street and parcel network, however, I think that maybe some of the parcels are either to big and / or I could have added more streets. I created a rule file that included some very basic planning rules, I will of course include more rules in future but this will also require me to understand what the planning rules are, what they intend to allow or not allow to happen on a zone and how this can be translated into a rule file. I also created an output visualisation, this step was by far the easiest and using the Web Scene technology is something that I very much look forward to utilising again in future.
Below is the full rule file created for this project:
/**
* File:
StarterProject.cga
* Created: 01 Jan 2013 01:02:07 GMT
* Author:
ellawayc
*/
version "2012.1"
## Hidden Attributes ##
@Hidden
attr ParcelArea = 0
@Hidden
attr FootprintNeeded = 0
@Hidden
attr Length = 0
@Hidden
attr Width = 0
## Attributes ##
@Range("Residential","Commercial")
attr ZONETYPE = "Residential"
@Range(0,5)
attr YARD = 2.5
@Range(25,100)
attr COVERAGE = 30
## Functions ##
getHeight =
25%
: 8.5
50%
: 12.5
else : 16.5
## Constants ##
## Assets ##
## Rules
@startRule
Lot -->
alignScopeToGeometry(yUp, auto)
set(ParcelArea, geometry.area)
report("A Parcel
Area (m2)", ParcelArea)
Lot1
Lot1 -->
case ZONETYPE == "Residential" : ResidentialLot
else : CommercialLot
##### Residential Zone #####
ResidentialLot -->
setback(YARD) {street.front
: NIL | remainder : ResidentialLot2}
ResidentialLot2 -->
innerRect
shapeL(scope.sz*0.75,scope.sx*0.75) {shape : ResidentialLot3 | remainder : NIL}
ResidentialLot3 -->
set(FootprintNeeded, (ParcelArea/100)*COVERAGE)
report("B
Footprint Needed (m2)", FootprintNeeded)
ResidentialLot4
ResidentialLot4 -->
case geometry.area > FootprintNeeded : s('0.99,0,'0.99) center(xz) ResidentialLot4
else : ResidentialLot5
ResidentialLot5 -->
extrude(world.y, 5)
split(y){~0.25 : ResidentialLot6 BaseKeeper | 5 : NIL}
ResidentialLot6 -->
comp(f){top : alignScopeToGeometry(yUp, auto) ResidentialLot7}
ResidentialLot7 -->
extrude(5.5)
comp(f){top : Roof | all : ResidentialLot8}
Roof -->
roofHip(18.5, 0.4)
##### Commercial Zone #####
CommercialLot -->
innerRect
alignScopeToGeometry(yUp, 0,
longest)
set(Length, scope.sx)
set(Width, scope.sz)
report("B Length
(m)", Length)
report("C Width
(m)", Width)
CommercialLot1
CommercialLot1 -->
20%
: CommercialLot3
else :
case ParcelArea < 500 : CommercialLot3
case Width < 15 :
50%
: setback(4){street.left
: NIL | remainder : CommercialLot2}
else : setback(4){street.right : NIL | remainder : CommercialLot2}
else :
50%
: setback(scope.sz*0.2){street.left
: NIL | remainder : CommercialLot2}
else : setback(scope.sz*0.2){street.right
: NIL | remainder : CommercialLot2}
CommercialLot2 -->
20%
: CommercialLot3
else :
case Length > 30 : setback(scope.sx*0.3){street.back
: NIL | remainder : CommercialLot3}
else :
50%
: setback(4){street.back
: NIL | remainder : CommercialLot3}
else : CommercialLot3
CommercialLot3 -->
extrude(world.y, 5)
split(y){~0.25 : CommercialLot4 BaseKeeper | 5 : NIL}
CommercialLot4 -->
comp(f){top : alignScopeToGeometry(yUp, auto) CommercialLot5}
CommercialLot5 -->
extrude(getHeight)
split(y){4.5 : GroundFloor | {~4 : UpperFloor(split.index, split.total)}*}
GroundFloor -->
comp(f){side: GroundFloor1}
GroundFloor1 -->
split(x){0.5 : Wall | ~5 : LargeWindow | 3 : Entrance | {~5 : LargeWindow}* | 0.5 : Wall}
UpperFloor(idx,n) -->
case idx == n-1 : TopFloor UpperFloor1
else : UpperFloor1
UpperFloor1 -->
comp(f){side: UpperFloor2}
UpperFloor2 -->
split(x){0.5 : Wall | {~2.5 : Window}* | 0.5 : Wall}
LargeWindow -->
split(x){0.25 : SolidWall | ~5 : split(y){0.50 : SolidWall | ~1 : LargeWindow1 | 0.25 : SolidWall} | 0.25 : SolidWall}
LargeWindow1 -->
t(0,0,-0.4)
Window -->
split(x){0.2 : SolidWall | ~2.5 : split(y){0.2 : SolidWall | ~1 : Window1 | 0.2 : SolidWall} | 0.2 : SolidWall}
Window1 -->
t(0,0,-0.2)
Entrance -->
split(x){0.2 : SolidWall | ~2.5 : split(y){~1 : Entrance1 | 0.35 : SolidWall} | 0.2 : SolidWall}
Entrance1 -->
t(0,0,-0.4)
SolidWall -->
extrude(0.4)
t(0,-0.4,0)
TopFloor -->
comp(f){top : CommercialRoof}
CommercialRoof -->
extrude(0.15)
comp(f){top : CommercialRoof1 RoofKeeper | all : RoofKeeper }
CommercialRoof1 -->
setback(0.4){all : CommercialRoof2}
CommercialRoof2 -->
extrude(0.4)
No comments:
Post a Comment