Creating a 3D model based on time spent programming.
Tags: wakatime, programming, showdev
Published: 2023-02-15 14:56:13

I have recently released version 1.1.0 of my newest project [WakaSkies on GitHub](https://github.com/MoonstoneStudios/WakaSkies). WakaSkies lets you generate a 3D model based on your time spent programming. You can save it as an STL to 3D print! This is a [WakaTime](https://wakatime.com/) version of [GitHub Skyline](https://skyline.github.com/).

I wanted to share how I accomplished this project.

## Building a 3D Model From Code
To render and export the 3D model, I would need to make a list of triangles all in a specific shape and place.

### My Approach
The bars on top of the model will change height depending on how long the user programs on a specific date. I called these bars a `RectangularPrism` in the code. Each prism has a list of its 6 points that make the shape. This is how the points are laid out behind the scenes:
```
E------H.
|`.    | `.
|  `F--+---G
|   |  |   |
A---+--D.  |
 `. |    `.|
   `B------C
```

When a new prism is created, point `A` is the base position. Then point `B` is positioned by just adding 1 to `A`'s Y position (3D printers use +Z as up). `C` is placed at `A` plus 1 on the Y and X axes and so on.

After all of the vertices of the rectangular prism are created, it gets triangulated. Triangulation is the process of creating triangles from the vertices of a shape. This is where I cheated. Because I knew that every shape will be a rectangular prism, I manually typed out the triangles!

Each triangle is then added to a `WakaModel`, the class that represents a 3D model.


> ![The generated model. It is floating in a pretty skybox.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hvjbel5acpnt4e326ikh.png)
> The model generated from the code! It is floating in \~space~.

### Adding a Base
As of now, the 3D model is looking pretty boring. Let's spice it up with a base! The base and all other 3D models in the final model were created in [Blender](https://www.blender.org/). I originally exported the models as an ASCII STL file. I later wrote a binary STL loader that was faster. I ended up using that one instead.

The triangles are loaded from the base's file and are added to the already generated WakaModel from before. The WakaTime logo, numbers, and the "hours" text are all loaded into the model the same way.

> ![The 3D model of the base. It is inside the Blender 3D viewport.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k29de95e3o0wp01qdn26.png)
> The base that will be added to the generated model.

## Rendering
The app uses [MonoGame](https://www.monogame.net/) to render and to create the desktop application. Because MonoGame uses a +Y up rendering system, I rotated the model 90 degrees to appear in the correct orientation.

## Exporting
Because STL is such a simple format, exporting the model is just spitting out all the vertex data into a file. I added support for binary STL and ASCII STL files.

And there we have it! Creating a 3D model from code!
> ![The final model. It has a base, statistics, and the generated rectangular prisms.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v2sc3y8lfywoiabbh1ve.png)
> The completed model!

I hope your enjoyed reading this post! WakaSkies is available on my GitHub and you can download the latest release here: [WakaSkies GitHub page](https://github.com/MoonstoneStudios/WakaSkies).