Is it possible to know if models are touching each other?

2555
9
Jump to solution
10-21-2014 12:28 AM
KennethLindhardt
Occasional Contributor

I got my building footprint, with a lot of buildings with different year of built, but a lot of those are totally aligned next to each other in different polygons. My big issue is that I don’t know which way CE would orientate those, so the front could actually be orientated to what visually is the side. Maybe there is a way to fix that, without manually go in and   orientate each building.

What I was thinking would be the easiest way (if possible) was prevent the rule from writing if faces are touching each other. Right know I got the same rule going around the building, which could work, but check the picture to see why this is not the best way. (Windows going to the neighbor wall)

If I could get this to work I could also specify my rule to only create a gable roof if the buildings are touching each other. 

1235.PNG

0 Kudos
1 Solution

Accepted Solutions
DavidWasserman
Regular Contributor

Hi Kenneth,

It is possible to query on whether you are "touching" something with occlusion tests.

http://cehelp.esri.com/help/index.jsp?topic=/com.procedural.cityengine.help/html/cgareference/func_o...


However, another way to potentially handle is this to use the street selectors for different faces, or develop case logic to create side facades if and only if the setback on its respective side is >0 (if it is zero, they are touching in most cases).  I might misunderstand the issue though,and if that is the case use the link above to look at occlusion testing. I hope this is helpful.

David

David Wasserman, AICP

View solution in original post

0 Kudos
9 Replies
DavidWasserman
Regular Contributor

Hi Kenneth,

It is possible to query on whether you are "touching" something with occlusion tests.

http://cehelp.esri.com/help/index.jsp?topic=/com.procedural.cityengine.help/html/cgareference/func_o...


However, another way to potentially handle is this to use the street selectors for different faces, or develop case logic to create side facades if and only if the setback on its respective side is >0 (if it is zero, they are touching in most cases).  I might misunderstand the issue though,and if that is the case use the link above to look at occlusion testing. I hope this is helpful.

David

David Wasserman, AICP
0 Kudos
KennethLindhardt
Occasional Contributor

Thank you David,

That was very useful information I haven’t noticed those functions before. They did exactly what needed. I don’t think it is possible to find a street side when the streets are comeing from one feature class, and the buildings from another, and course of the buildings geometry  randomness, the streets will not touch, but please correct me if I misunderstood the documentation.

Thanks again, and have a great day.

Capture.PNG

0 Kudos
DavidWasserman
Regular Contributor

Hi Kenneth,

I was not sure of the context so I tried to mention a few things. I am glad the Occlusion test worked, I would think it would be of great benefit to Geonet users if you shared the relevant code from this experience if you can.

When you are working with imported data, I believe it is possible to compute the street edges based on a street created or imported in the model. Creating and Editing Shapes Manually - See further manipulations at the bottom. I could be incorrect.

This may be the best solution to your problem, and I am glad it worked. I mention this because the occlusion tests work by creating "ghost models" that check to see if there is an instance that triggers the "occlusion" sensors. This works well, but in practice with huge models it can increase the work done by CityEngine significantly. It is one of the more computationally intensive functions to use in a model if it is triggered a lot. It is certainly useful and necessary, but just try to keep this in mind when using it. This is the only reason I mentioned other options.

Keep the geometry flowing,

David

David Wasserman, AICP
0 Kudos
KennethLindhardt
Occasional Contributor

Hi David,

Sorry for getting back so late. These functions are still giving me some issues, although I thought everything was perfect.

As soon I was switching from the test rule, to a little more advanced rule, and assigned it to 500 buildings, I noticed an issue.

First of all I needed to do the inside function, since the touches function had some troubles with more advanced geometry, as soon as there where some kind of setback in the geometry, the touch thought that the setback was touching. Then if I assigned a random floor height, then if one building was just touching a little part of the building floor nest to it, it would choose the whole side of the floor to be inside/touching which wasn’t my wish.

Well right now I’m using the inside function, but the floors and sides “inside” will go directly to my material selector, and therefor skip my advanced splitting with windows and so on. So it will reduce the amount of polygons a lot.

I will be happy to share my rule, but at this point I don’t think my rule would make that much sense to you.

I’m using attributes used in Denmark, with public available data, so I got a lot linked to Danish words, and a lot created in Danish.

As soon as I figure out what is unnecessary or useless to anyone but me, I will delete it and translate the rest, then I will share my rule.

Ok?    

0 Kudos
by Anonymous User
Not applicable

One thing to know about the occlusion functions ... they will test for any model within range, even if the layer is turned off. So this might conflict if you have other models that you can't see in the viewport.

Chris

0 Kudos
KennethLindhardt
Occasional Contributor

Yes, I must correct my last answer. The touches also work. I had a split on my ground façade where I was extruding the base/socket, which was resulting in the “touches” of course was not working when there was a setback in the geometry, since the base would touch the façade.

Thanks Chris, for make me think twice  ;)

Did a NIL, where it was touching:NIL.PNG

0 Kudos
DavidWasserman
Regular Contributor

Hi  Kenneth,

Glad Chris could get to that.

