Fractal Cities

Fractal Cities is a small project looking at techniques to show the evolution of cityscapes. What started off as an abstract experimentation in voxelising cities turned into a bit more of a deep dive into geometric problem solving. In this blog I look at some of the techniques used to visualise building growth over time, all analysis and data preparation was completed in a GIS (Geographic Information Systems) and 3d workflow & animation techniques were done through SideFX Houdini. 

New York City - Voroni Fracture: The basis for a lot of discussion in this blog as the dataset I utilised proved to be incredibly difficult to work with. This is also the only visualisation that utilises real data for 'construction year' so the order of growth in this animation is 'very close' to being accurate (more on that later).

Hannover - Tetrominoes: A fun little concept and evolution of a voxel idea for having buildings construct using geometry similar to tetrominoes. Building growth is randomised here whilst I test out the idea. I like the voxel vibe for streetscape elements like trees and lamps too. Fun!

Tokyo City - Voroni Fractures: A dreamlike cityscape aesthetic showing how voronoi fracture can show building growth for cities like Tokyo. Growth is randomised here for testing purposes.

Tokyo City - Voronoi Fractures:  A darker cityscape aesthetic showing how voronoi fracture can show building growth for cities like Tokyo. Growth is randomised here for testing purposes. The buildings ended up looking like Magnum ice creams!

The beginning of my experimentation for voxelised growth for the City of San Francisco. Growth is randomised and the building height greatly exaggerated for dramatic effect.  

The beginning of my experimentation for voxelised growth for the City of San Francisco. Growth is randomised and the building height greatly exaggerated for dramatic effect.  

I‘ve always been interested in visualising building growth, a few years ago I put together a little tutorial on how I do it in Houdini but this year I wanted to look in a little more detail at how to show that growth a bit more organically. I’ve been familiar with 'Voronoi fracture' tools for a while and have experimented with fracturing terrain-based meshes in the past.

I‘ve always been interested in visualising building growth, a few years ago I put together a little tutorial on how I do it in Houdini but this year I wanted to look in a little more detail at how to show that growth a bit more organically. I’ve been familiar with 'Voronoi fracture' tools for a while and have experimented with fracturing terrain-based meshes in the past.

A very early concept animation for building growth I completed for the #30daymapchallenge a few years ago. 

A couple of years I produced my City Dome project which utilised some hyper-detailed city models for New York City and Tokyo. My previous building animations (like the one above) were just extruded polygons which look a little simplistic so I wanted to use these detailed models as a base for some city animations.

There are a few hurdles to cross at this point...

Interoperability

The detailed models I used previously were derived from CityGML data, a format which I still don’t fully understand, I think it’s geared more towards BIM which means it’s interoperability into other 3d packages (Houdini,Blender,C4d etc) is limited. The CityGML data is quite interesting though, a 3d format which retains attributes, something which I would love to utilise more. Up to this point the only 3d format I have used to transfer attributes,(e.g particle sims from Houdini into Cinema4D, or Blender) are alembic (.abc) files. In fact, one of the hardest parts of animating geo-data is finding a format to retain all the attributes you work with and being able to transfer this across different software. 

Most of my analysis work is done in GIS, I then have a really long-winded workflow of exploding a geometry and assigning attributes to the vertices, exporting this to a tabular form and then reconstructing in Houdini. Far too long-winded and time-consuming but I don’t know a better way of doing it at the moment. CityGML looks interesting in this regard but ingesting it into 3d workflow software, like Houdini, is a no-go at the moment. So for the time being handy FME comes into play to convert these models into .obj or .fbx files, something which I can bring into Houdini easily. 

Multiple data sources

For the Tokyo example, I randomly generated construction years, it was a concept visualisation to see how something like this would look with real data. The next hurdle was how to assign building age to a geometry file. This was hard and the workflow is still not 100% fool proof. 

Fist of all I needed a footprint from my GML conversion, this was a pretty straightforward task of grouping all Normals with a -1 direction in the Z. Isolating these gave me a nice footprint for the building geometry.

