diff --git a/docs/changelog/avoid-rendering-fpe.md b/docs/changelog/avoid-rendering-fpe.md new file mode 100644 index 000000000..1cfa5e7d2 --- /dev/null +++ b/docs/changelog/avoid-rendering-fpe.md @@ -0,0 +1,10 @@ +# Avoid floating point exceptions in rendering code + +There were some places in the rendering code where floating point +exceptions (FPE) could happen under certain circumstances. Often we do not +care about invalid floating point operation in rendering as they often +occur in degenerate cases that don't contribute anyway. However, +simulations that might include VTK-m might turn on FPE to check their own +operations. In such cases, we don't want errant rendering arithmetic +causing an exception and bringing down the whole code. Thus, we turn on FPE +in some of our test platforms and avoid such operations in general. diff --git a/vtkm/rendering/Wireframer.h b/vtkm/rendering/Wireframer.h index 44a633a36..0e7879653 100644 --- a/vtkm/rendering/Wireframer.h +++ b/vtkm/rendering/Wireframer.h @@ -234,7 +234,9 @@ public: vtkm::Float32 dx = x2 - x1; vtkm::Float32 dy = y2 - y1; - vtkm::Float32 gradient = (dx == 0.0) ? 1.0f : (dy / dx); + if (dx == 0.0) + dx = vtkm::Epsilon32(); // Avoid FPE + vtkm::Float32 gradient = dy / dx; vtkm::Float32 xEnd = vtkm::Round(x1); vtkm::Float32 yEnd = y1 + gradient * (xEnd - x1); diff --git a/vtkm/rendering/raytracing/GlyphIntersector.cxx b/vtkm/rendering/raytracing/GlyphIntersector.cxx index b097d82ec..67ad2b90b 100644 --- a/vtkm/rendering/raytracing/GlyphIntersector.cxx +++ b/vtkm/rendering/raytracing/GlyphIntersector.cxx @@ -418,7 +418,11 @@ public: normal[0] = (vtkm::Abs(vtkm::Abs(lp[0]) - 1.0f) <= eps) ? lp[0] : 0.0f; normal[1] = (vtkm::Abs(vtkm::Abs(lp[1]) - 1.0f) <= eps) ? lp[1] : 0.0f; normal[2] = (vtkm::Abs(vtkm::Abs(lp[2]) - 1.0f) <= eps) ? lp[2] : 0.0f; - vtkm::Normalize(normal); + Precision magSquared = vtkm::MagnitudeSquared(normal); + if (magSquared > eps) + { + normal = vtkm::RSqrt(magSquared) * normal; + } // Flip normal if it is pointing the wrong way if (vtkm::Dot(normal, rayDir) > 0.0f)