I just like to see coding examples on Geonet so users can try to learn from them if they have similar questions. Even if it is largely indecipherable most the time (which is often the case with code), some example is better than none. Share if you want, my only interest is sharing knowledge and learning within Geonet.

Kind Regards,

David

David Wasserman, AICP
0 Kudos
KennethLindhardt
Occasional Contributor

Okay, here is most of the rule I’ve been working on. I started from the top and figured stuff out along the way, so this is not very pretty or organized. I have hidden all the attr that wasn’t ment to be used, but should be const, but I still needed those when developing.

You got the opportunity to controle the window size and placement, the start pillar and other pillar sizes. I haven’t translated the attr that I use from the public available data, but hopefully you can get the idea. There will not be any materials, but you can create folders like shown in the material selector. If the texture name+ the path contains lets say 36 characters it will take 1 bump map 37 another and so on. So this is my first rule, there will probably be a lot to approve on.

If someone would like some explanation got suggestions or want to ask anything don’t hesitate.

Kenneth 

Copy and see what happens :)

/**

* File:    DK_rule_ENG.cga

* Created: 7 NOV 2014 07:28:19 GMT

* Author:  KennethL

*/

version "2014.1"

const Vindue_asset = "sash_window.obj"

#######################

#

# OBJECT ATTRIBUTES

#

#######################

@Range ("Low","High")

attr LOD = "Low"

attr Year = rand(1800,2020)

attr NUM_FLOORS = rand(2,7)

@hidden

attr Shape_Area = 1

@Hidden

attr Number_of_Floors =

case geometry.area < 50 : 1

case NUM_FLOORS == 0 : 30% : 1 30%: 2 20% : 3 else : 4

else : NUM_FLOORS

@Hidden

attr BYG_ANVEND_KODE = 110

@Hidden

attr TAG_KODE = 60% : 5 30% : 2 else : 1

@Hidden

attr YDERVAEG_KODE = 60% : 1 else: 12

#######################

#

# Design ATTRIBUTES Facade

#

#######################

attr Ground_Hight =

case YDERVAEG_KODE == 12 : Floor_Hight

else : rand(3.2,4)

attr Floor_Hight = rand(3,3.4)

attr Window_Width = rand(0.8,1.5)

attr Window_Hight =

case YDERVAEG_KODE == 12 && LOD == "Low" : Floor_Hight - 0.2

case YDERVAEG_KODE == 12 : Floor_Hight

else : rand(0.8,1.5)

@Hidden

attr Door_Width = rand(0.9,2)

const Door_Hight = rand(2.2,3)

attr Sill_H =

case YDERVAEG_KODE == 12 && LOD == "Low" : 0.1

case YDERVAEG_KODE == 12 : 0

else : rand(0.8,1.2)

attr Pillar_Width =

case YDERVAEG_KODE == 12 && LOD == "Low" : 0.1

case YDERVAEG_KODE == 12 : 0

else : rand(0.5,1.5)

attr Start_Pillar =

case YDERVAEG_KODE == 12 && LOD == "Low" : 0.1

case YDERVAEG_KODE == 12 : 0

else : rand(0.8,1.2)

attr Base_H = rand(0.1,1)

@Hidden

attr Samlet_Floor_H = Floor_Hight * Number_of_Floors

@Hidden

attr Total_Building_H = (Floor_Hight * (Number_of_Floors -1)) + Ground_Hight

const Tile_complet = Window_Width + Pillar_Width

const Tile_complet_Door = Door_Width + Pillar_Width

@Hidden

attr Cornise_Size = rand(0.15,0.3)

@Hidden

attr Current_Floor = 0

@Range ("No", "Yes")

attr Plaster = 80% : "No" else : "Yes"

@Hidden

attr Inside = inside

#######################

#

# Design ATTRIBUTES Roofe

#

#######################

#######################

#

# Viste attributter BBR-Link

# Datamodel Version 10.0 April 2013

#

#######################

@Range("Parcelhus","Groundhus landbrug","Rækkehus","Floorbolig","Kollegium","Døgninstition","Parcelhus","Hotel, lign.","Anden bygning til helårsbolig","(Landbrug)Erhvervsmæssig produktion","(Industri) Erhvervsmæssig produktion","Varmeværk, forbrændinger","Anden industri","Biograf/teater","Undervisning","Hospital","Daginstitution","Anden institution","Sommerhus","Bygning til ferieformål","Garage til 2 køretøjer","Carport","Udhus")