Now to get that into a GIS, it’s fairly simple to export attributes from Houdini so I exported an ‘id’ along with the coordinates of the base. 

Importing into QGIS I could then run a ‘point to path’ and ‘path to polygon’ function to recreate the footprint. I’d pay good money for a shapefile importer/exporter in Houdini at this point!

The next task was to import some actual building footprint data, complete with the construction year I found from the NYC Open Data hub. Hopefully, these two datasets would roughly line up. 

Running an intersect analysis on the points to their corresponding footprint data was easy enough and I’d say I got around a 90% match rate. Obviously, this isn’t perfect but without sense checking each parcel individually I was happy enough with the data.

So now I had a dataset with an id (from my gml data) and a linked construction year, perfect, time to import back into Houdini and run some attribute transfers to join the data back to my original model.

Screenshot of the footprint and building age intersect  | viewport representation of the link back to the 3d model

Islands

The Tokyo model was perfect for analysing and fracturing, each building, its towers, facades and all those little details were merged into one nice mesh, or an island group as Houdini likes to refer to them. The NYC model was not, take one building below for example, each part of that building was a separate mesh. So how do I join the age attribute onto these islands? They have a different id than the base and are essentially unconnected.

This was a major stumbling block for me and I gave up numerous times trying to think of a way around it.

Then I remembered my previous intersect analysis and had a great idea. Generally, the base footprint of a tower encompasses the smaller parts of a larger model. Unless buildings grow outwards towards the top, which isn't unheard of, then I could surmise that the extruding the footprint of my building along the z-axis would eventually include all its remaining parts.

So I looped through each island or part of the entire model extracted it's centroid. Once I had this I removed the height association so I had the points clamped to the floor. 

All I had to do was export this dataset into GIS and run the same intersect analysis on these points. For each model part which has an id, let’s call it island_id, I then had a corresponding larger footprint id base_id. Joining this base_id onto my model data meant that I could then get a positive lookup for the building age data. Phew. 

Voronoi Fractures

Splitting complex geometry is hard, the Tokyo model fractured easily with no issues but this NYC model was really hard to split nicely. So let’s have a look at what this fracturing node is and why I wanted to use it. 

Previously I’d always animated buildings growing as just that, growing in height from the ground up. For this, I wanted to simulate more of a construction-type animation and have chunks of rubble build up into these lovely structures. This is Houdini’s bread and butter really, creating simulation models, cracking geometry, adding physics to it etc. However, this model was just giving me lots of issues. I found that when I split the geometry the outside edges were nice but the inner polygons had lots of artefacts on them. When rendered they stuck outside of the model which was really distracting as you can see from the green geometry below. 

So just to review the initial method for fracturing which is interesting in itself.

  • I first looped through all my base_id’s, this gave me buildings with the previous islands included. 

  • For each building, I converted it into a fog vbd and scattered ~20 points within the model.

  • These points would then serve as my points of fracture in the building model. Ideally, these points should have been scattered proportional to the size of the building but I’ll leave that to another day.

  • Feeding these points and the baseline geometry into the 'Voronoi Fracture' node split the model into 20 chunks. I can add groups to the outside and inside edges which is useful for later too.

I had the models split but the inside groups were a mess, the culprit being the initial geometry. I tried a lot of different methods here;

  • Poly doctor - to fix any irregular polygons

  • Divide/Subdivide sops - trying to increase the complexity of the buildings so the Voronoi node had more reference points

  • Remesh tools - to try and triangulate the buildings

But they all had the same issue with the inner meshes. I did solve this initially by converting the initial building geometry to a VDB but the polycount for the entire model was too high, even with running some geometry reductions.

In the end, I settled with isolating the inner groups and re-meshing/cleaning the polygons, this, mostly, fixed the errors but if you start looking closely at the model you can still see minor artefacts.

Animating voronoi chunks.

After those hurdles, I was in the clear, so I thought, I could focus on animating these voronoi chunks in accordance with the date the building was constructed. There are a few strands to this animation that I wanted explore: 

  • the building animate in construction year order 

  • the fractures animate from the ground up 

  • there is some random variation to the vertical animation.

