complex_factory Namespace Reference

Contains functions to initialise a complex. More...

Classes

struct  HexFiller
 For internal use only! More...
class  ObjReaderError
 Error object returned by the complex_factory::objreader functions. More...
struct  SquareFiller
 For internal use only! More...

Typedefs

typedef util::Vector< 2, size_t > Point2u
typedef util::Vector< 3, double > Point3d

Functions

template<class Graph >
void connectJunction (const typename Graph::vertex_t &j, const typename Graph::vertex_t &nj, const typename Graph::vertex_t &pj, Graph &S, bool direct=true)
 Connect j to nj knowing than pj is the junction before j in the current cell.
template<typename Complex , class Model >
bool hex_grid (size_t N, size_t M, Complex &T, Model &model, const Point3d &bottom_left=Point3d(0, 0, 0), const Point3d &u=Point3d(1, 0, 0), const Point3d &v=Point3d(0, 1, 0))
 Create a hexagonal grid with N lines and M columns.
template<class CellComplex , class Model >
ObjReaderError objreader (std::string filename, CellComplex &T, Model &model)
 Convenience methods that read a Wavefront OBJ file.
template<class CellComplex , class Model >
ObjReaderError objreader (const QString &filename, CellComplex &T, Model &model)
 Convenience methods that read a Wavefront OBJ file.
template<class CellComplex , class Model >
ObjReaderError objreader (QTextStream &content, CellComplex &T, Model &model)
 Read a Wavefront OBJ file describing a surface and return the complex representing it.
template<typename Complex , class Model >
bool square_grid (size_t N, size_t M, Complex &T, Model &model, const Point3d &bottom_left=Point3d(0, 0, 0), const Point3d &shift_right=Point3d(1, 0, 0), const Point3d &shift_up=Point3d(0, 1, 0))
 Create a square grid with N lines and M columns.
template<typename Complex , class Model >
SquareFiller< Complex, ModelsquareFiller (const Point3d &bottom_left, const Point3d &shift_right, const Point3d &shift_up, Complex &T, Model &model)
 Create a square filler.

Detailed Description

Contains functions to initialise a complex.


Function Documentation

template<class Graph >
void complex_factory::connectJunction ( const typename Graph::vertex_t &  j,
const typename Graph::vertex_t &  nj,
const typename Graph::vertex_t &  pj,
Graph &  S,
bool  direct = true 
) [inline]

Connect j to nj knowing than pj is the junction before j in the current cell.

Note:
For internal use only!

Definition at line 275 of file complex_grid.h.

Referenced by hex_grid().

00280   {
00281     typedef typename Graph::vertex_t vertex;
00282     if(S.empty(j))
00283     {
00284       S.insertEdge(j, nj);
00285       return;
00286     }
00287     if(S.edge(j, pj))
00288     {
00289       if(direct)
00290         S.spliceBefore(j, pj, nj);
00291       else
00292         S.spliceAfter(j, pj, nj);
00293       return;
00294     }
00295     const vertex& v = S.anyIn(j);
00296     S.spliceBefore(j, v, nj);
00297   }

template<typename Complex , class Model >
bool complex_factory::hex_grid ( size_t  N,
size_t  M,
Complex &  T,
Model model,
const Point3d bottom_left = Point3d(0,0,0),
const Point3d u = Point3d(1,0,0),
const Point3d v = Point3d(0,1,0) 
) [inline]

Create a hexagonal grid with N lines and M columns.

Parameters:
N Number of lines
M Number of columns
G Graph to initialize as a grid
m Model containing the initialization functions
bottom_left Position of the center of the bottom-left cell
u Vector describing the reference system. if u=(1,0,0) and v=(0,1,0), then the hexagon drawn would be of radius 1 and placed vertically.
v Vector describing the reference system.
Returns:
True if successful

The model should contain this method:

   void saveGridCellPosition(const cell& c, Point2u pos, Complex&)
  • Initialize a newly created vertex at line i and column j. This method is called only on centers, before the junctions exist.
  Point2u gridCellPosition(const cell& c, Complex&)

The neighbors are oriented in that order: bottom -> right -> top -> left

With the bottom-left corner being the one of coordinate (0,0).

The graph is cleared at the beginning of the process

Definition at line 333 of file complex_grid.h.

