feat(model): build and read solids with the geometry kernel

Every 3-D solid OCS makes or opens now goes through cadkernel, which holds
analytic surfaces — a cylinder is a cylinder record, not a spline that looks
like one. That is what lets a solid built here be written back out as exact
ACIS instead of a triangulation, and a facetted export is a one-way door: the
next application to open the file would have no way back to the circle.

The Model tab's seven primitives, the Design-group booleans, 3DROTATE,
3DMIRROR, 3DALIGN, SLICE, SECTION, POLYSOLID and PYRAMID all come from the
kernel now, and `scene.solid_models` holds a `Body`. A mirrored solid needed
its own care before; the kernel reverses the loops on the way through, so it
comes back the right way out rather than lighting black.

EXTRUDE and REVOLVE sweep the profile `entities::curve` already defines, so a
circle, an arc-bulged polyline and a closed spline arrive as the same thing.
A circle extrudes into four cylinder patches rather than a run of chords, and
a profile turned about an axis becomes a cone, a sphere or a torus. A spline
profile has no analytic side wall and is refused rather than approximated.

ACIS goes both ways through the codec's own bridge: `lift` to read and
`append` to write. That drops the 679-line truck conversion and the planar-
only exporter, and the tessellator keeps its bespoke sampler as a fallback for
whatever the kernel cannot yet express — reported rather than passed off as
whole, since a mesh missing a wall looks finished.

truck-shapeops is no longer used and is gone from the manifest. truck-modeling
stays for now: fourteen files use it as a 3-D NURBS evaluator, which the
kernel has no answer for yet, and SWEEP and LOFT have no kernel operation
behind them either.

The two `automation` test failures are unchanged from before this and are not
caused by it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Opus 5 committed 2026-08-10 00:32:34 +03:00
1 parent 8016b79ddf
commit 1f642bb40a
15 files changed
+905 -1627

No files matched your search

+12 -10
View File
@@ -1779,11 +1779,12 @@ pub struct Scene {
/// owning block emits a transformed instance so a block placed at an
/// INSERT scale renders at the right size. (#123)
pub block_meshes: HashMap<Handle, MeshLodSet>,
/// Live truck B-reps for solids created this session by the Model tab,
/// keyed by entity handle. Backs the Design-group boolean tools (a solid
/// must be here to be combined). Not persisted — rebuilt only by creating
/// or combining primitives in-session.
pub solid_models: HashMap<Handle, truck_modeling::Solid>,
/// Live B-reps for solids created this session by the Model tab, keyed by
/// entity handle. Backs the Design-group boolean tools (a solid must be
/// here to be combined) and the exact-geometry save path, which writes
/// each one back out as ACIS rather than as facets. Not persisted —
/// rebuilt only by creating or combining primitives in-session.
pub solid_models: HashMap<Handle, acadrust::kernel::brep::Body>,
/// GPU render data for raster images (RasterImage entities), keyed by handle.
pub images: HashMap<Handle, ImageModel>,
/// The viewport that is currently "entered" (MSPACE mode).
@@ -2719,11 +2720,12 @@ impl Scene {
}
/// Re-evaluate every cached mesh's color through `render_style` so a
/// Register a Model-tab solid: cache its truck B-rep (for boolean ops) and
/// tessellate it into the shaded mesh pipeline under `handle`. The solid is
/// in the same offset-relative frame the mesh pipeline uses, so the mesh is
/// stored as-is (Model-tab geometry is authored at world_offset 0).
pub fn register_solid_model(&mut self, handle: Handle, solid: truck_modeling::Solid) {
/// Register a Model-tab solid: cache its B-rep (for boolean ops and the
/// exact-geometry save path) and tessellate it into the shaded mesh
/// pipeline under `handle`. The body is in the same offset-relative frame
/// the mesh pipeline uses, so the mesh is stored as-is (Model-tab geometry
/// is authored at world_offset 0).
pub fn register_solid_model(&mut self, handle: Handle, solid: acadrust::kernel::brep::Body) {
let entity = self.document.get_entity(handle);
let color = entity
.map(|e| self.render_style(e).0)