aimsdata  5.1.2
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;
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 
129  inline bool operator == ( const AimsSurface<D, T> & s ) const
130  {
131  return _vertex == s._vertex && _normal == s._normal
132  && _polygon == s._polygon && _texture == s._texture;
133  }
134  inline bool operator != ( const AimsSurface<D, T> & s ) const
135  {
136  return !( *this == s );
137  }
138 
140  friend
141  std::ostream& operator << <>( std::ostream& out,
142  const AimsSurface<D,T>& thing );
143 
144 };
145 
146 
147 template <int D,class T> inline
149 {
150  float xmini=1e38,ymini=1e38,zmini=1e38;
151 
152  std::vector<Point3df>::const_iterator it;
153  for (it=_vertex.begin();it!=_vertex.end();it++)
154  { if (it->item(0) < xmini) xmini = it->item(0);
155  if (it->item(1) < ymini) ymini = it->item(1);
156  if (it->item(2) < zmini) zmini = it->item(2);
157  }
158  _mini = Point3df(xmini,ymini,zmini);
159 }
160 
161 
162 template <int D,class T> inline
164 {
165  float xmaxi=-1e38,ymaxi=-1e38,zmaxi=-1e38;
166 
167  std::vector<Point3df>::const_iterator it;
168  for (it=_vertex.begin();it!=_vertex.end();it++)
169  { if (it->item(0) > xmaxi) xmaxi = it->item(0);
170  if (it->item(1) > ymaxi) ymaxi = it->item(1);
171  if (it->item(2) > zmaxi) zmaxi = it->item(2);
172  }
173  _maxi = Point3df(xmaxi,ymaxi,zmaxi);
174 }
175 
176 
177 template <int D,class T> inline
179 {
180  _vertex.erase( _vertex.begin() , _vertex.end() );
181  _normal.erase( _normal.begin() , _normal.end() );
182  _texture.erase( _texture.begin() , _texture.end() );
183  _polygon.erase( _polygon.begin() , _polygon.end() );
184 }
185 
186 
187 template <int D,class T> inline
189 {
190  // No general method to calculate normals
191  // see specialization for D=3 and T=Void
192 }
193 
194 
195 template <> inline
197 {
198  unsigned int i;
199  std::vector< Point3df >::size_type nVert=_vertex.size();
200  Polygons::size_type nPoly=_polygon.size();
201  std::vector<std::set<uint> > polyVert(_vertex.size());
202  Point3df norm;
203 
204  if (_normal.size() != nVert)
205  _normal.resize(nVert);
206 
207  // build vector of set(poly id)
208  for (i=0; i<nPoly; ++i)
209  for (Polygons::size_type j=0; j<3; j++)
210  polyVert[_polygon[i][j]].insert(i);
211 
212  // fill normals
213  for (i=0; i<nVert; ++i)
214  {
215  norm=Point3df(0.0); // for each point, run through polygons it belongs
216  std::set<uint>::const_iterator it;
217  for (it= polyVert[i].begin(); it != polyVert[i].end(); it++)
218  {
219  /* For each polygon which the point belongs to,
220  calculate area.Normal=0.5.(ABxAC) */
221  norm += crossed(
222  (_vertex[_polygon[(*it)][1]]-_vertex[_polygon[(*it)][0]]),
223  (_vertex[_polygon[(*it)][2]]-_vertex[_polygon[(*it)][0]]) ) * 0.5F;
224  }
225  norm.normalize();
226  _normal[i]=norm;
227  }
228 }
229 
230 
231 template <> inline
233 {
234  unsigned int i;
235  std::vector< Point3df >::size_type nVert=_vertex.size();
236  Polygons::size_type nPoly=_polygon.size();
237  std::vector<std::pair<std::set<uint>, std::set<uint> > >
238  polyVert(_vertex.size());
239  Point3df norm;
240 
241  if( _normal.size() != nVert )
242  _normal.resize( nVert );
243 
244  // build vector of set(poly id), each quad divided in 2 distinct triangles
245  for( i=0; i<nPoly; ++i )
246  {
247  polyVert[_polygon[i][0]].first.insert(i);
248  polyVert[_polygon[i][1]].first.insert(i);
249  polyVert[_polygon[i][2]].first.insert(i);
250  polyVert[_polygon[i][0]].second.insert(i);
251  polyVert[_polygon[i][2]].second.insert(i);
252  polyVert[_polygon[i][3]].second.insert(i);
253  }
254 
255  // fill normals
256  for( i=0; i<nVert; ++i )
257  {
258  norm=Point3df(0.0);
259  // for each point, run through triangles it belongs (both sets)
260  std::set<uint>::const_iterator it;
261  const std::pair<std::set<uint>, std::set<uint> > & polySet = polyVert[i];
262  for( it=polySet.first.begin(); it != polySet.first.end(); ++it )
263  {
264  /* For each polygon which the point belongs to,
265  calculate area.Normal=0.5.(ABxAC) */
266  norm += crossed(
267  (_vertex[_polygon[(*it)][1]]-_vertex[_polygon[(*it)][0]]),
268  (_vertex[_polygon[(*it)][2]]-_vertex[_polygon[(*it)][0]]) ) * 0.5F;
269  }
270  for( it=polySet.second.begin(); it != polySet.second.end(); ++it )
271  {
272  /* For each polygon which the point belongs to,
273  calculate area.Normal=0.5.(ABxAC) */
274  norm += crossed(
275  (_vertex[_polygon[(*it)][2]]-_vertex[_polygon[(*it)][0]]),
276  (_vertex[_polygon[(*it)][3]]-_vertex[_polygon[(*it)][0]]) ) * 0.5F;
277  }
278  norm.normalize();
279  _normal[i] = norm;
280  }
281 }
282 
283 
284 template <int D,class T> inline
285 std::ostream& operator << (std::ostream& out,const AimsSurface<D,T>& thing)
286 {
287  out << "{D=" << D << ","
288  << "vertex=" << thing.vertex().size() << ","
289  << "normal=" << thing.normal().size() << ","
290  << "texture=" << thing.texture().size() << ","
291  << "polygon=" << thing.polygon().size() << "}";
292 
293  return out;
294 }
295 
296 
297 //
298 // Mixing surface and time
299 //
300 
301 template <int D,class T = Void> class AimsTimeSurface;
302 
303 template <int D,class T> AIMSDATA_API
304 std::ostream& operator << ( std::ostream& out,
305  const AimsTimeSurface<D,T>& thing );
306 
314 template <int D,class T>
316  : public virtual carto::RCObject, public std::map< int, AimsSurface<D,T> >
317 {
318  public:
319  typedef typename std::map< int , AimsSurface<D,T> >::iterator iterator;
320  typedef typename std::map< int , AimsSurface<D,T> >::const_iterator
323  AimsTimeSurface() : std::map< int, AimsSurface<D,T> >() { }
325  virtual ~AimsTimeSurface() { }
326 
328  inline const aims::PythonHeader &header() const { return _header; }
329  inline aims::PythonHeader &header() { return _header; }
330 
332  void setHeader( const aims::PythonHeader &hdr ) { _header = hdr; }
333 
344  const std::vector<Point3df>& vertex() const
345  { return (*(AimsTimeSurface<D,T>*)this)[0].vertex(); }
347  std::vector<Point3df>& vertex() { return (*this)[0].vertex(); }
348 
350  const std::vector<Point3df>& normal() const
351  { return (*(AimsTimeSurface<D,T>*)this)[0].normal(); }
353  std::vector<Point3df>& normal() { return (*this)[0].normal(); }
354 
356  const std::vector<T>& texture() const
357  { return (*(AimsTimeSurface<D,T>*)this)[0].texture(); }
359  std::vector<T>& texture() { return (*this)[0].texture(); }
360 
362  const std::vector< AimsVector<uint,D> >& polygon() const
363  { return (*(AimsTimeSurface<D,T>*)this)[0].polygon(); }
365  std::vector< AimsVector<uint,D> >& polygon()
366  { return (*this)[0].polygon(); }
367 
369  Point3df minimum() const { return _mini; }
371  Point3df maximum() const { return _maxi; }
372 
374  inline void setMini();
376  inline void setMaxi();
377 
379  inline void erase();
380 
382  inline void updateNormals();
383 
384  bool operator == ( const AimsTimeSurface<D,T> & ) const;
385  inline bool operator != ( const AimsTimeSurface<D, T> & other ) const
386  {
387  return !( *this == other );
388  }
389 
391  friend
392  std::ostream& operator << <>( std::ostream& out,
393  const AimsTimeSurface<D,T>& thing );
394 
395  protected:
405 };
406 
407 
408 #ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
409 
410 namespace carto
411 {
412 
413  template<int D, class T> class DataTypeCode<AimsTimeSurface<D,T> >
414  {
415  public:
416  static std::string objectType()
417  { return "Mesh"; }
418  static std::string dataType()
419  { return DataTypeCode<T>::dataType(); }
420  static std::string name()
421  {
422  return objectType() + std::string(" of ") + DataTypeCode< T >::name();
423  }
424  // Nothing about D ?
425  };
426 
427 
428  template<typename T> class DataTypeCode<AimsTimeSurface<2,T> >
429  {
430  public:
431  static std::string objectType()
432  { return "Segments"; }
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<typename T> class DataTypeCode<AimsTimeSurface<4,T> >
443  {
444  public:
445  static std::string objectType()
446  { return "Mesh4"; }
447  static std::string dataType()
448  { return DataTypeCode<T>::dataType(); }
449  static std::string name()
450  {
451  return objectType() + std::string(" of ") + DataTypeCode< T >::name();
452  }
453  };
454 
455  /*
456  template<> inline std::string
457  DataTypeCode<AimsTimeSurface<3,Void> >::name()
458  {
459  return "mesh of VOID";
460  }
461  */
462 
463 }
464 
465 #endif // DOXYGEN_HIDE_INTERNAL_CLASSES
466 
467 
468 template <int D,class T> inline
470 {
471  typename AimsTimeSurface<D,T>::iterator it;
472  float xmini=1e38,ymini=1e38,zmini=1e38;
473  Point3df tmp;
474 
475  for (it=this->begin();it!=this->end();it++)
476  { ((*it).second).setMini();
477  tmp = ((*it).second).minimum();
478  if (tmp.item(0) < xmini) xmini = tmp.item(0);
479  if (tmp.item(1) < ymini) ymini = tmp.item(1);
480  if (tmp.item(2) < zmini) zmini = tmp.item(2);
481  }
482  _mini = Point3df(xmini,ymini,zmini);
483 }
484 
485 
486 template <int D,class T> inline
488 {
489  typename AimsTimeSurface<D,T>::iterator it;
490  float xmaxi=-1e38,ymaxi=-1e38,zmaxi=-1e38;
491  Point3df tmp;
492 
493  for (it=this->begin();it!=this->end();it++)
494  { ((*it).second).setMaxi();
495  tmp = ((*it).second).maximum();
496  if (tmp.item(0) > xmaxi) xmaxi = tmp.item(0);
497  if (tmp.item(1) > ymaxi) ymaxi = tmp.item(1);
498  if (tmp.item(2) > zmaxi) zmaxi = tmp.item(2);
499  }
500  _maxi = Point3df(xmaxi,ymaxi,zmaxi);
501 }
502 
503 
504 template <int D,class T> inline
506 {
507  typename AimsTimeSurface<D,T>::iterator it;
508  for (it=this->begin();it!=this->end();it++)
509  ((*it).second).erase();
510  std::map< int, AimsSurface<D,T> >::erase( this->begin(), this->end() );
511 }
512 
513 template <int D,class T> inline
515 {
516  // No general method to calculate normals
517  // see specialization for D=3 and T=Void
518 }
519 
520 
521 template <> inline
523 {
525  for (it=this->begin();it!=this->end();it++)
526  ((*it).second).updateNormals();
527 }
528 
529 
530 template <> inline
532 {
534  for (it=this->begin();it!=this->end();it++)
535  ((*it).second).updateNormals();
536 }
537 
538 
539 template <int D, typename T> inline
541  const
542 {
543  if( this->size() != other.size() )
544  return false;
545  if( header() != other.header() )
546  return false;
547  const_iterator i, j, e = this->end();
548  for( i=this->begin(), j=other.begin(); i!=e; ++i, ++j )
549  {
550  if( i->first != j->first )
551  return false;
552  if( i->second != j->second )
553  return false;
554  }
555  return true;
556 }
557 
558 
559 template <int D, class T> inline
560 std::ostream& operator << (std::ostream& out,
561  const AimsTimeSurface<D,T>& thing)
562 {
563  out << "{";
564 
566 
567  for (it=thing.begin();it!=thing.end();it++)
568  { out << "{";
569  out << "t=" << (*it).first << ",";
570  out << (*it).second << "},";
571  }
572 
573  return out << "NULL}" << std::flush;
574 }
575 
576 //
577 // Useful typedefs
578 //
579 
583 
584 namespace carto {
585 
589 
590 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< AimsSegments > )
592 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< AimsSurfaceFacet > )
593 
594 #define _mesh_type AimsTimeSurface<2, float>
596 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
597 #undef _mesh_type
598 #define _mesh_type AimsTimeSurface<3, float>
600 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
601 #undef _mesh_type
602 #define _mesh_type AimsTimeSurface<4, float>
604 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
605 #undef _mesh_type
606 #define _mesh_type AimsTimeSurface<2, Point2df>
608 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
609 #undef _mesh_type
610 #define _mesh_type AimsTimeSurface<3, Point2df>
612 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
613 #undef _mesh_type
614 #define _mesh_type AimsTimeSurface<4, Point2df>
616 DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
617 #undef _mesh_type
618 
619 } // namespace carto
620 
621 #endif
#define AIMSDATA_API
The template class to manage a mesh.
Definition: surface.h:69
Point3df maximum() const
Get the superior point of the box containing the mesh.
Definition: surface.h:116
AimsSurface()
Constructor does nothing special.
Definition: surface.h:88
std::vector< AimsVector< uint, D > > & polygon()
Get a non const reference to the vector of polygons.
Definition: surface.h:111
void erase()
Clear the mesh.
Definition: surface.h:178
const std::vector< Point3df > & normal() const
Get a const reference to the vector of normals.
Definition: surface.h:98
std::vector< Point3df > _normal
Vector of normals.
Definition: surface.h:74
std::vector< Point3df > & normal()
Get a non const reference to the vector of normals.
Definition: surface.h:100
virtual ~AimsSurface()
Destructor does nothing.
Definition: surface.h:90
void setMaxi()
Calculate the superior point of the box containing the mesh.
Definition: surface.h:163
Point3df _mini
Inferior point of a box containing the whole mesh in the 3D space.
Definition: surface.h:82
std::vector< Point3df > _vertex
Vector of vertices.
Definition: surface.h:72
const std::vector< Point3df > & vertex() const
Get a const reference to the vector of vertices.
Definition: surface.h:93
void updateNormals()
Update/Compute the normals.
Definition: surface.h:188
Point3df minimum() const
Get the inferior point of the box containing the mesh.
Definition: surface.h:114
Point3df _maxi
Superior point of a box containing the whole mesh in the 3D space.
Definition: surface.h:84
std::vector< Point3df > & vertex()
Get a non const reference to the vector of verteces.
Definition: surface.h:95
Polygons _polygon
Definition: surface.h:79
void setMini()
Calculate the inferior point of the box containing the mesh.
Definition: surface.h:148
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.
Definition: surface.h:103
std::vector< T > & texture()
Get a non const reference to the vector of textures.
Definition: surface.h:105
const std::vector< AimsVector< uint, D > > & polygon() const
Get a const reference to the vector of polygons.
Definition: surface.h:108
std::vector< AimsVector< uint, D > > Polygons
Vector of polygons.
Definition: surface.h:78
The template class to manage a mesh with time if needed.
Definition: surface.h:317
Point3df minimum() const
Get the inferior point of the box containing all the meshes.
Definition: surface.h:369
void erase()
Clear all the meshes.
Definition: surface.h:505
Point3df maximum() const
Get the superior point of the box containing all the meshes.
Definition: surface.h:371
bool operator==(const AimsTimeSurface< D, T > &) const
Definition: surface.h:540
void setHeader(const aims::PythonHeader &hdr)
Set the header.
Definition: surface.h:332
aims::PythonHeader _header
Header.
Definition: surface.h:399
const std::vector< AimsVector< uint, D > > & polygon() const
Get a const reference to the vector of polygons of the 0 surface.
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:359
std::vector< Point3df > & normal()
Get a non const reference to the vector of normals of the 0 surface.
Definition: surface.h:353
const std::vector< T > & texture() const
Get a const reference to the vector of textures of the 0 surface.
Definition: surface.h:356
std::map< int, AimsSurface< D, T > >::iterator iterator
Definition: surface.h:319
virtual ~AimsTimeSurface()
Destructor does nothing.
Definition: surface.h:325
const aims::PythonHeader & header() const
Get the header.
Definition: surface.h:328
std::map< int, AimsSurface< D, T > >::const_iterator const_iterator
Definition: surface.h:321
std::vector< Point3df > & vertex()
Get a non const reference to the vector of verteces of the 0 surface.
Definition: surface.h:347
aims::PythonHeader & header()
Definition: surface.h:329
void setMini()
Calculates the inferior point of the box containing all the meshes.
Definition: surface.h:469
void updateNormals()
Update/Compute the normals.
Definition: surface.h:514
const std::vector< Point3df > & normal() const
Get a const reference to the vector of normals of the 0 surface.
Definition: surface.h:350
Point3df _maxi
Inferior point of the box containing all the meshes.
Definition: surface.h:403
std::vector< AimsVector< uint, D > > & polygon()
Get a non const reference to the vector of polygons of the 0 surface.
Definition: surface.h:365
void setMaxi()
Calculates the superior point of the box containing all the meshes.
Definition: surface.h:487
AimsTimeSurface()
Constructor does nothing special.
Definition: surface.h:323
const std::vector< Point3df > & vertex() const
Get a const reference to the vector of verteces of the surface of index 0.
Definition: surface.h:344
Point3df _mini
Inferior point of the box containing all the meshes.
Definition: surface.h:401
const T & item(int d) const
Attributed python-like header, stores all needed information about an object, currently used for volu...
Definition: pheader.h:52
std::string name()
std::string objectType()
std::string dataType()
int operator==(const AimsBucketItem< T > &thing1, const AimsBucketItem< T > &thing2)
Definition: item.h:110
#define DECLARE_GENERIC_OBJECT_TYPE(T)
AIMSDATA_API AimsTimeSurface< 3, Void > AimsSurfaceTriangle
Definition: surface.h:581
AIMSDATA_API std::ostream & operator<<(std::ostream &out, const AimsSurface< D, T > &thing)
Definition: surface.h:285
#define _mesh_type
Definition: surface.h:614
AIMSDATA_API AimsTimeSurface< 2, Void > AimsSegments
Definition: surface.h:580
AIMSDATA_API AimsTimeSurface< 4, Void > AimsSurfaceFacet
Definition: surface.h:582
AIMSDATA_API float norm(const Tensor &thing)
Definition: tensor.h:141
AimsVector< T, 3 > crossed(const AimsVector< T, D > &v1, const AimsVector< T, D > &v2)