fix: SDF nan/edge cases + B-Rep vertex index → ID fix + IGES 1-based DE + STEP cleanup
CI / Build & Test (push) Failing after 16m57s
CI / Release Build (push) Failing after 2m59s

This commit is contained in:
茂之钳
2026-07-24 08:42:53 +00:00
parent ebc47a25c9
commit a323776fd3
12 changed files with 139 additions and 70 deletions
+8 -5
View File
@@ -142,8 +142,11 @@ struct GradResult {
{
double rho = std::sqrt(p.x() * p.x() + p.z() * p.z());
if (rho < 1e-30) {
// On the Y axis: gradient points radially outward in XZ plane
return Vector3D(0.0, (p.y() >= 0.0 ? 1.0 : -1.0), 0.0);
// On the Y axis: x and z gradients are 0 by symmetry;
// y gradient = py / sqrt(major² + py²)
double inner = std::sqrt(major_r * major_r + p.y() * p.y());
if (inner < 1e-30) return Vector3D::Zero();
return Vector3D(0.0, p.y() / inner, 0.0);
}
double inner = std::sqrt((rho - major_r) * (rho - major_r) + p.y() * p.y());
if (inner < 1e-30) return Vector3D::Zero();
@@ -209,11 +212,11 @@ struct GradResult {
return (d1 > d2) ? grad_a : grad_b;
}
/// Gradient after difference: max(-d1, d2)
/// Gradient after difference: max(d1, -d2)
[[nodiscard]] inline Vector3D chain_difference(const Vector3D& grad_a, const Vector3D& grad_b,
double d1, double d2)
{
return (-d1 > d2) ? Vector3D(-grad_a.x(), -grad_a.y(), -grad_a.z()) : grad_b;
return (d1 > -d2) ? grad_a : Vector3D(-grad_b.x(), -grad_b.y(), -grad_b.z());
}
/// Gradient after smooth union with full chain rule
@@ -222,7 +225,7 @@ struct GradResult {
double d1, double d2, double k)
{
if (k <= 0.0) return chain_union(grad_a, grad_b, d1, d2);
double h = std::clamp(0.5 + 0.5 * (d2 - d1) / k, 0.0, 1.0);
double h = std::clamp(0.5 + 0.5 * (d1 - d2) / k, 0.0, 1.0);
if (h <= 0.0) return grad_a;
if (h >= 1.0) return grad_b;
+6 -6
View File
@@ -19,25 +19,25 @@ using core::Vector3D;
}
[[nodiscard]] inline double op_difference(double d1, double d2) {
return std::max(-d1, d2);
return std::max(d1, -d2);
}
[[nodiscard]] inline double op_smooth_union(double d1, double d2, double k) {
if (k <= 0.0) return std::min(d1, d2);
double h = std::clamp(0.5 + 0.5 * (d2 - d1) / k, 0.0, 1.0);
double h = std::clamp(0.5 + 0.5 * (d1 - d2) / k, 0.0, 1.0);
return d1 * (1.0 - h) + d2 * h - k * h * (1.0 - h);
}
[[nodiscard]] inline double op_smooth_intersection(double d1, double d2, double k) {
if (k <= 0.0) return std::max(d1, d2);
double h = std::clamp(0.5 - 0.5 * (d2 - d1) / k, 0.0, 1.0);
double h = std::clamp(0.5 - 0.5 * (d1 - d2) / k, 0.0, 1.0);
return d1 * (1.0 - h) + d2 * h + k * h * (1.0 - h);
}
[[nodiscard]] inline double op_smooth_difference(double d1, double d2, double k) {
if (k <= 0.0) return std::max(-d1, d2);
if (k <= 0.0) return std::max(d1, -d2);
double h = std::clamp(0.5 - 0.5 * (d2 + d1) / k, 0.0, 1.0);
return (-d1) * (1.0 - h) + d2 * h + k * h * (1.0 - h);
return d1 * (1.0 - h) + (-d2) * h + k * h * (1.0 - h);
}
// ── Modifiers (operate on a distance value) ──
@@ -47,7 +47,7 @@ using core::Vector3D;
}
[[nodiscard]] inline double op_onion(double d, double thickness) {
return std::abs(d) - thickness;
return std::abs(d) - thickness * 0.5;
}
// ── Domain deformation operators (transform point space) ──
+10 -1
View File
@@ -46,7 +46,12 @@ using core::Vector3D;
[[nodiscard]] inline double capsule(const Point3D& p, const Point3D& a, const Point3D& b, double radius) {
Point3D pa = p - a;
Point3D ba = b - a;
double h = std::clamp(pa.dot(ba) / ba.squaredNorm(), 0.0, 1.0);
double ba_sq = ba.squaredNorm();
if (ba_sq < 1e-30) {
// Degenerate to sphere
return pa.norm() - radius;
}
double h = std::clamp(pa.dot(ba) / ba_sq, 0.0, 1.0);
return (pa - ba * h).norm() - radius;
}
@@ -75,6 +80,10 @@ using core::Vector3D;
double k1 = Point3D(p.x() / (radii.x() * radii.x()),
p.y() / (radii.y() * radii.y()),
p.z() / (radii.z() * radii.z())).norm();
if (k1 < 1e-30) {
// Degenerate: point at origin → distance = -min(radii)
return -std::min({radii.x(), radii.y(), radii.z()});
}
return k0 * (k0 - 1.0) / k1;
}