References connectJunction(), forall, factory::hex_grid(), IMPORT_COMPLEX_TYPES, util::Vector< dim, T >::x(), and util::Vector< dim, T >::y().

00337   {
00338     IMPORT_COMPLEX_TYPES(Complex);
00339     HexFiller<Complex,Model> sf(bottom_left, u, v, T, model);
00340     if(!factory::hex_grid(N, M, T.C, sf))
00341       return false;
00342     size_t nb_corners = (M+1)*(N+1)-1;
00343     // Bottom-left and top-left corners
00344     std::vector<junction> bottom_corner(nb_corners,junction(0)), top_corner(nb_corners, junction(0));
00345     size_t k = 0;
00346     Point3d shift_top_left = bottom_left + v*0.5 - u*std::sqrt(3)/2;
00347     Point3d shift_bottom_left = bottom_left - v*0.5 - u*std::sqrt(3)/2;
00348     Point3d delta_pos_j = std::sqrt(3)*u;
00349     Point3d delta_pos_i = 1.5*v;
00350     Point3d odd_shift_pos = std::sqrt(3)/2*u;
00351 
00352     // Grid of cells
00353     std::vector<std::vector<cell> > cell_grid(N, std::vector<cell>(M, cell(0)));
00354     forall(const cell& c, T.C)
00355     {
00356       Point2u ij = model.gridCellPosition(c, T);
00357       cell_grid[ij.x()][ij.y()] = c;
00358     }
00359 
00360     for(size_t i = 0 ; i < N+1 ; ++i)
00361       for(size_t j = 0 ; j < M+1 ; ++j, ++k)
00362       {
00363         if(i == N and j == M)
00364           continue;
00365         junction top;
00366         junction bottom;
00367         T.W.insert(top); T.W.insert(bottom);
00368         T.S.insert(top); T.S.insert(bottom);
00369         Point3d delta_pos;
00370         delta_pos = (double)j*delta_pos_j + (double)i*delta_pos_i;
00371         if(i%2)
00372           delta_pos += odd_shift_pos;
00373         else if(i == N)
00374           delta_pos += 2*odd_shift_pos;
00375         Point3d pos_top;
00376         if(i == N)
00377         {
00378           pos_top = (double)j*delta_pos_j - v;
00379         }
00380         else
00381           pos_top = shift_top_left + delta_pos;
00382         Point3d pos_bottom = shift_bottom_left + delta_pos;
00383         model.setPosition(top, pos_top);
00384         model.setPosition(bottom, pos_bottom);
00385         bottom_corner[k] = bottom;
00386         top_corner[k] = top;
00387       }
00388 
00389     // Connect everything
00390     for(size_t i = 0 ; i < N ; ++i)
00391       for(size_t j = 0 ; j < M ; ++j)
00392       {
00393         const cell& c = cell_grid[i][j];
00394         T.S.insert(c);
00395         const junction& c1 = TF_TOP_CORNER(i,j);
00396         const junction& c2 = TF_BOTTOM_CORNER(i,j);
00397         const junction& c3 = (i%2)?TF_TOP_CORNER(i-1,j+1):TF_TOP_CORNER(i-1,j);
00398         const junction& c4 = TF_BOTTOM_CORNER(i,j+1);
00399         const junction& c5 = TF_TOP_CORNER(i,j+1);
00400         const junction& c6 = (i%2)?TF_BOTTOM_CORNER(i+1,(i==N-1)?j:j+1):TF_BOTTOM_CORNER(i+1,j);
00401         // Connect the junctions to each other
00402         connectJunction(c1, c2, c6, T.W);
00403         connectJunction(c2, c3, c1, T.W);
00404         connectJunction(c3, c4, c2, T.W);
00405         connectJunction(c4, c5, c3, T.W);
00406         connectJunction(c5, c6, c4, T.W);
00407         connectJunction(c6, c1, c5, T.W);
00408 
00409         if(i == 0)
00410         {
00411           connectJunction(c3, c2, c4, T.W, false);
00412           connectJunction(c4, c3, c5, T.W, false);
00413         }
00414         if(j == 0)
00415         {
00416           if(i%2 == 0)
00417           {
00418             if(i != 0)
00419               connectJunction(c3, c2, c4, T.W, false);
00420             if(i != N-1)
00421               connectJunction(c1, c6, c2, T.W, false);
00422           }
00423           connectJunction(c2, c1, c3, T.W, false);
00424         }
00425         if(i == N-1)
00426         {
00427           connectJunction(c1, c6, c2, T.W, false);
00428           connectJunction(c6, c5, c1, T.W, false);
00429         }
00430         if(j == M-1)
00431         {
00432           if(i%2)
00433           {
00434             if(i != N-1)
00435               connectJunction(c6, c5, c1, T.W, false);
00436             if(i != 0)
00437               connectJunction(c4, c3, c5, T.W, false);
00438           }
00439           connectJunction(c5, c4, c6, T.W, false);
00440         }
00441 
00442         // Connect the center to the junctions
00443         T.S.insertEdge(c, c1);
00444         T.S.insertEdge(c, c2);
00445         T.S.spliceAfter(c, c2, c3);
00446         T.S.spliceAfter(c, c3, c4);
00447         T.S.spliceAfter(c, c4, c5);
00448         T.S.spliceAfter(c, c5, c6);
00449 
00450         // Connect the junctions to the center
00451         if(i == 0 or j == 0)
00452         {
00453           T.S.insertEdge(c1, c);
00454           T.S.insertEdge(c2, c);
00455         }
00456         else
00457         {
00458           const cell& nc = T.S.anyIn(c1);
00459           T.S.spliceAfter(c1, nc, c);
00460           T.S.spliceBefore(c2, nc, c);
00461         }
00462         {
00463           const cell& nc = T.S.anyIn(c4);
00464           if(nc)
00465             T.S.spliceAfter(c3, nc, c);
00466           else
00467             T.S.insertEdge(c3, c);
00468         }
00469         T.S.insertEdge(c4, c);
00470         T.S.insertEdge(c5, c);
00471         T.S.insertEdge(c6, c);
00472       }
00473     return true;
00474   }

