From 686030ef7ed6316b6dd4d2a0db1ade000bb7ea4e Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Mon, 20 Sep 2010 20:50:30 +0200 Subject: [PATCH] feature to track down use of unitialized values (initialize vectors etc. with NaNs if a compile-time flag is set) --- include/mitsuba/core/point.h | 12 ++++++++++++ include/mitsuba/core/spectrum.h | 8 ++++++++ include/mitsuba/core/vector.h | 12 ++++++++++++ src/librender/shape.cpp | 14 +++++++++----- src/librender/trimesh.cpp | 10 +++++----- 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/include/mitsuba/core/point.h b/include/mitsuba/core/point.h index fcc18243..144d8da8 100644 --- a/include/mitsuba/core/point.h +++ b/include/mitsuba/core/point.h @@ -39,7 +39,11 @@ template struct TPoint2 { * computations involving uninitialized memory, which will probably * lead to a difficult-to-find bug. */ +#if !defined(MTS_DEBUG_UNINITIALIZED) TPoint2() { } +#else + TPoint2() { x = y = std::numeric_limits::quiet_NaN(); } +#endif /// Initialize the point with the specified X, Y and Z components TPoint2(T x, T y) : x(x), y(y) { } @@ -221,7 +225,11 @@ template struct TPoint3 { * computations involving uninitialized memory, which will probably * lead to a difficult-to-find bug. */ +#if !defined(MTS_DEBUG_UNINITIALIZED) TPoint3() { } +#else + TPoint3() { x = y = z = std::numeric_limits::quiet_NaN(); } +#endif /// Initialize the point with the specified X, Y and Z components TPoint3(T x, T y, T z) : x(x), y(y), z(z) { } @@ -406,7 +414,11 @@ template struct TPoint4 { * computations involving uninitialized memory, which will probably * lead to a difficult-to-find bug. */ +#if !defined(MTS_DEBUG_UNINITIALIZED) TPoint4() { } +#else + TPoint4() { x = y = z = w = std::numeric_limits::quiet_NaN(); } +#endif /// Initialize the point with the specified X, Y and Z components TPoint4(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) { } diff --git a/include/mitsuba/core/spectrum.h b/include/mitsuba/core/spectrum.h index 19f628ff..c5b79fb9 100644 --- a/include/mitsuba/core/spectrum.h +++ b/include/mitsuba/core/spectrum.h @@ -104,7 +104,15 @@ private: struct MTS_EXPORT_CORE Spectrum { public: /// Create a new spectral power distribution, but don't initialize the contents +#if !defined(MTS_DEBUG_UNINITIALIZED) inline Spectrum() { } +#else + inline Spectrum() { + for (int i=0; i::quiet_NaN(); + } +#endif + /// Create a new spectral power distribution with all samples set to the given value explicit inline Spectrum(Float v) { diff --git a/include/mitsuba/core/vector.h b/include/mitsuba/core/vector.h index f061d258..3b557d4b 100644 --- a/include/mitsuba/core/vector.h +++ b/include/mitsuba/core/vector.h @@ -40,7 +40,11 @@ public: * computations involving uninitialized memory, which will probably * lead to a difficult-to-find bug. */ +#if !defined(MTS_DEBUG_UNINITIALIZED) TVector2() { } +#else + TVector2() { x = y = std::numeric_limits::quiet_NaN(); } +#endif /// Initialize the vector with the specified X and Z components TVector2(T x, T y) : x(x), y(y) { } @@ -222,7 +226,11 @@ public: * computations involving uninitialized memory, which will probably * lead to a difficult-to-find bug. */ +#if !defined(MTS_DEBUG_UNINITIALIZED) TVector3() { } +#else + TVector3() { x = y = z = std::numeric_limits::quiet_NaN(); } +#endif /// Initialize the vector with the specified X, Y and Z components TVector3(T x, T y, T z) : x(x), y(y), z(z) { } @@ -417,7 +425,11 @@ public: * computations involving uninitialized memory, which will probably * lead to a difficult-to-find bug. */ +#if !defined(MTS_DEBUG_UNINITIALIZED) TVector4() { } +#else + TVector4() { x = y = z = w = std::numeric_limits::quiet_NaN(); } +#endif /// Initialize the vector with the specified X, Y and Z components TVector4(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) { } diff --git a/src/librender/shape.cpp b/src/librender/shape.cpp index 14096f54..26693730 100644 --- a/src/librender/shape.cpp +++ b/src/librender/shape.cpp @@ -179,7 +179,7 @@ std::string Intersection::toString() const { void Intersection::computePartials(const RayDifferential &ray) { /* Compute the texture coordinates partials wrt. - changes in the screen-space position. Based on PBRT */ + changes in the screen-space position. Based on PBRT */ if (hasUVPartials) return; hasUVPartials = true; @@ -210,14 +210,17 @@ void Intersection::computePartials(const RayDifferential &ray) { Point px = ray.rx(tx), py = ray.ry(ty); /* Calculate the U and V partials by solving two out - of a set of 3 equations in an overconstrained system */ + of a set of 3 equations in an overconstrained system */ Float A[2][2], Bx[2], By[2], x[2]; int axes[2]; - if (std::abs(geoFrame.n.x) > std::abs(geoFrame.n.y) - && std::abs(geoFrame.n.x) > std::abs(geoFrame.n.z)) { + Float absX = std::abs(geoFrame.n.x), + absY = std::abs(geoFrame.n.y), + absZ = std::abs(geoFrame.n.z); + + if (absX > absY && absX > absZ) { axes[0] = 1; axes[1] = 2; - } else if (std::abs(geoFrame.n.y) > std::abs(geoFrame.n.z)) { + } else if (absY > absZ) { axes[0] = 0; axes[1] = 2; } else { axes[0] = 0; axes[1] = 1; @@ -227,6 +230,7 @@ void Intersection::computePartials(const RayDifferential &ray) { A[0][1] = dpdv[axes[0]]; A[1][0] = dpdu[axes[1]]; A[1][1] = dpdv[axes[1]]; + Bx[0] = px[axes[0]] - p[axes[0]]; Bx[1] = px[axes[1]] - p[axes[1]]; By[0] = py[axes[0]] - p[axes[0]]; diff --git a/src/librender/trimesh.cpp b/src/librender/trimesh.cpp index 908b188d..7fdea0d9 100644 --- a/src/librender/trimesh.cpp +++ b/src/librender/trimesh.cpp @@ -170,7 +170,7 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo if (!hasNormals) { for (unsigned int i=0; i