mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-23 21:38:51 +00:00
Make CGAL circle-segments 0-default deflection-driven (rework #8368)
Address maintainer request on #8368: instead of a deflection floor on top
of a fixed CircleSegments count, use one mode or the other. When
CircleSegments == 0 (the new default) the CGAL kernel derives the conic
segment count from MesherLinearDeflection, matching the deflection based
meshing OpenCascade already does and fixing #8051. When CircleSegments is
non zero it is used directly as a fixed, radius independent count.
CircleSegments is only read by the CGAL kernel; OpenCascade meshes by
deflection and never reads it, so the new default has no effect there.
Update the setting description and the ifcconvert / geometry-settings docs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 0d70812641)
This commit is contained in:
committed by
Dion Moult
parent
b774c9ad18
commit
c57da082a5
@@ -373,8 +373,8 @@ namespace ifcopenshell {
|
|||||||
|
|
||||||
struct CircleSegments : public SettingBase<CircleSegments, int> {
|
struct CircleSegments : public SettingBase<CircleSegments, int> {
|
||||||
static constexpr const char* const name = "circle-segments";
|
static constexpr const char* const name = "circle-segments";
|
||||||
static constexpr const char* const description = "Number of segments to approximate full circles in CGAL kernel.";
|
static constexpr const char* const description = "Number of segments to approximate full circles in the CGAL kernel. When 0 (the default) the segment count is derived from mesher-linear-deflection instead, so curves stay within the deflection tolerance regardless of radius.";
|
||||||
static constexpr int defaultvalue = 16;
|
static constexpr int defaultvalue = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CgalSmoothAngleDegrees : public SettingBase<CgalSmoothAngleDegrees, double> {
|
struct CgalSmoothAngleDegrees : public SettingBase<CgalSmoothAngleDegrees, double> {
|
||||||
|
|||||||
@@ -436,22 +436,30 @@ namespace {
|
|||||||
b += 2 * M_PI;
|
b += 2 * M_PI;
|
||||||
}
|
}
|
||||||
const double span = std::fabs(a - b);
|
const double span = std::fabs(a - b);
|
||||||
int num_segments = (int)std::ceil(span / (2 * M_PI) * settings_.get<settings::CircleSegments>().get());
|
// CircleSegments controls how conics (circles, ellipses, arcs) are approximated
|
||||||
// CircleSegments allocates segments as a fraction of the *full* circle and is
|
// in the CGAL kernel. Two modes, one or the other:
|
||||||
// radius-agnostic. A large-radius arc spanning a small angle therefore collapses
|
// - CircleSegments == 0 (the default): the segment count is derived from
|
||||||
// to a single chord (issue #8051: curved curtain-wall mullions became straight in
|
// MesherLinearDeflection, so the chord deviation stays within the mesher's
|
||||||
// the CGAL kernels while OpenCascade, which meshes by deflection, kept them curved).
|
// linear deflection regardless of radius. This matches the deflection based
|
||||||
// Enforce a deflection-based floor so the chord deviation stays within the mesher's
|
// meshing the OpenCascade kernel already does and fixes issue #8051, where
|
||||||
// linear deflection, matching OpenCascade behaviour.
|
// large radius arcs (curved curtain wall mullions) collapsed to straight chords
|
||||||
const double radius = conic_radius(t);
|
// because a fixed segment count is radius agnostic.
|
||||||
const double deflection = settings_.get<settings::MesherLinearDeflection>().get();
|
// - CircleSegments > 0: it is used directly as the number of segments for a full
|
||||||
if (deflection > 0. && radius > deflection) {
|
// circle, giving deterministic, radius independent output.
|
||||||
const double max_segment_angle = 2.0 * std::acos(1.0 - deflection / radius);
|
int num_segments;
|
||||||
if (max_segment_angle > 0.) {
|
const int circle_segments = settings_.get<settings::CircleSegments>().get();
|
||||||
const int num_segments_deflection = (int)std::ceil(span / max_segment_angle);
|
if (circle_segments > 0) {
|
||||||
if (num_segments_deflection > num_segments) {
|
num_segments = (int)std::ceil(span / (2 * M_PI) * circle_segments);
|
||||||
num_segments = num_segments_deflection;
|
} else {
|
||||||
}
|
const double radius = conic_radius(t);
|
||||||
|
const double deflection = settings_.get<settings::MesherLinearDeflection>().get();
|
||||||
|
if (deflection > 0. && radius > deflection) {
|
||||||
|
const double max_segment_angle = 2.0 * std::acos(1.0 - deflection / radius);
|
||||||
|
num_segments = (int)std::ceil(span / max_segment_angle);
|
||||||
|
} else {
|
||||||
|
// Radius within the deflection tolerance (or no deflection set): a chord per
|
||||||
|
// quarter turn already keeps the deviation within tolerance.
|
||||||
|
num_segments = (int)std::ceil(span / (M_PI / 2.));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (num_segments < 1) {
|
if (num_segments < 1) {
|
||||||
|
|||||||
@@ -310,8 +310,12 @@ CLI Manual
|
|||||||
output.
|
output.
|
||||||
--force-space-transparency arg Overrides transparency of spaces in
|
--force-space-transparency arg Overrides transparency of spaces in
|
||||||
geometry output.
|
geometry output.
|
||||||
--circle-segments arg (= 16) Number of segments to approximate full
|
--circle-segments arg (= 0) Number of segments to approximate full
|
||||||
circles in CGAL kernel.
|
circles in the CGAL kernel. When 0 (the
|
||||||
|
default) the segment count is derived from
|
||||||
|
mesher-linear-deflection instead, so curves
|
||||||
|
stay within the deflection tolerance
|
||||||
|
regardless of radius.
|
||||||
--cgal-smooth-angle-degrees arg (= -1)
|
--cgal-smooth-angle-degrees arg (= -1)
|
||||||
Angle in degrees under which adjacent
|
Angle in degrees under which adjacent
|
||||||
facets will have averaged vertex
|
facets will have averaged vertex
|
||||||
|
|||||||
@@ -228,10 +228,10 @@ circle-segments
|
|||||||
+------+-----------------------+---------+
|
+------+-----------------------+---------+
|
||||||
| Type | IfcConvert Option | Default |
|
| Type | IfcConvert Option | Default |
|
||||||
+======+=======================+=========+
|
+======+=======================+=========+
|
||||||
| INT | ``--circle-segments`` | 16 |
|
| INT | ``--circle-segments`` | 0 |
|
||||||
+------+-----------------------+---------+
|
+------+-----------------------+---------+
|
||||||
|
|
||||||
Number of segments to approximate full circles in CGAL kernel.
|
Number of segments to approximate full circles in the CGAL kernel. When 0 (the default) the segment count is derived from mesher-linear-deflection instead, so curves stay within the deflection tolerance regardless of radius.
|
||||||
|
|
||||||
context-identifiers
|
context-identifiers
|
||||||
^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|||||||
Reference in New Issue
Block a user