Growth description using a set of triangles moving. More...
#include <algorithms/triangle_growth.h>
Public Types | |
typedef TriangleSurface::Position | Position |
Public Member Functions | |
std::vector< Position > | contour () const |
Return a description of the contour of the surface independent of the time. | |
double | endTime () const |
Returns the end time. | |
const QString & | errorMsg () const |
If the object is not valid, return the reason. | |
template<typename Model , typename ComplexGraph > | |
bool | init (const ComplexGraph &cplx, std::vector< double > times, Model *model) |
Initialize the growth from a data structure. | |
bool | readOBJs (const std::string &desc_filepath) |
Initialize the growth with a description file or a directory. | |
bool | readOBJs (QString desc_filepath) |
Initialize the growth with a description file or a directory. | |
void | setTime (double t) |
Set the current time. | |
size_t | size () const |
Returns the number of time points. | |
double | startTime () const |
Returns the start time. | |
TriangleSurface | surface (double time) |
Return the surface at the current time. | |
const TriangleSurface & | surface () const |
Return the surface at the current time. | |
double | time () const |
Return the current time. | |
int | timePos () const |
Return the current position in the time scale. | |
bool | valid () const |
Protected Types | |
typedef vvcomplex::VVComplexGraph < Cell, Vertex > | CellComplex |
Protected Member Functions | |
EXPORT_COMPLEX_VERTICES (CellComplex) | |
void | setSurface (TriangleSurface &s) const |
Position | vertexPosition (const junction &j) const |
Protected Attributes | |
QString | _errorMsg |
double | _time |
int | _time_pos |
bool | _valid |
std::vector< cell > | faces |
CellComplex | S |
std::vector< double > | times |
TriangleSurface | TS |
std::vector< junction > | vertices |
Growth description using a set of triangles moving.
The number of points and triangles must be constant for this class to work. Also, the different OBJ files must keep the same indices for the same points.
Definition at line 205 of file triangle_growth.h.
std::vector< TriangleGrowth::Position > algorithms::TriangleGrowth::contour | ( | ) | const |
Return a description of the contour of the surface independent of the time.
Definition at line 912 of file triangle_growth.cpp.
References algorithms::TriangleSurface::contour(), and surface().
00913 { 00914 return surface().contour(); 00915 }
double algorithms::TriangleGrowth::endTime | ( | ) | const [inline] |
Returns the end time.
Definition at line 286 of file triangle_growth.h.
const QString& algorithms::TriangleGrowth::errorMsg | ( | ) | const [inline] |
If the object is not valid, return the reason.
Definition at line 271 of file triangle_growth.h.
bool algorithms::TriangleGrowth::init | ( | const ComplexGraph & | cplx, | |
std::vector< double > | times, | |||
Model * | model | |||
) | [inline] |
Initialize the growth from a data structure.
cplx | Graph complex representing the triangulated mesh | |
times | List of key frame times, ordered from the earliest to the latest (i.e. times must be strictely increasing). | |
model | Object able interrogated for informations about vertices and cells. |
The Model class is suppose to include a few methods:
Returns the position of the junction v at the specified key frame.
Returns the normal to the junction v at the specified key frame.
Definition at line 343 of file triangle_growth.h.
References graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::clear(), forall, graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::insert(), graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::insertEdge(), graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::reference(), graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::spliceAfter(), and graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::valence().
00344 { 00345 typedef typename ComplexGraph::cell ext_cell; 00346 typedef typename ComplexGraph::junction ext_junction; 00347 00348 //QTextStream out(stdout); 00349 00350 _valid = false; 00351 00352 std::unordered_map<ext_cell, cell> cell_convert; 00353 std::unordered_map<ext_junction, junction> junction_convert; 00354 00355 faces.clear(); 00356 vertices.clear(); 00357 S.clear(); 00358 00359 //out << "Init the structure " << flush; 00360 00361 if(_times.empty()) 00362 return false; 00363 size_t nb_times = _times.size(); 00364 times = _times; 00365 _time = times.front(); 00366 _time_pos = 0; 00367 faces.resize(cplx.nb_cells(), cell(0)); 00368 vertices.resize(cplx.nb_junctions(), junction(0)); 00369 00370 //out << "done" << endl; 00371 00372 //out << "Create the faces " << flush; 00373 00374 // Create faces 00375 int i = 0; 00376 forall(const ext_cell& ec, cplx.cells()) 00377 { 00378 //out << '.' << flush; 00379 cell c; 00380 c->id = i; 00381 faces[i] = c; 00382 S.insert(c); 00383 cell_convert[ec] = c; 00384 i++; 00385 } 00386 //out << " OK" << endl; 00387 00388 //out << "Create the vertices " << flush; 00389 00390 // Create vertices 00391 i = 0; 00392 forall(const ext_junction& ej, cplx.junctions()) 00393 { 00394 //out << '.' << flush; 00395 junction j; 00396 j->id = i; 00397 j->pos.resize(nb_times); 00398 j->normal.resize(nb_times); 00399 for(size_t t = 0 ; t < nb_times ; ++t) 00400 { 00401 j->pos[t] = model->position(ej, t); 00402 j->normal[t] = model->normal(ej, t); 00403 } 00404 vertices[i] = j; 00405 S.insert(j); 00406 junction_convert[ej] = j; 00407 i++; 00408 } 00409 //out << " OK" << endl; 00410 00411 //out << "Copy faces neighborhood " << flush; 00412 00413 // Copy faces neighborhood 00414 forall(const ext_cell& ec, cplx.cells()) 00415 { 00416 //out << '.' << flush; 00417 const cell& c = S.reference(cell_convert[ec]); 00418 forall(const ext_junction& ej, cplx.neighbors(ec)) 00419 { 00420 junction j = junction_convert[ej]; 00421 if(S.valence(c) < 2) 00422 { 00423 S.insertEdge(c, j); 00424 } 00425 else 00426 { 00427 junction pj = junction_convert[cplx.prevTo(ec, ej)]; 00428 S.spliceAfter(c, pj, j); 00429 } 00430 } 00431 vvassert_msg(S.valence(c) == 3, QString("Face %1 has %2 junctions instead of 3").arg(c->id).arg(S.valence(c))); 00432 } 00433 //out << " OK" << endl; 00434 00435 //out << "Copy faces neighborhood " << flush; 00436 // Copy vertices neighborhood 00437 forall(const ext_junction& ej, cplx.junctions()) 00438 { 00439 //out << '.' << flush; 00440 const junction& j = S.reference(junction_convert[ej]); 00441 forall(const ext_cell& ec, cplx.neighbors(ej)) 00442 { 00443 cell c = cell_convert[ec]; 00444 if(S.valence(j) < 2) 00445 { 00446 S.insertEdge(j, c); 00447 } 00448 else 00449 { 00450 cell pc = cell_convert[cplx.prevTo(ej, ec)]; 00451 S.spliceAfter(j, pc, c); 00452 } 00453 } 00454 } 00455 //out << " OK" << endl; 00456 00457 _valid = true; 00458 return true; 00459 }
bool algorithms::TriangleGrowth::readOBJs | ( | const std::string & | desc_filepath | ) | [inline] |
Initialize the growth with a description file or a directory.
Definition at line 238 of file triangle_growth.h.
References QString::fromStdString(), and readOBJs().
Referenced by readOBJs().
00238 { return readOBJs(QString::fromStdString(desc_filepath)); }
bool algorithms::TriangleGrowth::readOBJs | ( | QString | desc_filepath | ) |
Initialize the growth with a description file or a directory.
Definition at line 313 of file triangle_growth.cpp.
References QString::arg(), QTextStream::atEnd(), QFile::close(), QFileInfo::dir(), graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::edge(), QDir::exists(), QFileInfo::exists(), QDir::filePath(), forall, graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::iAnyIn(), graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::iEmpty(), QString::indexOf(), graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::iNeighbors(), graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::insert(), graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::insertEdge(), QString::isEmpty(), QFileInfo::isFile(), graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::iValence(), graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::neighbors(), graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::nextTo(), QFile::open(), graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::prevTo(), QTextStream::readLine(), graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::spliceAfter(), graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::spliceBefore(), QString::split(), QDir::toNativeSeparators(), QString::truncate(), and graph::VVBiGraph< Vertex1Content, Vertex2Content, Edge1Content, Edge2Content_, compact >::valence().
00314 { 00315 desc_filepath = QDir::toNativeSeparators(desc_filepath); 00316 _valid = false; 00317 std::vector<QString> data_files; 00318 std::vector<double> data_scales; 00319 times.clear(); 00320 QFileInfo info(desc_filepath); 00321 if(not (info.exists() and info.isFile())) 00322 { 00323 if(info.exists()) 00324 _errorMsg = QString(tr("Path '%1' exists but is not a file.")).arg(desc_filepath); 00325 else 00326 _errorMsg = QString(tr("Path '%1' does not exists.")).arg(desc_filepath); 00327 return false; 00328 } 00329 QDir main_dir = info.dir(); 00330 QFile desc_file(desc_filepath); 00331 if(!desc_file.open(QIODevice::ReadOnly)) 00332 { 00333 _errorMsg = QString(tr("Error while opening file '%1':\n%2")).arg(desc_filepath).arg(desc_file.errorString()); 00334 return false; 00335 } 00336 QTextStream desc(&desc_file); 00337 double current_time = -HUGE_VAL; 00338 size_t ln = 0; 00339 while(!desc.atEnd()) 00340 { 00341 QString line = desc.readLine().simplified(); 00342 int comment = line.indexOf('#'); 00343 if(comment != -1) 00344 line.truncate(comment); 00345 ln++; 00346 if(!line.isEmpty()) 00347 { 00348 QString data_file; 00349 double data_time; 00350 double data_scale = 1; 00351 QStringList fields = line.split(" "); 00352 bool ok; 00353 switch(fields.size()) 00354 { 00355 case 3: 00356 data_scale = fields[2].toDouble(&ok); 00357 if(!ok) 00358 { 00359 _errorMsg = QString(tr("Line %1 of file '%2', the scaling field cannot be parsed as a double.")).arg(ln).arg(desc_filepath); 00360 return false; 00361 } 00362 if(data_scale <= 0) 00363 { 00364 _errorMsg = QString(tr("Line %1 of file '%2', the scaling field must be strictly positive.")).arg(ln).arg(desc_filepath); 00365 return false; 00366 } 00367 case 2: 00368 data_time = fields[0].toDouble(&ok); 00369 if(!ok) 00370 { 00371 _errorMsg = QString(tr("Line %1 of file '%2', the time field cannot be parsed as a double.")).arg(ln).arg(desc_filepath); 00372 return false; 00373 } 00374 if(data_time <= current_time) 00375 { 00376 _errorMsg = QString(tr("Line %1 of file '%2', the time field is smaller or equal than the previous one.")).arg(ln).arg(desc_filepath); 00377 desc_file.close(); 00378 return false; 00379 } 00380 data_file = fields[1]; 00381 if(!main_dir.exists(data_file)) 00382 { 00383 _errorMsg = QString(tr("Line %1 of file '%2', the file '%3' does not exist.")).arg(ln).arg(desc_filepath).arg(data_file); 00384 return false; 00385 } 00386 times.push_back(data_time); 00387 data_files.push_back(data_file); 00388 data_scales.push_back(data_scale); 00389 break; 00390 default: 00391 _errorMsg = QString(tr("Line %1 of file '%2' is invalid.")).arg(ln).arg(desc_filepath); 00392 return false; 00393 } 00394 } 00395 } 00396 desc_file.close(); 00397 vertices.clear(); 00398 faces.clear(); 00399 if(times.empty()) 00400 return false; 00401 // Read the first OBJ file to create the cell complex 00402 QString first_filepath = main_dir.filePath(data_files.front()); 00403 _time = times.front(); 00404 _time_pos = 0; 00405 QFile first_file(first_filepath); 00406 if(!first_file.open(QIODevice::ReadOnly)) 00407 { 00408 _errorMsg = QString(tr("Impossible to open file '%1' for reading")).arg(first_filepath); 00409 times.clear(); 00410 return false; 00411 } 00412 ln = 0; 00413 QTextStream first(&first_file); 00414 size_t nb_timepoints = times.size(); 00415 size_t current_normal = 0; 00416 while(!first.atEnd()) 00417 { 00418 QString line = first.readLine().simplified(); 00419 ln++; 00420 int comment = line.indexOf('#'); 00421 if(comment != -1) 00422 line.truncate(comment); 00423 if(!line.isEmpty()) 00424 { 00425 QStringList fields = line.split(' '); 00426 QString field_type = fields[0]; 00427 if(field_type == "v") 00428 { 00429 if(fields.size() != 4) 00430 { 00431 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: vertex position must 3D")).arg(first_filepath).arg(ln); 00432 return false; 00433 } 00434 junction j; 00435 double x,y,z; 00436 bool ok; 00437 x = fields[1].toDouble(&ok); 00438 if(!ok) 00439 { 00440 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: x coordinate is not convertible to a double number")).arg(first_filepath).arg(ln); 00441 return false; 00442 } 00443 y = fields[2].toDouble(&ok); 00444 if(!ok) 00445 { 00446 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: y coordinate is not convertible to a double number")).arg(first_filepath).arg(ln); 00447 return false; 00448 } 00449 z = fields[3].toDouble(&ok); 00450 if(!ok) 00451 { 00452 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: z coordinate is not convertible to a double number")).arg(first_filepath).arg(ln); 00453 return false; 00454 } 00455 j->pos.resize(nb_timepoints, Point3d(x,y,z)); 00456 j->id = (int)vertices.size(); 00457 vertices.push_back(j); 00458 S.insert(j); 00459 } 00460 else if(field_type == "vn") 00461 { 00462 if(current_normal >= vertices.size()) 00463 { 00464 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: the vertex normal is specified before the vertex")).arg(first_filepath).arg(ln); 00465 return false; 00466 } 00467 if(fields.size() != 4) 00468 { 00469 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: vertex normal must 3D")).arg(first_filepath).arg(ln); 00470 return false; 00471 } 00472 double x,y,z; 00473 bool ok; 00474 x = fields[1].toDouble(&ok); 00475 if(!ok) 00476 { 00477 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: x coordinate is not convertible to a double number")).arg(first_filepath).arg(ln); 00478 return false; 00479 } 00480 y = fields[2].toDouble(&ok); 00481 if(!ok) 00482 { 00483 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: y coordinate is not convertible to a double number")).arg(first_filepath).arg(ln); 00484 return false; 00485 } 00486 z = fields[3].toDouble(&ok); 00487 if(!ok) 00488 { 00489 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: z coordinate is not convertible to a double number")).arg(first_filepath).arg(ln); 00490 return false; 00491 } 00492 const junction& j = vertices[current_normal]; 00493 j->normal.resize(nb_timepoints, Point3d(x,y,z)); 00494 } 00495 else if(field_type == "f") 00496 { 00497 if(fields.size() != 4) 00498 { 00499 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: face must be a triangle")).arg(first_filepath).arg(ln); 00500 return false; 00501 } 00502 int i1, i2, i3; 00503 bool ok; 00504 i1 = fields[1].toInt(&ok); 00505 if(!ok) 00506 { 00507 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: first vertex index is not an integer")).arg(first_filepath).arg(ln); 00508 return false; 00509 } 00510 if(i1 > (int)vertices.size()) 00511 { 00512 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: first vertex index doesn't reference an existing vertex")).arg(first_filepath).arg(ln); 00513 return false; 00514 } 00515 i2 = fields[2].toInt(&ok); 00516 if(!ok) 00517 { 00518 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: second vertex index is not an integer")).arg(first_filepath).arg(ln); 00519 return false; 00520 } 00521 if(i2 > (int)vertices.size()) 00522 { 00523 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: second vertex index doesn't reference an existing vertex")).arg(first_filepath).arg(ln); 00524 return false; 00525 } 00526 i3 = fields[3].toInt(&ok); 00527 if(!ok) 00528 { 00529 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: third vertex index is not an integer")).arg(first_filepath).arg(ln); 00530 return false; 00531 } 00532 if(i3 > (int)vertices.size()) 00533 { 00534 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: third vertex index doesn't reference an existing vertex")).arg(first_filepath).arg(ln); 00535 return false; 00536 } 00537 cell f; 00538 f->id = (int)faces.size(); 00539 S.insert(f); 00540 junction v1 = vertices[i1-1]; 00541 junction v2 = vertices[i2-1]; 00542 junction v3 = vertices[i3-1]; 00543 S.insertEdge(f, v1); 00544 S.insertEdge(f, v2); 00545 S.spliceAfter(f, v2, v3); 00546 faces.push_back(f); 00547 } 00548 } 00549 } 00550 first_file.close(); 00551 // Read the other positions 00552 for(size_t i = 1 ; i < times.size() ; ++i) 00553 { 00554 QString filepath = main_dir.filePath(data_files[i]); 00555 QFile file(filepath); 00556 if(!file.open(QIODevice::ReadOnly)) 00557 { 00558 _errorMsg = QString(tr("Impossible to open file '%1' for reading")).arg(filepath); 00559 times.clear(); 00560 return false; 00561 } 00562 ln = 0; 00563 QTextStream fstream(&file); 00564 current_normal = 0; 00565 size_t current_vertex = 0; 00566 while(!fstream.atEnd()) 00567 { 00568 QString line = fstream.readLine().simplified(); 00569 ln++; 00570 int comment = line.indexOf('#'); 00571 if(comment != -1) 00572 line.truncate(comment); 00573 if(!line.isEmpty()) 00574 { 00575 QStringList fields = line.split(' '); 00576 QString field_type = fields[0]; 00577 if(field_type == "v") 00578 { 00579 if(fields.size() != 4) 00580 { 00581 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: vertex position must 3D")).arg(filepath).arg(ln); 00582 return false; 00583 } 00584 double x,y,z; 00585 bool ok; 00586 x = fields[1].toDouble(&ok); 00587 if(!ok) 00588 { 00589 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: x coordinate is not convertible to a double number")).arg(filepath).arg(ln); 00590 return false; 00591 } 00592 y = fields[2].toDouble(&ok); 00593 if(!ok) 00594 { 00595 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: y coordinate is not convertible to a double number")).arg(filepath).arg(ln); 00596 return false; 00597 } 00598 z = fields[3].toDouble(&ok); 00599 if(!ok) 00600 { 00601 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: z coordinate is not convertible to a double number")).arg(filepath).arg(ln); 00602 return false; 00603 } 00604 vertices[current_vertex++]->pos[i] = Point3d(x,y,z); 00605 } 00606 else if(field_type == "vn") 00607 { 00608 if(fields.size() != 4) 00609 { 00610 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: vertex normal must 3D")).arg(filepath).arg(ln); 00611 return false; 00612 } 00613 double x,y,z; 00614 bool ok; 00615 x = fields[1].toDouble(&ok); 00616 if(!ok) 00617 { 00618 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: x coordinate is not convertible to a double number")).arg(filepath).arg(ln); 00619 return false; 00620 } 00621 y = fields[2].toDouble(&ok); 00622 if(!ok) 00623 { 00624 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: y coordinate is not convertible to a double number")).arg(filepath).arg(ln); 00625 return false; 00626 } 00627 z = fields[3].toDouble(&ok); 00628 if(!ok) 00629 { 00630 _errorMsg = QString(tr("Error in OBJ file '%1', line %2: z coordinate is not convertible to a double number")).arg(filepath).arg(ln); 00631 return false; 00632 } 00633 vertices[current_normal++]->normal[i] = Point3d(x,y,z); 00634 } 00635 } 00636 } 00637 } 00638 // Reconstruct the graphs 00639 forall(const junction& j, S.junctions()) 00640 { 00641 if(!S.iEmpty(j)) 00642 { 00643 cell left = S.iAnyIn(j); 00644 cell right = left; 00645 S.insertEdge(j, left); 00646 while(S.valence(j) != S.iValence(j)) 00647 { 00648 forall(const cell& c, S.iNeighbors(j)) 00649 { 00650 if(S.edge(j,c)) 00651 continue; 00652 // const junction& right_j = S.prevTo(right, j); 00653 // const junction& left_j = S.nextTo(left, j); 00654 if(S.edge(c, S.prevTo(right, j))) 00655 { 00656 S.spliceAfter(j, right, c); 00657 right = c; 00658 } 00659 else if(S.edge(c, S.nextTo(left, j))) 00660 { 00661 S.spliceBefore(j, left, c); 00662 left = c; 00663 } 00664 } 00665 } 00666 } 00667 } 00668 // For all vertices that do not have their normals ... compute them ! 00669 forall(const junction& j, S.junctions()) 00670 { 00671 if(j->normal.empty()) 00672 { 00673 std::vector<Point3d> &normal = j->normal; 00674 normal.resize(nb_timepoints); 00675 const std::vector<Point3d>& jpos = j->pos; 00676 forall(const cell& c, S.neighbors(j)) 00677 { 00678 const junction& jp = S.prevTo(c, j); 00679 const junction& jn = S.nextTo(c, j); 00680 const std::vector<Point3d>& jppos = jp->pos; 00681 const std::vector<Point3d>& jnpos = jn->pos; 00682 for(size_t i = 0 ; i < nb_timepoints ; ++i) 00683 { 00684 normal[i] += (jnpos[i]-jpos[i]) ^ (jppos[i]-jpos[i]); 00685 } 00686 } 00687 for(size_t i = 0 ; i < nb_timepoints ; ++i) 00688 { 00689 normal[i].normalize(); 00690 } 00691 } 00692 } 00693 _valid = true; 00694 return true; 00695 }
void algorithms::TriangleGrowth::setTime | ( | double | t | ) |
Set the current time.
Definition at line 702 of file triangle_growth.cpp.
00703 { 00704 if(!_valid) 00705 return; 00706 if(t < times.front()) 00707 t = times.front(); 00708 else if(t > times.back()) 00709 t = times.back(); 00710 _time = t; 00711 for(size_t i = 0 ; i < times.size()-1 ; ++i) 00712 { 00713 if(times[i+1] > t) 00714 { 00715 _time_pos = (int)i; 00716 return; 00717 } 00718 } 00719 _time_pos = (int)times.size()-1; 00720 }
size_t algorithms::TriangleGrowth::size | ( | ) | const |
Returns the number of time points.
Definition at line 697 of file triangle_growth.cpp.
double algorithms::TriangleGrowth::startTime | ( | ) | const [inline] |
Returns the start time.
Definition at line 281 of file triangle_growth.h.
TriangleSurface algorithms::TriangleGrowth::surface | ( | double | time | ) |
Return the surface at the current time.
Definition at line 733 of file triangle_growth.cpp.
References algorithms::TriangleSurface::time.
00734 { 00735 TriangleSurface ts; 00736 if(time < times.front()) 00737 time = times.front(); 00738 else if(time > times.back()) 00739 time = times.back(); 00740 ts.time = time; 00741 ts.time_index = (int)times.size()-1; 00742 for(size_t i = 0 ; i < times.size()-1 ; ++i) 00743 { 00744 if(times[i+1] > time) 00745 { 00746 ts.time_index = (int)i; 00747 break; 00748 } 00749 } 00750 setSurface(ts); 00751 return ts; 00752 }
const TriangleSurface & algorithms::TriangleGrowth::surface | ( | ) | const |
Return the surface at the current time.
Definition at line 722 of file triangle_growth.cpp.
References algorithms::TriangleSurface::time.
Referenced by contour().
double algorithms::TriangleGrowth::time | ( | ) | const [inline] |
int algorithms::TriangleGrowth::timePos | ( | ) | const [inline] |
Return the current position in the time scale.
Definition at line 304 of file triangle_growth.h.
bool algorithms::TriangleGrowth::valid | ( | ) | const [inline] |
Definition at line 266 of file triangle_growth.h.