Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add STL instructions #35

Merged
merged 4 commits into from
Apr 30, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add STL instructions
KL484 committed Apr 29, 2020
commit d3bdba28b0b9593e6d6e1d3a778844755352a1f5
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -46,7 +46,9 @@
![Map Generator Screen Shot](docs/images/screenshot.png)
<!-- TODO YT video -->

This tool procedurally generates images of city maps. The process can be automated, or controlled at each stage give you finer control over the output. Generated cities can be downloaded as a `.png` or an `.svg`. There are a few choices for drawing style, ranging from colour themes similar to Google or Apple maps, to a hand-drawn sketch.
This tool procedurally generates images of city maps. The process can be automated, or controlled at each stage give you finer control over the output.
3D models of generated cities can be downloaded as a `.stl`. The download is a `zip` containing multiple `.stl` files for different components of the map.
Images of generated cities can be downloaded as a `.png` or an `.svg`. There are a few choices for drawing style, ranging from colour themes similar to Google or Apple maps, to a hand-drawn sketch.


### Built With
3 changes: 2 additions & 1 deletion docs/_coverpage.md
Original file line number Diff line number Diff line change
@@ -5,7 +5,8 @@
> Create procedural American-style cities

- Run in browser
- Multiple themes
- PNG, SVG download
- STL download

