Skip to content

Commit 5d29f65

Browse files
committed
Prevent zero-length tangents and normals.
Lathed surfaces with a point on the lathe axis, there is a degenerate edge where one of the tangents is zero and the computed normal will be zero. That messes up booleans when the seams are in-plane with another surface. To prevent that we avoid taking tangents at the vertex and instead use on nearby.
1 parent d72eba8 commit 5d29f65

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

src/srf/ratpoly.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,19 @@ void SSurface::TangentsAt(double u, double v, Vector *tu, Vector *tv) const {
340340
den_u = 0,
341341
den_v = 0;
342342

343+
// we don't want zero-length tangents when control points are coincident.
344+
if(0 == u) {
345+
u += 0.000000001;
346+
} else if(1 == u) {
347+
u -= 0.000000001;
348+
}
349+
350+
if(0 == v) {
351+
v += 0.000000001;
352+
} else if(1 == v) {
353+
v -= 0.000000001;
354+
}
355+
343356
int i, j;
344357
for(i = 0; i <= degm; i++) {
345358
for(j = 0; j <= degn; j++) {
@@ -371,9 +384,13 @@ Vector SSurface::NormalAt(Point2d puv) const {
371384
}
372385

373386
Vector SSurface::NormalAt(double u, double v) const {
374-
Vector tu, tv;
387+
Vector tu, tv, n;
375388
TangentsAt(u, v, &tu, &tv);
376-
return tu.Cross(tv);
389+
n = tu.Cross(tv);
390+
if(EXACT(n.Magnitude() == 0)) {
391+
dbp("Zero surface normal u,v = %lf, %lf", u, v);
392+
}
393+
return n;
377394
}
378395

379396
void SSurface::ClosestPointTo(Vector p, Point2d *puv, bool mustConverge) {

0 commit comments

Comments
 (0)