attr BuildingUse =

  case BYG_ANVEND_KODE == 110: "Parcelhus"

  case BYG_ANVEND_KODE == 120: "Groundhus landbrug"

  case BYG_ANVEND_KODE == 130: "Rækkehus"

  case BYG_ANVEND_KODE == 140: "Floorbolig"

  case BYG_ANVEND_KODE == 150: "Kollegium"

  case BYG_ANVEND_KODE == 160: "Døgninstition"

  case BYG_ANVEND_KODE == 190: "Anden bygning til helårsbolig"

  case BYG_ANVEND_KODE == 210: "(Landbrug)Erhvervsmæssig produktion"

  case BYG_ANVEND_KODE == 220: "(Industri) Erhvervsmæssig produktion"

  case BYG_ANVEND_KODE == 230: "Varmeværk, forbrændinger"

  case BYG_ANVEND_KODE == 290: "Anden industri"

  case BYG_ANVEND_KODE == 320: "Anden industri"

  case BYG_ANVEND_KODE == 330: "Hotel, lign."

  case BYG_ANVEND_KODE == 410: "Biograf/teater"

  case BYG_ANVEND_KODE == 420: "Undervisning"

  case BYG_ANVEND_KODE == 430: "Hospital"

  case BYG_ANVEND_KODE == 440: "Daginstitution"

  case BYG_ANVEND_KODE == 490: "Anden institution"

  case BYG_ANVEND_KODE == 510: "Sommerhus"

  case BYG_ANVEND_KODE == 590: "Bygning til ferieformål"

  case BYG_ANVEND_KODE == 910: "Garage til 2 køretøjer."

  case BYG_ANVEND_KODE == 920: "Carport."

  case BYG_ANVEND_KODE == 930: "Udhus."

  else: "Ikke Defineret"

@Range("Built-up","Roofpap (med hældning)","Fibercement","Cementsten","RoofTile","Metalplader","Stråtag","Fibercement (asbestfri)","PVC","Glas","Grønne tage","Inge","Andet","Ikke Defineret")

attr Rooftype =

  case TAG_KODE == 1: "Built-up"

  case TAG_KODE == 2: "Roofpap (med hældning)"

  case TAG_KODE == 3: "Fibercement"

  case TAG_KODE == 4: "Cementsten"

  case TAG_KODE == 5: "RoofTile"

  case TAG_KODE == 6: "Metalplader"

  case TAG_KODE == 7: "Stråtag"

  case TAG_KODE == 10: "Fibercement (asbestfri)"

  case TAG_KODE == 11: "PVC"

  case TAG_KODE == 12: "Glas"

  case TAG_KODE == 20: "Grønne tage"

  case TAG_KODE == 80: "Ingen"

  else: "Ikke Defineret"

@Range("Brick","Letbeton","Plader af fibercement","Bindingsværk","Træbeklædning","Concreteelementer","Metalplader","Plader af fibercement (asbestfri)","PVC","Glas","Inge","Andet")

attr Material =

  case YDERVAEG_KODE == 1: "Brick"

  case YDERVAEG_KODE == 2: "Letbeton"

  case YDERVAEG_KODE == 3: "Plader af fibercement"

  case YDERVAEG_KODE == 4: "Bindingsværk"

  case YDERVAEG_KODE == 5: "Træbeklædning"

  case YDERVAEG_KODE == 6: "Concreteelementer"

  case YDERVAEG_KODE == 8: "Metalplader"

  case YDERVAEG_KODE == 10: "Plader af fibercement (asbestfri))"

  case YDERVAEG_KODE == 11: "PVC"

  case YDERVAEG_KODE == 12: "Glas"

  case YDERVAEG_KODE == 80: "Ingen"

  else: "Ikke Defineret"

#######################

#

# Splitter

#

#######################

Ground_Floor-->

case YDERVAEG_KODE == 12 : extrude(Ground_Hight) comp(f) {top : Floor |  side : Floor_Facade | bottom : Inder_Floor}

else:

extrude(Ground_Hight) comp(f) {top : Floor |  side : Ground_Facade_begin | bottom : Inder_Floor}

Floor-->

case Current_Floor > Number_of_Floors - 2 : 

  extrude (0.01) trim comp(f) {top: Roof }

else :

set(Current_Floor, Current_Floor +1)

extrude(Floor_Hight) comp(f)  {top : Floor | side : Floor_Facade | bottom : Inder_Floor}

Inder_Floor-->

offset(-0.2, inside) extrude(world.y, 0.2)

Ground_Facade_begin-->

case Year < 1940 : split(y) {Ground_Hight -Cornise_Size : Ground_Facade | Cornise_Size : Cornise}

else: Ground_Facade

Ground_Facade-->

case geometry.area(surface) / Floor_Hight < Tile_complet * 2 + Start_Pillar * 2  : Little_Facader_Ground

case geometry.area(surface) / Ground_Hight > (Start_Pillar * 2) + (Tile_complet * 4) + (Tile_complet_Door):

split(x){ Start_Pillar : Start_Wall

  | Tile_complet : Tile_Ground_Stor|{Tile_complet : Tile_Ground_Stor|Tile_complet_Door : Tile_door_Stor

  |  Tile_complet : Tile_Ground_Stor }*

  | Start_Pillar : Start_Wall }

else:

split(x){ Start_Pillar : Start_Wall

  |~Pillar_Width / 2 : Start_Wall | Window_Width : Tile_Ground | ~Pillar_Width / 2 : Start_Wall

  |{ Door_Width : Tile_door

  |~Pillar_Width / 2 : Start_Wall | Window_Width : Tile_Ground | ~Pillar_Width / 2 : Start_Wall}*

  | Start_Pillar : Start_Wall }

