Hi all, I'm just getting started with City Engine and am trying to apply textures to facades based on building attributes (i.e. brick, wood, stone etc.). Can anyone give an example of how to write the code for this? Thx.
Put in your assets folder: (find attached CGA and Assets)
brick.jpg, wood.jpg, and stone.jpg
BrickWoodStone.cga:
version "2014.0"
const facadeDirectory = "assets/BrickWoodStone/"
attr buildingHeight = 10
@Range("brick", "wood", "stone")
attr facadeTexture = "brick"
attr textureScaleX = 4
attr textureScaleY = 4
BuildingFootprint -->
# Make footprint flat by scaling to zero in y direction.
s('1,0,'1)
# Make footprint into mass.
extrude(buildingHeight)
# Pop off sides and top.
comp(f) {top: Roof | side: Facade}
Roof -->
roofGable(30)
Facade -->
setupProjection(0, scope.xy, textureScaleX, textureScaleY)
projectUV(0)
texture(facadeDirectory + facadeTexture + ".jpg")
great help here, Chris !
Matt
Matthias Buehler
Head of 3D Technologies
twitter: @MattB3D
------------------------------
Garsdale Design Limited
Great! Thanks for this. I was wondering though how exactly do I assign textures based on attributes already specified to the object? I have a set of historic building footprints that have information attached to them (height, # of stories, material etc) and I've been able to extrude them to correspond with their height, but I'm still not sure how to link textures to the given material.
Can you give a brief example...pseudo-code or just explain the logic/goal? How do the attribute values correspond to the material choices. Is random involved, or exact/unique textures per building or per attribute value?
Chris
Sure. There are no random values. I imported a shapefile of historic building footprints that have a field called "material", which specifies whether the building was constructed from brick, wood, metal, etc. I'd like to assign textures to the facades based on the material specified in that field, which are just recorded as "brick", "wood", "metal" etc. The outcome would be that all buildings specified as "brick" in the material field would receive a brick textured facade, and so on.
So it seems this is the same rule as earlier in the post (see above CGA), but you need to use the Connection Editor. See the small icon to the left of the values in the Inspector. Clicking into that, you will see the third option is "object attribute". That is how you connect your rule to object attributes of the shapes that the rule is running on. To enable this linkage, the object attribute name must match the attribute name in your rule.
So in the rule above, change this line, so that "facadeTexture" matches you object attributes on the shapes:
attr facadeTexture = "brick"
Is this what you meant?
Okay thanks. So this is what I have (note LAYER is the name of the attribute field):
const facadeDirectory = "assets/brick_facade_01/"
attr LAYER = "brick"
@Range("brick", "stone", "frame", "iron", "special frame")
attr facadeTexture = LAYER
attr textureScaleX = 4
attr textureScaleY = 4
Facade -->
setupProjection(0, scope.xy, textureScaleX, textureScaleY)
projectUV(0)
texture(facadeDirectory + facadeTexture + "brick_facade_01.jpg")
This worked in that it changed the value in the connection editor to the individual prescribed attribute for every object. I'm still not sure about facade texture though. This code didn't project anything and I'm not sure how to make it more specific to differentiate between the attributes. So far I only included one image (brick) just to test.
One easy way to test this is change this:
texture(facadeDirectory + facadeTexture + "brick_facade_01.jpg")
To this:
print(facadeDirectory + facadeTexture + "brick_facade_01.jpg")
It should display this in the CGA console:
assets/brick_facade_01/brickbrick_facade_01.jpg
This shows the file you are asking for. Notice you need a slash before the file name, so then change the line to this:
texture(facadeDirectory + facadeTexture + "/" + "brick_facade_01.jpg")
Or if you weren't using a literal file name:
texture(facadeDirectory + facadeTexture + "/" + yourFileNameHere)
Hmm, okay this actually didn't change anything. Nothing still projects. Also, just to be clear, this the correct line of code: "assets/brick_facade_01/brickbrick_facade_01.jpg"