forked from 1b-agent/opencadstudio-upstream
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 <[email protected]>
This commit is contained in:
1 parent
8016b79ddf
commit
1f642bb40a
15 files changed
+905
-1627
No files matched your search
@@ -11,7 +11,7 @@ use acadrust::entities::Solid3D;
|
||||
use acadrust::{primitives, EntityType};
|
||||
use glam::DVec3;
|
||||
use crate::t;
|
||||
use truck_modeling::Solid;
|
||||
use acadrust::kernel::brep::Body;
|
||||
|
||||
use crate::command::{CadCommand, CmdResult, WorkingPlane};
|
||||
use crate::scene::model::solid_model;
|
||||
@@ -100,9 +100,9 @@ impl PrimitiveCommand {
|
||||
.max(1.0)
|
||||
}
|
||||
|
||||
/// Build both the acadrust `Solid3D` (ACIS, for persistence) and the truck
|
||||
/// `Solid` B-rep (rendering + booleans) from the footprint + `height`.
|
||||
fn build(&self, height: f64) -> Option<(EntityType, Solid)> {
|
||||
/// Build both the acadrust `Solid3D` (ACIS, for persistence) and the
|
||||
/// kernel `Body` (rendering + booleans) from the footprint + `height`.
|
||||
fn build(&self, height: f64) -> Option<(EntityType, Body)> {
|
||||
let (doc, solid) = match self.shape {
|
||||
Shape::Box | Shape::Wedge => {
|
||||
let (a, b) = (self.pts[0], self.pts[1]);
|
||||
@@ -174,6 +174,7 @@ impl PrimitiveCommand {
|
||||
)
|
||||
}
|
||||
};
|
||||
let solid = solid?;
|
||||
let mut s3d = Solid3D::new();
|
||||
s3d.set_sat_document(&doc);
|
||||
// Edge wires make the solid click-pickable and draw a wireframe over
|
||||
@@ -185,27 +186,26 @@ impl PrimitiveCommand {
|
||||
fn commit(&self, height: f64) -> CmdResult {
|
||||
match self.build(height) {
|
||||
Some((entity, solid)) => {
|
||||
let matrix = truck_modeling::Matrix4::new(
|
||||
self.plane.x.x,
|
||||
self.plane.x.y,
|
||||
self.plane.x.z,
|
||||
0.0,
|
||||
self.plane.y.x,
|
||||
self.plane.y.y,
|
||||
self.plane.y.z,
|
||||
0.0,
|
||||
self.plane.z.x,
|
||||
self.plane.z.y,
|
||||
self.plane.z.z,
|
||||
0.0,
|
||||
self.plane.origin.x,
|
||||
self.plane.origin.y,
|
||||
self.plane.origin.z,
|
||||
1.0,
|
||||
// Built upright in its own frame, then put on the working
|
||||
// plane — the same move `place_entity` makes for the ACIS
|
||||
// copy, so the two stay on top of each other.
|
||||
let placed = solid_model::placed(
|
||||
&solid,
|
||||
[self.plane.x.x, self.plane.x.y, self.plane.x.z],
|
||||
[self.plane.y.x, self.plane.y.y, self.plane.y.z],
|
||||
[self.plane.z.x, self.plane.z.y, self.plane.z.z],
|
||||
[
|
||||
self.plane.origin.x,
|
||||
self.plane.origin.y,
|
||||
self.plane.origin.z,
|
||||
],
|
||||
);
|
||||
CmdResult::CommitSolid {
|
||||
entity: self.plane.place_entity(entity),
|
||||
solid: Box::new(truck_modeling::builder::transformed(&solid, matrix)),
|
||||
match placed {
|
||||
Some(placed) => CmdResult::CommitSolid {
|
||||
entity: self.plane.place_entity(entity),
|
||||
solid: Box::new(placed),
|
||||
},
|
||||
None => CmdResult::Cancel,
|
||||
}
|
||||
}
|
||||
None => CmdResult::Cancel,
|
||||
|
||||
Reference in new issue
Block a user