fix(model): restore saved solid booleans

Reload exact B-reps from solid history or ACIS before model operations and pin the closed-cut kernel fix.
This commit is contained in:
Hakan Seven committed 2026-08-23 19:35:48 +03:00
1 parent e94cbedaa2
commit 44a40eda0b
7 files changed
+82 -85

No files matched your search

+28
View File
@@ -1,5 +1,6 @@
use acadrust::entities::acis::{SabReader, SatBody, SatDocument};
use acadrust::entities::{Body, Region, Solid3D};
use cadkernel::brep::{self, Body as KernelBody};
use crate::scene::model::mesh_model::{MeshLodSet, MeshModel};
@@ -154,6 +155,33 @@ fn parse_acis(
})
}
pub fn kernel_body(solid: &Solid3D) -> Option<KernelBody> {
let sat = parse_acis(
|| solid.parse_sat(),
solid.acis_data.is_binary,
&solid.acis_data.sab_data,
)?;
let (mut bodies, loss) = cadkernel::acis::lift(&sat);
if !loss.is_empty() || bodies.len() != 1 {
return None;
}
let body = bodies.pop()?;
let source = body.provenance.source()?;
let Some((matrix, translation, scale)) = body_transform(&sat, source.index() as usize).ok()?
else {
return Some(body);
};
brep::transform(
&body,
&brep::Placement {
x_axis: [scale * matrix[0], scale * matrix[1], scale * matrix[2]],
y_axis: [scale * matrix[3], scale * matrix[4], scale * matrix[5]],
z_axis: [scale * matrix[6], scale * matrix[7], scale * matrix[8]],
origin: translation,
},
)
}
fn remap_acis_material_bindings(
set: &mut MeshLodSet,
acis: &acadrust::entities::AcisData,
+22 -5
View File
@@ -586,11 +586,28 @@ impl Scene {
self.images.insert(handle, model);
}
self.refresh_meshes_for_handles(&[handle]);
if let Some(operation) = self.document.solid_history_operation(handle).cloned() {
if let Ok(body) = cadkernel::acis::rebuild_body(&operation) {
self.solid_models.insert(handle, body);
}
}
self.restore_solid_models(&[handle]);
}
pub fn restore_solid_models(&mut self, handles: &[Handle]) {
let bodies: Vec<(Handle, cadkernel::brep::Body)> = handles
.iter()
.filter(|handle| !self.solid_models.contains_key(handle))
.filter_map(|&handle| {
let from_history = self
.document
.solid_history_operation(handle)
.and_then(|operation| cadkernel::acis::rebuild_body(operation).ok());
let body = from_history.or_else(|| match self.document.get_entity(handle) {
Some(EntityType::Solid3D(solid)) => {
crate::scene::convert::solid3d_tess::kernel_body(solid)
}
_ => None,
})?;
Some((handle, body))
})
.collect();
self.solid_models.extend(bodies);
}
/// Re-tessellate only the named ACIS entities. The former edit path
+1 -5
View File
@@ -1645,11 +1645,7 @@ 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 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.
/// Kernel B-reps used by solid operations and exact-geometry saves.
pub solid_models: HashMap<Handle, cadkernel::brep::Body>,
/// GPU render data for raster images (RasterImage entities), keyed by handle.
pub images: HashMap<Handle, ImageModel>,