feat(model): 3D solid modelling tab — primitives + boolean ops

Rename the Home tab to "Draw" and add a Model tab beside it with two
groups:

- Model: BOX / CYLINDER / CONE / SPHERE / WEDGE / TORUS, placed with a
  footprint + height. Each is built as a real ACIS Solid3D (acadrust
  primitive builders) plus a truck B-rep, tessellated into the shaded
  mesh pipeline, with edge wires for picking + wireframe.
- Design: UNION / SUBTRACT / INTERSECT via truck-shapeops.

A session-only Scene.model_solids cache holds each solid's truck B-rep
so the boolean tools can combine and chain them. Supersedes the old
command-line BOX/SPHERE/CYLINDER (insert::solid3d_cmds keeps EXTRUDE/
REVOLVE/SWEEP/LOFT).

Known limitations: booleans need solids created this session; curved
ACIS primitives render in-session but not after reload (the SAT
tessellator handles only planar caps); geometry assumes world_offset 0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-05-31 19:27:06 +03:00
1 parent 4acb820e01
commit 7bf9ce31ae
17 files changed
+1095 -397

No files matched your search

+27
View File
@@ -0,0 +1,27 @@
// Boolean operations on 3D solids (Design group). The actual CSG runs in
// `App::solid_boolean` (src/app/model_ops.rs) using truck-shapeops on the
// session-cached truck B-reps; this module just names the operations.
/// Which boolean a Design-group tool performs on the two selected solids.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum BoolOp {
Union,
Subtract,
Intersect,
}
impl BoolOp {
pub fn from_id(id: &str) -> Option<BoolOp> {
Some(match id {
"UNION" => BoolOp::Union,
"SUBTRACT" => BoolOp::Subtract,
"INTERSECT" => BoolOp::Intersect,
_ => return None,
})
}
}
// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration {
names: &["UNION", "SUBTRACT", "INTERSECT"]
});