mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-03 18:45:55 +00:00
kernel: mesh bodies built by Body::of_mesh; fuzz booleans have no fallback counts
Mesh distance callers take geom's closest_on_triangle in place of the deleted guard's copy. (not built: base in progress) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017itGh5fpMEousnZ91cYcVt
This commit is contained in:
@@ -99,8 +99,6 @@ pub struct BoolCase {
|
||||
/// "ok", or the kind of failure: "error", "invalid", "identity".
|
||||
pub outcome: String,
|
||||
pub detail: String,
|
||||
pub boolean_fallbacks: std::collections::BTreeMap<crate::BooleanStrategy, usize>,
|
||||
pub boolean_reports_truncated: bool,
|
||||
}
|
||||
|
||||
fn vol(b: &Option<Body>) -> crate::Result<f64> {
|
||||
@@ -126,8 +124,6 @@ pub fn boolean_case(seed: u64) -> BoolCase {
|
||||
b: b.clone(),
|
||||
outcome: "ok".into(),
|
||||
detail: String::new(),
|
||||
boolean_fallbacks: Default::default(),
|
||||
boolean_reports_truncated: false,
|
||||
};
|
||||
let fail = |c: &mut BoolCase, kind: &str, d: String| {
|
||||
c.outcome = kind.into();
|
||||
@@ -139,11 +135,7 @@ pub fn boolean_case(seed: u64) -> BoolCase {
|
||||
};
|
||||
let mut res = Vec::new();
|
||||
for op in [BoolOp::Union, BoolOp::Intersect, BoolOp::Cut] {
|
||||
let (result, diagnostics) = crate::capture_boolean_diagnostics(|| boolean(&ba, &bb, op));
|
||||
case.boolean_reports_truncated |= diagnostics.truncated;
|
||||
for event in diagnostics.events {
|
||||
*case.boolean_fallbacks.entry(event.strategy).or_default() += 1;
|
||||
}
|
||||
let result = boolean(&ba, &bb, op);
|
||||
match result {
|
||||
Ok(x) => {
|
||||
if let Some(body) = &x {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
//! export; B-rep features refuse them.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use solidcraft_geom::{Mesh, Vec3};
|
||||
|
||||
@@ -101,23 +100,7 @@ pub fn mesh_body(positions: &[Vec3], triangles: &[[u32; 3]]) -> Result<Body> {
|
||||
t.swap(1, 2);
|
||||
}
|
||||
}
|
||||
Ok(Body {
|
||||
solid: Arc::new(crate::body::Solid::new_unchecked(Vec::new())),
|
||||
size: 0.0,
|
||||
volume: Some(std::sync::Arc::new(std::sync::Mutex::new(None))),
|
||||
coarse_missing: None,
|
||||
mesh: Some(Arc::new(out)),
|
||||
color: None,
|
||||
paint: None,
|
||||
splits: None,
|
||||
face_sources: None,
|
||||
history: None,
|
||||
display_of: None,
|
||||
meshes: None,
|
||||
phased: false,
|
||||
tolerances: None,
|
||||
regularization_protected: false,
|
||||
})
|
||||
Ok(Body::of_mesh(out))
|
||||
}
|
||||
|
||||
/// Wind every connected piece one way: a triangle that runs a side in the same direction as
|
||||
@@ -201,22 +184,11 @@ impl Body {
|
||||
t.swap(1, 2);
|
||||
}
|
||||
}
|
||||
Some(Body {
|
||||
solid: self.solid.clone(),
|
||||
size: 0.0,
|
||||
volume: Some(std::sync::Arc::new(std::sync::Mutex::new(None))),
|
||||
coarse_missing: None,
|
||||
mesh: Some(Arc::new(out)),
|
||||
color: self.color,
|
||||
paint: self.paint.clone(),
|
||||
splits: self.splits.clone(),
|
||||
face_sources: None,
|
||||
history: None,
|
||||
display_of: None,
|
||||
meshes: None,
|
||||
phased: false,
|
||||
tolerances: None,
|
||||
regularization_protected: self.regularization_protected,
|
||||
})
|
||||
let mut placed = Body::of_mesh(out);
|
||||
placed.color = self.color;
|
||||
placed.paint = self.paint.clone();
|
||||
placed.splits = self.splits.clone();
|
||||
placed.regularization_protected = self.regularization_protected;
|
||||
Some(placed)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
use crate::{Body, KernelError, Result, guard};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{Map, Number, Value};
|
||||
use std::sync::Arc;
|
||||
|
||||
mod binary;
|
||||
mod metadata;
|
||||
|
||||
@@ -161,7 +161,7 @@ fn faces_under(b: &Body, at: &[Vec3]) -> Result<Vec<usize>> {
|
||||
.triangles
|
||||
.iter()
|
||||
.zip(&mesh.tri_face)
|
||||
.filter_map(|(t, f)| mesh.tri(t).map(|[x, y, z]| (crate::boolean_guard::point_triangle_dist(*p, x, y, z), *f as usize)))
|
||||
.filter_map(|(t, f)| mesh.tri(t).map(|[x, y, z]| (solidcraft_geom::compare::closest_on_triangle(*p, x, y, z).dist(*p), *f as usize)))
|
||||
.min_by(|x, y| x.0.total_cmp(&y.0));
|
||||
match near {
|
||||
Some((d, f)) if d < reach => {
|
||||
@@ -214,7 +214,7 @@ fn with_offsets(result: &Body, input: &Body, mut h: History, distance: f64) -> O
|
||||
let tris = at(&made, i);
|
||||
let p = tris.iter().max_by(|x, y| area(x).total_cmp(&area(y))).map(|[a, b, c]| (*a + *b + *c) * (1.0 / 3.0))?;
|
||||
let under = at(&source, face);
|
||||
let d = under.iter().map(|[a, b, c]| crate::boolean_guard::point_triangle_dist(p, *a, *b, *c)).fold(f64::INFINITY, f64::min);
|
||||
let d = under.iter().map(|[a, b, c]| solidcraft_geom::compare::closest_on_triangle(p, *a, *b, *c).dist(p)).fold(f64::INFINITY, f64::min);
|
||||
if !d.is_finite() {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ pub fn offset_faces(b: &Body, at: &[Vec3], distance: f64) -> Result<Body> {
|
||||
.triangles
|
||||
.iter()
|
||||
.zip(&mesh.tri_face)
|
||||
.filter_map(|(t, f)| mesh.tri(t).map(|[x, y, z]| (crate::boolean_guard::point_triangle_dist(*p, x, y, z), *f as usize)))
|
||||
.filter_map(|(t, f)| mesh.tri(t).map(|[x, y, z]| (solidcraft_geom::compare::closest_on_triangle(*p, x, y, z).dist(*p), *f as usize)))
|
||||
.min_by(|a, c| a.0.total_cmp(&c.0));
|
||||
match near {
|
||||
Some((d, f)) if d < size * 1e-3 + 1e-6 => {
|
||||
|
||||
@@ -292,7 +292,7 @@ pub fn cylinder_face_at(b: &Body, p: Vec3) -> Option<CylinderFace> {
|
||||
let mut near: HashMap<u32, f64> = HashMap::new();
|
||||
for (t, f) in mesh.triangles.iter().zip(&mesh.tri_face) {
|
||||
let Some([a, bb, c]) = mesh.tri(t) else { continue };
|
||||
let d = crate::boolean_guard::point_triangle_dist(p, a, bb, c);
|
||||
let d = solidcraft_geom::compare::closest_on_triangle(p, a, bb, c).dist(p);
|
||||
near.entry(*f).and_modify(|x| *x = x.min(d)).or_insert(d);
|
||||
}
|
||||
let nearest = near.values().copied().fold(f64::INFINITY, f64::min);
|
||||
|
||||
Reference in New Issue
Block a user