Floor_Facade-->

case geometry.area(surface) / Floor_Hight < Tile_complet * 2 + Start_Pillar * 2  : Little_Facader

case geometry.area(surface) / Floor_Hight > (Start_Pillar * 2) + (Tile_complet * 4) + (Tile_complet_Door):

split(x){ Start_Pillar : Wall_Ashlar_Left

  | Tile_complet : Tile_Stor|{Tile_complet : Tile_Stor|Tile_complet_Door : Tile_opgang_Stor

  |  Tile_complet : Tile_Stor }*

  | Start_Pillar : Wall_Ashlar_Right }

 

else:

split(x){ Start_Pillar : Wall_Ashlar_Left

  |~Pillar_Width / 2 : Wall | Window_Width : Tile | ~Pillar_Width / 2 : Wall

  |{  Door_Width : Tile_opgang

  |~Pillar_Width / 2 : Wall | Window_Width : Tile | ~Pillar_Width / 2 : Wall}*

  | Start_Pillar : Wall_Ashlar_Right }

Little_Facader-->

case geometry.area(surface) / Floor_Hight < Window_Width + 0.6 : Wall

else:

split(x) {~1 : Wall | Window_Width : 

split(y){ Sill_H: Wall | Window_Hight: Vindue | ~1: Wall }

  |~1: Wall }

Little_Facader_Ground-->

case geometry.area(surface) / Floor_Hight < Window_Width + 0.6 : Start_Wall

else:

split(x) {~1 : Start_Wall | Window_Width : 

split(y){ Sill_H: Start_Wall | Window_Hight: Vindue | ~1: Start_Wall}

  |~1: Start_Wall }

Start_Wall-->

split(y) {Base_H : Base | ~1 : Wall_Ground}

Tile_Ground-->

split(y){ Base_H : Base | Sill_H - Base_H: Wall_Ground_Sill | Window_Hight: Vindue | ~1: Wall_Ground }

Tile_Ground_Stor-->

  split(x){ Pillar_Width/2 : Start_Wall

  |  split(y){ Base_H : Base | Sill_H - Base_H: Wall_Ground_Sill | Window_Hight: Vindue | ~1: Wall_Ground }

  | Pillar_Width/2 : Start_Wall }

Tile-->

split(y){ Sill_H: Wall | Window_Hight: Vindue | ~1: Wall }

Tile_Stor-->

  split(x){ Pillar_Width/2 : Wall

  |  split(y){ Sill_H: Wall | Window_Hight: Vindue | ~1: Wall }

  | Pillar_Width/2 : Wall }

Tile_door-->

split(y) {Door_Hight: Door | ~1: Wall_Ground }

Tile_door_Stor-->

  split(x){ ~Pillar_Width/2 : Start_Wall

  | split(y) {Door_Hight: Door | ~1: Wall_Ground }

  | ~Pillar_Width/2 : Start_Wall }

Tile_opgang-->

split(y){ Sill_H: Wall | Window_Hight: Vindue_Opgang | ~1: Wall }

Tile_opgang_Stor-->

  split(x){ ~Pillar_Width/2 : Wall

  | split(y){ Sill_H: Wall | Window_Hight: Vindue_Opgang | ~1: Wall }

  | ~Pillar_Width/2 : Wall }

#######################

#

# Vinduer

#

#######################

@Range ("Normal", "Dannebro", "Midt_Split", "Midt_Split2")

attr Window_Type =

29% : "Normal"

29% : "Midt_Split"

29% : "Midt_Split2"

else: "Dannebro"

Vindue-->

case LOD == "Low" : color(DoorColor)

case Window_Type == "Normal" :

t(0,0,-0.10)

split(y) {0.02 : Saalbaenk | 0.06 : Ramme | 0.04 : Inv_Ramme | ~0.5 : Glas | 0.04 : Inv_Ramme | 0.06 : Ramme}

split(x) {0.05 : Ramme| 0.04 : Inv_Ramme | ~0.5 : Glas | 0.04 : Inv_Ramme | 0.05 : Ramme}

case Window_Type == "Midt_Split":

t(0,0,-0.10)

split(y) {0.02 : Saalbaenk | 0.06 : Ramme | 0.04 : Inv_Ramme | ~0.5 : Glas | 0.04 : Inv_Ramme | 0.06 : Ramme}

split(x) {0.05 : Ramme| 0.04 : Inv_Ramme | ~0.5 : Glas | 0.04 : Inv_Ramme | 0.05 : Ramme | 0.04 : Inv_Ramme| ~0.5 : Glas |0.04 : Inv_Ramme | 0.05 : Ramme}

case Window_Type == "Midt_Split2":

t(0,0,-0.10)

split(y) {0.02 : Saalbaenk | 0.06 : Ramme | 0.04 : Inv_Ramme | ~0.5 : Glas | 0.04 : Inv_Ramme | ~0.25 : Glas | 0.04 : Inv_Ramme | 0.06 : Ramme}