template<class CellComplex , class Model >
ObjReaderError complex_factory::objreader ( std::string  filename,
CellComplex &  T,
Model model 
) [inline]

Convenience methods that read a Wavefront OBJ file.

See also:
objreader(QTextStream&,CellComplex&,Model&)

Definition at line 461 of file objreader.h.

References QString::fromLocal8Bit(), and objreader().

00462   {
00463     QString fn = QString::fromLocal8Bit(filename.c_str());
00464     return objreader(fn, T, model);
00465   }

template<class CellComplex , class Model >
ObjReaderError complex_factory::objreader ( const QString filename,
CellComplex &  T,
Model model 
) [inline]

Convenience methods that read a Wavefront OBJ file.

See also:
objreader(QTextStream&,CellComplex&,Model&)

Definition at line 444 of file objreader.h.

References objreader(), and QFile::open().

00445   {
00446     QFile f(filename);
00447     if(!f.open(QIODevice::ReadOnly))
00448     {
00449       return ObjReaderError(ObjReaderError::CANNOT_OPEN_FILE, f.errorString());
00450     }
00451     QTextStream ts(&f);
00452     return objreader(ts, T, model);
00453   }

template<class CellComplex , class Model >
ObjReaderError complex_factory::objreader ( QTextStream content,
CellComplex &  T,
Model model 
) [inline]

Read a Wavefront OBJ file describing a surface and return the complex representing it.

Parameters:
content Stream containing the OBJ file
T Complex to fill with the OBJ file mesh
model Object containing needed methods

This version interpret vertices, faces and normals on vertices.

The model object should include, in addition to the methods required by the complex object, the following methods:

 void setVertexId(const junction& v, int id);

Associate the identifier id with the vertex v. The identifiers for faces and junctions are independant. Typically, the id will be store in the vertex itself.

 void setFaceId(const cell& f, int id);

Associate the identifier id with the face f. The identifiers for faces and junctions are independant. Typically, the id will be store in the face itself.

 int vertexId(const junction& v);

Returns the identifier that was previously associated with the vertex v.

 int faceId(const cell& f);

Returns the identifier that was previously associated with the face f.

 void setNormal(const cell& c, const Point3d& normal);

Set the normal of the face v to normal. The normal is just for information, and do not have to be used.

 void setNormal(const junction& v, const Point3d& normal);

Set the normal of the vertex v to normal. The normal is just for information, and do not have to be used.

