forked from 1b-agent/opencadstudio-upstream
fix(acis): complete curved solid faces
Prevent partial sweeps and reversed boundary sampling from dropping surface segments and connector corners.
This commit is contained in:
1 parent
f18ba87858
commit
2c5b7e76fb
2 files changed
+23
-13
No files matched your search
@@ -374,9 +374,9 @@ fn loop_normal(pts: &[[f64; 3]]) -> [f64; 3] {
|
||||
|
||||
// ── Cone / cylinder face ─────────────────────────────────────────────────────
|
||||
|
||||
/// Build a cone/cylinder lateral surface as revolution faces. A plain closed
|
||||
/// revolution uses the parametric sampler; a pierced one stays here so its
|
||||
/// additional boundary loops can trim holes into the curved surface.
|
||||
/// Build a pierced cone/cylinder lateral surface as revolution faces. A
|
||||
/// single-loop face uses the parametric sampler, avoiding partial revolution
|
||||
/// segments that can disappear when the profile crosses a coordinate plane.
|
||||
fn cone_faces(
|
||||
sat: &SatDocument,
|
||||
face: &SatFace,
|
||||
@@ -411,6 +411,9 @@ fn cone_faces(
|
||||
};
|
||||
|
||||
let loops = collect_face_loops(sat, face, BOUNDARY_CHORD_FRAC);
|
||||
if loops.len() == 1 {
|
||||
return None;
|
||||
}
|
||||
let arcs: Vec<(f64, f64)> = loops
|
||||
.iter()
|
||||
.map(|lp| cone_boundary_arc(lp, [cx, cy, cz], axis, udir, vdir))
|
||||
|
||||
@@ -1424,17 +1424,23 @@ pub(crate) fn append_coedge_points(
|
||||
// The edge's own sense (relative to its curve) decides the ellipse
|
||||
// winding; a reversed edge samples the opposite handedness.
|
||||
let reversed = matches!(edge.sense(), Sense::Reversed);
|
||||
let mut sampled = sample_ellipse_arc(
|
||||
// Orient the parameter range before sampling. Reversing an
|
||||
// endpoint-exclusive sample afterwards would drop the traversal
|
||||
// start and retain its end, duplicating the next coedge's point and
|
||||
// cutting the connector corner out of the face boundary.
|
||||
let (start, end) = if fwd {
|
||||
(edge.start_param(), edge.end_param())
|
||||
} else {
|
||||
(edge.end_param(), edge.start_param())
|
||||
};
|
||||
let sampled = sample_ellipse_arc(
|
||||
&ellipse,
|
||||
edge.start_param(),
|
||||
edge.end_param(),
|
||||
start,
|
||||
end,
|
||||
chord_frac,
|
||||
reversed,
|
||||
);
|
||||
if !sampled.is_empty() {
|
||||
if !fwd {
|
||||
sampled.reverse();
|
||||
}
|
||||
pts.extend(sampled);
|
||||
return;
|
||||
}
|
||||
@@ -1452,12 +1458,13 @@ pub(crate) fn append_coedge_points(
|
||||
.into_iter()
|
||||
.map(|(x, y, z)| [x, y, z])
|
||||
.collect();
|
||||
// Drop the shared end point so adjacent coedges don't double up.
|
||||
// Orient the inclusive sample first, then drop the traversal end so
|
||||
// the adjacent coedge contributes that shared point.
|
||||
if !fwd {
|
||||
sampled.reverse();
|
||||
}
|
||||
sampled.pop();
|
||||
if sampled.len() >= 2 {
|
||||
if !fwd {
|
||||
sampled.reverse();
|
||||
}
|
||||
pts.extend(sampled);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user