00001 #include "VStreamLine.h"
00002 #include "glew.h"
00003
00004 VStreamLine::VStreamLine() : mPositionVBOHandle( 0 ), mIndexVBOHandle( 0 )
00005 {
00006
00007 }
00008
00009 VStreamLine::VStreamLine(std::vector<VVector> m_Positions) : mPositionVBOHandle( 0 ), mIndexVBOHandle( 0 )
00010 {
00011
00012 mPositions = m_Positions;
00013
00014 for(int i = 0; i < (int)mPositions.size(); ++i)
00015 {
00016 mIndices.push_back(i);
00017 mTaperFactors.push_back(1.0f);
00018 mTaperVectors.push_back(VVector());
00019 }
00020
00021
00022 }
00023
00024 VStreamLine::VStreamLine(std::vector<VVector> m_Positions, std::vector<float> m_TaperFactors) : mPositionVBOHandle( 0 ), mIndexVBOHandle( 0 )
00025 {
00026
00027 mPositions = m_Positions;
00028 mTaperFactors = m_TaperFactors;
00029
00030 for(int i = 0; i < (int)mPositions.size(); ++i)
00031 {
00032 mIndices.push_back(i);
00033 }
00034
00035
00036 }
00037
00038
00039
00040 void VStreamLine::draw( bool tap, float scale , bool glyph)
00041 {
00042
00043
00044
00045 if( tap )
00046 {
00047 if( glyph )
00048 {
00049 glBegin(GL_TRIANGLES);
00050 for(int i = 0; i < (mPositions.size() - 10) && ( (i + 10) < (int)mPositions.size()); i = i + 10)
00051 {
00052 VVector c1 = mPositions[ i ];
00053 VVector c2 = mPositions[ i + 10 ];
00054
00055 VVector normalVec(-(c2.getY() - c1.getY()), c2.getX() - c1.getX(), 0.0f);
00056 normalVec.normalize();
00057 VVector offset_p1 = normalVec * mTaperFactors[i] * pow( ( scale ) * 2.0f, 3.0f );
00058 VVector offset_p2 = normalVec * mTaperFactors[i + 10] * pow( ( scale ) * 2.0f, 3.0f );
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 VVector p1 = c1;
00082 VVector p2 = c2;
00083
00084 VVector p4 = c2 - offset_p2 * 2.0f;
00085
00086 glColor4f( 1.0f, 0.0f, 0.0f, 1.0f );
00087 glMultiTexCoord2f( GL_TEXTURE0, offset_p1.getX(), offset_p1.getY() );
00088 glMultiTexCoord2f( GL_TEXTURE1, 0.0f, 0.5f );
00089 glVertex3fv( p1.getPtr() );
00090 glMultiTexCoord2f( GL_TEXTURE0, offset_p2.getX(), offset_p2.getY() );
00091 glMultiTexCoord2f( GL_TEXTURE1, 1.0f, 0.5f );
00092 glVertex3fv( p2.getPtr() );
00093
00094
00095
00096
00097 glMultiTexCoord2f( GL_TEXTURE0, -offset_p1.getX(), -offset_p1.getY() );
00098 glMultiTexCoord2f( GL_TEXTURE1, 0.0f, 1.0f );
00099 glVertex3fv( p4.getPtr() );
00100
00101 }
00102 glEnd();
00103 }
00104 else
00105 {
00106 glBegin(GL_QUADS);
00107 for(int i = 0; i < mPositions.size() - 1; i++)
00108 {
00109 VVector offset_p1 = mTaperVectors[ i ] * pow( ( scale ) * 2.0f, 3.0f );
00110 VVector offset_p2 = mTaperVectors[ i + 1 ] * pow( ( scale ) * 2.0f, 3.0f );
00111
00112 VVector c1 = mPositions[ i ];
00113 VVector c2 = mPositions[ i + 1 ];
00114
00115 VVector p1 = c1 - offset_p1;
00116 VVector p2 = c2 - offset_p2;
00117 VVector p3 = c2;
00118 VVector p4 = c1;
00119
00120 glColor4f( 1.0f, 0.0f, 0.0f, 0.0f );
00121 glMultiTexCoord2f( GL_TEXTURE0, offset_p1.getX(), offset_p1.getY() );
00122 glMultiTexCoord2f( GL_TEXTURE1, 0.0f, 0.0f );
00123 glVertex3fv( p1.getPtr() );
00124 glMultiTexCoord2f( GL_TEXTURE0, offset_p2.getX(), offset_p2.getY() );
00125 glMultiTexCoord2f( GL_TEXTURE1, 1.0f, 0.0f );
00126 glVertex3fv( p2.getPtr() );
00127 glColor4f( 1.0f, 0.0f, 0.0f, 1.0f );
00128 glMultiTexCoord2f( GL_TEXTURE0, -offset_p2.getX(), -offset_p2.getY() );
00129 glMultiTexCoord2f( GL_TEXTURE1, 1.0f, 0.5f );
00130 glVertex3fv( p3.getPtr() );
00131 glMultiTexCoord2f( GL_TEXTURE0, -offset_p1.getX(), -offset_p1.getY() );
00132 glMultiTexCoord2f( GL_TEXTURE1, 0.0f, 0.5f );
00133 glVertex3fv( p4.getPtr() );
00134
00135 p1 = c1;
00136 p2 = c2;
00137 p3 = c2 + offset_p2;
00138 p4 = c1 + offset_p1;
00139
00140 glColor4f( 1.0f, 0.0f, 0.0f, 1.0f );
00141 glMultiTexCoord2f( GL_TEXTURE0, offset_p1.getX(), offset_p1.getY() );
00142 glMultiTexCoord2f( GL_TEXTURE1, 0.0f, 0.5f );
00143 glVertex3fv( p1.getPtr() );
00144 glMultiTexCoord2f( GL_TEXTURE0, offset_p2.getX(), offset_p2.getY() );
00145 glMultiTexCoord2f( GL_TEXTURE1, 1.0f, 0.5f );
00146 glVertex3fv( p2.getPtr() );
00147 glColor4f( 1.0f, 0.0f, 0.0f, 0.0f );
00148 glMultiTexCoord2f( GL_TEXTURE0, -offset_p2.getX(), -offset_p2.getY() );
00149 glMultiTexCoord2f( GL_TEXTURE1, 1.0f, 1.0f );
00150 glVertex3fv( p3.getPtr() );
00151 glMultiTexCoord2f( GL_TEXTURE0, -offset_p1.getX(), -offset_p1.getY() );
00152 glMultiTexCoord2f( GL_TEXTURE1, 0.0f, 1.0f );
00153 glVertex3fv( p4.getPtr() );
00154
00155 }
00156 glEnd();
00157 }
00158
00159
00160
00161 }
00162 else
00163 {
00164 if(glyph)
00165 {
00166 glBegin(GL_TRIANGLES);
00167 for(int i = 0; (i < mPositions.size() - 10) && ( (i + 10) < (int)mPositions.size()); i = i + 10)
00168 {
00169 VVector c1 = mPositions[ i ];
00170 VVector c2 = mPositions[ i + 10 ];
00171
00172 VVector normalVec(-(c2.getY() - c1.getY()), c2.getX() - c1.getX(), 0.0f);
00173 normalVec.normalize();
00174 VVector offset_p1 = normalVec * ( scale / 10.0f );
00175 VVector offset_p2 = normalVec * ( scale / 10.0f );
00176
00177 VVector p1 = c1;
00178 VVector p2 = c2;
00179
00180 VVector p4 = c2 - offset_p2 * 2.0f;
00181
00182 glColor4f( 1.0f, 0.0f, 0.0f, 1.0f );
00183 glMultiTexCoord2f( GL_TEXTURE1, 0.0f, 0.0f );
00184 glVertex3fv( p1.getPtr() );
00185 glMultiTexCoord2f( GL_TEXTURE1, 1.0f, 0.0f );
00186 glVertex3fv( p2.getPtr() );
00187 glColor4f( 1.0f, 0.0f, 0.0f, 1.0f );
00188
00189
00190 glMultiTexCoord2f( GL_TEXTURE1, 0.0f, 1.0f );
00191 glVertex3fv( p4.getPtr() );
00192
00193 }
00194 glEnd();
00195 }
00196 else
00197 {
00198 glColor4f( 1.0f, 0.0f, 0.0f, 1.0f );
00199 activateVBO();
00200 glDrawElements(GL_LINE_STRIP, (int) mIndices.size(), GL_UNSIGNED_INT, 0);
00201 deactivateVBO();
00202
00203 }
00204 }
00205
00206
00207
00208
00209 }
00210
00211 void VStreamLine::clearVBO()
00212 {
00213 if( mPositionVBOHandle != 0 )
00214 {
00215 glDeleteBuffersARB( 1, &mPositionVBOHandle );
00216 mPositionVBOHandle = 0;
00217 }
00218 if( mIndexVBOHandle != 0)
00219 {
00220 glDeleteBuffersARB( 1, &mIndexVBOHandle );
00221 mIndexVBOHandle = 0;
00222 }
00223 if( mTaperVBOHandle != 0)
00224 {
00225 glDeleteBuffersARB( 1, &mTaperVBOHandle );
00226 mTaperVBOHandle = 0;
00227 }
00228 }
00229
00230 std::vector< VVector > VStreamLine::getCandidateSeeds( float dsep )
00231 {
00232 std::vector< VVector > cand;
00233
00234 int size = getNumberOfPoints();
00235
00236 if ( size == 0 ) return cand;
00237
00238 int factor = 10;
00239
00240 for(int i = ( size - 2 ) / factor ; i > 1; i--)
00241 {
00242 VVector c1 = mPositions[ i * factor ];
00243 VVector c2 = mPositions[ i * factor - 1 ];
00244
00245 VVector orientation = c2 - c1;
00246 VVector normorient = VVector( - orientation.getY(), orientation.getX(), 0.0f );
00247
00248 normorient.normalize();
00249 normorient = ( normorient ) * dsep;
00250
00251 VVector s1 = c2 + normorient;
00252 VVector s2 = c2 - normorient;
00253
00254 if ( i == ( size - 2 ) / factor )
00255 {
00256 cand.push_back( s1 );
00257 cand.push_back( s2 );
00258 }
00259 else
00260 {
00261 bool distanceok = true;
00262 for ( int j = 0; j < cand.size(); j++ )
00263 {
00264 VVector _pt = cand[ j ];
00265 float tmpDistance = (_pt - s1).getMagnitude();
00266
00267 if ( tmpDistance < dsep )
00268 {
00269 distanceok = false;
00270 break;
00271 }
00272
00273 }
00274
00275 if( distanceok )
00276 {
00277 cand.push_back( s1 );
00278 }
00279
00280 distanceok = true;
00281 for ( int j = 0; j < cand.size(); j++ )
00282 {
00283 VVector _pt = cand[ j ];
00284 float tmpDistance = (_pt - s2).getMagnitude();
00285
00286 if ( tmpDistance < dsep )
00287 {
00288 distanceok = false;
00289 break;
00290 }
00291
00292 }
00293
00294 if( distanceok )
00295 {
00296 cand.push_back( s2 );
00297 }
00298 }
00299
00300 }
00301
00302 return cand;
00303 }
00304
00305 void VStreamLine::computeThicknessCoefficients( float dtest, float dsep, std::vector< VStreamLine > others, int itself, float datasizemax )
00306 {
00307
00308 mTaperVectors.resize( mPositions.size() );
00309 mTaperFactors.resize( mPositions.size() );
00310
00311 for( int h = 0; h < mPositions.size(); h++ )
00312 {
00313 float mind = 10000.0f;
00314
00315 for ( int j = 0; j < others.size(); j++ )
00316 {
00317
00318 if ( j == itself ) continue;
00319
00320 float d = others[ j ].getMinimalDistance( mPositions[ h ] );
00321
00322 mind = ( d < mind ) ? d : mind;
00323
00324 }
00325
00326 mTaperFactors[ h ] = ( mind >= dsep ) ? 1.0f : ( mind - dtest) / ( dsep - dtest );
00327 mTaperFactors[ h ] /= 18.0f;
00328
00329
00330 }
00331
00332 mTaperVectors[ 0 ] = VVector();
00333 mTaperVectors[ mPositions.size() - 2 ] = VVector();
00334
00335 for( int h = 1; h < mPositions.size() - 1; h++ )
00336 {
00337 VVector c0 = mPositions[ h - 1 ];
00338 VVector c2 = mPositions[ h + 1 ];
00339
00340 VVector orientation = c2 - c0;
00341 VVector normorient = VVector( - orientation.getY(), orientation.getX(), 0.0f );
00342
00343 normorient.normalize();
00344 normorient = ( normorient ) * mTaperFactors[ h ];
00345
00346 mTaperVectors[ h ] = - normorient;
00347
00348 }
00349
00350 }
00351
00352 float VStreamLine::getMinimalDistance( VVector m_Point )
00353 {
00354 float mind;
00355
00356 if ( !mPositions.empty() )
00357 {
00358 mind = ( mPositions[ 0 ] - m_Point ).getMagnitude();
00359 }
00360 else
00361 {
00362
00363 return 100000.0;
00364 }
00365
00366 for ( int i = 1; i < mPositions.size() /10 ; i++ )
00367 {
00368 float _d = ( mPositions[ i * 10 ] - m_Point ).getMagnitude();
00369
00370 if ( _d < mind )
00371 {
00372
00373 mind = _d;
00374 }
00375 }
00376
00377 return mind;
00378 }
00379
00380 bool VStreamLine::isPointAllowed( VVector m_Point, float m_Epsilon )
00381 {
00382 float pointdistance;
00383 int mindistanceIndex;
00384
00385
00386 for( int i = 0; i < (int)mPositions.size() / 5; ++i )
00387 {
00388 VVector _pt = VVector( mPositions[ 5 * i].getX(), mPositions[ 5 * i ].getY(), mPositions[ 5 * i ].getZ() );
00389 float tmpDistance = (_pt - m_Point).getMagnitude();
00390
00391 if( i == 0 )
00392 {
00393 pointdistance = tmpDistance;
00394 mindistanceIndex = 5 * i;
00395 }
00396 if(tmpDistance < pointdistance)
00397 {
00398 pointdistance = tmpDistance;
00399 mindistanceIndex = 5 * i;
00400 }
00401
00402 if((pointdistance) < m_Epsilon)
00403 {
00404 return false;
00405 }
00406 }
00407
00408
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 return true;
00441 }
00442
00443 bool VStreamLine::isPointAllowed( VVector m_Point, float m_Epsilon, float * m_Distance )
00444 {
00445 float pointdistance;
00446 int mindistanceIndex;
00447
00448 m_Distance[ 0 ] = m_Epsilon * 2.0f;
00449
00450 for( int i = 0; i < (int)mPositions.size() / 5; ++i )
00451 {
00452 VVector _pt = VVector( mPositions[ 5 * i].getX(), mPositions[ 5 * i ].getY(), mPositions[ 5 * i ].getZ() );
00453 float tmpDistance = (_pt - m_Point).getMagnitude();
00454
00455 if( i == 0 )
00456 {
00457 pointdistance = tmpDistance;
00458 mindistanceIndex = 5 * i;
00459 }
00460 if(tmpDistance < pointdistance)
00461 {
00462 pointdistance = tmpDistance;
00463 mindistanceIndex = 5 * i;
00464 }
00465
00466 if((pointdistance) < m_Epsilon)
00467 {
00468 return false;
00469 }
00470 }
00471
00472 m_Distance[ 0 ] = pointdistance;
00473 return true;
00474 }
00475
00476 bool VStreamLine::interSectsStreamLine( VVector m_Point1, VVector m_Point2 )
00477 {
00478 float x1 = m_Point1.getX();
00479 float x2 = m_Point2.getX();
00480
00481 float y1 = m_Point1.getY();
00482 float y2 = m_Point2.getY();
00483
00484 float x3, x4;
00485 float y3, y4;
00486
00487 for( int i = 0; i < (int)mPositions.size() - 1; ++i )
00488 {
00489 x3 = mPositions[i].getX();
00490 y3 = mPositions[i].getY();
00491
00492 x4 = mPositions[i+1].getX();
00493 y4 = mPositions[i+1].getY();
00494
00495 float s = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3))
00496 / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
00497
00498 float t = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3))
00499 / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
00500
00501 if( (0.0f <= s) && (s <= 1.0f) &&
00502 (0.0f <= t) && (t <= 1.0f) )
00503 {
00504 return true;
00505 }
00506 }
00507
00508 return false;
00509 }
00510
00511 void VStreamLine::loadStreamLine( FILE * m_FilePointer )
00512 {
00513 clearVBO();
00514 mPositions.clear();
00515 mIndices.clear();
00516 mTaperFactors.clear();
00517 mTaperVectors.clear();
00518
00519 int numPoints;
00520 fread( &numPoints, sizeof(int),1, m_FilePointer );
00521
00522 std::vector<float> input;
00523 input.resize(numPoints * 5);
00524
00525 fread( &input[0], sizeof(float), numPoints * 5, m_FilePointer);
00526
00527 for ( int i = 0; i < numPoints * 5; i = i + 5 )
00528 {
00529 VVector newPos(input[i], input[i + 1], 0.0f);
00530 mPositions.push_back(newPos);
00531 mTaperFactors.push_back(input[i + 2]);
00532 VVector taperVec(input[ i + 3], input[ i + 4], 0.0f);
00533 mTaperVectors.push_back(taperVec);
00534 }
00535
00536 for(int i = 0; i < (int)mPositions.size(); ++i)
00537 {
00538 mIndices.push_back(i);
00539 }
00540
00541 generateVBO();
00542 }
00543
00544 void VStreamLine::saveStreamLine( FILE * m_FilePointer )
00545 {
00546 int numPoints = (int)mPositions.size();
00547
00548 fwrite(reinterpret_cast<char*>(&numPoints), sizeof(unsigned int), 1, m_FilePointer);
00549
00550 std::vector<float> output;
00551
00552 for ( int i = 0; i < numPoints; ++i )
00553 {
00554 output.push_back(mPositions[i].getX());
00555 output.push_back(mPositions[i].getY());
00556 output.push_back(mTaperFactors[i]);
00557 output.push_back(mTaperVectors[i].getX());
00558 output.push_back(mTaperVectors[i].getY());
00559 }
00560
00561 fwrite(reinterpret_cast<char*>(&output[0]), sizeof(float), 5 * numPoints, m_FilePointer);
00562 }
00563
00564
00565 void VStreamLine::generateVBO()
00566 {
00567 glGenBuffersARB( 1, &(mPositionVBOHandle) );
00568 glBindBufferARB( GL_ARRAY_BUFFER_ARB, mPositionVBOHandle );
00569 glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(float) * (int)mPositions.size() * 3, &(mPositions[0]), GL_STATIC_DRAW_ARB );
00570
00571 glGenBuffersARB( 1, &(mIndexVBOHandle) );
00572 glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, mIndexVBOHandle );
00573 glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(int) * (int)mIndices.size(), &(mIndices[0]), GL_STATIC_DRAW_ARB );
00574
00575 glGenBuffersARB(1, &( mTaperVBOHandle) );
00576 glBindBufferARB(GL_ARRAY_BUFFER_ARB, mTaperVBOHandle);
00577 glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(float) * (int)(mTaperVectors.size()) * 3, &(mTaperVectors[0]), GL_STATIC_DRAW_ARB);
00578
00579 glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, 0 );
00580 glBindBufferARB( GL_ARRAY_BUFFER, 0 );
00581 }
00582
00583 void VStreamLine::activateVBO()
00584 {
00585
00586
00587 glActiveTextureARB( GL_TEXTURE0_ARB );
00588 glClientActiveTextureARB( GL_TEXTURE0_ARB );
00589 glEnableClientState( GL_TEXTURE_COORD_ARRAY_EXT );
00590 glBindBuffer( GL_ARRAY_BUFFER, mTaperVBOHandle );
00591 glTexCoordPointerEXT( 3, GL_FLOAT, 0, 0, 0 );
00592
00593 glEnableClientState( GL_VERTEX_ARRAY );
00594 glBindBuffer( GL_ARRAY_BUFFER, mPositionVBOHandle );
00595 glVertexPointer( 3, GL_FLOAT, 0, 0 );
00596
00597 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexVBOHandle);
00598 }
00599
00600 void VStreamLine::deactivateVBO()
00601 {
00602 glDisableClientState(GL_VERTEX_ARRAY);
00603
00604 glClientActiveTextureARB(GL_TEXTURE0_ARB);
00605 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00606
00607 glBindBufferARB(GL_ARRAY_BUFFER, 0);
00608 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
00609 }
00610