MVB++ is a C++23 equivalent of the Python/CadQuery-based ../MVB library, using OpenCASCADE 7.9.3 directly to generate 3D geometry (cores, bobbins, turns, spacers, FR4 boards) and 2D drawings (sections, projections) from MAS JSON. Outputs match Python MVB references and are consumed by C++, Python (pybind11) and WebFrontend (WASM / Emscripten).
- Self-contained build — fetch and build OCCT 7.9.3 from source automatically.
- Direct MAS.hpp usage — generated
MASC++ types, no wrappers. - Meters internally — scale to mm only at STEP/STL export time.
- MKF integration —
OpenMagnetics::magnetic_autocomplete_safeenriches raw MAS JSONs. - Unified Named API — every shape returned as
NamedShape{shape, name}so names survive symmetry cuts, STEP export, and binding boundaries. - DrawConfig — single config struct shared by all bindings.
- Concentric cores (E, T, U, etc.): profile in XY, extruded along Z, rotated
-90°around X → column axis aligns with Y. - Toroidal cores: profile in XY, extruded along Z, origin at toroid center.
include/mvb/ — public headers (MagneticBuilder, BobbinBuilder, TurnBuilder,
SpacerBuilder, FR4Builder, SectionBuilder, Symmetry,
StepExporter, ProjectionDrawing, SectionDrawing, NamedShape, Utils)
src/ — library implementation
src/shapes/ — one builder per core shape family (Factory + Shape*)
tests/ — Catch2 tests (steps, assemblies, all shapes, gapping, symmetry,
battery, toroidal top view) + Python reference generator
tools/ — CLI utilities (step_generator, section, bobbin_generator)
bindings/python/ — pybind11 module + pytest suite
bindings/wasm/ — Emscripten module + JS tests
- Infrastructure — CMake fetches OCCT 7.9.3, MKF (+ submodules
cci_coords,CAS,EAS), MAS, nlohmann/json, Catch2, pybind11. Builds staticlibmvb++.a, sharedlibmvb++.so, Python wheel and WASM module. - Core shape builders —
ShapeE,ShapeT,ShapeEr,ShapeP,ShapeEtd,ShapeU,ShapeToroidal, plus families wired viashapes/Factory.cpp(drivesget_supported_families()inUtils.cpp). 882/882 non-excluded MAS shapes build a non-empty solid. - Bobbin —
BobbinBuilderhandles rectangular and round bobbins, hollow body + flanges + holes, matches PythonStandardBobbinvolumes/bboxes. - Turns —
TurnBuilderbuilds round and rectangular wire turns for concentric and toroidal cores.buildFromTurnAlonelets bindings render turns without a wire/bobbin lookup. - Symmetry — plane detection, cutting, high-level binding helpers (
filter_by_side,apply_symmetry, spec parsers). - Sections & projections —
SectionBuilder::cut2DFaces,parseSectionPlane,drawViewdispatcher,SectionDrawing,ProjectionDrawing. - Spacers and FR4 —
SpacerBuilderfor gap spacers,FR4Builderfor PCB boards. - STEP / STL export —
StepExporterwith mm scaling; STL tests pass. - Bindings
- Python (pybind11 + scikit-build-core), wheel installable, pytest suite green.
- WASM (Emscripten): exposes
buildMagneticSTEP,buildMagneticSTL, drawCore/drawTurns/drawSpacer/drawBoard,parseEnrichedfallback, tagged exception bridging, whole-archive cmrc for embedded data.
- MAS 1.0 migration — schema enum casing migrated;
magnetic_autocomplete_safelogs failures to stderr. - No-fallback policy — required MAS fields throw on missing data instead of using defaults.
| Tag | Result | Notes |
|---|---|---|
[step] |
pass | E/T core + assembly STEPs match references |
[stl] |
pass | |
[assembly] |
pass (4/4) | rect_one_turn, etd49_5t |
[shapes] |
pass (882 ran, 8 excluded, 0 failed) | Excluded: 4 ui + 3 pqi + 1 ut (intentional, mirrors MVB Python) |
[get_families] |
pass | |
[symmetry] |
pass (8/8, ~1:35 wall) | AABB-prefiltered analyze/cut + per-fixture test cache; was 4:32 baseline |
[battery] |
25/25 simple pass; overlap phase ~free (was the dominant cost) | PM uses 64-faceted cylinders in the test (vs default 16) to keep the bobbin/core polygon chord-error under the artefact tolerance |
[topview] |
pass (toroidal 2D) | |
[json] |
pass | |
[gapping][additive] |
pass (448 ran, 0 failed) | |
[gapping][subtractive] |
pass (448 ran, 0 failed) | Fixed: U/UR/C zero-length gap + UR cylindrical column tool |
[gapping][distributed] |
pass (448 ran, 0 failed) | Fixed alongside subtractive |
None. README + architecture diagram are in; Python/WASM API surfaces cross-checked against their test suites.
- MKF-always for bobbin defaults. When MAS input has no explicit bobbin,
MVB++ follows the dimensions produced by
magnetic_autocomplete(MKF), even when those differ from PythonStandardBobbindefaults. Rationale: MKF is the single source of truth for derived magnetic data; mirroring Python defaults would fork the geometry model and require keeping a second defaults table in sync forever. Callers that need Python-MVB parity should pre-fill the bobbin in their MAS JSON.
LD_LIBRARY_PATH=build/occt-install/librequired for the test binary- MKF
SHARED→STATICpatch is a fragile string replace inCMakeLists.txt - MKF submodules (
cci_coords,CAS,EAS) auto-init in CMake configure; manual fix path documented - MAS 1.0 enum casing changes —
python3 MAS/scripts/migrate-to-1.0.pyis the migration tool
| File / Dir | Purpose |
|---|---|
CMakeLists.txt |
Build, OCCT external project, MKF/MAS fetch + patches |
include/mvb/ + src/ |
Public headers and library implementation |
src/shapes/Factory.cpp |
Single source of truth for supported families |
src/MagneticBuilder.cpp |
Top-level assembly (core + bobbin + turns + spacers) |
src/Symmetry.cpp |
Symmetry plane detection + cutting + spec parser |
src/SectionBuilder.cpp + src/SectionDrawing.cpp + src/ProjectionDrawing.cpp |
2D drawing pipeline |
tests/test_all_shapes.cpp |
882-shape sanity battery |
tests/test_all_gapped.cpp |
Per-shape additive/subtractive/distributed gapping |
tests/test_symmetry.cpp |
Symmetry plane and cutting |
tests/test_mas_battery.cpp |
Wide MAS-fixture coverage |
tests/test_toroidal_topview.cpp |
Toroidal 2D top view |
tools/mvbpp_step_generator.cpp |
CLI single/batch STEP generator |
tools/mvbpp_section.cpp |
Section/projection CLI |
bindings/python/ |
pybind11 module + pytest suite |
bindings/wasm/ |
Emscripten module + (stale) JS tests |
AGENTS.md |
Build instructions, gotchas, conventions |
PLAN.md |
This file |