This wasn’t too tricky actually, a lot of 'for loops' later and for each building, I have the ‘construction year’, ‘order of fracture animation’ and ‘random offset.’ Simply adding these together with a little bit of math to standardise some metrics gave me a nice animation of building growth.

Packing Primitives


Then I gave in for a while again! The animation formula should have resulted in a scaling factor for the ‘chunks’, however passing this factor into a ‘primative sop’ (a node where each primitive is transformed independently of the whole) resulted in each sub-polygon of that chunk being scaled itself, which in hindsight was obvious. It didn’t look right, the buildings just kind of melted upwards. It took me far to long to understand that I needed to ‘pack’ each voronoi fracture. Doing this meant that the primitive sop transformed the whole fracture and not just the individual faces - win!

Tetrominoes

The last little concept I want to talk about briefly are 'tetrominoes', a fun little tilt on a tetris style animation by packing geometry with tetris-type blocks (tetrominoes). This came about from a bit of research into how to create more regular voronoi chunks i.e. with 90 degree angles. I was trying to find ways of splitting geometry up into nice building blocks but wasn't having a lot of success. After stumbling down a rabbit hole for tetris geometry I found a link where someone had done something similar: https://www.reddit.com/r/Houdini/comments/obon4t/procedural_tetrislike_geometry/ 

The idea is brilliant really, you start by creating a regular grid of points within the building geometry. You then create a workflow that optimises the placement of a simplistic set of trails throughout the geometry limiting the size and direction change of the trail to the grid it is in. 

The resulting output looks similar to this...

Looping through each building to create this matrix took a while but from there it was simple enough to apply the previous growth techniques and create a nice animation of tetrominoes building up within the buildings. 

I also think this would be an amazing game idea, sort of like a 3d relaxing geometry based game where your aim is to build a city over time by completing Tetris-style challenges within buildings. The game would be isometrically tilted and you start with little glass greenhouses which you have to fill throughout the course of a level, like this example of the Mitte region in Hannover. Now to learn Unity/Unreal?!

Was it worth it?

As with most of my side projects the main aim is to learn concepts and techniques to apply to interesting jobs. I love the problem-solving nature of spatial geometry and I learnt a lot from this project even if it did test my patience and I came close to quitting a few times! I think the inherent problem with this kind of animation is "scale". Cities are made up of thousands of complex geometric designs; translating these to a format where you can crack, fracture and explode isn't easy. Even after finding some nice workflows I'd say a good 15% of the geometry had issues - luckily select camera angles and animation techniques can hide these but it is hard to get a perfect result. 

I'd like to keep iterating on some of these concepts by adding more contextual data and create busier scenes - perhaps animating traffic or simulating people flow but for now, I am pleased with the result of this mini-project.

Added thoughts...

I feel like there are a few areas of 3d design that could be hugely improved up when it comes to animating spatial data but the main one, for me, is:

Better interoperability. 

Shapefiles, OBJ, FBX, CityGML, Alembic, Collada, all different formats suitable for different software but essentially just a file store for vertices, edges and primitives along with attributes (for some). I would love one universal format that let’s you convert between many software without the use of FME. Deconstructing and reconstructing geometry just to pass it into another software feels archaic now. 

Maybe it’s just I don’t know enough about formats like CityGML, for now though if someone could make a tool that exports from a QGIS polygon, point or line to a nice 3d format with stored attributes that would be great!


I hope this write-up has been of use to someone, my plan is to do more of these this year so watch this space!

Screenshot of the footprint and building age intersect  | viewport representation of the link back to the 3d model

Example of the island classification in one building | wireframe representation of how the footprint encompasses smaller islands

Fracture based on initial GML-OBJ geometry | fracture based on converting to VDB and back to polygon (huge increase in polys)

Unpacked primitives, notice the disconnect with faces, and a lot more weird artefacts!

Packed primitives all scaling around their locales.

Close up of some very simplistic street level lighting and trees.

Quick concept for Tetris cities with greenhouse empty buildings ready for filling!

Previous
Previous

MTB DataViz & Analytics

Next
Next

Make sense of it all: Mapping Movement