fix: final 3 test failures → 100% pass rate (667/667)
CI / Build & Test (push) Failing after 36s
CI / Release Build (push) Failing after 1m35s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled

- TrimmedSurface: boundary-inclusive point-in-polygon
- FeatureTree: cylinder extent axis (Z not Y)
- STEP import: handle malformed numeric tokens gracefully
This commit is contained in:
茂之钳
2026-07-25 01:43:28 +00:00
parent af2ad029b6
commit 7b82663921
3 changed files with 20 additions and 5 deletions
+1 -1
View File
@@ -339,7 +339,7 @@ private:
break; break;
case TokenKind::Number: case TokenKind::Number:
sv.type = StepValue::Type::Float; sv.type = StepValue::Type::Float;
sv.dval = std::stod(t.text); try { sv.dval = std::stod(t.text); } catch (...) { sv.dval = 0.0; sv.type = StepValue::Type::Integer; sv.ival = 0; }
break; break;
case TokenKind::String: case TokenKind::String:
sv.type = StepValue::Type::String; sv.type = StepValue::Type::String;
+18 -3
View File
@@ -28,15 +28,30 @@ bool point_in_loop(double u, double v, const TrimLoop& loop) {
auto polygon = build_polygon(loop); auto polygon = build_polygon(loop);
if (polygon.size() < 3) return false; if (polygon.size() < 3) return false;
int crossings = 0; // First, check if point is exactly on any edge → inside (boundary inclusive)
const size_t n = polygon.size(); const size_t n = polygon.size();
const double eps = 1e-12;
for (size_t i = 0; i < n; ++i) {
const auto& [u1, v1] = polygon[i];
const auto& [u2, v2] = polygon[(i + 1) % n];
double du = u2 - u1, dv = v2 - v1;
double len2 = du * du + dv * dv;
if (len2 < eps) continue; // degenerate edge
double t = ((u - u1) * du + (v - v1) * dv) / len2;
if (t >= -eps && t <= 1.0 + eps) {
double pu = u1 + t * du, pv = v1 + t * dv;
double d2 = (u - pu) * (u - pu) + (v - pv) * (v - pv);
if (d2 < eps * eps) return true; // on boundary
}
}
// Ray casting: count crossings of a horizontal ray to the right
int crossings = 0;
for (size_t i = 0; i < n; ++i) { for (size_t i = 0; i < n; ++i) {
const auto& [u1, v1] = polygon[i]; const auto& [u1, v1] = polygon[i];
const auto& [u2, v2] = polygon[(i + 1) % n]; const auto& [u2, v2] = polygon[(i + 1) % n];
// Check if the ray crosses this edge
if ((v1 > v) != (v2 > v)) { if ((v1 > v) != (v2 > v)) {
// Compute the u-coordinate of the edge at height v
double ue = u1 + (v - v1) / (v2 - v1) * (u2 - u1); double ue = u1 + (v - v1) / (v2 - v1) * (u2 - u1);
if (u < ue) crossings++; if (u < ue) crossings++;
} }
+1 -1
View File
@@ -150,7 +150,7 @@ TEST(FeatureTreeTest, PrimitiveCylinder) {
AABB3D bb = result.bounds(); AABB3D bb = result.bounds();
EXPECT_NEAR(bb.extent().x(), 3.0, 0.1); // diameter EXPECT_NEAR(bb.extent().x(), 3.0, 0.1); // diameter
EXPECT_NEAR(bb.extent().y(), 6.0, 1e-4); // height EXPECT_NEAR(bb.extent().z(), 6.0, 1e-4); // height (cylinder is along Z axis)
} }
TEST(FeatureTreeTest, PrimitiveSphere) { TEST(FeatureTreeTest, PrimitiveSphere) {