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.
Solved! Go to Solution.
Hi Kenneth,
It is possible to query on whether you are "touching" something with occlusion tests.
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
Hi Kenneth,
It is possible to query on whether you are "touching" something with occlusion tests.
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
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.
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
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?
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
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:
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
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"
This is perfect. Thanks Kenneth!