From e56f09071a12409fcc92a04ffb75fb88566a170d Mon Sep 17 00:00:00 2001 From: Richard Brice <37087370+RickBrice@users.noreply.github.com> Date: Sun, 27 Jul 2025 15:09:00 -0700 Subject: [PATCH] Updates IfcOffsetCurveByDistance to be more permissive --- .../mapping/IfcOffsetCurveByDistance.cpp | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/ifcgeom/mapping/IfcOffsetCurveByDistance.cpp b/src/ifcgeom/mapping/IfcOffsetCurveByDistance.cpp index a506049a95..92fc2bee7b 100644 --- a/src/ifcgeom/mapping/IfcOffsetCurveByDistance.cpp +++ b/src/ifcgeom/mapping/IfcOffsetCurveByDistance.cpp @@ -108,12 +108,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst dp *= length_unit_; dn *= length_unit_; - if ((dp < 0.0 || basis_curve_length < dp) // previous is out of range - || - (dn < 0.0 || basis_curve_length < dn) // next is out of range - || - (dn < dp) // next is before previous - ) + if (dn < dp) // next is before previous { Logger::Warning("IfcOffsetCurveByDistance offset value is out of bounds."); continue; @@ -124,6 +119,33 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst double yp = (*prev)->OffsetLateral().get_value_or(0.0) * length_unit_; double zn = (*next)->OffsetVertical().get_value_or(0.0) * length_unit_; double zp = (*prev)->OffsetVertical().get_value_or(0.0) * length_unit_; + + if ( (dp < 0.0 && dn < 0.0) || (basis_curve_length < dp && basis_curve_length < dn) ) { + // both points are either before the start of the curve or after the end of the curve. ignore them. + continue; + } + + if (dp < 0.0) { + // previous is before the start of the curve + // compute y and z offsets at the start of the curve + auto yp_at_start = yp - (yn - yp) * dp / l; + auto zp_at_start = zp - (zn - zp) * dp / l; + + dp = 0.0; + yp = yp_at_start; + zp = zp_at_start; + } + + if (basis_curve_length < dn) { + // next is after the end of the curve + // compute y and z offsets at the end of the curve + auto yn_at_end = yn - (yn - yp) * (dn - basis_curve_length) / l; + auto zn_at_end = zn - (zn - zp) * (dn - basis_curve_length) / l; + dn = basis_curve_length; + yn = yn_at_end; + zn = zn_at_end; + } + auto fn = [yp, yn, zp, zn, l](double u) -> Eigen::Matrix4d { Eigen::Matrix4d m = Eigen::Matrix4d::Identity(); @@ -140,10 +162,6 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst #else double last_distance = *(*prev)->DistanceAlong()->as() * length_unit_; #endif - - if (basis_curve_length < last_distance) { - Logger::Warning("IfcOffsetCurveByDistance last offset value is after the end of the curve."); - } if (last_distance < basis_curve_length) { // Last offset is defined before the end of the curve so the lateral and vertical offsets