split(x) {0.05 : Ramme| 0.04 : Inv_Ramme | ~0.5 : Glas | 0.04 : Inv_Ramme | 0.05 : Ramme | 0.04 : Inv_Ramme| ~0.5 : Glas |0.04 : Inv_Ramme | 0.05 : Ramme}

case Window_Type == "Dannebro":

t(0,0,-0.10)

split(y) {0.02 : Saalbaenk | 0.06 : Ramme | 0.04 : Inv_Ramme | {~0.2 : Glas | 0.04 : Inv_Ramme | ~0.2 : Glas}* | 0.06 : Ramme}

split(x) {0.05 : Ramme| 0.04 : Inv_Ramme | {~0.2 : Glas | 0.04 : Inv_Ramme | ~0.2 : Glas}* |0.04 : Inv_Ramme | 0.05 : Ramme}

else:NIL

Vindue_Opgang-->

case LOD == "Low" : color(DoorColor)

case Window_Type == "Normal" :

t(0,0,-0.10)

split(y) {0.02 : Saalbaenk_Opgang | 0.06 : Ramme | 0.04 : Inv_Ramme | ~0.5 : Glas | 0.04 : Inv_Ramme | 0.06 : Ramme}

split(x) {0.05 : Ramme| 0.04 : Inv_Ramme | ~0.5 : Glas | 0.04 : Inv_Ramme | 0.05 : Ramme}

case Window_Type == "Midt_Split":

t(0,0,-0.10)

split(y) {0.02 : Saalbaenk_Opgang | 0.06 : Ramme | 0.04 : Inv_Ramme | ~0.5 : Glas | 0.04 : Inv_Ramme | 0.06 : Ramme}

split(x) {0.05 : Ramme| 0.04 : Inv_Ramme | ~0.5 : Glas | 0.04 : Inv_Ramme | 0.05 : Ramme | 0.04 : Inv_Ramme| ~0.5 : Glas |0.04 : Inv_Ramme | 0.05 : Ramme}

case Window_Type == "Midt_Split2":

t(0,0,-0.10)

split(y) {0.02 : Saalbaenk_Opgang | 0.06 : Ramme | 0.04 : Inv_Ramme | ~0.5 : Glas | 0.04 : Inv_Ramme | ~0.25 : Glas | 0.04 : Inv_Ramme | 0.06 : Ramme}

split(x) {0.05 : Ramme| 0.04 : Inv_Ramme | ~0.5 : Glas | 0.04 : Inv_Ramme | 0.05 : Ramme | 0.04 : Inv_Ramme| ~0.5 : Glas |0.04 : Inv_Ramme | 0.05 : Ramme}

case Window_Type == "Dannebro":

t(0,0,-0.10)

split(y) {0.02 : Saalbaenk_Opgang | 0.06 : Ramme | 0.04 : Inv_Ramme | {~0.2 : Glas | 0.04 : Inv_Ramme | ~0.2 : Glas}* | 0.06 : Ramme}

split(x) {0.05 : Ramme| 0.04 : Inv_Ramme | {~0.2 : Glas | 0.04 : Inv_Ramme | ~0.2 : Glas}* |0.04 : Inv_Ramme | 0.05 : Ramme}

else:NIL

Ramme-->

extrude(0.1)trim

projectUV(0)

set(material.colormap, Ramme_Material)

Inv_Ramme-->

extrude(0.05)trim

projectUV(0)

set(material.colormap, Ramme_Material)

Saalbaenk-->

extrude(0.2)

t(-0.04,0,-0.03)

r(20,0,0)

s(Window_Width + 0.08,0.2,0.04)trim

projectUV(0)

set(material.colormap, Ashlar_Material)

Saalbaenk_Opgang-->

extrude(0.2)trim

t(-0.04,0,-0.03)trim

r(20,0,0)trim

s(Door_Width + 0.08,0.2,0.04)trim

projectUV(0)

set(material.colormap, Ashlar_Material)

Glas-->

20% :

setupProjection(0, scope.xy, '1, '1) projectUV(0) 

  set(material.opacity,0.6)

  set(material.reflectivity, 0.3)

  set(material.specular.r,70)

  set(material.specular.g,70)

  set(material.specular.b,70)

  set(material.shininess,20)

else:

setupProjection(0, scope.xy, '1, '1) projectUV(0) 

  set(material.reflectivity, 0.3)

  set(material.specular.r,70)

  set(material.specular.g,70)

  set(material.specular.b,70)

  set(material.shininess,20)

  color("#808080")

#######################

#

# Døre

#

#######################

@Hidden

attr Setback = rand(-0.10,-1)

Door-->

case LOD == "Low" : color(DoorColor)

case Door_Width > 1.6 :

t(0,0,Setback)

split(y) {0.01 : projectUV(0)set(material.colormap, Plaster_Material) | Door_Hight : Door_Material

split(x) {0.01 : Ramme_Door| ~0.5 : Door_Material | 0.06 : Door_Material| ~0.5 : Door_Material |  0.01 : Ramme_Door} | 0.04 : Inv_Ramme | ~0.25 : Glas | 0.04 : Inv_Ramme | 0.01 : Ramme_Door}

else:

t(0,0,Setback)

