00001 #include <assert.h>
00002 #ifndef NOGL
00003 #include "opengl/glos.h"
00004 #include <gl/gl.h>
00005 #endif
00006 #include <geometry/igs/IGS_Mesh.h>
00007 #include <geometry/igs/IGS_MeshTri.h>
00008 #include <math/Vector4.h>
00009 #include <stdio.h>
00010 #include <string.h>
00011 #include "utility.h"
00012 #include "VrmlCoordinate3.h"
00013 #include "VrmlIndexedFaceSet.h"
00014 #include "VrmlStack.h"
00015
00016
00017
00018
00019
00020
00021 VrmlIndexedFaceSet::VrmlIndexedFaceSet()
00022 :
00023 m_Coords( NULL ),
00024 m_TexCoord( NULL ),
00025 m_NormalsComputed( false )
00026 {
00027 }
00028
00029
00030
00031
00032
00033
00034 VrmlIndexedFaceSet::~VrmlIndexedFaceSet()
00035 {
00036 if( m_Coords != NULL )
00037 {
00038 m_Coords->Release();
00039 m_Coords = NULL;
00040 }
00041
00042 if( m_TexCoord != NULL )
00043 {
00044 m_TexCoord->Release();
00045 m_TexCoord = NULL;
00046 }
00047 }
00048
00049
00050
00051
00052
00053
00054
00055 void VrmlIndexedFaceSet::ComputeNormals( VrmlStack& stack ) const
00056 {
00057 int index = 0;
00058 int size = this->indexes.size();
00059 this->m_Normals.resize( size );
00060 while( index < size )
00061 {
00062
00063 int i0 = this->indexes[ index + 0 ];
00064 int i1 = this->indexes[ index + 1 ];
00065 int i2 = this->indexes[ index + 2 ];
00066
00067 Vector4 v0 = stack.vrmlCoordinate3->GetCoordinate( i0 );
00068 Vector4 v1 = stack.vrmlCoordinate3->GetCoordinate( i1 );
00069 Vector4 v2 = stack.vrmlCoordinate3->GetCoordinate( i2 );
00070
00071 Vector4 n = ( v1 - v0 ).Cross( v2 - v0 );
00072 n.Normalize();
00073
00074 for( index; this->indexes[ index ] != -1; index++ )
00075 {
00076 this->m_Normals[ index ] = n;
00077 }
00078 index++;
00079 }
00080 this->m_NormalsComputed = true;
00081 }
00082
00083
00084
00085
00086
00087
00088
00089 Vector4 VrmlIndexedFaceSet::GetNormal( const int index, VrmlStack& stack ) const
00090 {
00091 if( !m_NormalsComputed )
00092 {
00093 ComputeNormals( stack );
00094 }
00095
00096 return this->m_Normals[ index ];
00097 }
00098
00099
00100
00101
00102
00103
00104 Keyword VrmlIndexedFaceSet::GetKeyword( char*& buffer )
00105 {
00106 char keyword[ 80 ] = "";
00107 VrmlNode::GetKeywordString( buffer, keyword );
00108
00109
00110 if( strcmp( keyword, VrmlKeywordCcw ) == 0 )
00111 {
00112 return VRML_Ccw;
00113 }
00114 if( strcmp( keyword, VrmlKeywordCoordIndex ) == 0 )
00115 {
00116 return VRML_CoordIndex;
00117 }
00118 if( strcmp( keyword, VrmlKeywordMaterialIndex ) == 0 )
00119 {
00120 return VRML_MaterialIndex;
00121 }
00122 if( strcmp( keyword, VrmlKeywordNormalIndex ) == 0 )
00123 {
00124 return VRML_NormalIndex;
00125 }
00126 if( strcmp( keyword, VrmlKeywordTextureCoordIndex ) == 0 )
00127 {
00128 return VRML_TextureCoordIndex;
00129 }
00130
00131 assert( false );
00132 return VRML_Invalid;
00133 }
00134
00135
00136
00137
00138
00139
00140 void VrmlIndexedFaceSet::Parse( char*& buffer )
00141 {
00142 EatWhite( buffer );
00143 while( *buffer != '}' )
00144 {
00145 EatWhite( buffer );
00146 Keyword keyword = VrmlNode::GetKeyword( buffer );
00147 this->ParseSubnode( keyword, buffer );
00148 EatWhite( buffer );
00149 }
00150
00151
00152 EatWhite( buffer );
00153 buffer++;
00154 }
00155
00156
00157
00158
00159
00160
00161 void VrmlIndexedFaceSet::ParseNodeColor( char*& buffer )
00162 {
00163 EatWhite( buffer );
00164 buffer = strchr( buffer, '}' );
00165 buffer++;
00166 }
00167
00168
00169
00170
00171
00172
00173 void VrmlIndexedFaceSet::ParseNodeCoord( char*& buffer )
00174 {
00175 Keyword keyword = VrmlNode::GetKeyword( buffer );
00176 EatWhite( buffer );
00177 if( ( keyword != VRML_Define ) && ( keyword != VRML_Use ) )
00178 {
00179 buffer++;
00180 }
00181 VrmlNode* node = VrmlNode::ParseNode( keyword, buffer );
00182 assert( m_Coords == NULL );
00183 this->m_Coords = node;
00184 this->m_Coords->AddRef();
00185 }
00186
00187
00188
00189
00190
00191
00192 void VrmlIndexedFaceSet::ParseNodeCoordIndex( char*& buffer )
00193 {
00194 EatWhite( buffer );
00195 assert( *buffer == '[' );
00196 buffer++;
00197 EatWhite( buffer );
00198
00199 while( true )
00200 {
00201 int value = 0;
00202 int number = sscanf( buffer, "%d", &value );
00203 if( number == 1 )
00204 {
00205 indexes.push_back( value );
00206 }
00207
00208 int position = strcspn( buffer, ",]" );
00209 buffer += position;
00210 if( *buffer == ']' )
00211 {
00212 break;
00213 }
00214 assert( *buffer == ',' );
00215 buffer++;
00216 }
00217
00218
00219 buffer++;
00220 }
00221
00222
00223
00224
00225
00226
00227
00228 void VrmlIndexedFaceSet::ParseNodeIgnore( char*& buffer )
00229 {
00230 EatWhite( buffer );
00231 assert( *buffer == '[' );
00232 buffer = strchr( buffer, ']' );
00233 buffer++;
00234 }
00235
00236
00237
00238
00239
00240
00241 void VrmlIndexedFaceSet::ParseNodeMaterialIndex( char*& buffer )
00242 {
00243 EatWhite( buffer );
00244 assert( *buffer == '[' );
00245 buffer++;
00246 EatWhite( buffer );
00247
00248 while( true )
00249 {
00250 int value = 0;
00251 int number = sscanf( buffer, "%d", &value );
00252 if( number == 1 )
00253 {
00254
00255 }
00256
00257 int position = strcspn( buffer, ",]" );
00258 buffer += position;
00259 if( *buffer == ']' )
00260 {
00261 break;
00262 }
00263 assert( *buffer == ',' );
00264 buffer++;
00265 }
00266
00267
00268 buffer++;
00269
00270 }
00271
00272
00273
00274
00275
00276
00277 void VrmlIndexedFaceSet::ParseNodeNormalIndex( char*& buffer )
00278 {
00279 EatWhite( buffer );
00280 assert( *buffer == '[' );
00281 buffer++;
00282 EatWhite( buffer );
00283
00284 while( true )
00285 {
00286 int value = 0;
00287 int number = sscanf( buffer, "%d", &value );
00288 if( number == 1 )
00289 {
00290
00291 }
00292
00293 int position = strcspn( buffer, ",]" );
00294 buffer += position;
00295 if( *buffer == ']' )
00296 {
00297 break;
00298 }
00299 assert( *buffer == ',' );
00300 buffer++;
00301 }
00302
00303 buffer++;
00304 }
00305
00306
00307
00308
00309
00310
00311 void VrmlIndexedFaceSet::ParseNodeTexCoord( char*& buffer )
00312 {
00313 EatWhite( buffer );
00314 Keyword keyword = VrmlNode::GetKeyword( buffer );
00315 EatWhite( buffer );
00316 if( ( keyword != VRML_Define ) && ( keyword != VRML_Use ) )
00317 {
00318 buffer++;
00319 }
00320 VrmlNode* node = VrmlNode::ParseNode( keyword, buffer );
00321 this->m_TexCoord = node;
00322 this->m_TexCoord->AddRef();
00323 }
00324
00325
00326
00327
00328
00329
00330 void VrmlIndexedFaceSet::ParseSubnode( Keyword keyword, char*& buffer )
00331 {
00332 switch( keyword )
00333 {
00334 case VRML_Ccw:
00335 case VRML_ColorPerVertex:
00336 case VRML_Convex:
00337 case VRML_CreaseAngle:
00338 case VRML_Solid:
00339 case VRML_NormalPerVertex:
00340 {
00341
00342 while( buffer[ 0 ] != '\n' )
00343 {
00344 buffer++;
00345 }
00346 break;
00347 }
00348 case VRML_Coord:
00349 {
00350 this->ParseNodeCoord( buffer );
00351 break;
00352 }
00353 case VRML_Color:
00354 case VRML_Normal:
00355 {
00356 ParseNodeColor( buffer );
00357 break;
00358 }
00359 case VRML_CoordIndex:
00360 {
00361 this->ParseNodeCoordIndex( buffer );
00362 break;
00363 }
00364 case VRML_NormalIndex:
00365 {
00366 this->ParseNodeNormalIndex( buffer );
00367 break;
00368 }
00369 case VRML_MaterialIndex:
00370 {
00371 this->ParseNodeMaterialIndex( buffer );
00372 break;
00373 }
00374 case VRML_TexCoord:
00375 {
00376 this->ParseNodeTexCoord( buffer );
00377 break;
00378 }
00379 case VRML_TextureCoordIndex:
00380 case VRML_TexCoordIndex:
00381 case VRML_Vector:
00382 {
00383 this->ParseNodeIgnore( buffer );
00384 break;
00385 }
00386 default:
00387 {
00388 printf( "WARNING: VrmlIndexedFaceSet::ParseSubnode - Don't know how to parse this keyword\n" );
00389 IJG_Assert( false );
00390 break;
00391 }
00392 }
00393 }
00394
00395
00396
00397
00398
00399
00400 void VrmlIndexedFaceSet::Render( VrmlStack& stack ) const
00401 {
00402 if( this->m_Coords != NULL )
00403 {
00404 this->m_Coords->Render( stack );
00405 }
00406 }
00407
00408
00409
00410
00411
00412
00413 void VrmlIndexedFaceSet::RenderOpenGl( VrmlStack& stack ) const
00414 {
00415 #ifndef NOGL
00416 this->Render( stack );
00417
00418
00419
00420 ::glPushMatrix();
00421 double matrixValues[ 16 ];
00422 stack.m_Matrix.GetValuesOpenGl( matrixValues );
00423 ::glMultMatrixd( reinterpret_cast< double* >( matrixValues ) );
00424
00425
00426 int i = 0;
00427 int size = indexes.size();
00428 while( i < size )
00429 {
00430
00431 glBegin( GL_POLYGON );
00432
00433 int index = indexes[ i ];
00434 while( index != -1 )
00435 {
00436
00437 Vector4 n = this->GetNormal( i, stack );
00438 ::glNormal3f( n[ 0 ], n[ 1 ], n[ 2 ] );
00439
00440
00441 Vector4 v = stack.vrmlCoordinate3->GetCoordinate( index );
00442 ::glVertex3f( v[ 0 ], v[ 1 ], v[ 2 ] );
00443 i++;
00444 index = indexes[ i ];
00445 }
00446 i++;
00447 glEnd();
00448 }
00449
00450 ::glPopMatrix();
00451 GLenum errorcode = ::glGetError();
00452 assert( errorcode == GL_NO_ERROR );
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493 #endif
00494 }
00495
00496
00497
00498
00499
00500
00501 IGS_Object* VrmlIndexedFaceSet::RenderToIGS( VrmlStack& stack ) const
00502 {
00503 this->Render( stack );
00504
00505
00506 IGS_Mesh* mesh = new IGS_Mesh;
00507 MeshFacet facet;
00508
00509 int maxIndex = -1;
00510
00511 int i;
00512 for( i = 0; i < this->indexes.size(); i++ )
00513 {
00514 int index = indexes[ i ];
00515 if( index == -1 )
00516 {
00517 mesh->AddFacet( facet );
00518 facet.Clear();
00519 }
00520 else
00521 {
00522 facet.AddVertexIndex( index );
00523 if( index > maxIndex )
00524 {
00525 maxIndex = index;
00526 }
00527 }
00528 }
00529
00530 for( i = 0; i < maxIndex + 1; i++ )
00531 {
00532 assert( stack.vrmlCoordinate3 != NULL );
00533 Vector4 vector = stack.vrmlCoordinate3->GetCoordinate( i );
00534 assert( vector.Magnitude() < 1000.0 );
00535 vector = stack.m_Matrix * vector;
00536 assert( vector.Magnitude() < 1000.0 );
00537 mesh->AddVertexCoordinates( vector );
00538 }
00539
00540
00541 IGS_MeshTri* triangulatedMesh = new IGS_MeshTri( *mesh );
00542 delete mesh;
00543 mesh = NULL;
00544 return triangulatedMesh;
00545 }