Commit 02d59e21 authored by Romain Pacanowski's avatar Romain Pacanowski

code refactoring

parent 4ca60bd0
...@@ -88,49 +88,13 @@ _Mesh<VEC3_TYPE>::generateTangentsPerVertex( std::vector<VEC3_TYPE> const & vert ...@@ -88,49 +88,13 @@ _Mesh<VEC3_TYPE>::generateTangentsPerVertex( std::vector<VEC3_TYPE> const & vert
std::vector<VEC3_TYPE> const & normals, std::vector<VEC3_TYPE> const & normals,
std::vector<VEC3_TYPE> & tangents ) std::vector<VEC3_TYPE> & tangents )
{ {
tangents.clear();
//TODO use logging system //TODO use logging system
//std::cout << " [INFO] COMPUTING INTIAL TANGENTS FROM NORMALS " << std::endl; std::cout << " [INFO] COMPUTING INTIAL TANGENTS FROM NORMALS " << std::endl;
computeTangents( vertices, normals, tangents);
// std::cout << "[INFO] Tangents computed " << std::endl;
for( unsigned int i=0; i < vertices.size(); i++)
{
//Variant 1: A more robust strategy than just assigning a fixed value
//tangents.push_back( vertices[i].generateOrthogonal() );
//Variant 2:
// TODO: Test it
VEC3_TYPE const Y( 0.0, 1.0, 0.0);
//Variant 3: TODO http://www.imm.dtu.dk/~jerf/papers/abstracts/onb.html
//If the normal is colinear to Y then the following code will not work
double dot_Y_N = Y.dot(normals[i]);
if ( dot_Y_N >= 1.0 || dot_Y_N <= -1.0 )
{
VEC3_TYPE const new_tangent(1.0,0.0,0.0);
tangents.push_back( new_tangent );
}
else
{
VEC3_TYPE const new_tangent = (Y - Y.dot(normals[i])*normals[i]).normalize();
if (new_tangent.isInfOrNan() )
{
//TODO use logging system
//std::cout << " normals[i] = " << normals[i] << std::endl;
assert(0);
}
tangents.push_back( new_tangent );
}
}
} }
template< class VEC3_TYPE > template< class VEC3_TYPE >
...@@ -394,6 +358,7 @@ template< class VEC3_TYPE > ...@@ -394,6 +358,7 @@ template< class VEC3_TYPE >
void void
_Mesh<VEC3_TYPE>::checkNormalTangentOrthogonality( ) _Mesh<VEC3_TYPE>::checkNormalTangentOrthogonality( )
{ {
#define MRF_GEOM_MESH_DEBUG
using namespace std; using namespace std;
unsigned int nb_invalid_tangents =0; unsigned int nb_invalid_tangents =0;
unsigned int nb_invalid_normals =0; unsigned int nb_invalid_normals =0;
......
...@@ -201,10 +201,15 @@ class _Mesh : public Intersectable ...@@ -201,10 +201,15 @@ class _Mesh : public Intersectable
/** /**
* @brief Compute Normals from vertices * @brief Compute Normals from vertices
*/ */
static void computeNormals( std::vector<VEC3_TYPE> const & vertices, static void computeNormals( std::vector<VEC3_TYPE> const & vertices,
std::vector< unsigned int> const & faces, std::vector< unsigned int> const & faces,
std::vector<VEC3_TYPE> & normals ); std::vector<VEC3_TYPE> & normals );
static void computeTangents( std::vector<VEC3_TYPE> const & vertices,
std::vector<VEC3_TYPE> const & normals,
std::vector<VEC3_TYPE> & tangents);
/** /**
* @brief Compute Tangents for each vertex using Lengyel’s Method * @brief Compute Tangents for each vertex using Lengyel’s Method
* *
...@@ -266,7 +271,6 @@ class _Mesh : public Intersectable ...@@ -266,7 +271,6 @@ class _Mesh : public Intersectable
template< typename T > template< typename T >
inline VEC3_TYPE computeTangentFromTensor( mrf::math::Mat3<T> const & tenseur, VEC3_TYPE const & init_tangent ) const; inline VEC3_TYPE computeTangentFromTensor( mrf::math::Mat3<T> const & tenseur, VEC3_TYPE const & init_tangent ) const;
}; };
//Define Here the //Define Here the
...@@ -312,14 +316,14 @@ operator<<( std::ostream & os, _Mesh<VEC3_TYPE> const & mesh ) ...@@ -312,14 +316,14 @@ operator<<( std::ostream & os, _Mesh<VEC3_TYPE> const & mesh )
} }
template< class VEC3_TYPE > template< class VEC3_TYPE >
void void
_Mesh<VEC3_TYPE>::computeNormals( std::vector<VEC3_TYPE> const & vertices, _Mesh<VEC3_TYPE>::computeNormals( std::vector<VEC3_TYPE> const & vertices,
std::vector< unsigned int> const & faces, std::vector< unsigned int> const & faces,
std::vector<VEC3_TYPE> & normals ) std::vector<VEC3_TYPE> & normals )
{ {
using namespace mrf::math; using namespace mrf::math;
normals.resize(vertices.size() ); normals.resize(vertices.size() );
#pragma omp parallel for #pragma omp parallel for
...@@ -330,50 +334,118 @@ _Mesh<VEC3_TYPE>::computeNormals( std::vector<VEC3_TYPE> const & vertices, ...@@ -330,50 +334,118 @@ _Mesh<VEC3_TYPE>::computeNormals( std::vector<VEC3_TYPE> const & vertices,
unsigned int const num_faces = faces.size()/3; unsigned int const num_faces = faces.size()/3;
// TODO Open MP // TODO Open MP
#pragma omp parallel for default(none) shared(normals,faces,vertices) #pragma omp parallel for default(none) shared(normals,faces,vertices,std::cout) num_threads(1)
for( unsigned int f=0; f < num_faces; f++ ) for( unsigned int f=0; f < num_faces; f++ )
{ {
unsigned int const i1 = faces[3*f]; unsigned int const i1 = faces[3*f];
unsigned int const i2 = faces[3*f+1]; unsigned int const i2 = faces[3*f+1];
unsigned int const i3 = faces[3*f+2]; unsigned int const i3 = faces[3*f+2];
Vec3f const & a = vertices[i1]; VEC3_TYPE const & a = vertices[i1];
Vec3f const & b = vertices[i2]; VEC3_TYPE const & b = vertices[i2];
Vec3f const & c = vertices[i3]; VEC3_TYPE const & c = vertices[i3];
Vec3f const ab = (b - a); VEC3_TYPE const ab = (b - a);
Vec3f const ac = (c - a); VEC3_TYPE const ac = (c - a);
Vec3f const triangle_normal = ab.cross(ac); VEC3_TYPE const triangle_normal = ab.cross(ac);
#ifdef MRF_MESH_DEBUG
double const sqr_length = triangle_normal.sqrLength();
if( std::abs(sqr_length) < 0.00000001)
{
std::cout << " Triangle normal " << triangle_normal << " sqrLength = " << sqr_length << " at vertices " << a << " " << b << " " << c << " from indexes " << i1 << " " << i2 << " " << i3 << std::endl;
}
#endif
#pragma omp atomic update #pragma omp atomic update
normals[i1][0] += triangle_normal.x(); normals[i1][0] += triangle_normal.x();
#pragma omp atomic update
normals[i1][1] += triangle_normal.y(); normals[i1][1] += triangle_normal.y();
#pragma omp atomic update
normals[i1][2] += triangle_normal.z(); normals[i1][2] += triangle_normal.z();
#pragma omp atomic update #pragma omp atomic update
normals[i2][0] += triangle_normal.x(); normals[i2][0] += triangle_normal.x();
#pragma omp atomic update
normals[i2][1] += triangle_normal.y(); normals[i2][1] += triangle_normal.y();
#pragma omp atomic update
normals[i2][2] += triangle_normal.z(); normals[i2][2] += triangle_normal.z();
#pragma omp atomic update #pragma omp atomic update
normals[i3][0] += triangle_normal.x(); normals[i3][0] += triangle_normal.x();
#pragma omp atomic update
normals[i3][1] += triangle_normal.y(); normals[i3][1] += triangle_normal.y();
#pragma omp atomic update
normals[i3][2] += triangle_normal.z(); normals[i3][2] += triangle_normal.z();
} }
//Normalization Pass //Normalization Pass
#pragma omp parallel for unsigned int nb_invalid_normal = 0;
for( unsigned int i=0; i < normals.size(); i++)
#pragma omp parallel for num_threads(1)
for (long unsigned int i = 0; i < normals.size(); i++)
{ {
normals[i].normalize(); double const length = normals[i].length();
normals[i] /= length;
if( normals[i].isInfOrNan() )
{
normals[i] = VEC3_TYPE(0.0, 0.0, 1.0);
#pragma omp atomic update
nb_invalid_normal++;
}
#ifdef MRF_MESH_DEBUG
if( length < 0.000000001)
{
std::cout << " Normals [ " << i << " ] = " << normals[i] << "Could not be normalized with length = " << length << std::endl;
assert(0);
}
#endif
}
std::cout << " Number of invalid normals " << nb_invalid_normal << " over " << normals.size() << " i.e., " << static_cast<double>(nb_invalid_normal)/normals.size() * 100.0 << " % " << std::endl;
}
template <class VEC3_TYPE>
void
_Mesh<VEC3_TYPE>::computeTangents(std::vector<VEC3_TYPE> const &vertices,
std::vector<VEC3_TYPE> const &normals,
std::vector<VEC3_TYPE> &tangents)
{
tangents.clear();
tangents.resize( vertices.size() );
unsigned int nb_invalid_tangents = 0;
#pragma omp parallel for default(none) shared(tangents, vertices, normals, nb_invalid_tangents)
for (unsigned int i = 0; i < vertices.size(); i++)
{
//Variant 1: A more robust strategy than just assigning a fixed value
tangents[i] = normals[i].generateOrthogonal();
if( tangents[i].isInfOrNan() )
{
tangents[i] = VEC3_TYPE(1.0, 0.0, 0.0);
#pragma omp atomic update
nb_invalid_tangents++;
}
} }
std::cout << " Nb Invalid Tangents : " << nb_invalid_tangents << " i.e., " << static_cast<double>(nb_invalid_tangents) / tangents.size() << "%" << std::endl;
} }
template< class VEC3_TYPE > template< class VEC3_TYPE >
void void
_Mesh<VEC3_TYPE>::computeTangentsFromUV( std::vector<VEC3_TYPE> const & vertices, _Mesh<VEC3_TYPE>::computeTangentsFromUV( std::vector<VEC3_TYPE> const & vertices,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment