CGA : Recursive Highrise Building rule (with good control over floor volumes)

3978
5
12-05-2012 06:12 AM
MatthiasBuehler1
Frequent Contributor II
Here's a cool simple approach to create some variating building volumes, which can grow thinner from floor to floor.


/**
 * File:    recursiveStepbacks.cga
 * Created: 5 Dec 2012 15:27:58 GMT
 * Author:  matt6767
 */

version "2012.1"

############################################################
# GENERIC ATTRIBUTES
############################################################


@Group ("Building Volume",0)   @Order(0)
attr Number_Of_Floors  = 8
@Group ("Building Volume")    @Order(1)
attr Groundfloor_Height  = 6
@Group ("Building Volume")    @Order(2)
attr Upperfloor_Height  = 3.5

@Group ("Recursive Detailing",1) @Order(0)
attr Minimal_Stepback_Dimension  = 12
@Group ("Recursive Detailing") @Order(1)
attr Stepback_Probability   = 0.25
@Group ("Recursive Detailing") @Order(2)
attr Stepback_Dim     = rand(5,12)

############################################################
# FUNCTIONS
############################################################

Floorheight_Function(floorNumber) =
 case floorNumber == 0 :
  Groundfloor_Height
 else :
  Upperfloor_Height

############################################################
# GENERIC ATTRIBUTES
############################################################
@Hidden
attr Current_Floor = 0

############################################################
# START
############################################################

Lot -->
 alignScopeToAxes(y)
 LotAligned(scope.sy)

LotAligned(yDim) -->
# create a flat base
 extrude(world.y, 100)
 split(y) {yDim : BaseVolume | ~1 : NIL}

BaseVolume -->
 comp(f) {bottom : NIL | side : BaseFacade | top : alignScopeToGeometry(yUp, 0, longest) BuildingRecursion}

BuildingRecursion -->
 case Current_Floor > Number_Of_Floors :
  NIL
 else :
  extrude(world.y, Floorheight_Function(Current_Floor))
  FloorVolume
  set (Current_Floor, Current_Floor + 1)
  comp(f) {top : FloorShape | all : NIL}

FloorShape -->
 case p(Stepback_Probability) && scope.sx > Minimal_Stepback_Dimension :
  alignScopeToGeometry(yUp, 0, longest)
  split(x) {Stepback_Dim : BalconyShape | ~1 : BuildingRecursion}
 else :
  alignScopeToGeometry(yUp, 0, longest)
  BuildingRecursion

############################################################
# VOLUMES AND FACADES
############################################################

FloorVolume -->
 case Current_Floor == Number_Of_Floors :
  # top floor
  color(1,0,0)
 else :
  Floor.

BaseFacade -->
 color(.3,.3,.3)
 X.

BalconyShape -->
 case Current_Floor > Number_Of_Floors :
  NIL
 else :
  extrude(1)
  comp(f) {top : NIL | bottom : NIL | front : BalconyWall | back : BalconyWall | left : BalconyWall }

BalconyWall -->
 color(.5,.7,.5)
 set (material.opacity, 0.7)


[ATTACH=CONFIG]19717[/ATTACH]
0 Kudos
5 Replies
larryzhang1
New Contributor III
Matt,

For learning the powers of CE, can you pls instruct to implement the following idea?

1. Steps to import and organize the SHP (saying, Trees.shp) into CE project (the attachment) where there is a 'field' for different kinds of tree (1, 2, or 3), which individually represents �??pine, oak, or ash tree�??;
2.  Code trees�?? rule (with the field 'TreeHeight' & �??TreeType�??)

Regards and many thanks,



Here's a cool simple approach to create some variating building volumes, which can grow thinner from floor to floor.


/**
 * File:    recursiveStepbacks.cga
 * Created: 5 Dec 2012 15:27:58 GMT
 * Author:  matt6767
 */

version "2012.1"

############################################################
# GENERIC ATTRIBUTES
############################################################


@Group ("Building Volume",0)   @Order(0)
attr Number_Of_Floors  = 8
@Group ("Building Volume")    @Order(1)
attr Groundfloor_Height  = 6
@Group ("Building Volume")    @Order(2)
attr Upperfloor_Height  = 3.5

@Group ("Recursive Detailing",1) @Order(0)
attr Minimal_Stepback_Dimension  = 12
@Group ("Recursive Detailing") @Order(1)
attr Stepback_Probability   = 0.25
@Group ("Recursive Detailing") @Order(2)
attr Stepback_Dim     = rand(5,12)

############################################################
# FUNCTIONS
############################################################

Floorheight_Function(floorNumber) =
 case floorNumber == 0 :
  Groundfloor_Height
 else :
  Upperfloor_Height

############################################################
# GENERIC ATTRIBUTES
############################################################
@Hidden
attr Current_Floor = 0

############################################################
# START
############################################################

Lot -->
 alignScopeToAxes(y)
 LotAligned(scope.sy)

LotAligned(yDim) -->
# create a flat base
 extrude(world.y, 100)
 split(y) {yDim : BaseVolume | ~1 : NIL}

BaseVolume -->
 comp(f) {bottom : NIL | side : BaseFacade | top : alignScopeToGeometry(yUp, 0, longest) BuildingRecursion}

BuildingRecursion -->
 case Current_Floor > Number_Of_Floors :
  NIL
 else :
  extrude(world.y, Floorheight_Function(Current_Floor))
  FloorVolume
  set (Current_Floor, Current_Floor + 1)
  comp(f) {top : FloorShape | all : NIL}

FloorShape -->
 case p(Stepback_Probability) && scope.sx > Minimal_Stepback_Dimension :
  alignScopeToGeometry(yUp, 0, longest)
  split(x) {Stepback_Dim : BalconyShape | ~1 : BuildingRecursion}
 else :
  alignScopeToGeometry(yUp, 0, longest)
  BuildingRecursion

############################################################
# VOLUMES AND FACADES
############################################################

FloorVolume -->
 case Current_Floor == Number_Of_Floors :
  # top floor
  color(1,0,0)
 else :
  Floor.

BaseFacade -->
 color(.3,.3,.3)
 X.

BalconyShape -->
 case Current_Floor > Number_Of_Floors :
  NIL
 else :
  extrude(1)
  comp(f) {top : NIL | bottom : NIL | front : BalconyWall | back : BalconyWall | left : BalconyWall }

BalconyWall -->
 color(.5,.7,.5)
 set (material.opacity, 0.7)


[ATTACH=CONFIG]19717[/ATTACH]
0 Kudos
by Anonymous User
Not applicable
Original User: matthiasbuehler

Hi !

There's one example which does this already available in the Philadelphia Example rules : Vegetation.cga

That rule can do a little more of what you expect here, but it should be easy for you to track this down.

Let me know if questions remain ..

m.
0 Kudos
larryzhang1
New Contributor III
Matt,

On CGA, the example of Philadelphia 2012 confuses me. Is it right example for this idea?

Here, I have quick Q for consulting (sorry about those):

Where are the GIS points for tree to �??grow�?? in the example CE? It looks there is no GIS points in this example. If used the attachment of SHP, how to organize the point SHP in new CE project and then make use of this example code?

/**
 * File:    Vegetation.cga
 * Created: 12 Nov 2011 13:22:05 GMT
 */

version "2011.1"


##############################################
# Attributes
#

# Driven by Object Attributes

@Group("ATTRS",1) @Order(1) @Range("Trees","Shrub","Bush","Azalia","Iris","Fern","Rhododendron")
attr type = "Trees"

@Group("ATTRS",1) @Order(2) @Range(0,30)
attr height = 20

@Group("ATTRS",1) @Order(3) @Range(360)
attr ROTATION = rand(360)

# User Attributes

@Group("OPTIONS",2) @Order(1) @Range("low","high") @Description("High LOD only available for Trees yet")
attr MODEL_LOD = "low"

@Group("OPTIONS",2) @Order(2) 
attr MODEL_ASSET =
 case type == "Trees": 
  case MODEL_LOD=="high": fileRandom("assets/vegetation/trees-geometry/Tree*.obj")
  else      : fileRandom("assets/vegetation/trees-billboards/alleyTree*.obj")
 else: 
  fileRandom("assets/vegetation/plants-billboards/"+type+"*.obj")

@Group("OPTIONS",2) @Order(3) @Range("Meters","Feet")
attr SIZE_UNIT = "Meters"

@Group("OPTIONS",2) @Order(4)
attr SIZE_RANDOMIZE = true

@Group("OPTIONS",2) @Order(5)
attr ROTATION_RANDOMIZE = true

##############################################
# Constants
#

const unitScale = case SIZE_UNIT=="Feet": 0.3048 else: 1

const randomScale = case SIZE_RANDOMIZE: rand(0.7,1.3) else: 1
const randomRotation = case ROTATION_RANDOMIZE: rand(0,360) else: 0


##############################################
# Rules
#

@StartRule
Point -->
 alignScopeToAxes(y)
 s(0,height*unitScale*randomScale,0) center(xz) 
 r(0,-ROTATION+randomRotation,0)
 i(MODEL_ASSET)
 
 
 

0 Kudos
by Anonymous User
Not applicable
Original User: hlzhang

Really amazing and powerful! 

Of course, it is much more understandable to me, after exporting all trees and lots into SHP (including attributes) and then comparing those CGA in CE vs. ArcGIS.

Quick questions are, Matt,

1. Even though the rule uses �??Point�?? for tree CGA, why is the trees�?? SHP represented in polygon geometry rather than �??point�??? Does the 'point' geometry matter?

2. What does the �??Rotation�?? represent in the attributes? Orientation azimuth angle? Why does the tree rule need this (It looks that it is Not one of Options in CGA)?



Matt,

On CGA, the example of Philadelphia 2012 confuses me.  ....

0 Kudos
by Anonymous User
Not applicable
Original User: matthiasbuehler

Hi Larry,

CE does not yet know 'point' features, so it has no data type 'points' yet. At import, just teeny tiny shapes are created ( 2x2 cm or so ). That's basically at the moment a small 'hack'.

The orientation is the rotation around the vertical axis ( direction of gravity ). Makes really no sense in reality for trees, but we want to rotate them each slightly because otherwise, they're all oriented the same, which looks weird when using all the same tree assets. It makes more sense when you have e.g. street furniture point data which has the world orientation stored properly, as in the Philly example, where all park benches are oriented the correct way.

ok ?

m.
0 Kudos