3D viewer: Parallelized 3D model vertex normal calculations to use all available CPU cores for significant speedup.

This commit is contained in:
Andrew Zonenberg 2014-08-12 10:51:10 +02:00 committed by Maciej Suminski
commit ff79e4d2ff
1 changed files with 27 additions and 20 deletions

View File

@ -24,13 +24,17 @@
/**
* @file 3d_mesh_model.cpp
* @brief
* @brief
*/
#include <3d_mesh_model.h>
#include <boost/geometry/algorithms/area.hpp>
#ifdef USE_OPENMP
#include <omp.h>
#endif /* USE_OPENMP */
S3D_MESH::S3D_MESH()
{
isPerFaceNormalsComputed = false;
@ -118,21 +122,21 @@ void S3D_MESH::openGL_Render()
for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
{
if( m_MaterialIndex.size() > 1 )
{
{
if( m_Materials )
{
m_Materials->SetOpenGLMaterial( m_MaterialIndex[idx] );
}
}
}
switch( m_CoordIndex[idx].size() )
{
case 3: glBegin( GL_TRIANGLES );break;
case 4: glBegin( GL_QUADS ); break;
default: glBegin( GL_POLYGON ); break;
case 3: glBegin( GL_TRIANGLES );break;
case 4: glBegin( GL_QUADS ); break;
default: glBegin( GL_POLYGON ); break;
}
if( m_PerVertexNormalsNormalized.size() > 0 )
{
@ -167,7 +171,7 @@ void S3D_MESH::openGL_Render()
glNormal3fv( &normal.x );
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
glVertex3fv( &point.x );
}
}
@ -258,7 +262,7 @@ void S3D_MESH::calcPerFaceNormals ()
//DBG( printf("m_CoordIndex.size %u\n", m_CoordIndex.size()) );
//DBG( printf("m_PointNormalized.size %u\n", m_PointNormalized.size()) );
for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
{
@ -307,7 +311,7 @@ void S3D_MESH::calcPerFaceNormals ()
if( haveAlreadyNormals_from_model_file == false )
{
// normalize vertex normal
// normalize vertex normal
float l = glm::length( cross_prod );
if( l > FLT_EPSILON ) // avoid division by zero
@ -331,7 +335,7 @@ void S3D_MESH::calcPerFaceNormals ()
m_PerFaceNormalsNormalized.push_back( cross_prod );
}
}
}
@ -355,13 +359,18 @@ void S3D_MESH::calcPerPointNormals ()
m_PerFaceVertexNormals.clear();
// Pre-allocate space for the entire vector of vertex normals so we can do parallel writes
m_PerFaceVertexNormals.resize( m_CoordIndex.size() );
// for each face A in mesh
#ifdef USE_OPENMP
#pragma omp parallel for
#endif /* USE_OPENMP */
for( unsigned int each_face_A_idx = 0; each_face_A_idx < m_CoordIndex.size(); each_face_A_idx++ )
{
// n = face A facet normal
std::vector< glm::vec3 > face_A_normals;
face_A_normals.clear();
face_A_normals.resize(m_CoordIndex[each_face_A_idx].size());
std::vector< glm::vec3 >& face_A_normals = m_PerFaceVertexNormals[each_face_A_idx];
face_A_normals.resize( m_CoordIndex[each_face_A_idx].size() );
// loop through all 3 vertices
// for each vert in face A
@ -393,16 +402,14 @@ void S3D_MESH::calcPerPointNormals ()
}
}
// normalize vertex normal
// normalize vertex normal
float l = glm::length( face_A_normals[each_vert_A_idx] );
if( l > FLT_EPSILON ) // avoid division by zero
{
face_A_normals[each_vert_A_idx] /= l;
}
}
m_PerFaceVertexNormals.push_back( face_A_normals );
}
}
}