split(y) {0.01 : projectUV(0)set(material.colormap, Tiles_Material) | 2.2 : Door_Material

split(x) {0.01 : Ramme_Door| ~0.5 : Door_Material |  0.01 : Ramme_Door} | split(x) { 0.01 : Ramme_Door} | 0.04 : Inv_Ramme | ~0.25 : Glas split(x) { 0.01 : Ramme_Door} | 0.04 : Inv_Ramme | 0.01 : Ramme_Door}

Door_Material-->

projectUV(0)

set(material.colormap, Ramme_Material)

Ramme_Door-->

extrude(Setback * -1)trim

projectUV(0)

set(material.colormap, Plaster_Material)

#######################

#

# Vægge

#

#######################

Wall-->

case LOD == "Low" : color(BuildingColor)

else:

t(0,0,-0.10)

extrude(0.11) trim

Material_Selector

Wall_Ashlar_Left-->

case LOD == "Low" : color(BuildingColor)

case Year < 1950 :

split(y) { ~Ashlar_H : Ashlar | ~Ashlar_H : Ashlar_halv_Left}*

else : Wall

Wall_Ashlar_Right-->

case LOD == "Low" : color(BuildingColor)

case Year < 1950 :

split(y) { ~Ashlar_H : Ashlar | ~Ashlar_H : Ashlar_halv_Right}*

else : Wall

Ashlar_halv_Left-->

case LOD == "Low" : color(BuildingColor)

else:

split { Start_Pillar / 2 : Ashlar | ~1 : Wall}

Ashlar_halv_Right-->

case LOD == "Low" : color(BuildingColor)

else:

split {~1 : Wall | Start_Pillar / 2 : Ashlar }

 

Base-->

case LOD == "Low" : color(BuildingColor)

else:

  extrude(0.02) projectUV(0)

set(material.colormap, Base_Material)

 

Wall_Ground-->

case LOD == "Low" : color(BuildingColor)

case Year < 1930 && Number_of_Floors > 1 : Ashlar_Split

else:

Material_Selector

Wall_Ground_Sill-->

case LOD == "Low" : color(BuildingColor)

case Year < 1930 && Number_of_Floors > 1 : Ashlar_Split

else:

Material_Selector 

#######################

#

# Ashlar

#

#######################

const Ashlar_B = rand(0.3,0.7)

const Ashlar_H = rand(0.15,0.4)

 

Ashlar_Split-->

case LOD == "Low" : color(BuildingColor)

else :

split(y) { ~Ashlar_H : Ashlar | {Ashlar_H : Ashlar }* }

Ashlar-->

case LOD == "Low" : color(BuildingColor)

else :

split(x) { ~Ashlar_B : Ashlar2}*

Ashlar2-->

envelope(normal, 0.05, 0, 60)

projectUV(0) set(material.colormap, Ashlar_Material)

Cornise-->

case LOD == "Low" : color(BuildingColor)

case Year > 1970 : Material_Selector

else:

split(x) {Cornise_Size : Cornise_Asset}* trim

Cornise_Asset-->

case overlaps :

s(0,0,0)

i(Corniseer)

projectUV(0)

set(material.colormap, Ashlar_Material)

else:

s(0,'1,'1)

i("Objects/ledge.02.twopart.obj")

projectUV(0)

set(material.colormap, Ashlar_Material)

#######################

#

# Roofe

#

####################### 

/**import Parisian_Roof: "/Example_Paris__2014_0/rules/ParisianRoofs_DK.cga" //(Tile_Width) //(Type=RoofType,Covering=RoofCovering,Level_of_Detail,Tile_Width)

Roof -->

  Parisian_Roof.Roof*/

@Hidden

attr ROOF_SLOPE_MENS = rand(70,88)

#######################

#

# Roof regel

#

#######################

@Range("Valmet tag","Saddel tag", "Roofskur")

attr Roof_design =

case TAG_KODE == 1 : "Roofskur"

case inside : "Saddel tag"

case touches : "Saddel tag"

case BYG_ANVEND_KODE == 140 : "Saddel tag"

case YDERVAEG_KODE == 12 : "Roofskur"

else :

"NIL"

attr RoofAngel =

case Rooftype == "Roofpap (med hældning)" : rand(5,20)

case Rooftype == "RoofTile" : rand(22,40)

case Rooftype == "Stråtag" : rand(35,45)

case Rooftype == "Fibercement" : rand(22,40)

else:rand(22.5,40)

mansard_vinkel = case RoofAngel*3<65: 65 case RoofAngel*3>80: 80 else: RoofAngel*3

@Hidden

attr Udhaeng_X = 0.01

@Hidden

attr Udhaeng_Y = 0.01

Roof-->

case Roof_design == "Valmet tag" : Valmet_tag

case Roof_design == "Saddel tag" : Saddel_tag

case Roof_design == "Roofskur" : Roof_skur

case Rooftype == "Built-up": extrude (world.y, 0.10) comp(f) { top : Roof_materiale | all : Staal }

case Rooftype == "Roofpap (med hældning)": 60% : Saddel_tag 10% : Roof_skur else : Valmet_tag

