aimsdata  5.0.5
Neuroimaging data handling
surface.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 /*
35  * Surface class
36  */
37 #ifndef AIMS_SURFACE_SURFACE_H
38 #define AIMS_SURFACE_SURFACE_H
39 
40 
41 #include <cartobase/smart/rcptr.h>
43 #include <aims/vector/vector.h>
44 #include <aims/def/general.h>
45 #include <aims/data/pheader.h>
46 #include <iostream>
47 #include <vector>
48 #include <map>
49 #include <set>
50 
51 //
52 // Basic surface class
53 //
54 
55 
56 template <int D,class T = Void> class AimsSurface;
57 
58 template <int D,class T> AIMSDATA_API
59 std::ostream& operator << ( std::ostream& out, const AimsSurface<D,T>& thing);
60 
61 
67 template <int D,class T>
69 {
70  protected:
72  std::vector< Point3df > _vertex;
74  std::vector< Point3df > _normal;
76  std::vector< T > _texture;
78  typedef std::vector< AimsVector< uint, D > > Polygons;
79  Polygons _polygon;
80 
85 
86  public:
90  virtual ~AimsSurface() { }
91 
93  const std::vector<Point3df>& vertex() const { return _vertex; }
95  std::vector<Point3df>& vertex() { return _vertex; }
96 
98  const std::vector<Point3df>& normal() const { return _normal; }
100  std::vector<Point3df>& normal() { return _normal; }
101 
103  const std::vector<T>& texture() const { return _texture; }
105  std::vector<T>& texture() { return _texture; }
106 
108  const std::vector< AimsVector<uint,D> >& polygon() const
109  { return _polygon; }
111  std::vector< AimsVector<uint,D> >& polygon() { return _polygon; }
112 
114  Point3df minimum() const { return _mini; }
116  Point3df maximum() const { return _maxi; }
117 
119  inline void setMini();
121  inline void setMaxi();
122 
124  inline void erase();
125 
127  inline void updateNormals();
128 
130  friend
131  std::ostream& operator << <>( std::ostream& out,
132  const AimsSurface<D,T>& thing );
133 };
134 
135 
136 template <int D,class T> inline
138 {
139  float xmini=1e38,ymini=1e38,zmini=1e38;
140 
141  std::vector<Point3df>::const_iterator it;
142  for (it=_vertex.begin();it!=_vertex.end();it++)
143  { if (it->item(0) < xmini) xmini = it->item(0);
144  if (it->item(1) < ymini) ymini = it->item(1);
145  if (it->item(2) < zmini) zmini = it->item(2);
146  }
147  _mini = Point3df(xmini,ymini,zmini);
148 }
149 
150 
151 template <int D,class T> inline
153 {
154  float xmaxi=-1e38,ymaxi=-1e38,zmaxi=-1e38;
155 
156  std::vector<Point3df>::const_iterator it;
157  for (it=_vertex.begin();it!=_vertex.end();it++)
158  { if (it->item(0) > xmaxi) xmaxi = it->item(0);
159  if (it->item(1) > ymaxi) ymaxi = it->item(1);
160  if (it->item(2) > zmaxi) zmaxi = it->item(2);
161  }
162  _maxi = Point3df(xmaxi,ymaxi,zmaxi);
163 }
164 
165 
166 template <int D,class T> inline
168 {
169  _vertex.erase( _vertex.begin() , _vertex.end() );
170  _normal.erase( _normal.begin() , _normal.end() );
171  _texture.erase( _texture.begin() , _texture.end() );
172  _polygon.erase( _polygon.begin() , _polygon.end() );
173 }
174 
175 
176 template <int D,class T> inline
178 {
179  // No general method to calculate normals
180  // see specialization for D=3 and T=Void
181 }
182 
183 
184 template <> inline
186 {
187  unsigned int i;
188  std::vector< Point3df >::size_type nVert=_vertex.size();
189  Polygons::size_type nPoly=_polygon.size();
190  std::vector<std::set<uint> > polyVert(_vertex.size());
191  Point3df norm;
192 
193  if (_normal.size() != nVert)
194  _normal.resize(nVert);
195 
196  // build vector of set(poly id)
197  for (i=0; i<nPoly; ++i)
198  for (Polygons::size_type j=0; j<3; j++)
199  polyVert[_polygon[i][j]].insert(i);
200 
201  // fill normals
202  for (i=0; i<nVert; ++i)
203  {
204  norm=Point3df(0.0); // for each point, run through polygons it belongs
205  std::set<uint>::const_iterator it;
206  for (it= polyVert[i].begin(); it != polyVert[i].end(); it++)
207  {
208  /* For each polygon which the point belongs to,
209  calculate area.Normal=0.5.(ABxAC) */
210  norm += crossed(
211  (_vertex[_polygon[(*it)][1]]-_vertex[_polygon[(*it)][0]]),
212  (_vertex[_polygon[(*it)][2]]-_vertex[_polygon[(*it)][0]]) ) * 0.5F;
213  }
214  norm.normalize();
215  _normal[i]=norm;
216  }
217 }
218 
219 
220 template <> inline
222 {
223  unsigned int i;
224  std::vector< Point3df >::size_type nVert=_vertex.size();
225  Polygons::size_type nPoly=_polygon.size();
226  std::vector<std::pair<std::set<uint>, std::set<uint> > >
227  polyVert(_vertex.size());
228  Point3df norm;
229 
230  if( _normal.size() != nVert )
231  _normal.resize( nVert );
232 
233  // build vector of set(poly id), each quad divided in 2 distinct triangles
234  for( i=0; i<nPoly; ++i )
235  {
236  polyVert[_polygon[i][0]].first.insert(i);
237  polyVert[_polygon[i][1]].first.insert(i);
238  polyVert[_polygon[i][2]].first.insert(i);
239  polyVert[_polygon[i][0]].second.insert(i);
240  polyVert[_polygon[i][2]].second.insert(i);
241  polyVert[_polygon[i][3]].second.insert(i);
242  }
243 
244  // fill normals
245  for( i=0; i<nVert; ++i )
246  {
247  norm=Point3df(0.0);
248  // for each point, run through triangles it belongs (both sets)
249  std::set<uint>::const_iterator it;
250  const std::pair<std::set<uint>, std::set<uint> > & polySet = polyVert[i];
251  for( it=polySet.first.begin(); it != polySet.first.end(); ++it )
252  {
253  /* For each polygon which the point belongs to,
254  calculate area.Normal=0.5.(ABxAC) */
255  norm += crossed(
256  (_vertex[_polygon[(*it)][1]]-_vertex[_polygon[(*it)][0]]),
257  (_vertex[_polygon[(*it)][2]]-_vertex[_polygon[(*it)][0]]) ) * 0.5F;
258  }
259  for( it=polySet.second.begin(); it != polySet.second.end(); ++it )
260  {
261  /* For each polygon which the point belongs to,
262  calculate area.Normal=0.5.(ABxAC) */
263  norm += crossed(
264  (_vertex[_polygon[(*it)][2]]-_vertex[_polygon[(*it)][0]]),
265  (_vertex[_polygon[(*it)][3]]-_vertex[_polygon[(*it)][0]]) ) * 0.5F;
266  }
267  norm.normalize();
268  _normal[i] = norm;
269  }
270 }
271 
272 
273 template <int D,class T> inline
274 std::ostream& operator << (std::ostream& out,const AimsSurface<D,T>& thing)
275 {
276  out << "{D=" << D << ","
277  << "vertex=" << thing.vertex().size() << ","
278  << "normal=" << thing.normal().size() << ","
279  << "texture=" << thing.texture().size() << ","
280  << "polygon=" << thing.polygon().size() << "}";
281 
282  return out;
283 }
284 
285 
286 //
287 // Mixing surface and time
288 //
289 
290 template <int D,class T = Void> class AimsTimeSurface;
291 
292 template <int D,class T> AIMSDATA_API
293 std::ostream& operator << ( std::ostream& out,
294  const AimsTimeSurface<D,T>& thing );
295 
303 template <int D,class T>
305  : public virtual carto::RCObject, public std::map< int, AimsSurface<D,T> >
306 {
307  public:
308  typedef typename std::map< int , AimsSurface<D,T> >::iterator iterator;
309  typedef typename std::map< int , AimsSurface<D,T> >::const_iterator
312  AimsTimeSurface() : std::map< int, AimsSurface<D,T> >() { }
314  virtual ~AimsTimeSurface() { }
315 
317  inline const aims::PythonHeader &header() const { return _header; }
318  inline aims::PythonHeader &header() { return _header; }
319 
321  void setHeader( const aims::PythonHeader &hdr ) { _header = hdr; }
322 
335  const std::vector<Point3df>& vertex() const
336  { return (*(AimsTimeSurface<D,T>*)this)[0].vertex(); }
338  std::vector<Point3df>& vertex() { return (*this)[0].vertex(); }
339 
341  const std::vector<Point3df>& normal() const
342  { return (*(AimsTimeSurface<D,T>*)this)[0].normal(); }
344  std::vector<Point3df>& normal() { return (*this)[0].normal(); }
345 
347  const std::vector<T>& texture() const
348  { return (*(AimsTimeSurface<D,T>*)this)[0].texture(); }
350  std::vector<T>& texture() { return (*this)[0].texture(); }
351 
353  const std::vector< AimsVector<uint,D> >& polygon() const
354  { return (*(AimsTimeSurface<D,T>*)this)[0].polygon(); }
356  std::vector< AimsVector<uint,D> >& polygon()
357  { return (*this)[0].polygon(); }
358 
360  Point3df minimum() const { return _mini; }
362  Point3df maximum() const { return _maxi; }
363 
365  inline void setMini();
367  inline void setMaxi();
368 
370  inline void erase();
371 
373  inline void updateNormals();
374 
376  friend
377  std::ostream& operator << <>( std::ostream& out,
378  const AimsTimeSurface<D,T>& thing );
380 
381  protected:
384  aims::PythonHeader _header;
391 };
392 
393 
394 #ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
395 
396 namespace carto
397 {
398 
399  template<int D, class T> class DataTypeCode<AimsTimeSurface<D,T> >
400  {
401  public:
402  static std::string objectType()
403  { return "Mesh"; }
404  static std::string dataType()
405  { return DataTypeCode<T>::dataType(); }
406  static std::string name()
407  {
408  return objectType() + std::string(" of ") + DataTypeCode< T >::name();
409  }
410  // Nothing about D ?
411  };
412 
413 
414  template<typename T> class DataTypeCode<AimsTimeSurface<2,T> >
415  {
416  public:
417  static std::string objectType()
418  { return "Segments"; }
419  static std::string dataType()
420  { return DataTypeCode<T>::dataType(); }
421  static std::string name()
422  {
423  return objectType() + std::string(" of ") + DataTypeCode< T >::name();
424  }
425  };
426 
427 
428  template<typename T> class DataTypeCode<AimsTimeSurface<4,T> >
429  {
430  public:
431  static std::string objectType()
432  { return "Mesh4"; }
433  static std::string dataType()
434  { return DataTypeCode<T>::dataType(); }
435  static std::string name()
436  {
437  return objectType() + std::string(" of ") + DataTypeCode< T >::name();
438  }
439  };
440 
441  /*
442  template<> inline std::string
443  DataTypeCode<AimsTimeSurface<3,Void> >::name()
444  {
445  return "mesh of VOID";
446  }
447  */
448 
449 }
450 
451 #endif // DOXYGEN_HIDE_INTERNAL_CLASSES
452 
453 
454 template <int D,class T> inline
456 {
457  typename AimsTimeSurface<D,T>::iterator it;
458  float xmini=1e38,ymini=1e38,zmini=1e38;
459  Point3df tmp;
460 
461  for (it=this->begin();it!=this->end();it++)
462  { ((*it).second).setMini();
463  tmp = ((*it).second).minimum();
464  if (tmp.item(0) < xmini) xmini = tmp.item(0);
465  if (tmp.item(1) < ymini) ymini = tmp.item(1);
466  if (tmp.item(2) < zmini) zmini = tmp.item(2);
467  }
468  _mini = Point3df(xmini,ymini,zmini);
469 }
470 
471 
472 template <int D,class T> inline
474 {
475  typename AimsTimeSurface<D,T>::iterator it;
476  float xmaxi=-1e38,ymaxi=-1e38,zmaxi=-1e38;
477  Point3df tmp;
478 
479  for (it=this->begin();it!=this->end();it++)
480  { ((*it).second).setMaxi();
481  tmp = ((*it).second).maximum();
482  if (tmp.item(0) > xmaxi) xmaxi = tmp.item(0);
483  if (tmp.item(1) > ymaxi) ymaxi = tmp.item(1);
484  if (tmp.item(2) > zmaxi) zmaxi = tmp.item(2);
485  }
486  _maxi = Point3df(xmaxi,ymaxi,zmaxi);
487 }
488 
489 
490 template <int D,class T> inline
492 {
493  typename AimsTimeSurface<D,T>::iterator it;
494  for (it=this->begin();it!=this->end();it++)
495  ((*it).second).erase();
496  std::map< int, AimsSurface<D,T> >::erase( this->begin(), this->end() );
497 }
498 
499 template <int D,class T> inline
501 {
502  // No general method to calculate normals
503  // see specialization for D=3 and T=Void
504 }
505 
506 
507 template <> inline
509 {
511  for (it=this->begin();it!=this->end();it++)
512  ((*it).second).updateNormals();
513 }
514 
515 
516 template <> inline
518 {
520  for (it=this->begin();it!=this->end();it++)
521  ((*it).second).updateNormals();
522 }
523 
524 
525 template <int D, class T> inline
526 std::ostream& operator << (std::ostream& out,
527  const AimsTimeSurface<D,T>& thing)
528 {
529  out << "{";
530 
532 
533  for (it=thing.begin();it!=thing.end();it++)
534  { out << "{";
535  out << "t=" << (*it).first << ",";
536  out << (*it).second << "},";
537  }
538 
539  return out << "NULL}" << std::flush;
540 }
541 
542 //
543 // Useful typedefs
544 //
545 
549 
550 namespace carto {
551 
555 
556 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< AimsSegments > )
558 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< AimsSurfaceFacet > )
559 
560 #define _mesh_type AimsTimeSurface<2, float>
562 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
563 #undef _mesh_type
564 #define _mesh_type AimsTimeSurface<3, float>
566 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
567 #undef _mesh_type
568 #define _mesh_type AimsTimeSurface<4, float>
570 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
571 #undef _mesh_type
572 #define _mesh_type AimsTimeSurface<2, Point2df>
574 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
575 #undef _mesh_type
576 #define _mesh_type AimsTimeSurface<3, Point2df>
578 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
579 #undef _mesh_type
580 #define _mesh_type AimsTimeSurface<4, Point2df>
582 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
583 #undef _mesh_type
584 
585 } // namespace carto
586 
587 #endif
#define DECLARE_GENERIC_OBJECT_TYPE(T)
Point3df maximum() const
Get the superior point of the box containing the mesh.
Definition: surface.h:116
void setMini()
Calculates the inferior point of the box containing all the meshes.
Definition: surface.h:455
void setMaxi()
Calculates the superior point of the box containing all the meshes.
Definition: surface.h:473
Attributed python-like header, stores all needed information about an object, currently used for volu...
Definition: pheader.h:51
void setMaxi()
Calculate the superior point of the box containing the mesh.
Definition: surface.h:152
AIMSDATA_API AimsTimeSurface< 3, Void > AimsSurfaceTriangle
Definition: surface.h:547
Polygons _polygon
Definition: surface.h:79
AIMSDATA_API AimsTimeSurface< 4, Void > AimsSurfaceFacet
Definition: surface.h:548
void erase()
Clear the mesh.
Definition: surface.h:167
Point3df minimum() const
Get the inferior point of the box containing all the meshes.
Definition: surface.h:360
#define AIMSDATA_API
STL namespace.
AIMSDATA_API AimsTimeSurface< 2, Void > AimsSegments
Definition: surface.h:546
const std::vector< Point3df > & vertex() const
Get a const reference to the vector of vertices.
Definition: surface.h:93
AimsVector< T, 3 > crossed(const AimsVector< T, D > &v1, const AimsVector< T, D > &v2)
std::vector< AimsVector< uint, D > > & polygon()
Get a non const reference to the vector of polygons of the 0 surface.
Definition: surface.h:356
std::map< int, AimsSurface< D, Void > >::iterator iterator
Definition: surface.h:308
#define _mesh_type
Definition: surface.h:580
The template class to manage a mesh with time if needed.
Definition: surface.h:290
AimsSurface()
Constructor does nothing special.
Definition: surface.h:88
std::vector< T > _texture
Vector of textures.
Definition: surface.h:76
const std::vector< T > & texture() const
Get a const reference to the vector of textures of the 0 surface.
Definition: surface.h:347
std::vector< AimsVector< uint, D > > & polygon()
Get a non const reference to the vector of polygons.
Definition: surface.h:111
const std::vector< AimsVector< uint, D > > & polygon() const
Get a const reference to the vector of polygons of the 0 surface.
Definition: surface.h:353
void updateNormals()
Update/Compute the normals.
Definition: surface.h:177
const std::vector< Point3df > & normal() const
Get a const reference to the vector of normals of the 0 surface.
Definition: surface.h:341
const std::vector< AimsVector< uint, D > > & polygon() const
Get a const reference to the vector of polygons.
Definition: surface.h:108
std::vector< Point3df > & normal()
Get a non const reference to the vector of normals of the 0 surface.
Definition: surface.h:344
std::vector< Point3df > _normal
Vector of normals.
Definition: surface.h:74
std::vector< Point3df > & vertex()
Get a non const reference to the vector of verteces.
Definition: surface.h:95
Point3df _maxi
Inferior point of the box containing all the meshes.
Definition: surface.h:389
Point3df maximum() const
Get the superior point of the box containing all the meshes.
Definition: surface.h:362
std::vector< T > & texture()
Get a non const reference to the vector of textures of the 0 surface.
Definition: surface.h:350
const std::vector< T > & texture() const
Get a const reference to the vector of textures.
Definition: surface.h:103
std::vector< Point3df > & vertex()
Get a non const reference to the vector of verteces of the 0 surface.
Definition: surface.h:338
void updateNormals()
Update/Compute the normals.
Definition: surface.h:500
The template class to manage a mesh.
Definition: surface.h:56
virtual ~AimsSurface()
Destructor does nothing.
Definition: surface.h:90
AIMSDATA_API std::ostream & operator<<(std::ostream &out, const AimsSurface< D, T > &thing)
Definition: surface.h:274
aims::PythonHeader & header()
Definition: surface.h:318
Point3df _mini
Inferior point of a box containing the whole mesh in the 3D space.
Definition: surface.h:82
Point3df _maxi
Superior point of a box containing the whole mesh in the 3D space.
Definition: surface.h:84
std::vector< T > & texture()
Get a non const reference to the vector of textures.
Definition: surface.h:105
Point3df minimum() const
Get the inferior point of the box containing the mesh.
Definition: surface.h:114
const std::vector< Point3df > & vertex() const
Get a const reference to the vector of verteces of the surface of index 0.
Definition: surface.h:335
virtual ~AimsTimeSurface()
Destructor does nothing.
Definition: surface.h:314
AIMSDATA_API float norm(const Tensor &thing)
Definition: tensor.h:141
Point3df _mini
Inferior point of the box containing all the meshes.
Definition: surface.h:387
std::vector< Point3df > & normal()
Get a non const reference to the vector of normals.
Definition: surface.h:100
std::map< int, AimsSurface< D, Void > >::const_iterator const_iterator
Definition: surface.h:310
AimsTimeSurface()
Constructor does nothing special.
Definition: surface.h:312
void setMini()
Calculate the inferior point of the box containing the mesh.
Definition: surface.h:137
void setHeader(const aims::PythonHeader &hdr)
Set the header.
Definition: surface.h:321
std::vector< AimsVector< uint, D > > Polygons
Vector of polygons.
Definition: surface.h:78
const T & item(int d) const
void erase()
Clear all the meshes.
Definition: surface.h:491
std::vector< Point3df > _vertex
Vector of vertices.
Definition: surface.h:72
const aims::PythonHeader & header() const
Get the header.
Definition: surface.h:317
const std::vector< Point3df > & normal() const
Get a const reference to the vector of normals.
Definition: surface.h:98