Building a 3D Geometry Modeling Tool for Awatif.co
Building a 3D geometry modeling tool sounds intimidating — but it doesn't have to be. It's one of those projects that sits right between challenging and deeply satisfying.
In this post, I'll walk you through how I built this feature for Awatif.co — the first open-source structural engineering software.
Why Build This Feature (and Why Now)?
For a long time, I was all-in on parametric modeling. It's efficient, fast, and saves engineers countless hours of repetitive work. But it also comes with a big trade-off: it limits your design space.
When everything is parameter-driven, you often lose the creative freedom to model things manually — which is sometimes exactly what you need, especially in conceptual or experimental stages.
So, we decided to take a hybrid approach:
Combine the flexibility of manual modeling with the speed of parametric tools.
This gives engineers the best of both worlds — the freedom to experiment without sacrificing efficiency.
If you're curious, the entire implementation lives in one file:
👉 https://github.com/madil4/awatif/blob/main/ui/src/viewer/polylines/getPolylines.ts
And you can even try it yourself here:
👉 https://awatif.co/examples/polylines/
Defining the Core Functionality
Adding, editing, and dragging points to create complex geometries.
Before writing any code, I listed out what users really need to do. The trick is to keep it minimal — fewer requirements usually mean cleaner, more maintainable code.
Here's what I wanted this tool to handle:
- Add multiple polylines
- Append and remove points
- Drag points around freely
And all of that without touching the keyboard — just using the mouse.
Why? Because simplicity leads to better UX, and in modeling tools, every small friction matters.
Designing the Data Model
Choosing between a tree (graph) structure vs. a simple list.
The data model is the backbone of any modeling system. It determines how flexible and modular your app can become — and how painful it'll be to refactor later.
I spent a while debating between two options:
- Graph-based (tree) structure — gives you more relationships, hierarchy, and branching info.
- List-based structure — simpler, more direct, easier to work with.
Eventually, I chose the list-based approach.
Sure, I lose adjacency and branching data, but in this application, that trade-off didn't really matter. The simplicity gained was worth it.
Keeping the Architecture Simple
Awatif is built around functional programming, not OOP. So instead of classes and complex hierarchies, this entire modeling tool is essentially one function that takes polyline data as input.
Whenever that data changes, the function reacts automatically — thanks to the signal-based reactivity system from VanJS.
This function does two main things:
- Render the polylines on screen.
- Handle mouse interactions (add, remove, edit, drag).
Now, here's where things get interesting.
The tool has four modes — Add, Edit, New, and Drag — but only three mouse events — Click, Move, and Right-click.
That means the same mouse event behaves differently depending on which mode you're in. For example, clicking in "Add" mode adds a new point, but clicking in "Edit" mode selects one.
That's what makes this feature tricky — not the code itself, but the state logic behind it.
Managing four modes with just three mouse events — simple, but state-heavy.
Wrapping Up
Building this tool was a great reminder that elegance comes from constraint. By focusing on simplicity — both in user experience and in architecture — you can create tools that feel smooth and intuitive, even when the underlying logic is complex.
I'll continue sharing updates as we publicly build Awatif. If you're into engineering, software, or the intersection of both, follow me on LinkedIn or subscribe to our newsletter at Awatif.co.
Thanks for reading — and happy modeling 👷♂️💻