[Launch](https://probabletrain.itch.io/city-generator)
[GitHub](https://github.com/probabletrain/mapgenerator)
1 change: 1 addition & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
* [Home](/)
* [Usage Guide](usageguide.md)
* [Implementation Details](algorithmoverview.md)
* [3D Model](stl.md)
* [Heightmap](heightmap.md)
- **Links**
- [![Generator](https://icongr.am/feather/map.svg?size=16&color=808080)Generator](https://probabletrain.itch.io/city-generator)
Binary file added docs/images/STL/0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/11.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/12.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/13.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/14.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/15.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/17.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/18.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/19.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/20.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/21.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/22.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/23.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/24.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/25.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/26.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/27.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/28.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/29.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/30.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/STL/31.png
Binary file added docs/images/STL/32.png
Binary file added docs/images/STL/4.png
Binary file added docs/images/STL/5.png
Binary file added docs/images/STL/6.png
Binary file added docs/images/STL/7.png
Binary file added docs/images/STL/8.png
Binary file added docs/images/STL/9.png
Binary file added docs/images/STL/map(79).png
Binary file added docs/images/STL/model_finished.png
Binary file added docs/images/STL/model_preview.png
180 changes: 180 additions & 0 deletions docs/stl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# Creating a 3D Model

The tool allows you to download a `.zip` containing `.stl` files. Unfortunately, properly combining these in the browser currently seems infeasible so you'll have to use your own 3D modeling software to combine them yourself.
This does, however, give you more control over the final 3D model.

| STL Files |
| :----------: |
| ![STL_files](images/stl/model_preview.png) |
| From top to bottom: buildings, blocks, roads, river, sea, domain |

| Finished Render |
| :----------: |
| ![Finished_render](images/stl/model_finished.png) |

| Map |
| :----------: |
| ![Map](images/stl/map(79).png) |


To download the STL files, click `downloadSTL` from the `Options` folder.

For questions, problems, or improvements, contact me on Twitter [@probabletrain](https://twitter.com/probabletrain), email: probabletrain@gmail.com, or raise an issue on Github.

## Quick Blender Overview

For this guide I'm using Blender, which is excellent and free 3D modeling software.
If you're already handy with Blender this section might be all you need. Otherwise, see the next section for screenshots and more detail.

**Version**: Constructing the model requires boolean operations on objects with co-planar surfaces. The only way I got this to properly work in Blender was using version **2.79b** which still has the `Carve` solver for the boolean modifier. I couldn't get it to work on 2.8+. According to the Blender forums, proper boolean operations with coplanar surfaces is in development, so this may change.

- Import `sea` and `domain` and extrude them both in the z axis. Subtract `sea` from `domain` using boolean difference. Make sure to use `Carve` as the solver.
- Import `coastline` and extrude in the z axis. Union with `domain`.
- Import `river` and extrude in z axis. Subtract from `domain` with boolean difference.
- If you don't care about accurate roads, import `blocks` and `buildings` and place them on top of `domain`.
- If you want proper road geometry, import `roads`. Extract in z, select all, press `p -> By loose parts`. This splits each road into its own object.
- Enable `Bool Tools` addon
- Select `domain` and all of the separate road objects, with `domain` as the active object.
- Use `BoolTools -> difference` to subtract roads from `domain`.
- If the resulting mesh is fine, move on. Otherwise, select one of the top faces, press `shift+G -> normal` or `shift+G -> coplanar` to select all the top faces. Move these to a separate object with `p -> selection`. Delete the old object, extrude the new object.
- Import roads again, extrude in z, use it to create the roads by filling the gaps in `domain`. Control the road depth with the z location of `roads`.
- Import `domain` again, use it to create the sea and river. Control the depth with its z value.


## Detailed Blender Overview

Note that this isn't intended to be a first-time Blender tutorial, and may assume basic Blender knowledge.

### Create Land

Import `domain.stl`, which represents the area of the city including land and sea. Import `sea.stl`. Don't move any of these in the `x` or `y` axes after import to make sure that they stay in the same place relative to each other.
Extrude both in the `z` axis, as shown below.

We're going to be using the `Boolean` modifier a lot here, which adds and subtracts meshes from each other. Hide the sea object (`h`) and in object mode, select `domain`. Go to the 'Modifiers' tab and add a boolean modifier.
In this order select `Difference`, `Carve`, then set the object to `Sea`.

| Extruded Sea and Domain | Domain-Sea Boolean Settings |
| :----------: | :----------: |
| ![Extruded Sea and Domain](images/stl/0.png) | ![Domain-Sea Boolean Settings](images/stl/1.png) |



Click `Apply`. You should see that the sea has been subtracted from the domain. You can now delete the `sea` object.

| Land |
| :----------: |
| ![Land](images/stl/2.png) |



Import `coastline`. The JS libraries used to build the mesh may not always triangulate in the best way. An optional step here is to select all of the `coastline` in edit mode, and press `x -> Dissolve Faces`.
Extrude it downwards along the z axis. If some of the faces look strangely dark, in edit mode, select all with `A` and press `Ctrl+n` to correct normals.

Hide the coastline (`h`), and select the `domain` in object mode. Add another `Boolean` modifier. Use the same settings as last time except choose `Union` and set the target object as `coastline`. This will join the coastline to the land.
Press `Apply`. You can now delete the `coastline` object.

| Combine faces into one | Extrude coastline |
| :----------: | :----------: |
| ![Combine faces into one](images/stl/3.png) | ![Extrude coastline](images/stl/4.png) |


Use similar steps to subtract `river.stl` from the `domain`. Make sure to 'Apply' the modifiers. You can delete the river object now.

| Import and extrude river | River boolean settings | Subtracted river |
| :----------: | :----------: | :----------: |
| ![Import and extrude river](images/stl/5.png) | ![River boolean settings](images/stl/6.png) | ![Subtracted river](images/stl/7.png) |



### Easy, less accurate roads

Properly creating the roads requires subtracting them all from this mesh. If you don't want or need accurate roads, you can just import and place `blocks.stl` and `buildings.stl` to create the city.
Roads will be 'created' in the spaces between the `blocks`. Note that this method does not create the paths through parks.
Skip ahead to the 'Add Sea' section.

| Import and place blocks | Import and place buildings | No paths through park |
| :----------: | :----------: | :----------: |
| ![Import and place blocks](images/stl/8.png) | ![Import and place buildings](images/stl/9.png) | ![No paths through park](images/stl/10.png) |



### Harder, more accurate roads

The issue with the roads is that each one is its own separate geometry - there are no vertices at intersections.
The boolean modifier does not like this because of all the coplanar faces, but we have ways of dealing with it.

Make sure `domain` is the only visible object in the scene (including any lights, cameras, etc).
Import `roads.stl` and optionally: Edit mode, select all, `x -> dissolve faces`. Extrude along the z axis.
Select all, press `p -> By loose parts`. This will separate each individual road into its own object.


| Import roads | Extrude | Separate |
| :----------: | :----------: | :----------: |
| ![Import roads](images/stl/11.png) | ![Extrude roads](images/stl/12.png) | ![Extrude roads](images/stl/13.png) |


We're going to apply the boolean difference modifier between the domain object and each road in turn, but doing this manually would be madness.
Go to `User Preferences -> Addons` and enable the `Bool Tools` addon. This already comes (disabled) with Blender.
Translate the roads in the `z` axis until they are intersected by `domain`.

Select everything (all roads + domain) making sure `domain` is the active object (highlighted in orange). You can do this by selecting `domain`, then pressing `a` twice to unselect, then select all.
Go to `Bool tools` in the tool bar on the left and click `Difference`.

| Translate in Z | Select all, Domain active object | Difference |
| :----------: | :----------: | :----------: |
| ![Translate in Z](images/stl/14.png) | ![Select all, Domain active object](images/stl/15.png) | ![Difference](images/stl/16.png) |


| Resulting Domain |
| :----------: |
| ![Resulting Domain](images/stl/17.png) |

This may have produced a clean mesh, but it doesn't always. Here's what to do if your mesh is missing faces like the one below.

- In edit mode, select any top face of the mesh
- Select all top faces using `Shift+G -> Normal` or `Shift+G -> Coplanar`
- Move these faces to a new object using `p -> selection` (you could also invert selection and delete)
- Delete the old object
- Extrude the new object in `z`

| Mesh missing faces | Select top face | Select all top faces |
| :----------: | :----------: | :----------: |
| ![Mesh missing faces](images/stl/18.png) | ![Select top face](images/stl/19.png) | ![Select all top faces](images/stl/20.png) |

| Select all top faces | To new object | Resulting object |
| :----------: | :----------: | :----------: |
| ![Select all top faces](images/stl/21.png) | ![To new object](images/stl/22.png) | ![Resulting object](images/stl/23.png) |


Import `roads.stl` again and extrude in `z`. Place inside `domain` to create the roads. Use the `z` value to control the depth of the roads.
Import `buildings.stl` and place them at the correct `z` value.

| Extrude roads | Control road depth | Add buildings |
| :----------: | :----------: | :----------: |
| ![Extrude roads](images/stl/24.png) | ![Control road depth](images/stl/25.png) | ![Add buildings](images/stl/26.png) |


### Add Sea

Import `domain.stl` again and control sea/river depth with its `z` value.
Add materials to the different objects. You can select the faces that make up the grass in the parks and assign them to a new object to give them their own material, or assign them their own material there.

| Add sea and river | Select grass | Add materials |
| :----------: | :----------: | :----------: |
| ![Add sea and river](images/stl/27.png) | ![Select Grass](images/stl/28.png) | ![Add materials](images/stl/29.png) |


## Extra Details

- Select all buildings, then `Select menu -> Random`. In the properties check `deselect` and give it a probability of around 50%. `Ctrl+L` to select all building geometry from those faces and `p -> selected` to assign these to a new object. Do this a few times and you'll have a few different objects, all with random buildings. You can add more variation to building height by controlling these individually. Scaling roof faces along z will affect height variance, translating roof faces will affect average height.
- Select all building rooves and inset, extrude downwards to give them some depth. Check 'Offset Relative' in the inset properties to make it even across all buildings
- Shallow depth-of-field gives a convincing miniature effect
- Watch [Ian Hubert's 'Lazy Tutorial' on making cities](https://www.youtube.com/watch?v=JjnyapZ_P-g)

Some of my renders:

![Render](images/stl/30.jpg)

![Render](images/stl/31.png)

![Render](images/stl/32.png)