aimsdata 6.0.0
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
56template <int D,class T = Void> class AimsSurface;
57
58template <int D,class T> AIMSDATA_API
59std::ostream& operator << ( std::ostream& out, const AimsSurface<D,T>& thing);
60
61
67template <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; }
110
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
147template <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
162template <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
177template <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
187template <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
195template <> 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());
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
231template <> 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());
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
284template <int D,class T> inline
285std::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
301template <int D,class T = Void> class AimsTimeSurface;
302
303template <int D,class T> AIMSDATA_API
304std::ostream& operator << ( std::ostream& out,
305 const AimsTimeSurface<D,T>& thing );
306
314template <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 : std::map< int, AimsSurface<D,T> >( other ),
326 _mini( other._mini ), _maxi( other._maxi )
327 { _header.copy( other._header ); }
328
329 virtual ~AimsTimeSurface() { }
330
332 inline const aims::PythonHeader &header() const { return _header; }
333 inline aims::PythonHeader &header() { return _header; }
334
336 void setHeader( const aims::PythonHeader &hdr ) { _header = hdr; }
337
348 const std::vector<Point3df>& vertex() const
349 { return (*(AimsTimeSurface<D,T>*)this)[0].vertex(); }
350
351 std::vector<Point3df>& vertex() { return (*this)[0].vertex(); }
352
354 const std::vector<Point3df>& normal() const
355 { return (*(AimsTimeSurface<D,T>*)this)[0].normal(); }
356
357 std::vector<Point3df>& normal() { return (*this)[0].normal(); }
358
360 const std::vector<T>& texture() const
361 { return (*(AimsTimeSurface<D,T>*)this)[0].texture(); }
362
363 std::vector<T>& texture() { return (*this)[0].texture(); }
364
366 const std::vector< AimsVector<uint,D> >& polygon() const
367 { return (*(AimsTimeSurface<D,T>*)this)[0].polygon(); }
368
369 std::vector< AimsVector<uint,D> >& polygon()
370 { return (*this)[0].polygon(); }
371
373 Point3df minimum() const { return _mini; }
375 Point3df maximum() const { return _maxi; }
376
378 inline void setMini();
380 inline void setMaxi();
381
383 inline void erase();
384
386 inline void updateNormals();
387
388 bool operator == ( const AimsTimeSurface<D,T> & ) const;
389 inline bool operator != ( const AimsTimeSurface<D, T> & other ) const
390 {
391 return !( *this == other );
392 }
393
394 AimsTimeSurface<D, T> & operator = ( const AimsTimeSurface<D, T> & other )
395 {
396 std::map<int, AimsSurface<D, T> >::operator = ( other );
397 _header.copy( other._header );
398 _mini = other._mini;
399 _maxi = other._maxi;
400
401 return *this;
402 }
403
405 friend
406 std::ostream& operator << <>( std::ostream& out,
407 const AimsTimeSurface<D,T>& thing );
408
409 protected:
412
419};
420
421
422#ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
423
424namespace carto
425{
426
427 template<int D, class T> class DataTypeCode<AimsTimeSurface<D,T> >
428 {
429 public:
430 static std::string objectType()
431 { return "Mesh"; }
432 static std::string dataType()
433 { return DataTypeCode<T>::dataType(); }
434 static std::string name()
435 {
436 return objectType() + std::string(" of ") + DataTypeCode< T >::name();
437 }
438 // Nothing about D ?
439 };
440
441
442 template<typename T> class DataTypeCode<AimsTimeSurface<2,T> >
443 {
444 public:
445 static std::string objectType()
446 { return "Segments"; }
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<typename T> class DataTypeCode<AimsTimeSurface<4,T> >
457 {
458 public:
459 static std::string objectType()
460 { return "Mesh4"; }
461 static std::string dataType()
462 { return DataTypeCode<T>::dataType(); }
463 static std::string name()
464 {
465 return objectType() + std::string(" of ") + DataTypeCode< T >::name();
466 }
467 };
468
469 /*
470 template<> inline std::string
471 DataTypeCode<AimsTimeSurface<3,Void> >::name()
472 {
473 return "mesh of VOID";
474 }
475 */
476
477}
478
479#endif // DOXYGEN_HIDE_INTERNAL_CLASSES
480
481
482template <int D,class T> inline
484{
486 float xmini=1e38,ymini=1e38,zmini=1e38;
487 Point3df tmp;
488
489 for (it=this->begin();it!=this->end();it++)
490 { ((*it).second).setMini();
491 tmp = ((*it).second).minimum();
492 if (tmp.item(0) < xmini) xmini = tmp.item(0);
493 if (tmp.item(1) < ymini) ymini = tmp.item(1);
494 if (tmp.item(2) < zmini) zmini = tmp.item(2);
495 }
496 _mini = Point3df(xmini,ymini,zmini);
497}
498
499
500template <int D,class T> inline
502{
504 float xmaxi=-1e38,ymaxi=-1e38,zmaxi=-1e38;
505 Point3df tmp;
506
507 for (it=this->begin();it!=this->end();it++)
508 { ((*it).second).setMaxi();
509 tmp = ((*it).second).maximum();
510 if (tmp.item(0) > xmaxi) xmaxi = tmp.item(0);
511 if (tmp.item(1) > ymaxi) ymaxi = tmp.item(1);
512 if (tmp.item(2) > zmaxi) zmaxi = tmp.item(2);
513 }
514 _maxi = Point3df(xmaxi,ymaxi,zmaxi);
515}
516
517
518template <int D,class T> inline
520{
522 for (it=this->begin();it!=this->end();it++)
523 ((*it).second).erase();
524 std::map< int, AimsSurface<D,T> >::erase( this->begin(), this->end() );
525}
526
527template <int D,class T> inline
529{
530 // No general method to calculate normals
531 // see specialization for D=3 and T=Void
532}
533
534
535template <> inline
537{
539 for (it=this->begin();it!=this->end();it++)
540 ((*it).second).updateNormals();
541}
542
543
544template <> inline
546{
548 for (it=this->begin();it!=this->end();it++)
549 ((*it).second).updateNormals();
550}
551
552
553template <int D, typename T> inline
555 const
556{
557 if( this->size() != other.size() )
558 return false;
559 if( header() != other.header() )
560 return false;
561 const_iterator i, j, e = this->end();
562 for( i=this->begin(), j=other.begin(); i!=e; ++i, ++j )
563 {
564 if( i->first != j->first )
565 return false;
566 if( i->second != j->second )
567 return false;
568 }
569 return true;
570}
571
572
573template <int D, class T> inline
574std::ostream& operator << (std::ostream& out,
575 const AimsTimeSurface<D,T>& thing)
576{
577 out << "{";
578
580
581 for (it=thing.begin();it!=thing.end();it++)
582 { out << "{";
583 out << "t=" << (*it).first << ",";
584 out << (*it).second << "},";
585 }
586
587 return out << "NULL}" << std::flush;
588}
589
590//
591// Useful typedefs
592//
593
597
598namespace carto {
599
603
604DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< AimsSegments > )
605DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< AimsSurfaceTriangle > )
606DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< AimsSurfaceFacet > )
607
608#define _mesh_type AimsTimeSurface<2, float>
610DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
611#undef _mesh_type
612#define _mesh_type AimsTimeSurface<3, float>
614DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
615#undef _mesh_type
616#define _mesh_type AimsTimeSurface<4, float>
618DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
619#undef _mesh_type
620#define _mesh_type AimsTimeSurface<2, Point2df>
622DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
623#undef _mesh_type
624#define _mesh_type AimsTimeSurface<3, Point2df>
626DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
627#undef _mesh_type
628#define _mesh_type AimsTimeSurface<4, Point2df>
630DECLARE_GENERIC_OBJECT_TYPE( rc_ptr< _mesh_type > )
631#undef _mesh_type
632
633} // namespace carto
634
635#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
const std::vector< Point3df > & normal() const
Get a const reference to the vector of normals.
Definition surface.h:98
void erase()
Clear the mesh.
Definition surface.h:178
std::vector< Point3df > _normal
Definition surface.h:74
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
const std::vector< AimsVector< uint, D > > & polygon() const
Get a const reference to the vector of polygons.
Definition surface.h:108
std::vector< Point3df > _vertex
Definition surface.h:72
std::vector< T > & texture()
Get a non const reference to the vector of textures.
Definition surface.h:105
std::vector< Point3df > & normal()
Get a non const reference to the vector of normals.
Definition surface.h:100
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
std::vector< Point3df > & vertex()
Get a non const reference to the vector of verteces.
Definition surface.h:95
void setMini()
Calculate the inferior point of the box containing the mesh.
Definition surface.h:148
std::vector< Void > _texture
Definition surface.h:76
const std::vector< T > & texture() const
Get a const reference to the vector of textures.
Definition surface.h:103
const std::vector< Point3df > & vertex() const
Get a const reference to the vector of vertices.
Definition surface.h:93
std::vector< AimsVector< uint, D > > Polygons
Definition surface.h:78
std::vector< AimsVector< uint, D > > & polygon()
Get a non const reference to the vector of polygons.
Definition surface.h:111
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:373
void erase()
Clear all the meshes.
Definition surface.h:519
Point3df maximum() const
Get the superior point of the box containing all the meshes.
Definition surface.h:375
bool operator==(const AimsTimeSurface< D, T > &) const
Definition surface.h:554
void setHeader(const aims::PythonHeader &hdr)
Set the header.
Definition surface.h:336
const aims::PythonHeader & header() const
Get the header.
Definition surface.h:332
aims::PythonHeader _header
Definition surface.h:413
std::map< int, AimsSurface< D, Void > >::const_iterator const_iterator
Definition surface.h:321
const std::vector< Point3df > & normal() const
Get a const reference to the vector of normals of the 0 surface.
Definition surface.h:354
const std::vector< AimsVector< uint, D > > & polygon() const
Get a const reference to the vector of polygons of the 0 surface.
Definition surface.h:366
std::vector< T > & texture()
Get a non const reference to the vector of textures of the 0 surface.
Definition surface.h:363
virtual ~AimsTimeSurface()
Destructor does nothing.
Definition surface.h:329
const std::vector< T > & texture() const
Get a const reference to the vector of textures of the 0 surface.
Definition surface.h:360
std::map< int, AimsSurface< D, Void > >::iterator iterator
Definition surface.h:319
void setMini()
Calculates the inferior point of the box containing all the meshes.
Definition surface.h:483
void updateNormals()
Update/Compute the normals.
Definition surface.h:528
AimsTimeSurface(const AimsTimeSurface< D, T > &other)
Definition surface.h:324
std::vector< AimsVector< uint, D > > & polygon()
Get a non const reference to the vector of polygons of the 0 surface.
Definition surface.h:369
std::vector< Point3df > & vertex()
Get a non const reference to the vector of verteces of the 0 surface.
Definition surface.h:351
void setMaxi()
Calculates the superior point of the box containing all the meshes.
Definition surface.h:501
std::vector< Point3df > & normal()
Get a non const reference to the vector of normals of the 0 surface.
Definition surface.h:357
aims::PythonHeader & header()
Definition surface.h:333
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:348
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()
STL namespace.
#define DECLARE_GENERIC_OBJECT_TYPE(T)
AIMSDATA_API AimsTimeSurface< 3, Void > AimsSurfaceTriangle
Definition surface.h:595
#define _mesh_type
Definition surface.h:608
AIMSDATA_API std::ostream & operator<<(std::ostream &out, const AimsSurface< D, T > &thing)
Definition surface.h:285
AIMSDATA_API AimsTimeSurface< 2, Void > AimsSegments
Definition surface.h:594
AIMSDATA_API AimsTimeSurface< 4, Void > AimsSurfaceFacet
Definition surface.h:596
AimsVector< float, 3 > Point3df
AimsVector< T, 3 > crossed(const AimsVector< T, D > &v1, const AimsVector< T, D > &v2)
float norm(const AimsVector< T, D > &v1)