Draft of walls between caps on non-convex bodies: planes tilt about their neutral-plane line, cylinders become cones (47: drafted round-ended pocket)
Oracle: 56/76. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
1 parent
94a0cdef77
commit
7e373ff1f7
4 files changed
+252
-3
No files matched your search
@@ -161,7 +161,10 @@ pub fn draft(b: &Body, faces: &[Vec3], neutral: &Plane, pull: Vec3, angle: f64)
|
||||
return Err(KernelError::Invalid("draft angle must be between −90° and 90°".into()));
|
||||
}
|
||||
let pull = pull.normalized().ok_or_else(|| KernelError::Invalid("pull direction".into()))?;
|
||||
let hs = planar_convex(b)?;
|
||||
let hs = match planar_convex(b) {
|
||||
Ok(h) => h,
|
||||
Err(_) => return draft_walls(b, faces, neutral, pull, angle),
|
||||
};
|
||||
let size = b.size();
|
||||
let mut out = Vec::new();
|
||||
let mut moved = 0;
|
||||
@@ -187,6 +190,31 @@ pub fn draft(b: &Body, faces: &[Vec3], neutral: &Plane, pull: Vec3, angle: f64)
|
||||
convex_polyhedron(&out)
|
||||
}
|
||||
|
||||
/// Draft of a non-convex body: walls (planes, cylinders) next to caps square to `pull`.
|
||||
fn draft_walls(b: &Body, at: &[Vec3], neutral: &Plane, pull: Vec3, angle: f64) -> Result<Body> {
|
||||
let healed = Body::new(crate::heal::heal(b.deep_copy(), b.size()))?;
|
||||
let size = healed.size();
|
||||
let mesh = healed.tessellate((size * 1e-3).max(1e-3))?;
|
||||
let mut chosen: Vec<usize> = Vec::new();
|
||||
for p in at {
|
||||
let near = mesh
|
||||
.triangles
|
||||
.iter()
|
||||
.zip(&mesh.tri_face)
|
||||
.filter_map(|(t, f)| mesh.tri(t).map(|[x, y, z]| (point_tri(*p, x, y, z), *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 => {
|
||||
if !chosen.contains(&f) {
|
||||
chosen.push(f);
|
||||
}
|
||||
}
|
||||
_ => return Err(KernelError::Invalid(format!("no face at {:?}", [p.x, p.y, p.z]))),
|
||||
}
|
||||
}
|
||||
crate::offset::draft_walls(&healed, &chosen, neutral, pull, angle)
|
||||
}
|
||||
|
||||
/// Round every edge of a convex body with planar faces by `r`: faces shrink, each edge becomes a
|
||||
/// cylinder and each corner a sphere patch (the body is the inner polyhedron grown by a ball).
|
||||
pub fn round_all_edges(b: &Body, r: f64) -> Result<Body> {
|
||||
|
||||
Reference in new issue
Block a user