Definition at line 126 of file objreader.h.

References QTextStream::atEnd(), forall, forall_named, IMPORT_COMPLEX_TYPES, util::Vector< dim, T >::normalize(), QString::number(), QTextStream::readLine(), util::Vector< dim, T >::size(), QList::size(), QString::split(), QString::toInt(), util::Vector< dim, T >::x(), util::Vector< dim, T >::y(), and util::Vector< dim, T >::z().

Referenced by objreader().

00127   {
00128     IMPORT_COMPLEX_TYPES(CellComplex);
00129 
00130     std::vector<Point3d> vertices_pos;
00131     std::vector<Point3d> normals;
00132     std::vector<std::vector<int> > faces_idx;
00133 
00134     QString token;
00135 
00136     while(!content.atEnd())
00137     {
00138       content >> token;
00139       QString buffer = content.readLine();
00140 //      cerr << "Reading token '" << token.toStdString() << "'" << endl;
00141 //      cerr << "Buffer: '" << buffer.toStdString() << "'" << endl;
00142       if(token == QString("v"))
00143       {
00144         QList<QString> pos = buffer.split(' ', QString::SkipEmptyParts);
00145         if(pos.size() != 3)
00146         {
00147           QString msg = "Error, vertex " + QString::number(vertices_pos.size()) +
00148             " has " + QString::number(pos.size()) +  " dimensions instead of 3";
00149           return ObjReaderError(ObjReaderError::BAD_NUMBER_OF_DIMENSIONS, msg);
00150         }
00151         Point3d p;
00152         bool ok, ok_tmp;
00153         p.x() = pos[0].toDouble(&ok);
00154         p.y() = pos[1].toDouble(&ok_tmp);
00155         ok &= ok_tmp;
00156         p.z() = pos[2].toDouble(&ok_tmp);
00157         ok &= ok_tmp;
00158         if(!ok)
00159         {
00160           QString msg = "Error on vertex " + QString::number(vertices_pos.size()) +
00161             ": double value expected";
00162           return ObjReaderError(ObjReaderError::DOUBLE_EXPECTED, msg);
00163         }
00164         vertices_pos.push_back(p);
00165       }
00166       else if(token == QString("vn"))
00167       {
00168         QList<QString> pos = buffer.split(' ');
00169         if(pos.size() != 3)
00170         {
00171           QString msg = "Error, normal " + QString::number(normals.size()) + " has " +
00172             QString::number(pos.size()) + " dimensions instead of 3";
00173           return ObjReaderError(ObjReaderError::BAD_NUMBER_OF_DIMENSIONS, msg);
00174         }
00175         Point3d p;
00176         bool ok, ok_tmp;
00177         p.x() = pos[0].toDouble(&ok);
00178         p.y() = pos[1].toDouble(&ok_tmp);
00179         ok &= ok_tmp;
00180         p.z() = pos[2].toDouble(&ok_tmp);
00181         ok &= ok_tmp;
00182         if(!ok)
00183         {
00184           QString msg = "Error on normal " + QString::number(vertices_pos.size()) + ": double value expected";
00185           return ObjReaderError(ObjReaderError::DOUBLE_EXPECTED, msg);
00186         }
00187         normals.push_back(p);
00188       }
00189       else if(token == QString("f"))
00190       {
00191         std::vector<int> f;
00192         QList<QString> face = buffer.split(' ', QString::SkipEmptyParts);
00193         if(face.size() < 3)
00194         {
00195           QString msg = "Error, face " + QString::number(faces_idx.size()) + " has less than 3 vertices.";
00196           return ObjReaderError(ObjReaderError::INVALID_FACE, msg);
00197         }
00198         bool ok = true;
00199         forall(QString& value, face)
00200         {
00201           int vn = value.toInt(&ok);
00202           if(!ok)
00203           {
00204             QString msg = "Error on face " + QString::number(faces_idx.size()) + ": integer values expected";
00205             return ObjReaderError(ObjReaderError::INTEGER_EXPECTED, msg);
00206           }
00207           f.push_back(vn);
00208         }
00209         faces_idx.push_back(f);
00210       }
00211     }
00212     if(normals.size() > vertices_pos.size())
00213     {
00214       cerr << "Warning: more normals than vertices" << endl;
00215     }
00216     if(!normals.empty() and normals.size() < vertices_pos.size())
00217     {
00218       cerr << "Warning: not all vertices have a normal, ignoring the specified normals." << endl;
00219       normals.clear();
00220     }
00221     // First, add the vertices
00222     std::vector<junction> vertices;
00223     std::vector<cell> faces;
00224     int id = 0;
00225     forall(const Point3d& pos, vertices_pos)
00226     {
00227       junction v;
00228       T.S.insert(v);
00229       T.W.insert(v);
00230       model.setPosition(v, pos);
00231       vertices.push_back(v);
00232       model.setVertexId(v, ++id);
00233     }
00234     // Then add the faces and connect the center to the junctions (in the 
00235     // correct order)
00236     id = 0;
00237     forall(const std::vector<int>& face_idx, faces_idx)
00238     {
00239       cell face;
00240       junction pf(0);
00241       T.S.insert(face);
00242       T.C.insert(face);
00243       Point3d center;
00244       forall(int i, face_idx)
00245       {
00246         center += vertices_pos[i-1];
00247         junction current = vertices[i-1];
00248         if(pf)
00249         {
00250           T.S.spliceAfter(face, pf, current);
00251         }
00252         else
00253           T.S.insertEdge(face, current);
00254         pf = current;
00255       }
00256       center /= face_idx.size();
00257       model.setPosition(face, center);
00258       model.setFaceId(face, ++id);
00259     }
00260     // Connect the vertices to the faces
00261     forall_named(const junction& j, T.S, junctions)
00262     {
00263       if(T.S.iValence(j) < 3)
00264       {
00265         // There is nothing to sort ...
00266         forall(const cell& f, T.S.iNeighbors(j))
00267         {
00268           T.S.insertEdge(j, f);
00269         }
00270       }
00271       else
00272       {
00273         const cell& f_init = T.S.iAnyIn(j);
00274         cell pf = f_init;
00275         T.S.insertEdge(j, f_init);
00276         do
00277         {
00278           cell f(0);
00279           const junction& m = T.S.prevTo(pf, j);
00280           // Now, find the face that contains also m
00281           forall(const cell& of, T.S.iNeighbors(j))
00282           {
00283             if(of == pf)
00284               continue;
00285             if(T.S.edge(of, m))
00286             {
00287               f = of;
00288               break;
00289             }
00290           }
00291           if(!f or f == f_init)
00292           {
00293             break;
00294           }
00295           // Insert f after pf in j
00296           T.S.spliceAfter(j, pf, f);
00297           pf = f;
00298         } while( T.S.iValence(j) != T.S.valence(j));
00299         pf = f_init;
00300         // If we didn't find all the neighbors, it means we have to go the 
00301         // other way around
00302         while(T.S.iValence(j) != T.S.valence(j))
00303         {
00304           cell f(0);
00305           const junction& m = T.S.nextTo(pf, j);
00306           forall(const cell& of, T.S.iNeighbors(j))
00307           {
00308             if(of == pf)
00309               continue;
00310             if(T.S.edge(of, m))
00311             {
00312               f = of;
00313               break;
00314             }
00315           }
00316           if(!f)
00317             break;
00318           T.S.spliceBefore(j, pf, f);
00319           pf = f;
00320         }
00321         if(T.S.valence(j) != T.S.iValence(j))
00322         {
00323           cerr << "Error, vertex " << model.vertexId(j) << " was not properly connected to the faces" << endl;
00324         }
00325       }
00326     }
00327     // Connect the junctions
00328     forall_named(const junction& j, T.S, junctions)
00329     {
00330       junction prev(0);
00331       forall(const cell& c, T.S.neighbors(j))
00332       {
00333         const junction& jn = T.S.nextTo(c, j);
00334         const junction& jp = T.S.prevTo(c, j);
00335         if(prev.isNull())
00336         {
00337           T.W.insertEdge(j, jn);
00338           prev = jn;
00339         }
00340         else if(prev != jn)
00341         {
00342           T.W.spliceAfter(j, prev, jn);
00343         }
00344         T.W.spliceAfter(j, jn, jp);
00345         prev = jp;
00346       }
00347     }
00348     // if the normals aren't specified, then compute them
00349     if(normals.empty())
00350     {
00351       forall_named(const junction& v, T.S, junctions)
00352       {
00353         Point3d pos = model.position(v);
00354         Point3d normal;
00355         if(T.border(v))
00356         {
00357           // If this is a border index, first find the border
00358           forall(const junction& n, T.W.neighbors(v))
00359           {
00360             const junction& m = T.W.nextTo(v,n);
00361             if(T.border(v, m) and T.border(v, n))
00362             {
00363               junction n1 = m;
00364               do
00365               {
00366                 const junction& n2 = T.W.nextTo(v, n1);
00367                 Point3d p1 = model.position(n1) - pos;
00368                 Point3d p2 = model.position(n2) - pos;
00369                 normal += p1^p2;
00370                 n1 = n2;
00371               } while(n1 != n);
00372               break;
00373             }
00374           }
00375         }
00376         else
00377         {
00378           // If this is an inside vertex
00379           forall(const junction& n, T.W.neighbors(v))
00380           {
00381             Point3d p1 = model.position(n) - pos;
00382             Point3d p2 = model.position(T.W.nextTo(v, n)) - pos;
00383             normal += p1^p2;
00384           }
00385         }
00386         normal.normalize();
00387         model.setNormal(v, normal);
00388       }
00389     }
00390     else
00391     {
00392       int k = 0;
00393       forall(const Point3d& n, normals)
00394       {
00395         junction v = vertices[k++];
00396         model.setNormal(v, n);
00397       }
00398     }
00399     // Compute normals for the faces
00400     forall_named(const cell& f, T.S, cells)
00401     {
00402       Point3d pos = model.position(f);
00403       Point3d normal;
00404       forall(const junction& v, T.S.neighbors(f))
00405       {
00406         const junction& v1 = T.S.nextTo(f, v);
00407         Point3d p1 = model.position(v) - pos;
00408         Point3d p2 = model.position(v1) - pos;
00409         normal += p1^p2;
00410       }
00411       normal.normalize();
00412       model.setNormal(f, normal);
00413     }
00414     // At last, connect the cell graph
00415     forall_named(const cell& f, T.S, cells)
00416     {
00417       cell pf(0);
00418       forall(const junction& j, T.S.neighbors(f))
00419       {
00420         const cell& f2 = T.adjacentCell(f, j);
00421         if(f2)
00422         {
00423           if(pf)
00424           {
00425             T.C.spliceAfter(f, pf, f2);
00426           }
00427           else
00428           {
00429             T.C.insertEdge(f, f2);
00430           }
00431           pf = f2;
00432         }
00433       }
00434     }
00435     return ObjReaderError(ObjReaderError::NO_ERRORS);
00436   }

