A simple CAD/CAM made iteratively during the Geometric Modeling 1 labs at WUT.
One of the project requirements was to not use any external math library
dependencies, i.e., to design and use an own math library (cadm in this
project; see ./src/cad_math. This includes custom vector and
matrix types, quaternions and more.
The central concept of the system is an Entity. An Entity is a bag of type-unique components. The idea was to allow reuse of components and more flexibility. That flexibility is not exploited yet, though — component factories currently create entities with mostly a single component. This can be reworked in the future to allow sharing points between patches and curves of different types, i.e., one bag-of-points component and multiple curve-type components in a single entity.
The following entity types can be created:
- Torus
- Bezier C0 curve — C0-joint cubic Bezier curves
- Bezier C2 curve — C2-joint cubic Bezier curves
- Interpolating C2 curve — C2 interpolating Bezier curve
- Bezier C0 patch — a surface made of C0-joint cubic (4x4) Bezier patches
- Bezier C2 patch — a surface made of C2-joint cubic (4x4) Bezier patches
- Gregory patch — finds holes with cubic edges of Bezier C0 patches and fills them with Gregory nets. The UI only allows filling holes with 3 edges, although the underlying implementation supports holes of any size of at least 3.
- Intersections — intersects two (or one) surfaces and creates an intersection component that holds the points along the intersection and whether it is closed. The number of points and the precision of the intersection can be adjusted by the user upon creation. With no user-supplied initial seed point, the nonlinear conjugate gradient method is first run from a grid of starting points and possibly finds many intersections; the point(s) found become the initial guesses of a Newton–Raphson tracing algorithm. If no user-supplied seed points were used (i.e., many intersections were possibly found), a further deduplication step is applied. The boundaries of the intersection can be visualized in the (u,v) parameter space of both surfaces, and the intersected surfaces can be trimmed along the curve (a per-patch grid mask applied by the fragment shader at render time). The intersection curve can also be transformed into an interpolation curve. For further details, refer to the source code.
The command design pattern is used for the most important user actions. This makes actions easy to undo and redo, which matters a lot in software design (be forgiving).
Scenes can be saved and loaded in a custom JSON format (see the JSON schema at
./src/cad/format/schema.json. Scenes are
validated before loading, preventing corruption. On failure, the feedback is a
list of valijson validation issues.
The scene can be rendered in stereo, with automatically adjusted or user-set convergence and eye separation distances.
Part of the course is creating a model — with a single theme across the year — which will later be milled by a milling machine with 3 degrees of freedom (the model therefore needs to be relief-like). The 2025/26 theme was boats. The model I created will be available as a scene JSON at a later time (after the course is finished). The models screenshot are available below (no points rendered (no such feature available yet; modify the code by hand for the result); trimming applied)
The project uses CMake. You can use any CMake-compatible build system or IDE. The libraries used are:
- Qt6 — windowing and widgets
- OpenGL — graphics API
- TBB —
std::executiondependency (you might need to change this to compile on your system) - valijson — JSON schema validation
- Catch2 — tests
oneTBB, valijson, and Catch2 are supplied via CMake's FetchContent. Qt needs to be installed on your system, with paths set in CMake options if needed, e.g.
-DCMAKE_PREFIX_PATH=C:\Qt\6.10.2\msvc2022_64
to add Qt to the CMake search path on Windows.
The project was tested to compile and run with CLion on Ubuntu 22.04 LTS and Windows 11 25H2.
Configure a Release build with Qt matching your compiler, then build the bundle
target in CLion or from the command line:
# Linux: requires GCC and Qt 6.5 or newer; set CMAKE_PREFIX_PATH if needed
cmake -S . -B cmake-build-release-gcc -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc
cmake --build cmake-build-release-gcc --target bundle --config Release# Windows MinGW: put MinGW gcc/g++ and Ninja on PATH, with the MinGW version of Qt
cmake -S . -B cmake-build-release-mingw -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_PREFIX_PATH=C:/Qt/6.10.2/mingw_64
cmake --build cmake-build-release-mingw --target bundle --config Release# Windows: run from an MSVC developer shell, with the MSVC version of Qt
cmake -S . -B cmake-build-release-msvc -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=cl -DCMAKE_C_COMPILER=cl -DCMAKE_PREFIX_PATH=C:/Qt/6.10.2/msvc2022_64
cmake --build cmake-build-release-msvc --target bundle --config ReleaseArchives are created under <build-directory>/bundle/:
| Toolchain | Archive | Run after extracting |
|---|---|---|
| Windows MSVC | cad-windows-msvc-Release.zip |
cad.exe |
| Windows MinGW | cad-windows-mingw-Release.zip |
cad.exe |
| Linux GCC | cad-linux-gcc-Release.tar.gz |
./cad.sh |
The target builds the application and bundles Qt plugins, runtime dependencies,
TBB, shaders, the scene schema, and available dependency license texts.
Extract the entire archive and keep its subfolders together.
Windows bundles use windeployqt; Linux bundles use
Qt's CMake deployment API.
Windows requires Windows 10/11 and a matching architecture. Linux requires a compatible desktop system with glibc at least as new as the build host; build on the oldest distribution you intend to support. System libraries and graphics drivers are not fully bundled. Both platforms require OpenGL 4.5 support.
The repository also contains a standalone ellipse project (first lab). See
./src/ellipse/README.md for details.









