feature to track down use of unitialized values (initialize vectors etc. with NaNs if a compile-time flag is set)

metadata
Wenzel Jakob 2010-09-20 20:50:30 +02:00
parent 5128b77436
commit 686030ef7e
5 changed files with 46 additions and 10 deletions

View File

@ -39,7 +39,11 @@ template <typename T> 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<double>::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 <typename T> 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<double>::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 <typename T> 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<double>::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) { }

View File

@ -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<SPECTRUM_SAMPLES; i++)
s[i] = std::numeric_limits<double>::quiet_NaN();
}
#endif
/// Create a new spectral power distribution with all samples set to the given value
explicit inline Spectrum(Float v) {

View File

@ -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<double>::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<double>::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<double>::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) { }

View File

@ -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]];

View File

@ -170,7 +170,7 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo
if (!hasNormals) {
for (unsigned int i=0; i<m_vertexCount; i++)
m_vertexBuffer[i].n = Normal(0.0, 0.0f, 0.0f);
m_vertexBuffer[i].n = Normal(0.0f);
for (unsigned int i=0; i<m_triangleCount; i++) {
const Point &v0 = m_vertexBuffer[m_triangles[i].idx[0]].p;
const Point &v1 = m_vertexBuffer[m_triangles[i].idx[1]].p;
@ -219,11 +219,11 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo
int *sharers = new int[m_vertexCount];
for (unsigned int i=0; i<m_vertexCount; i++) {
m_vertexBuffer[i].dpdu = Vector(0.0, 0.0f, 0.0f);
m_vertexBuffer[i].dpdv = Vector(0.0, 0.0f, 0.0f);
m_vertexBuffer[i].dpdu = Vector(0.0f);
m_vertexBuffer[i].dpdv = Vector(0.0f);
if (m_vertexBuffer[i].n.isZero()) {
zeroNormals++;
m_vertexBuffer[i].n = Normal(1, 0, 0);
m_vertexBuffer[i].n = Normal(1.0f, 0.0f, 0.0f);
}
sharers[i] = 0;
}
@ -290,7 +290,7 @@ void TriMesh::calculateTangentSpaceBasis(bool hasNormals, bool hasTexCoords, boo
m_vertexBuffer[idx2].dpdv += dpdv;
sharers[idx0]++; sharers[idx1]++; sharers[idx2]++;
}
/* Orthogonalization + Normalization pass */
for (unsigned int i=0; i<m_vertexCount; i++) {
Vector dpdu = m_vertexBuffer[i].dpdu;