Designing a City Block Generator (Part 1)
In my team’s senior film, we were faced with a number of technical hurdles in order to meet the scale of our project. One of these hurdles was designing a building generator that would allow us to rapidly create a passable city environment for our setting. One of the most important components of this system was our block generator. This system would take in a curve representing the outline of a city block (or a set of curves, so that a flat map of the city could be drawn in curves), and would cut it into individual buildings, extrude, and add window, facade, and roof details. I will attempt to break down this system here.
To provide context as to what our needs were, we started this as a project of six people, later seven, with the task of creating an approximately two and a half minute short film over the course of three semesters. As is often the case with students, we perhaps over-scoped a bit, however this wasn’t apparent to us at the time. One of our environments was a city, somewhere in the late Renaissance period. Concepts were drawn, color scripts were done, and maps were made in order to plan out the path of the characters. Houdini was planned to be used from the beginning, however it was unknown how the system would work. After much though, I figured that perhaps the easiest way to generate the city outlined in the map would be to draw the map in Houdini using curves and have the buildings generate from there. This would allow for rapid edits the city layout, as changes could be made by simply dragging the corners of the drawn city blocks around. Basically all we needed to do was draw all the different curves out, and run them through a for-each loop within which the building generator asset was nested.

Once the blocks entered the asset, they were carved, resampled, and fused. The resampling length would correspond approximately to the width of each building. These would be tweaked later by setting non-corner points’ normals to their tangents, and running a mountain node against them. Before that, however, I had to figure out which points were corners, and among those, which were convex and which were concave, as concave cases would need to be handled differently.

After the various points are sorted through into different relevant groups, I could then run the previously mentioned mountain/building width randomization operation on only the side points. At this point I had a hollow curve whose sides were divided into segments ranging from approximately 8-20 meters. After studying how blocks in Prague were laid out, I figured one of the simplest ways to approximate that style would be to generate the corner buildings first, then connect their inner four corners together such that an inner courtyard was drawn out , then slicing the areas between each of the corner buildings into individual buildings. Corner buildings in Prague tend to have their inner sides be perpendicular to their outer sides, so I projected out a line perpendicular from one of each corner’s neighbors, and projected an intersect function perpendicular from the other neighboring point.
When I generated the corner buildings, I made a group of just the inner corner points. From those points I drew the outline of the inner courtyard, using a simple set of addprim functions connecting each corner via polyline. From there, I used an intersect function from each of the points on the outer walls that were not associated with the corner buildings, projected perpendicularly from the points to the courtyard line. After deleting the courtyard polylines, I created primitives for each building. At this point, some of the winding is wrong, so I fix that with some reverse nodes, harden the normals, and then I’m ready to start adding randomized attributes to affect different parameters of the window generation, roof generation, building height, and coloration in the Redshift shader.
I use these generated attributes to extrude different buildings to different heights. From there, the roofs and other details can be generated. Most of the rest that happens in this system takes place in a large for-each loop as I generate the details on a building to building level. I won’t go into the details of this process in this post, as it is running a bit long, and there are many different tutorials on how to stick details onto flat faces. I will likely come back and make a second post about creating the details.
I also want to shout out my teammate Sam Corbridge (https://www.artstation.com/samcorbridge), who helped set up the systems for detail generation, as well as helped produce some of the different detail variations.
