algorithms::TriangleGrowth Class Reference

Growth description using a set of triangles moving. More...

#include <algorithms/triangle_growth.h>

List of all members.

Public Types

typedef TriangleSurface::Position Position

Public Member Functions

std::vector< Positioncontour () const
 Return a description of the contour of the surface independent of the time.
double endTime () const
 Returns the end time.
const QStringerrorMsg () 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 TriangleSurfacesurface () 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

Detailed Description

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.


Member Function Documentation

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.

00286 { return times.back(); }

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.

00271 { return _errorMsg; }

template<typename Model , typename ComplexGraph >
bool algorithms::TriangleGrowth::init ( const ComplexGraph &  cplx,
std::vector< double >  times,
Model model 
) [inline]

Initialize the growth from a data structure.

Parameters:
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:

 Point3d position(const junction& v, int keyframe) const;

Returns the position of the junction v at the specified key frame.

 Point3d normal(const junction& v, int keyframe) const;

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.

Returns:
True if everything was fine. If not, the error is but in the error message of the class.

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.

Returns:
True if everything was fine. If not, the error is but in the error message of the class.

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.

Warning:
If you try to set a time less than the start time or greater than the end time, the time will be clamped to the start or end value.

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.

00698   {
00699     return times.size();
00700   }

double algorithms::TriangleGrowth::startTime (  )  const [inline]

Returns the start time.

Definition at line 281 of file triangle_growth.h.

00281 { return times.front(); }

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().

00723   {
00724     if(TS.time != _time)
00725     {
00726       TS.time = _time;
00727       TS.time_index = _time_pos;
00728       setSurface(TS);
00729     }
00730     return TS;
00731   }

double algorithms::TriangleGrowth::time (  )  const [inline]

Return the current time.

Definition at line 299 of file triangle_growth.h.

00299 { return _time; }

int algorithms::TriangleGrowth::timePos (  )  const [inline]

Return the current position in the time scale.

Definition at line 304 of file triangle_growth.h.

00304 { return _time_pos; }

bool algorithms::TriangleGrowth::valid (  )  const [inline]
Returns:
True if the growth is correctly initialized

Definition at line 266 of file triangle_growth.h.

00266 { return _valid; }


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Fri May 31 15:38:04 2013 for VVE by  doxygen 1.6.3