template<typename Complex , class Model >
bool complex_factory::square_grid ( size_t  N,
size_t  M,
Complex &  T,
Model model,
const Point3d bottom_left = Point3d(0,0,0),
const Point3d shift_right = Point3d(1,0,0),
const Point3d shift_up = Point3d(0,1,0) 
) [inline]

Create a square grid with N lines and M columns.

Parameters:
N Number of lines
M Number of columns
G Graph to initialize as a grid
m Model containing the initialization functions
bottom_left Position of the bottom-left corner of the bottom_left cell
shift_right Vector describing the width of a cell
shift_up Vector describing the height of a cell
Returns:
True if successful

The model should contain this method:

   void saveGridCellPosition(const cell&, Point2u pos, Complex&)
  • Initialize a newly created vertex at line i and column j. This method is called only on centers, before the junctions exist.
   Point2u gridCellPosition(const cell&, Complex&)

The neighbors are oriented in that order: bottom -> right -> top -> left

With the bottom-left corner being the one of coordinate (0,0).

The graph is cleared at the beginning of the process

Definition at line 116 of file complex_grid.h.

References forall, IMPORT_COMPLEX_TYPES, algorithms::insertAfter(), factory::square_grid(), util::Vector< dim, T >::x(), and util::Vector< dim, T >::y().

