basic/geometry/IGS/IGS_Mesh.cpp

Go to the documentation of this file.
00001 #include "IGS_Controller.h"
00002 #include "IGS_Mesh.h"
00003 #include "math/Matrix4x4.h"
00004 #ifndef NOGL
00005 #include "opengl/glos.h"
00006 #include <gl/gl.h>
00007 #endif
00008 #include <stdio.h>
00009 //=============================================================================
00010 // Constructor
00011 //
00012 // Description: Constructor
00013 //=============================================================================
00014 IGS_Mesh::IGS_Mesh()
00015 {
00016 }
00017 
00018 //=============================================================================
00019 // AddEdge
00020 //
00021 // Description: adds an edge to the list of edges
00022 //=============================================================================
00023 int IGS_Mesh::AddEdge( const int v0, const int v1 )
00024 {
00025         int vertex0 = min( v0, v1 );
00026         int vertex1 = max( v0, v1 );
00027         MeshEdge m;
00028         m.v0 = vertex0;
00029         m.v1 = vertex1;
00030 
00031         //check if the edge already exists - linear search = slow!
00032         int i;
00033         int esize = this->edges.size();
00034         for( i = 0; i < esize; i++ )
00035         {
00036                 MeshEdge& inarray = edges[ i ];
00037                 if( inarray == m )
00038                 {
00039                         return i;
00040                 }
00041         }
00042 
00043         //we couldn't find the edge
00044         this->edges.push_back( m );
00045         return this->edges.size() - 1;
00046 }
00047 
00048 //=============================================================================
00049 // AddVertex
00050 //
00051 // Description: adds a vertex to the list of points
00052 //=============================================================================
00053 int IGS_Mesh::AddFacet( const MeshFacet& facet )
00054 {
00055         this->facets.push_back( facet );
00056         return facets.size();
00057 }
00058 
00059 //=============================================================================
00060 // ClearSilhouetteEdges
00061 //
00062 // Description: clears all the computed silhouette edges from the last frame
00063 //=============================================================================
00064 void IGS_Mesh::ClearSilhouetteEdges() const
00065 {
00066         int i;
00067         int esize = this->edges.size();
00068         for( i = 0; i < esize; i++ )
00069         {
00070                 const MeshEdge& e = this->edges[ i ];
00071                 e.ClearSilhouetteInfo();
00072         }
00073 }
00074 
00075 //=============================================================================
00076 // ComputeNormalsForFacet
00077 //
00078 // Description: computes the facet normal( flat shading ) for a facet
00079 //=============================================================================
00080 Vector4 IGS_Mesh::ComputeNormalForFacet( const int facetNum ) const
00081 {
00082         const MeshFacet& f = this->facets[ facetNum ];
00083         int size = this->m_Vertexes.size();
00084 
00085         int i0 = f.GetVertexNum( 0 );
00086         int i1 = f.GetVertexNum( 1 );
00087         int i2 = f.GetVertexNum( 2 );
00088 
00089         const Vector4& v0 = this->GetVertex( i0 );
00090         const Vector4& v1 = this->GetVertex( i1 );
00091         const Vector4& v2 = this->GetVertex( i2 );
00092 
00093         Vector4 normal = ( v1 - v0 ).Cross( v2 - v0 );
00094         double mag = normal.Magnitude();
00095         if( mag == 0 )
00096         {
00097                 printf( "IGS_Mesh::ComputeNormalForFacet - found degenerate triangle\n" );
00098         }
00099         else
00100         {
00101                 normal.Normalize();
00102         }
00103         return ( normal );
00104 }
00105 
00106 //=============================================================================
00107 // GetBoundingBox
00108 //
00109 // Description: returns the bounding XYZ coordinates of the mesh
00110 //=============================================================================
00111 void IGS_Mesh::GetBoundingBox( double& xmin, double& xmax, double& ymin, double& ymax, double& zmin, double& zmax ) const
00112 {
00113         //setup the initial min/max
00114         const Vector4& v0 = this->GetVertex( 0 );
00115         xmin = xmax = v0[ 0 ];
00116         ymin = ymax = v0[ 1 ];
00117         zmin = zmax = v0[ 2 ];
00118 
00119         int i;
00120         int vsize = this->m_Vertexes.size();
00121         for( i = 0; i < vsize; i++ )
00122         {
00123                 const Vector4& v = this->GetVertex( i );
00124                 xmin = min( xmin, v[ 0 ] );
00125                 ymin = min( ymin, v[ 1 ] );
00126                 zmin = min( zmin, v[ 2 ] );
00127 
00128                 xmax = max( xmax, v[ 0 ] );
00129                 ymax = max( ymax, v[ 1 ] );
00130                 zmax = max( zmax, v[ 2 ] );
00131         }
00132 }
00133 
00134 //=============================================================================
00135 // Prepare
00136 //
00137 // Description: adds flat shaded normals to the object if it needs them
00138 //=============================================================================
00139 void IGS_Mesh::Prepare( const IGS_Controller& controller )
00140 {
00141         if( IGS_Object::PreparationComplete() )
00142         {
00143                 return;
00144         }
00145         IGS_Object::Prepare( controller );
00146 
00147         //compute normals for each facet
00148         int size = this->facets.size();
00149         int i;
00150         for( i = 0; i < size; i++ )
00151         {
00152                 Vector4 normal = this->ComputeNormalForFacet( i );
00153                 int normalNum = this->AddNormal( normal );
00154                 MeshFacet& f = this->facets[ i ];
00155                 f.ClearNormals();
00156 
00157                 int j;
00158                 int fsize = f.Size();
00159                 for( j = 0; j < fsize; j++ )
00160                 {
00161                         f.AddNormalIndex( normalNum );
00162                 }
00163         }
00164 
00165         //add edges for each facet
00166         for( i = 0; i < size; i++ )
00167         {
00168                 MeshFacet& f = this->facets[ i ];
00169                 int fsize = f.Size();
00170                 int j;
00171                 int v0 = f.GetVertexNum( 0 );
00172                 for( j = 1; j < fsize; j++ )
00173                 {
00174                         int v1 = f.GetVertexNum( j );
00175                         int edgenum = this->AddEdge( v0, v1 );
00176                         f.AddEdgeIndex( edgenum );
00177                         v0 = v1;
00178                 }
00179 
00180                 //don't foget the first/last wrapping
00181                 int v1 = f.GetVertexNum( 0 );
00182                 int edgenum = this->AddEdge( v0, v1 );
00183                 f.AddEdgeIndex( edgenum );
00184         }
00185 }
00186 
00187 //=============================================================================
00188 // Render
00189 //
00190 // Description: renders the mesh to an openGl context
00191 //=============================================================================
00192 void IGS_Mesh::Render( const IGS_Controller& controller ) const
00193 {
00194 #ifndef NOGL
00195         bool renderNormals = controller.SettingRenderNormals();
00196         bool renderSilhouettes = controller.SettingRenderSilhouettes();
00197 
00198         //clear all the silhouette info
00199         if( renderSilhouettes )
00200         {
00201                 this->ClearSilhouetteEdges();
00202         }
00203 
00204         //get the cameraDriection 
00205         Vector4 cameraDirection;
00206         cameraDirection = controller.GetCameraDirection();
00207         //need to transform camera direction by the inverse of the modelview matrix
00208         double modelview[ 16 ];
00209         glGetDoublev(  GL_MODELVIEW_MATRIX , modelview );
00210         Matrix4x4 modelviewMatrix;
00211         modelviewMatrix.SetValues( modelview );
00212         modelviewMatrix = modelviewMatrix.Transpose();
00213         Matrix4x4 iModelviewMatrix = modelviewMatrix;
00214         iModelviewMatrix = iModelviewMatrix.Transpose();
00215         iModelviewMatrix( 3, 0 ) = 0;
00216         iModelviewMatrix( 3, 1 ) = 0;
00217         iModelviewMatrix( 3, 2 ) = 0;
00218         cameraDirection = iModelviewMatrix * cameraDirection;
00219 
00220         GLenum errorcode;
00221 
00222         //render all the polygons
00223         int i;
00224         int fsize = facets.size();
00225         for( i = 0; i < this->facets.size(); i++ )
00226         {
00227                 const MeshFacet& f = facets[ i ];
00228 
00229                 if( renderSilhouettes == true )
00230                 {
00231                         //get the flat normal for this polygon
00232                         int normalNum = f.GetNormalNum( 0 );
00233                         const Vector4& normal = this->GetNormal( normalNum );
00234 
00235                         //transform the current normal by the modelview matrix
00236 
00237                         //compute the dot product of the camera direction and this normal
00238                         double dot = normal.Dot( cameraDirection );
00239                         if( dot > 0 ) 
00240                         {
00241                                 f.MarkFrontFacing( this );
00242                         }
00243                         else
00244                         {
00245                                 f.MarkBackFacing( this );
00246                         }
00247                 }
00248 
00249                 ::glBegin( GL_POLYGON );
00250                 int j;
00251                 int vsize = f.Size();
00252                 for( j = 0; j < vsize; j++ )
00253                 {
00254                         if( renderNormals == true )
00255                         {
00256                                 //submit the normal
00257                                 int normalNum = f.GetNormalNum( j );
00258                                 const Vector4& normal = this->m_Normals[ normalNum ];
00259                                 ::glNormal3d( normal[ 0 ], normal[ 1 ], normal[ 2 ] );
00260                         }
00261 
00262                         if( controller.SettingRenderNormalsAsColors() == true )
00263                         {
00264                                 //rendering normals as colors
00265                                 int normalNum = f.GetNormalNum( j );
00266                                 Vector4 normal = this->m_Normals[ normalNum ];
00267                                 if( controller.SettingNormalsRelativeToCamera() == true )
00268                                 {
00269                                         normal = iModelviewMatrix * normal;
00270 //                                      normal -= cameraDirection;
00271                                 }
00272 
00273                                 double n0 = normal[ 0 ];
00274                                 double n1 = normal[ 1 ];
00275                                 double n2 = normal[ 2 ];
00276                                 n0 = ( n0 + 1.0 ) / 2.0;
00277                                 n1 = ( n1 + 1.0 ) / 2.0;
00278                                 n2 = ( n2 + 1.0 ) / 2.0;
00279 
00280                                 ::glColor3d( n0, n1, n2 );
00281                         }
00282                         if( controller.GetRenderStyle() == G_PHOTOREALISTIC )
00283                         {
00284                                 //IMPROVE: need a better way to specify colors
00285                                 ::glColor3d( 0.5, 0.5, 0.5 );
00286                         }
00287                         else if( controller.GetRenderStyle() == G_COLOR )
00288                         {
00289                                 ::glColor3d( 1.0, 0.0, 0.0 );
00290                         }
00291 
00292                         //submit the vertex
00293                         int vertexNum = f.GetVertexNum( j );
00294                         const Vector4& vertex = this->GetVertex( vertexNum );
00295                         ::glVertex3f( vertex[ 0 ], vertex[ 1 ], vertex[ 2 ] );
00296                 }
00297 
00298                 ::glEnd();
00299                 errorcode = ::glGetError();
00300                 assert( errorcode == GL_NO_ERROR );
00301 
00302         }
00303 
00304         if( renderSilhouettes )
00305         {
00306                 //render all the edges
00307                 float silhouetteEdgeWidth = controller.GetSilhouetteEdgeWidth();
00308                 ::glDepthFunc( GL_LEQUAL );
00309                 ::glLineWidth( silhouetteEdgeWidth );
00310                 ::glEnable( GL_POINT_SMOOTH );
00311                 ::glEnable( GL_LINE_SMOOTH );
00312                 ::glPointSize( silhouetteEdgeWidth );
00313                 ::glDisable( GL_LIGHTING );
00314                 ::glColor3i( 0, 0, 0 );
00315                 errorcode = ::glGetError();
00316                 assert( errorcode == GL_NO_ERROR );
00317 
00318                 ::glBegin( GL_LINES );
00319                 int esize = this->edges.size();
00320                 for( i = 0; i < esize; i++ )
00321                 {
00322                         const MeshEdge& e = this->edges[ i ];
00323                         //draw all the edges marked as silhouette edges
00324                         if( e.IsSilhouette() )
00325                         {
00326                                 int vertex0i = e.v0;
00327                                 int vertex1i = e.v1;
00328                                 Vector4 v0 = this->GetVertex( vertex0i );
00329                                 Vector4 v1 = this->GetVertex( vertex1i );
00330                                 ::glVertex3f( v0[ 0 ], v0[ 1 ], v0[ 2 ] );
00331                                 ::glVertex3f( v1[ 0 ], v1[ 1 ], v1[ 2 ] );
00332                         }
00333                 }
00334                 ::glEnd();
00335                 errorcode = ::glGetError();
00336                 assert( errorcode == GL_NO_ERROR );
00337 
00338                 //render dots where all the edges end 
00339                 ::glBegin( GL_POINTS );
00340                 esize = this->edges.size();
00341                 for( i = 0; i < esize; i++ )
00342                 {
00343                         const MeshEdge& e = this->edges[ i ];
00344                         //draw all the edges marked as silhouette edges
00345                         if( e.IsSilhouette() )
00346                         {
00347                                 int vertex0i = e.v0;
00348                                 int vertex1i = e.v1;
00349                                 Vector4 v0 = this->GetVertex( vertex0i );
00350                                 Vector4 v1 = this->GetVertex( vertex1i );
00351                                 ::glVertex3f( v0[ 0 ], v0[ 1 ], v0[ 2 ] );
00352                                 ::glVertex3f( v1[ 0 ], v1[ 1 ], v1[ 2 ] );
00353                         }
00354                 }
00355                 ::glEnd();
00356                 errorcode = ::glGetError();
00357                 assert( errorcode == GL_NO_ERROR );
00358         }
00359 #endif
00360 }
00361 
00362 //=============================================================================
00363 // constructor
00364 //
00365 // Description: constructor
00366 //=============================================================================
00367 MeshEdge::MeshEdge():
00368         mRenderedForward( false ),
00369         mRenderedReverse( false ),
00370         mTimesRendered( 0 )
00371 {
00372 }
00373 
00374 //=============================================================================
00375 // operator==
00376 //
00377 // Description: comparison on two mesh edges
00378 //=============================================================================
00379 bool MeshEdge::operator==( const MeshEdge& right ) const
00380 {
00381         if( v0 != right.v0 )
00382         {
00383                 return false;
00384         }
00385         if( v1 != right.v1 )
00386         {
00387                 return false;
00388         }
00389         return true;
00390 }
00391 
00392 //=============================================================================
00393 // ClearSilhouetteInfo
00394 //
00395 // Description: removes all cached silhouete info
00396 //=============================================================================
00397 void MeshEdge::ClearSilhouetteInfo() const
00398 {
00399         this->mTimesRendered = 0;
00400         this->mRenderedForward = false;
00401         this->mRenderedReverse = false;
00402 }
00403 
00404 //=============================================================================
00405 // IsSilhouette
00406 //
00407 // Description: determines if an edge has been flagged as a silhouette or not
00408 //=============================================================================
00409 bool MeshEdge::IsSilhouette() const
00410 {
00411         if( ( this->mRenderedForward == true ) && ( this->mRenderedReverse == true ) )
00412         {
00413                 return true;
00414         }
00415         if( this->mTimesRendered != 2 )
00416         {
00417 //              assert( this->mTimesRendered == 2 );
00418                 return true;
00419         }
00420         return false;
00421 }
00422 
00423 //=============================================================================
00424 // MarkFrontFacing
00425 //
00426 // Description: marks an edge as front facing
00427 //=============================================================================
00428 void MeshEdge::MarkFrontFacing() const
00429 {
00430         this->mTimesRendered++;
00431         this->mRenderedForward = true;
00432 }
00433 
00434 //=============================================================================
00435 // MarkBackFacing
00436 //
00437 // Description: marks an edge as back facing
00438 //=============================================================================
00439 void MeshEdge::MarkBackFacing() const
00440 {
00441         this->mTimesRendered++;
00442         this->mRenderedReverse = true ;
00443 }
00444 
00445 
00446 //=============================================================================
00447 // AddEdgeIndex
00448 //
00449 // Description: adds an edge index to this facet of a mesh
00450 //=============================================================================
00451 void MeshFacet::AddEdgeIndex( const int index )
00452 {
00453         //check to see if this edge already exists
00454         int i;
00455         int esize = this->edgeNums.size();
00456         for( i = 0; i < esize; i++ )
00457         {
00458                 int inarray = this->edgeNums[ i ];
00459                 if( index == inarray )
00460                 {
00461                         return;
00462                 }
00463         }
00464 
00465         this->edgeNums.push_back( index );       
00466 }
00467 
00468 //=============================================================================
00469 // AddNormalIndex
00470 //
00471 // Description: adds a normal index to a facet
00472 //=============================================================================
00473 void MeshFacet::AddNormalIndex( const int index )
00474 {
00475         this->normalNums.push_back( index );
00476 }
00477 
00478 //=============================================================================
00479 // AddVertexIndex
00480 //
00481 // Description: adds a vertex index to a facet
00482 //=============================================================================
00483 void MeshFacet::AddVertexIndex( const int index )
00484 {
00485         this->vertexNums.push_back( index );
00486 }
00487 
00488 //=============================================================================
00489 // Clear
00490 //
00491 // Description: clears all the data out of the facet
00492 //=============================================================================
00493 void MeshFacet::Clear()
00494 {
00495         this->vertexNums.clear();
00496 }
00497 
00498 //=============================================================================
00499 // ClearNormals
00500 //
00501 // Description: clears all the data about the normals
00502 //=============================================================================
00503 void MeshFacet::ClearNormals()
00504 {
00505         this->normalNums.clear();
00506         this->normalNums.reserve( this->Size() );
00507 }
00508 
00509 //=============================================================================
00510 // GetNormalNum
00511 //
00512 // Description: gets the index of thr normal for vertex i
00513 //=============================================================================
00514 int MeshFacet::GetNormalNum( const int i ) const
00515 {
00516         return this->normalNums[ i ];
00517 }
00518 
00519 //=============================================================================
00520 // GetVertexNum
00521 //
00522 // Description: gets the index of the vertex for vertex i
00523 //=============================================================================
00524 int MeshFacet::GetVertexNum( const int i ) const
00525 {
00526         return this->vertexNums[ i ];
00527 }
00528 
00529 //=============================================================================
00530 // MarkFrontFacing
00531 //
00532 // Description: marks all the edges associated with this mesh as being front 
00533 //                              facing
00534 //=============================================================================
00535 void MeshFacet::MarkFrontFacing( const IGS_Mesh* parent ) const 
00536 {
00537         int i;
00538         int esize = this->edgeNums.size();
00539         int vsize = this->vertexNums.size();
00540         for( i = 0; i < esize; i++ )
00541         {
00542                 int index = this->edgeNums[ i ];
00543                 parent->edges[ index ].MarkFrontFacing();
00544         }
00545 }
00546 
00547 //=============================================================================
00548 // MarkBackFacing
00549 //
00550 // Description: marks all the edges associated with this mesh as being front 
00551 //                              facing
00552 //=============================================================================
00553 void MeshFacet::MarkBackFacing( const IGS_Mesh* parent ) const
00554 {
00555         int i;
00556         int esize = this->edgeNums.size();
00557         int vsize = this->vertexNums.size();
00558         for( i = 0; i < esize; i++ )
00559         {
00560                 int index = this->edgeNums[ i ];
00561                 parent->edges[ index ].MarkBackFacing();
00562         }
00563 }
00564 
00565 
00566 //=============================================================================
00567 // Size
00568 //
00569 // Description: determines how many verteces are int this facet
00570 //=============================================================================
00571 int MeshFacet::Size() const
00572 {
00573         return this->vertexNums.size();
00574 }
00575 
00576 

Generated on Sat Apr 1 21:30:32 2006 for Motion Planning Kernel by  doxygen 1.4.6-NO