Transcript
00:03Welcome to Tutorial 6: Basic Shape Grammar.
00:07In this video tutorial, we are going to recreate this building here, in CGA code...
00:13...but you can, of course, also download it from the Resource Center...
00:18...Tutorial 06_Basic_Shape_Grammar, download the project...
00:21...link it into CityEngine and look at the last scene file in here.
00:27But before we now start and actually code the building...
00:30...let's look at a few tricks, which I'm usually using, for the most efficient coding.
00:36So I'm going to select this building here, open the Model Hierarchy...
00:43...this window here, with first, a dark-grey canvas.
00:48Then I'm going to select or click this button here, which is the Inspect Model Mode.
00:54So I'm entering the Inspect Model Mode.
00:56And now here in the Model Hierarchy, you see that...
01:00...a few nodes have been generated or visualized, so if I'm zooming in we see...
01:06...that we have a Lot, a Building Frontfacade, Sidefacade, and so on and so on.
01:12So this is actually the way CityEngine created this 3D model in the Viewport...
01:20...according to the CGA code, which was applied to the footprint with Rule File.
01:28Say, if I'm opening the Rule File here, by clicking on the Rule File...
01:33...clicking on the Rule File link, I can visualize the code in here.
01:39We have seen before that there is a node-based or a visual representation of the rules...
01:45...but there is also a text-based, and this is the one I'm going to use for the code creation.
01:51Now, I had mentioned that there's a few tricks.
01:55So let's actually minimize the code again and even these out.
02:01Now, you have seen that something popped up in the Viewport when I clicked the Lot here.
02:08And what you see here is the visual representation of the so-called scope.
02:14The scope is like a bounding box for the shape...
02:18...which you are currently working on in the code.
02:21So the scope can be either two-dimensional or it can also be three-dimensional...
02:28...actually, it is always three-dimensional.
02:34But the scope is one of the most important concepts which you have to use...
02:39...if you want to learn how to code CGA.
02:43Now here you see the little GUI button, which activates, and deactivates...
02:49...the Shape Scope visualization.
02:54Then there's the Shape Pivot, which is currently the same as back here...
03:00...so nothing changes there.
03:02And then there is also -- that's a little bit advanced...
03:06...the Trim Planes visualization in here.
03:10So let me quickly hide...
03:16...let's do it like this -- hide all the rest and quickly create a new Rule File.
03:22I'm not going to save this one, but I'm going to create a new Rule File from scratch.
03:27So this is the simpleBuildingAgain.cga.
03:34And I'm going to use this on one of the lots right next to this building.
03:39So I'm going to use this footprint here and I'm going to assign...
03:45...the empty Rule File to this building.
03:48I'm getting a little error, but that's okay, so let us start with the Start Rule...
03:58...@StartRule, and I'm calling the StartRule "Lot."
04:03This is usually the very default, so I'm going to just write X here.
04:10This means that I'm writing all the geometry from the incoming shape into a new shape.
04:16And I'm naming the shape just "X."
04:19The point usually means I want to stop the execution at the end and don't continue.
04:25We're going to use this a lot in the upcoming minutes, so I'm going to save...
04:31...actually, let me add here a color, operator and say color "R-G-B," so that must be red.
04:41And select the building here, the building footprint, and press Generate.
04:46Now I can do the same thing with the Model Hierarchy in here.
04:51So let me select the model here, go into the Inspect Model Mode, and here you see, we...
04:58...have Lot, and then we have X as the final geometry which is visualized in the Viewport.
05:09Now, obviously, if I went in and would rename this to ABC...
05:16...save the Rule File, regenerate the model, this here would adapt.
05:23Okay, so let's go ahead and create our first attribute here....
05:28...an attribute called, "Building_Height" with a default value of, let's say, 20 meters.
05:40Now, how can I actually create a building which is 20 meters?
05:44For this, we have a specific operation which is called, "extrude."
05:49So I'm going to extrude, in the vertical direction; actually, it's world.y, so it is...
05:58...extruding exactly vertically up and I'm going to use this this attribute as the value.
06:06Save, and I'm going to name this, "Mass," or let's call it, "BuildingMass."
06:15And save the Rule File again, and regenerate the model.
06:20Now you see that we have Lot, and then we have Building.
06:27Okay, so that makes all sense, so let's continue.
06:34The next thing, actually, let me continue and create a new rule.
06:38So you see that any number of rules can be generated, and I can just go on and...
06:46...pass on rules, or call different rules, from any point in my code.
06:53So in here, I'm using another operation, which is the component split.
06:58And this actually splits off different faces based on some inputs.
07:03So I'm going to choose all the side polygons...
07:08...of this Mass and I'm going to name them "Facade."
07:13And then, I'm making this vertical pipe sign which says to me, "I want to continue."
07:22And then I'm going to choose top, and the top will obviously be a roof.
07:30So what we have done here is, from the geometry, which was created with selected...
07:36...all the side faces, all the side shapes, and define them as facades...
07:42...and all the top polygons, there is just one.
07:46There would be also a bottom one, but we are not calling this...
07:50...so this shape will get deleted afterwards.
07:53The top shape is Roof; now you see here I did not put a point here.
08:00And on the left-hand side, we get a little warning.
08:04So that means Undefined rule:Roof.
08:07Now that is nothing which matters, but so I can easily go and continue and...
08:15...generate the building again so nothing will happen.
08:20But it's just because these rules are not defined as rules themselves.
08:27So this is a rule definition and this is just missing.
08:30So I'm just going to continue with the roof here.
08:35And I'm going to go ahead and directly finalize the Roof.
08:39So, in the assets folder here, we have under roofs, we have a roof.tif.
08:47I can visualize this file right here and you will see that it is a picture.
08:55So this is a roof picture, and I want to use it and map this directly on top of the...
09:01...the building as a roof.
09:05It's a very simple roof, so I'm going to use it just that way.
09:11So now I can drag and drop this roof.tif into my rule...
09:18...and since it is recognized as a texture, it will automatically create...
09:26...the appropriate CGA code for me with the correct path for the file.
09:31So this is perfect.
09:33Let me go in and add something more because CityEngine does not yet know...
09:40...how I want to project this building onto the geometry.
09:44So we have to define this, and for this, there is also another CGA operation.
09:52And this is called "setupProjection."
09:55Now, sometimes it may happen that you don't know all the precise...
10:04...name of the operation, so you can also go ahead and just create or write...
10:12...a few of the characters and then hit CTRL+SPACE...
10:16...which triggers the command completion.
10:19Now this is also something which can also, obviously, save you some time.
10:24So I'm going to double-click it, then I'm going to define it uvset, which is the first uvset...
10:31...for the color space, then I'm going to say, in this case, I'm not going into all of the details.
10:40So otherwise, you wouldn't have to learn anything more.
10:43So I'm going to use scope.sy, I'm going to choose '1 and '1.
10:57Now, there is a little error, that's not .sy, that's .xy, and also now the warning is gone, yea.
11:15Okay, let me undo and create some more space here, okay, now, projectUV(0)...
11:29...okay, there you go.
11:39I went out of the Inspect Model Mode, and here you see that the picture has...
11:47...now been mapped on top of my building.
11:50So if I'm editing the building footprint, I can just go in, select the underlying road...
11:58...network and the whole building will be restructured or regenerated immediately...
12:05...adapting all the textures and all the side facade polygons.
12:12Now, I'm not going to dive into too much of the technical details...
12:16...because this is just a simple introduction here.
12:20But what I wanted to show you is again the setup projection in scope.xy.
12:27Now, if I'm again entering the Inspect Model Mode, and I'm selecting...
12:32...the roof shape here, you see that the scope again is visualized.
12:38Now scope.x, that is always red and scope.y, that is always green.
12:46So I am projecting this image in this plane, yea, in this plane...
12:53...and this is the scopes red and green plane.
12:57The dimensions I am actually using is in the direction...
13:01...in the horizontal direction, '1, which is exactly the same as scope.sx...
13:09...as a length, and it is also the same as scope.sy in the height.
13:17And then I'm actually applying or breaking down the UVaccord in the projection...
13:25...information into the polygon of the roof; and then I'm assigning the texture.
13:33So let's continue and work with the facade.
13:37So I'm not going to perfectly layout the code, so I'm just going to continue here.
13:44Now, often it may happen that you have a different floor height...
13:51...on the ground floor than on the upper floors.
13:56So I'm going to create another attribute, which is called, "Groundfloor_Height..."
14:06...which is, in my case, 5 meters, and then I'm creating another one...
14:13...Upperfloor_Height, and this is just 3 meters.
14:21So we can distinguish between these two geometries...
14:27...or between the heights visually, a little bit better.
14:31Now, the facade, what do I want to make with the facade actually?
14:36I want to split it into different floors, but the moment, at this...
14:42...as the geometry is, I want to make a little bit room on the side or split two shapes...
14:51...of the very edges of the wall, or of the facade, to just have some more space for...
15:06...between the edges of the...
15:17...so I'm going to split, so I want to go ahead and split two parts of the sides...
15:50...of the facade, just to make a little bit space between the edges of the actual facade.
15:57So I'm not going to define this as an attribute, and by the way, when I'm visualizing the rule...
16:04...in the Inspector, you see that all the attributes which I have defined...
16:08...are now available as attributes in the Inspector.
16:13So if I'm going to write the function, for example, like myValue = 10.
16:24Save the Rule File.
16:25Then you see that this value does not appear.
16:30But if I define it as an attribute...
16:33...attr, save the Rule File, then you see it appears in the Inspector as an attribute.
16:40So I'm not going to use an attribute in this case.
16:46I'm going to define WallSidePart_Width, which is, let's say, 1 meter wide.
17:01I'm going to use this in my next split, and I'm going to split this facade.
17:09So let me enter the Inspector -- oh! An error, let me fix this quickly -- there you go.
17:20Okay, let me...
17:22...enter the Inspect Model Mode again and again and select one of those side-faces here.
17:28Now you see again that we have a red line and a green line...
17:31...so that means this is scope sx and scope sy.
17:38So I'm going in and I'm writing split(x), because I want to split in that direction.
17:46And then I'm going to say the "Wall Width" part on the side...
17:56...which happens to be Wall part.
18:00Not to explain all the details here, than I'm writing ~ 1, which means...
18:13...Facade_Main, and then again, I'm going to create this part here.
18:21Save, regenerate, now you see what happened here.
18:26So, on the left side, Wall part was split off.
18:31Then, on the right-hand side, also a Wall part was split off.
18:37But in the middle, which is ~1 meter wide...
18:43...so this is a floating value, where CityEngine adapts the value, so I could also write...
18:51...~10, but it's just a short value since the left-hand side...
18:57...and the right-hand side is already defined.
19:00I can just write ~1 and this is defined as the Facade_Main part, which is in here...
19:08...and I'm not going to mess with the wall parts again; otherwise, then texturing them.
19:13So I'm going to copy-paste the Facade_Main here and I'm going to split vertically...
19:23...split in the green direction...
19:27...and here, the first thing which I want to do, is I want to first split off the ground floor.
19:32So Groundfloor_Height : Upper_Floors, I'm just going to name this shape that way.
19:42And then a second split -- no, sorry -- Groundfloor_Height : Floor, then...
19:56...~1 again gives Upper_Floors, and this is a new shape.
20:02Now let's visualize that by regenerating the building, and here you see that one shape...
20:10...has been created for the ground floor, and then ~1, which basically means the rest is...
20:18...defined in another shape, which is called "Upper_Floors."
20:22Now let's copy this whole thing here...
20:25...and paste it again and name this guy "Upper_Floors."
20:30And here, we split again vertically, but this time, into Upperfloor_Height...
20:36...and delete the rest.
20:39And then here is a new sign, a new little functionality, this is the *.
20:46So the star means do the stuff inside the brackets, the curly brackets...
20:53...as many times as possible.
20:56So I'm going to save again and regenerate.
20:59And now you see that multiple upper floors have been generated.
21:04You see that here a little bit better.
21:07Let me hide all the shapes.
21:10Okay, now the beauty of this whole process is obviously that if I'm changing...
21:17...the incoming building height to say, 40, it doesn't matter how many floors there are.
21:24CityEngine will always update the number, or the geometry, and thus also the number of...
21:32...the upper floors.
21:33And this is done by this little * sign here, so I'm going back to 20 meters.
21:41And regenerate, okay.
21:43Now we are at a Floor, and let's go in and...
21:50...split the floors, each of the floors, again, horizontally.
21:55Now we can go in and say, split(x), as many times as possible.
22:02And we are going to create another attribute, which is, or let's...
22:08...yea, let's create an attribute, an attribute which is the...
22:14...Tile_Width, which is, I'm going to define as, let's say, 5 meters.
22:22So I'm going to create big tiles in this facade.
22:27So let's use this Tile_Width and define a Tile.
22:35So here I'm going to, instead of, actually, let me quickly show you the difference here.
22:41So I'm generating the model, and here you see that we have 5 meter-wide tiles here.
22:52But there is one which isn't 5 meters wide, and this is because I did not define...
22:58...the ~ sign in here, so what the correlation is in this case...
23:04...specifically, actually let me split (x), here, oh, wrong position.
23:13I did not define the Tile and the ~ here, so what this does is the ~ together...
23:20...with the *, they will make a certain amount of full tiles, which all are the same width.
23:27So let me regenerate this -- actually, I messed up the code here -- yea, now it works again.
23:39So here, CityEngine again defines how many tiles there are.
23:44So let's continue with all of these tiles.
23:51Now split the tile again; let's say again, horizontally, with this structure here..
24:00...and define new values, let's say, Tile_Side_Width = 0.5...
24:21...Side_Width, and in between, that's the Tile_Main.
24:40Tile_Main again gets split vertically split(y) into...
24:50...let me redefine this as an attribute called "Window_BaseHeight," which is 0.9 meters...
25:14...attribute Window_Height = 1.4 meters.
25:27And now, split off that way, gives Wall, Window_Height : Window, and ~1 gives...
25:44...try to guess it: Wall.
25:49Let's save and regenerate.
25:52Now we see that on all of these tiles we have the base height, which is this high....
26:04...then the window height and the rest, which is wall.
26:08Now these geometries obviously change, or have changed, since there's a ground floor...
26:14...or between the ground floor and the upper floor.
26:18So let's go in and change one of these widths, which was the Tile_Side_Width...
26:23...which maybe does not make too much sense...
26:26...so 5 meters, that should be approximately 3.5 meters.
26:38Actually, hmmm, yea, that makes more sense.
26:46Okay, and in this case, I'm just going to continue with the Window Rule in here...
26:55...and I'm going to texture this again.
27:02So let me go grab the window texture, or one of the windows here...
27:16And now, I'm going to use a different function.
27:20I created a function which generates me one random or gets me one random image.
27:28So the texName, for example, = fileRandom in this path.
27:37So I'm going to copy this, delete this fileRandom, and put it in here.
27:48And now, the idea is that I'm replacing this number here with a *.
27:55So the *, in this context, means it's a wildcard search, and may bring back...
28:03...any of these images here.
28:06So it could be a random, or it is a random sample, between all of these windows here.
28:13So I'm going to have to set up the projection again.
28:17I'm going to copy some of this code here.
28:22Put it in, and I'm going to say "xy," that should be correct...
28:28...and I'm going to texture the shape with the texName.
28:36Regenerate the building, and now we see that each of those...
28:42...windows, again, has gotten a correct, or a new, individual texture.
28:50So now the facade itself looks a little bit...
28:55...uninteresting without the texture, so let's go in and also assign a texture to it.
29:04So let's find the facade first.
29:06So here is the place where we want to set up the projection.
29:11And here, I'm just going to search the image I'm want to use...
29:18...here is facades > textures and I am going to use just simply the brick wall.
29:27Drag and dropping this into the rule here, just quickly...
29:33...and also drag and dropping the dirtmap into the code here.
29:43So I'm going to do something with those two pictures.
29:49Let me comment out this code here.
29:53By the way, you can comment out code with either this #, or with just...
29:58...// the division sign here.
30:03Let me code this out.
30:06Okay, so I'm going to use not a full repetition of the texture...
30:16...along the whole facade, but I'm going to enter a different value.
30:21So we have seen that the image is repetitive, so I'm going to open it again...
30:29...just to visualize it.
30:30And this part is about, let's say, 50 centimeters high in reality...
30:36...and about 1 meter long, approximately.
30:40So I'm going to define this.
30:42This means ~1 and ~0.5.
30:49This here, CityEngine tries to adapt the number of repetitions of the texture.
30:56So I'm going to grab this texture and I'm deleting the rest out designing this...
31:02...and regenerate the building.
31:05Now we see that the texture has been...
31:10...assigned and repeated accordingly in the given dimension.
31:15Now, I've taken a second image here, which is the dirtmap, so I'm just quickly...
31:22...adding into other lines here, so I'm going to, actually, basically...
31:28...just paste what I had in my clipboard just before, which is these two lines here...
31:38...and I'm going to choose the UVset to UV(2).
31:43I'm changing the UVset to the so-called dirtmap UV layer.
31:50And I'm going to copy this here and then set, this is a little bit special, but...
32:00...material.dirtmap, and then the image itself.
32:09So what does this actually do?
32:11I am saving and regenerating the building.
32:15And now you see I have commented out...
32:18...the texture, so what we see only is what these three lines are doing.
32:23So again, I'm using the full dimension of the facade for the projection on the second...
32:29...UV layer, which is the dirtmap layer and then I'm assigning the dirtmap.
32:34And the dirtmap actually looks like this.
32:37It's quite a low-resolution image, but it is adding some dirt, as the name states...
32:44...onto the full facade -- here it is.
32:48The dimension is adapted so there is always a full repetition over the whole polygon.
32:55So let's go in and reactivate the texture.
33:01And save the rule again and regenerate the building as so.
33:10Now this is already quite beautiful, and we have a lot of different attributes now, too,...
33:16...to play with so I can go in, and for example, edit the Groundfloor_Height...
33:24...and you see how the number of upper floors is adapted...
33:30...or you can go in, and for example, change the Tile_Width and so on and so on.
33:40Now, in the written version of this tutorial which you find here in the scenes folder.
33:48There are more or different ways...
33:52...covered different elements of how you can write CGA code.
33:57So, for example, there is also a little topic about how you can...
34:01...embed different levels of detail.
34:04So I'm not going to cover all of these steps.
34:08Additionally, it's better than you just work through this PDF.
34:12A lot of the stuff will be the same as I have just shown you here...
34:16...but I don't want to spend too much time in this video.
34:23So I hope you liked this video, too, and let's continue with the next one.
Tutorial 6: Basic Shape Grammar
In this video, you learn the basics of CGA. The creation of the code for a simple building is covered step by step.
Please find the tutorial 6 project files here.
- Recorded: Sep 27th, 2012
- Runtime: 34:37
- Views: 681
- Published: Sep 28th, 2012
- Night Mode (Off)Automatically dim the web site while the video is playing. A few seconds after you start watching the video and stop moving your mouse, your screen will dim. You can auto save this option if you login.
- HTML5 Video (Off) Play videos using HTML5 Video instead of flash. A modern web browser is required to view videos using HTML5.
Right-click on these links to download and save this video.
- 480x270:MP4 (89.7 MB)
- 960x540:MP4 (198.3 MB)
If you don't have an Esri Global Login ID, please register here.