case Rooftype == "Grønne tage": extrude (world.y,0.10) comp(f) { top : Roof_materiale | all : Staal }

case Rooftype == "Stråtag": 50%:Valmet_tag else: Saddel_tag

case Rooftype == "RoofTile": 50%:Valmet_tag else: Saddel_tag

else: 40% : Saddel_tag 10% : Roof_skur else : Valmet_tag

Saddel_tag-->

  roofGable(RoofAngel, Udhaeng_X, Udhaeng_Y)

  Saddel_tag_extrude

Saddel_tag_extrude-->

extrude(world.y, 0.05) comp(f) {top : Roof_materiale | vertical : Wall}

Valmet_tag-->

  roofHip(RoofAngel, Udhaeng_X) extrude(world.y,0.1)

  comp(f) {vertical : Wall | all:Roof_materiale}

Roof_skur-->

roofShed(0.1)

comp(f) {vertical: Wall | top: Roof_materiale}

/**Mansard_tag -->

  roofHip(mansard_vinkel)

  split(y){3: comp(f){side: Mansard_split | top: Valmet_tag | bottom: RoofCovering } }

Mansard_split-->

  deleteUV(0) split(x, noAdjust){ Start_Pillar : RoofLer

  | { ~Tile_complet : Tile }*

  | Start_Pillar : Wall }

Shape */

#######################

#

# Roof materialer

#

#######################

@Range ("Rød","Dark","Standard")

attr Roof_Color = "Standard"

const tagpap_materiale = fileRandom("assets/Roofs/Pap/*.jpg")

const tagstaal_materiale = listRandom(fileSearch("assets/Roofs/Metal/*.png"))

const tagler_materiale = listRandom(fileSearch("assets/Roofs/Ler/*.jpg"))

const tagstraa_materiale = listRandom(fileSearch("assets/Roofs/Straa/*.jpg"))

const tagrand_materiale = listRandom(fileSearch("assets/Roofs/*.jpg"))

const tagler_materiale_bump = listRandom(fileSearch("Roofs/Ler_bump/Bump/*.jpg"))

Roof_materiale-->

  case LOD == "Low" : Oprydning_Hvid

  case Rooftype == "Built-up":

  setupProjection(0, scope.xy, '1, '1) projectUV(0)tileUV(1, 0.5, 1)

  texture(tagpap_materiale)

  case Rooftype == "Roofpap (med hældning)":

  setupProjection(0, scope.xy, '1, '1) projectUV(0)tileUV(0, 1.6, 1)

  set(material.colormap,tagpap_materiale)

  case Rooftype == "Fibercement" : setupProjection(0, scope.xy, '1, '1) projectUV(0) tileUV(0, 1.6, 1)texture(tagpap_materiale)

  case Rooftype == "Cementsten": setupProjection(0, scope.xy, '1, '1) projectUV(0) tileUV(0, 1.6, 1)texture(tagpap_materiale)

  case Rooftype == "RoofTile" && Roof_Color == "Standard":

  setupProjection(0, scope.xy, '1, '1) projectUV(0) tileUV(0, 1.6, 1)

  set(material.colormap,tagler_materiale)

  setupProjection(0, scope.xy, '1, '1) projectUV(1) tileUV(0, 1.6, 1)

  set(material.bumpmap,tagler_materiale_bump)

  case Rooftype == "RoofTile" && Roof_Color == "Rød":

  setupProjection(0, scope.xy, '1, '1) projectUV(0) tileUV(0, 1.6, 1)

  set(material.colormap,"Roofs/Ler/1378108_590621044330851_484551746_n.jpg")

  setupProjection(0, scope.xy, '1, '1) projectUV(1) tileUV(0, 1.6, 1)

  set(material.bumpmap,tagler_materiale_bump)

  case Rooftype == "RoofTile" && Roof_Color == "Dark":

  setupProjection(0, scope.xy, '1, '1) projectUV(0) tileUV(0, 1.6, 1)

  set(material.colormap,"Roofs/Ler/1379792_590620650997557_1896037340_n.jpg")

  setupProjection(0, scope.xy, '1, '1) projectUV(1) tileUV(0, 1.6, 1)

  set(material.bumpmap,tagler_materiale_bump)

  case Rooftype == "Metalplader": setupProjection(0, scope.xy, '1, '1) projectUV(0) tileUV(0, 1.6, 1)texture(tagstaal_materiale)

  case Rooftype == "Stråtag": setupProjection(0, scope.xy, '1, '1) projectUV(0) tileUV(0, 1.6, 1)texture(tagstraa_materiale)

  case Rooftype == "PVC": setupProjection(0, scope.xy, '1, '1) projectUV(0) tileUV(0, 1.6, 1)texture(tagpap_materiale)

  case Rooftype == "Glas": setupProjection(0, scope.xy, '1, '1) projectUV(0) tileUV(0, 1.6, 1)texture(tagpap_materiale)

  case Rooftype == "Grønne tage": setupProjection(0, scope.xy, '1, '1) projectUV(0) tileUV(0, 1.6, 1)texture(tagstraa_materiale)

  case Rooftype == "Ingen": setupProjection(0, scope.xy, '1, '1) projectUV(0) tileUV(0, 1.6, 1)texture(tagler_materiale)

