triangle_growth.h

Go to the documentation of this file.
00001 #ifndef VVELIB_ALGORITHMS_TRIANGLE_GROWTH_H
00002 #define VVELIB_ALGORITHMS_TRIANGLE_GROWTH_H
00003 
00011 #include <config.h>
00012 #include <geometry/geometry.h>
00013 #include <vector>
00014 #include <algorithms/complex.h>
00015 #include <QString>
00016 #include <storage/storage.h>
00017 #include <util/unorderedset.h>
00018 #include <util/unorderedmap.h>
00019 #include <util/assert.h>
00020 #include <QTextStream>
00021 
00022 namespace algorithms
00023 {
00024   using geometry::Point3d;
00025 
00031   class TriangleSurface
00032   {
00033   public:
00037     struct Cell
00038     {
00040       Point3d normal;
00042       int id;
00043     };
00044 
00048     struct Vertex
00049     {
00051       Point3d pos;
00053       Point3d normal;
00055       int id;
00056     };
00057 
00059     typedef vvcomplex::VVComplexGraph<Cell, Vertex> CellComplex;
00060     EXPORT_COMPLEX_VERTICES(CellComplex);
00061 
00063     CellComplex S;
00064 
00069     struct Position
00070     {
00071       Point3d barycentric;
00072       int v1, v2, v3;
00073       int face;
00074 
00075       Position() : v1(0), v2(0), v3(0), face(0) {}
00076       Position(const Point3d& bar, int vv1, int vv2, int vv3, int f)
00077         : barycentric(bar)
00078         , v1(vv1) , v2(vv2) , v3(vv3) , face(f)
00079         {}
00080       Position(const Position& copy)
00081         : barycentric(copy.barycentric)
00082         , v1(copy.v1), v2(copy.v2), v3(copy.v3), face(copy.face)
00083         {}
00084 #ifdef USE_CXX0X
00085       Position(Position&& copy) = default;
00086 #endif
00087 
00088       bool serialize(storage::VVEStorage&);
00089 
00090       operator bool() const { return face != 0; }
00091     };
00092 
00093     TriangleSurface();
00094 #ifdef USE_CXX0X
00095     TriangleSurface(TriangleSurface&& ) = default;
00096     TriangleSurface(const TriangleSurface& ) = default;
00097 #endif
00098 
00103     Point3d point3d(const Position& pos) const;
00107     Point3d normal(const Position& pos) const;
00115     Point3d smoothNormal(const Position& pos) const;
00116 
00121     Position position(const Point3d& pos) const;
00132     Position position(const Position& start, const Point3d& pos) const;
00133 
00140     Position centerPosition(int face) const;
00141 
00148     Point3d center3d(int face) const;
00149 
00157     Point3d vector3d(const Position& pos) const;
00158 
00162     Position vector(const Point3d& ref, const Point3d& pos) const;
00166     Position vector(const Position& ref, const Point3d& pos) const;
00167 
00171     void clear();
00172 
00177     std::vector<Position> contour() const;
00178 
00180     double time;
00181     int time_index;
00182 
00184     std::vector<junction> vertices;
00186     std::vector<cell> faces;
00187 
00189     Point3d pmin, pmax;
00190   protected:
00191     typedef std::unordered_set<cell> cell_set_t;
00192     Position find_position(const cell& c, const Point3d& pos, cell_set_t& visited) const;
00193     Position vertexPosition(const junction& j) const;
00194     std::vector<Position> nextContourVertex(const junction& first, const cell& c, const junction& j, std::vector<Position> acc) const;
00195   };
00196 
00205   class TriangleGrowth
00206   {
00207   public:
00208     typedef TriangleSurface::Position Position;
00209 
00210     struct Cell
00211     {
00212       int id;
00213     };
00214 
00215     struct Vertex
00216     {
00217       std::vector<Point3d> pos;
00218       std::vector<Point3d> normal;
00219       int id;
00220     };
00221 
00222     TriangleGrowth();
00223 
00230     bool readOBJs(QString desc_filepath);
00231 
00238     bool readOBJs(const std::string& desc_filepath) { return readOBJs(QString::fromStdString(desc_filepath)); }
00239 
00260     template <typename Model, typename ComplexGraph>
00261       bool init(const ComplexGraph& cplx, std::vector<double> times, Model *model);
00262 
00266     bool valid() const { return _valid; }
00267 
00271     const QString& errorMsg() const { return _errorMsg; }
00272 
00276     size_t size() const;
00277 
00281     double startTime() const { return times.front(); }
00282 
00286     double endTime() const { return times.back(); }
00287 
00294     void setTime(double t);
00295 
00299     double time() const { return _time; }
00300 
00304     int timePos() const { return _time_pos; }
00305 
00309     const TriangleSurface& surface() const;
00310 
00314     TriangleSurface surface(double time);
00315 
00320     std::vector<Position> contour() const;
00321 
00322   protected:
00323     void setSurface(TriangleSurface& s) const;
00324 
00325     typedef vvcomplex::VVComplexGraph<Cell,Vertex> CellComplex;
00326     EXPORT_COMPLEX_VERTICES(CellComplex);
00327 
00328     Position vertexPosition(const junction& j) const;
00329 
00330     mutable TriangleSurface TS;
00331 
00332     CellComplex S;
00333     std::vector<double> times;
00334     double _time;
00335     int _time_pos;
00336     bool _valid;
00337     QString _errorMsg;
00338     std::vector<cell> faces;
00339     std::vector<junction> vertices;
00340   };
00341 
00342   template <typename Model, typename ComplexGraph>
00343   bool TriangleGrowth::init(const ComplexGraph& cplx, std::vector<double> _times, Model *model)
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   }
00460 }
00461 
00462 #endif // VVELIB_ALGORITHMS_TRIANGLE_GROWTH_H
00463 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Fri May 31 15:37:50 2013 for VVE by  doxygen 1.6.3