forked from 1b-agent/opencadstudio-upstream
fix(solid): tessellate cone-surface faces to their arc, not a full circle
Curved 3D-solid faces backed by an ACIS cone-surface (e.g. the arched mullion bars of a storefront curtain wall) were swept a full revolution regardless of the face's actual angular extent, so a bar bounded to an 8-16 degree arc rendered as a full circle of the surface radius — a large jagged loop instead of a small arch. cone_faces (the truck B-rep path) now derives the angular span from the face's boundary loop and rsweeps only that arc; the bespoke fallback tess_cone_face no longer forces a full revolution when a thin face collapses to a single height. Arc extraction uses a seam-robust largest-gap method so faces straddling +/-pi (the crown of an arch) are not mistaken for full circles. Verified against Clinic_Architectural.dwg: the seven arch-bar solids drop from a ~12.9 (2R) bbox to their true ~1-2 unit extent, and a file-wide check of 155 cone-bearing solids shows none ballooned and none collapsed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
a8c368aef9
commit
9f7fdc5f8f
2 files changed
+86
-10
No files matched your search
@@ -609,14 +609,17 @@ fn tess_cone_face(
|
||||
// boundary alone can't span the height — the second extent (top rim or
|
||||
// apex) lives on a different face. When the boundary collapses to one
|
||||
// height, recover the span from the solid's coaxial circle rims plus the
|
||||
// analytic apex of a true cone, and sweep the full revolution.
|
||||
// analytic apex of a true cone. Only sweep the full revolution when the
|
||||
// boundary really is a closed rim; a bounded arc face (e.g. a curved
|
||||
// mullion bar) keeps its own angular span, else it balloons to a circle.
|
||||
if (h_max - h_min).abs() < 1e-9 {
|
||||
if let Some((vmin, vmax)) = cone_axis_span(sat, cone, axis, [cx, cy, cz]) {
|
||||
h_min = vmin;
|
||||
h_max = vmax;
|
||||
theta_min = 0.0;
|
||||
theta_max = TAU;
|
||||
full_circle = true;
|
||||
if full_circle {
|
||||
theta_min = 0.0;
|
||||
theta_max = TAU;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1012,3 +1015,4 @@ fn norm3(v: [f64; 3]) -> [f64; 3] {
|
||||
[v[0] / len, v[1] / len, v[2] / len]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user