else: setupProjection(0, scope.xy, '1, '1) projectUV(0) tileUV(0, 1.6, 1)texture(tagler_materiale)

Window_generering-->

case LOD == "Low" : Low_Detail

case inside : Wall

case geometry.area(surface) / Floor_Hight < Tile_complet * 2 + Start_Pillar * 2  : Oprydning

case geometry.area(surface) / Floor_Hight > (Start_Pillar * 2) + (Tile_complet * 4) + (Tile_complet_Door):

split(x){ Start_Pillar : Oprydning

  | Tile_complet : Tile_tag|{Tile_complet : Tile_tag|Tile_complet_Door : Oprydning

  |  Tile_complet : Tile_tag }*

  | Start_Pillar : Oprydning }

else:

Oprydning

/**split(x){ Start_Pillar+Udhaeng_X : Oprydning

  | Tile_complet : Oprydning|{Tile_complet : Tile_tag|Tile_complet_Door : Oprydning

  |  Tile_complet : Tile_tag }*

  |  Tile_complet : Oprydning |Start_Pillar+Udhaeng_X : Oprydning }*/

Tile_tag-->

split(x){ Pillar_Width/2 : Oprydning

  |  split(y){ 1: Oprydning  | 3: Vindue | ~1: Oprydning  }

  | Pillar_Width/2 : Oprydning  }

Oprydning-->

color(BuildingColor)

Oprydning_Hvid-->

color(BuildingColor)

Staal-->

setupProjection(0, scope.xy, '1, '1) projectUV(0) tileUV(0, 1.6, 1)

texture(tagstaal_materiale)

#######################

#

# Find Materialr

#

#######################

Material_Selector-->

case YDERVAEG_KODE == 1 && Plaster == "No" :

projectUV(0)

set(material.colormap, Brick_Material)

projectUV(1)

set(material.bumpmap, Bump_Material)set(material.bumpValue,1)

case YDERVAEG_KODE == 1 && Plaster == "Yes" :

projectUV(0)

set(material.colormap, Plaster_Material)

projectUV(1)

set(material.bumpmap, Bump_Material)set(material.bumpValue,1)

case YDERVAEG_KODE == 2 ||

  YDERVAEG_KODE == 3 ||

  YDERVAEG_KODE == 4 ||

  YDERVAEG_KODE == 8 ||

  YDERVAEG_KODE == 10 ||

  YDERVAEG_KODE == 11 ||

  YDERVAEG_KODE == 80 :

set(material.colormap, Plaster_Material)

projectUV(1)

set(material.bumpmap, Bump_Material)set(material.bumpValue,0.1)

case YDERVAEG_KODE == 6 : projectUV(0)

set(material.colormap, Concrete_Material)

case YDERVAEG_KODE == 5 : projectUV(0)

set(material.colormap, Woodbeklaedning)

case Plaster == "Yes" :

projectUV(0)

set(material.colormap, Plaster_Material)

projectUV(1)

set(material.bumpmap, Bump_Material)set(material.bumpValue,0.1)

else :

projectUV(0)

set(material.colormap, Brick_Material)

projectUV(1)

set(material.bumpmap, Bump_Material)set(material.bumpValue,1)

@Hidden  

attr LEN = len(Brick_Material) 

 

const Ground_Material = fileRandom("/Aalborg/images/Til_Klip/*.PNG")

const Woodbeklaedning = fileRandom("Brick/*.png")

const Tiles_Material = fileRandom("Tiles/*.png")

const Base_Material = fileRandom("Base/*.jpg")

const Concrete_Material = fileRandom("Base/*.jpg")

const Ramme_Material = fileRandom("Sprosser/*/*.png")

const Brick_Material = fileRandom("Brick/*.png")

const Plaster_Material = fileRandom("Plaster/*/*.png")

const Roof_Material = fileRandom("Roof/*.png")

const Bump_Material =

case Plaster == "Yes" : listRandom("Concrete/Concrete.Cast-in-Place.Formwork.Wood.Boards.bump.jpg")

case len(Brick_Material) == 40  : listRandom("Bump/Brick_Non_Uniform_Running_bump.png")

case len(Brick_Material) == 36  : listRandom("Bump/Masonry.Unit Masonry.Brick.Modular.Running.Scored.Red.bump.jpg")

case len(Brick_Material) == 35  : listRandom("Bump/Brick_Uniform_Running_bump.png")

else: ("X")

const Ashlar_Material = fileRandom("Ashlar/*.jpg")

#######################

#

# Assets

#

####################### 

const Corniseer =  "Objects/ledge.02.twopart.obj"

Low_Detail-->

color(BuildingColor)

const BuildingColor = "#DADADA"

const DoorColor = "#B6B6B6"

0 Kudos
DavidWasserman
Regular Contributor

This is perfect. Thanks Kenneth!

David Wasserman, AICP
0 Kudos