00120   {
00121     IMPORT_COMPLEX_TYPES(Complex);
00122     SquareFiller<Complex,Model> sf(bottom_left, shift_right, shift_up, T, model);
00123     if(!factory::square_grid(N, M, T.C, sf))
00124       return false;
00125     // Store the bottom-left corner of each cell
00126     std::vector<junction> corners((N+1)*(M+1), junction(0));
00127 
00128     // Grid of cells
00129     std::vector<std::vector<cell> > cell_grid(N, std::vector<cell>(M, cell(0)));
00130     forall(const cell& c, T.C)
00131     {
00132       Point2u ij = model.gridCellPosition(c, T);
00133       cell_grid[ij.x()][ij.y()] = c;
00134     }
00135 
00136     // Create the corners and connect them to the cells
00137     size_t k = 0;
00138     for(size_t i = 0 ; i < N+1 ; ++i)
00139       for(size_t j = 0 ; j < M+1 ; ++j, ++k)
00140       {
00141         Point3d pos = bottom_left + (1.0*i)*shift_up + (1.0*j)*shift_right;
00142         junction v;
00143         T.S.insert(v);
00144         T.W.insert(v);
00145         model.setPosition(v, pos);
00146         corners[k] = v;
00147       }
00148     // Connect the corners to each other
00149     const size_t delta_right = 1;
00150     const size_t delta_up = M+1;
00151     k = 0;
00152     for(size_t i = 0 ; i < N+1 ; ++i)
00153       for(size_t j = 0 ; j < M+1 ; ++j, ++k)
00154       {
00155         const junction& v = corners[k];
00156         junction pv(0);
00157         // First, connect up
00158         if(i < N)
00159         {
00160           pv = corners[k+delta_up];
00161           T.W.insertEdge(v, pv);
00162         }
00163         // Second, connect left
00164         if(j > 0)
00165         {
00166           pv = corners[k-delta_right];
00167           T.W.insertEdge(v, pv);
00168         }
00169         // Third, connect down
00170         if(i > 0)
00171         {
00172           const junction& nv = corners[k-delta_up];
00173           insertAfter(v, pv, nv, T.W);
00174           pv = nv;
00175         }
00176         // At last, connect right
00177         if(j < M)
00178         {
00179           const junction& nv = corners[k+delta_right];
00180           insertAfter(v, pv, nv, T.W);
00181         }
00182       }
00183     // Next, connect the cells to the corners
00184     for(size_t i = 0 ; i < N ; ++i)
00185       for(size_t j = 0 ; j < M ; ++j, ++k)
00186       {
00187         const cell& c = cell_grid[i][j];
00188         T.S.insert(c);
00189         junction c1 = TF_CORNER(i,j);
00190         junction c2 = TF_CORNER(i,j+1);
00191         junction c3 = TF_CORNER(i+1,j+1);
00192         junction c4 = TF_CORNER(i+1,j);
00193         T.S.insertEdge(c, c1);
00194         T.S.insertEdge(c, c2);
00195         T.S.spliceAfter(c, c2, c3);
00196         T.S.spliceAfter(c, c3, c4);
00197 
00198         if(i == 0)
00199         {
00200           T.S.insertEdge(c1, c);
00201           T.S.insertEdge(c2, c);
00202         }
00203         else
00204         {
00205           forall(const cell& cc, T.S.neighbors(c1))
00206           {
00207             Point2u ij = model.gridCellPosition(cc, T);
00208             if(ij.x() == i-1 and ij.y() == j)
00209             {
00210               T.S.spliceAfter(c1, cc, c);
00211               T.S.spliceBefore(c2, cc, c);
00212               break;
00213             }
00214           }
00215         }
00216 
00217         T.S.insertEdge(c3, c);
00218         T.S.insertEdge(c4, c);
00219 
00220         /*
00221            T.S.spliceAfter(c1, c2, c);
00222            T.S.spliceAfter(c2, c3, c);
00223            T.S.spliceAfter(c3, c4, c);
00224            T.S.spliceAfter(c4, c1, c);
00225            */
00226       }
00227     return true;
00228   }

template<typename Complex , class Model >
SquareFiller<Complex,Model> complex_factory::squareFiller ( const Point3d bottom_left,
const Point3d shift_right,
const Point3d shift_up,
Complex &  T,
Model model 
) [inline]

Create a square filler.

Definition at line 74 of file complex_grid.h.

00079   {
00080     return SquareFiller<Complex,Model>(bottom_left, shift_right, shift_up, T, model);
00081   }

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Fri May 31 15:38:07 2013 for VVE by  doxygen 1.6.3