aimsdata  5.1.2
Neuroimaging data handling
surfacemanip_d.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 #ifndef AIMS_SURFACE_SURFACEOPERATION_D_H
35 #define AIMS_SURFACE_SURFACEOPERATION_D_H
36 
37 #include <aims/mesh/surfacemanip.h>
38 #include <aims/mesh/texture.h>
39 #include <aims/resampling/motion.h>
40 
41 namespace aims
42 {
43 
44  template<int D, class T> std::vector<std::set<uint> >
46  {
47  const std::vector< AimsVector<uint,D> > & poly = surf.polygon();
48  uint n = poly.size();
49  std::vector<std::set<uint> > neigh( surf.vertex().size() );
50 
51  for ( uint i=0; i<n; ++i )
52  for ( uint j=0; j<D; ++j )
53  for ( uint k=0; k<D; ++k )
54  if ( j != k )
55  neigh[poly[i][j]].insert( poly[i][k] );
56 
57  return neigh;
58  }
59 
60  template<int D, class T> std::vector<std::set<uint> >
62  {
63  const std::vector< AimsVector<uint,D> > & poly = surf.polygon();
64  uint n = poly.size();
65  std::vector<std::set<uint> > neigh( surf.vertex().size() );
66 
67  for ( uint i=0; i<n; ++i )
68  for ( uint j=0; j<D; ++j )
69  for ( uint k=0; k<D; ++k )
70  if ( j != k )
71  neigh[poly[i][j]].insert( poly[i][k] );
72 
73  return neigh;
74  }
75 
76  template<int D, class T> std::vector<std::set<uint> >
78  {
79  const std::vector< AimsVector<uint,D> > & poly = surf.polygon();
80  uint n = poly.size();
81  std::vector<std::set<uint> > neigh( surf.vertex().size() );
82  std::vector<std::set<uint> > neigh_final( surf.vertex().size() );
83 
84  for ( uint i=0; i<n; ++i )
85  for ( uint j=0; j<D; ++j )
86  for ( uint k=0; k<D; ++k )
87  if ( j != k )
88  neigh[poly[i][j]].insert( poly[i][k] );
89 
90  for ( uint i=0; i<neigh.size() ; ++i)
91  {
92  std::set<uint> voisin=neigh[i];
93  std::set<uint> voisin_final=neigh[i];
94  std::set<uint>::iterator voisin_pt=voisin.begin();
95  for ( ; voisin_pt!=voisin.end(); ++voisin_pt)
96  {
97  uint j=*voisin_pt;
98  std::set<uint> vois2=neigh[j];
99  std::set<uint>::iterator v_pt=vois2.begin();
100  for ( ; v_pt!=vois2.end(); ++v_pt)
101  voisin_final.insert(*v_pt);
102  }
103  neigh_final[i]=voisin_final;
104  }
105 
106  return neigh_final;
107  }
108 
109 
110  template<int D, class T> std::vector<std::map<uint, float> >
112  {
113  const std::vector< AimsVector<uint,D> > & poly = surf.polygon();
114  uint n = poly.size();
115  const std::vector<Point3df> & vert = surf.vertex();
116  std::vector<std::map<uint, float> > neighDist(surf.vertex().size());
117  Point3df diff;
118  float dist;
119 
120  for ( uint i=0; i<n; ++i )
121  for ( uint j=0; j<D; ++j )
122  for ( uint k=0; k<D; ++k )
123  if ( j != k )
124  {
125  diff=vert[poly[i][j]] - vert[poly[i][k]]; // COURANT - VOISIN
126  dist = diff.norm(); //DISTANCE ENTRE LES DEUX;
127  neighDist[poly[i][j]][poly[i][k]] = dist;
128  }
129 
130  return neighDist;
131  }
132 
133  template<int D, class T>
135  {
136  typename AimsTimeSurface<D,T>::iterator is, fs=surface.end();
137  typename std::vector< AimsVector<uint,D> >::iterator ip, fp;
138  uint n = D/2;
139  for ( is=surface.begin(); is!=fs; ++is )
140  {
141  AimsSurface<D, T> & surf = is->second;
142  std::vector< AimsVector<uint,D> > & poly = surf.polygon();
143 
144  for ( ip=poly.begin(), fp=poly.end(); ip!=fp; ++ip )
145  {
146  AimsVector<uint,D> & p = *ip;
147  for ( uint i=0; i<n; ++i )
148  {
149  uint vert = p[i];
150  p[i] = p[D-i-1];
151  p[D-i-1] = vert;
152  }
153  }
154  }
155  }
156 
157 
158  template<int D, class T>
160  const AimsTimeSurface<D,T> & add )
161  {
162  typename AimsTimeSurface<D, T>::const_iterator is, es = add.end();
164 
165  for( is=add.begin(); is!=es; ++is )
166  {
167  int t = is->first;
168  const AimsSurface<D, T> & imesh = is->second;
169  AimsSurface<D, T> & omesh = dst[t];
170  std::vector<Point3df> & vert = omesh.vertex();
171  std::vector<Point3df> & norm = omesh.normal();
172  std::vector<AimsVector<uint,D> > & poly = omesh.polygon();
173  const std::vector<Point3df> & vert2 = imesh.vertex();
174  const std::vector<Point3df> & norm2 = imesh.normal();
175  const std::vector<AimsVector<uint,D> > & poly2 = imesh.polygon();
176  unsigned i, j, n = vert.size(), m = vert2.size(), p = poly2.size();
177 
178  // copy vertices & normals
179  for ( i=0; i<m; ++i )
180  vert.push_back( vert2[i] );
181  for ( i=0, m=norm2.size(); i<m; ++i )
182  norm.push_back( norm2[i] );
183 
184  // translate & copy polygons
185  for ( i=0; i<p; ++i )
186  {
187  AimsVector<uint,D> pol;
188  for ( j=0; j<D; ++j )
189  pol[j] = poly2[i][j] + n;
190  poly.push_back( pol );
191  }
192  if( t == 0 )
193  dst.header().setProperty( "vertex_number", int( n + m ) );
194  }
195  }
196 
197  template<int D, class T>
199  const std::list<AimsTimeSurface<D,T> > & src )
200  {
201  dst.erase();
202  typename std::list<AimsTimeSurface<D,T> >::const_iterator
203  im, em = src.end();
204  for ( im=src.begin(); im!=em; ++im )
205  meshMerge( dst, *im );
206  }
207 
208 
209  template<int D, class T>
211  const Motion & motion )
212  {
213  typename AimsTimeSurface<D,T>::iterator itime, tend = mesh.end();
214  float norm;
215 
216  for( itime=mesh.begin(); itime!=tend; ++itime )
217  {
218  typedef std::vector< Point3df > Points;
219  Points& vertex = itime->second.vertex();
220  Points& normal = itime->second.normal();
221  unsigned nnorm = normal.size();
222  for( Points::size_type k = 0; k < vertex.size(); ++k )
223  {
224  vertex[ k ] = motion.transform( vertex[ k ] );
225  /* Denis: applying this transformation to normals is WRONG if
226  there is any scale factor ! */
227  if( k < nnorm )
228  {
229  normal[ k ] = motion.transform( normal[ k ] )
230  - motion.translation();
231  // normalize normals
232  norm = normal[k][0] * normal[k][0] + normal[k][1] * normal[k][1]
233  + normal[k][2] * normal[k][2];
234  norm = 1. / sqrt( norm );
235  normal[k][0] *= norm;
236  normal[k][1] *= norm;
237  normal[k][2] *= norm;
238  }
239  }
240  }
241  if( !motion.isDirect() )
242  invertSurfacePolygons( mesh );
243  }
244 
245 
246  template <int D, typename T>
249  const TimeTexture<int16_t> & tex,
250  int16_t value,
251  std::vector<size_t> ** overtIndex )
252  {
254  typename AimsTimeSurface<D,T>::const_iterator imt, jmt, emt = mesh.end();
255  typename TimeTexture<int16_t>::const_iterator itt, jtt, ett = tex.end();
256  if( overtIndex )
257  * overtIndex = new std::vector<size_t>;
258  jmt = mesh.begin();
259  imt = jmt;
260  jtt = tex.begin();
261  itt = jtt;
262  int ti = 0;
263  while( jmt != emt || jtt != ett )
264  {
265  if( jmt != emt )
266  imt = jmt;
267  if( jtt != ett )
268  itt = jtt;
269  AimsSurface<D,T> & mh = (*omesh)[ ti ];
270  std::vector<Point3df> & overt = mh.vertex();
271  std::vector<Point3df> & onorm = mh.normal();
272  std::vector<AimsVector<uint, D> > & opoly = mh.polygon();
273  const std::vector<Point3df> & vert = imt->second.vertex();
274  const std::vector<Point3df> & norm = imt->second.normal();
275  const std::vector<AimsVector<uint, D> > & poly = imt->second.polygon();
276  typename std::vector<AimsVector<uint, D> >::const_iterator
277  im, em = poly.end();
278  int i = 0, k;
279  const Texture<int16_t> & tx = itt->second;
280  std::map<uint, uint> vmap;
281  typename std::map<uint, uint>::iterator iv, ev = vmap.end();
282  unsigned nt;
283  bool absmaj, hasdist;
284  int16_t y, mval = 0;
285  Point3df g;
286  float dist, dist2;
287  for( im=poly.begin(); im != em; ++im )
288  {
289  std::map<int16_t, unsigned> vals;
290  nt = 0;
291  absmaj = false;
292  g = Point3df( 0, 0, 0 );
293  // let's have a vote
294  for( k=0; k<D; ++k )
295  {
296  g += vert[ (*im)[k] ];
297  y = tx[ (*im)[k] ];
298  unsigned & x = vals[y];
299  ++x;
300  if( x > nt )
301  {
302  nt = x;
303  mval = y;
304  absmaj = true;
305  }
306  else if( x == nt )
307  absmaj = false;
308  }
309  if( vals[ value ] == nt )
310  {
311  // 'value' is amongst the most taken value
312  if( !absmaj )
313  {
314  // take nearest vertex from barycenter with value in majority
315  g /= D;
316  dist = 0;
317  hasdist = false;
318  for( k=0; k<D; ++k )
319  {
320  y = tx[ (*im)[k] ];
321  if( vals[ y ] == nt )
322  {
323  dist2 = ( vert[ (*im)[k] ] - g ).norm2();
324  if( !hasdist || dist2 < dist )
325  {
326  dist = dist2;
327  mval = y;
328  }
329  }
330  }
331  if( mval == value )
332  absmaj = true;
333  }
334  // else absmaj == true: value has absolute majority
335  }
336  else
337  // value is in minority
338  absmaj = false;
339  if( absmaj )
340  { // copy polygon
342  for( k=0; k<D; ++k )
343  {
344  iv = vmap.find( (*im)[k] );
345  if( iv == ev )
346  {
347  vmap[ (*im)[k] ] = i;
348  p[k] = i;
349  overt.push_back( vert[ (*im)[k] ] );
350  onorm.push_back( norm[ (*im)[k] ] );
351  if( overtIndex )
352  (** overtIndex).push_back((*im)[k]);
353  ++i;
354  }
355  else
356  p[k] = iv->second;
357  }
358  opoly.push_back( p );
359  }
360  }
361  ++ti;
362  if( jmt != emt )
363  ++jmt;
364  if( jtt != ett )
365  ++jtt;
366  }
367  return omesh;
368  }
369 
370 
371  template <int D, typename T>
374  bool asDistance )
375  {
377  typename AimsTimeSurface<D,T>::const_iterator is, es = mesh.end();
378  uint i;
379 
380  for( is=mesh.begin(); is!=es; ++is )
381  {
382  const AimsSurface<D,T> & surf = is->second;
383  const std::vector<Point3df> & vert = surf.vertex();
384  const std::vector<AimsVector<uint,D> > & poly = surf.polygon();
385 
386  // create corresponding timestep texture
387  std::vector<float> & tx = (*tex)[ is->first ].data();
388  std::vector<unsigned> counts;
389  tx.reserve( vert.size() );
390  tx.insert( tx.end(), vert.size(), 0. );
391  counts.reserve( vert.size() );
392  counts.insert( counts.end(), vert.size(), 0 );
393 
394  // record edges sizes on all polygons
395  typename std::vector<AimsVector<uint,D> >::const_iterator
396  ip, ep = poly.end(), jp;
397  float n;
398 
399  for( ip=poly.begin(); ip!=ep; ++ip )
400  {
401  for( i=0; i<D; ++i )
402  {
403  // edge distance, accounted on both vertices of the edge
404  uint vi = (*ip)[i];
405  uint vj = (*ip)[ (i+1) % D ];
406  n = ( vert[ vi ] - vert[ vj ] ).norm();
407  tx[ vi ] += n;
408  tx[ vj ] += n;
409  // count
410  ++counts[ vi ];
411  ++counts[ vj ];
412  }
413  }
414 
415  // now average distances, and invert them to get a density
416  std::vector<float>::iterator it, et = tx.end();
417  std::vector<unsigned>::const_iterator itc;
418  if( asDistance )
419  for( it=tx.begin(), itc=counts.begin(); it!=et; ++it, ++itc )
420  if( *itc != 0. )
421  *it /= float( *itc );
422  else
423  *it = 0.; // to avoid NaN
424  else
425  for( it=tx.begin(), itc=counts.begin(); it!=et; ++it, ++itc )
426  *it = float( *itc ) / *it;
427  }
428 
429  return tex;
430  }
431 
432 
433  template <int D, typename T>
436  const AimsTimeSurface<D,T> & nummesh,
437  const AimsTimeSurface<D,T> & denommesh )
438  {
440  typename AimsTimeSurface<D,T>::const_iterator is, es = nummesh.end(),
441  ids, eds = denommesh.end();
442  uint i;
443 
444  for( is=nummesh.begin(), ids=denommesh.begin(); is!=es && ids!=eds;
445  ++is, ++ids )
446  {
447  const AimsSurface<D,T> & surf = is->second;
448  const std::vector<Point3df> & vert = surf.vertex();
449  const std::vector<AimsVector<uint,D> > & poly = surf.polygon();
450  const std::vector<Point3df> & dvert = ids->second.vertex();
451 
452  // create corresponding timestep texture
453  std::vector<float> & tx = (*tex)[ is->first ].data();
454  std::vector<unsigned> counts;
455  tx.reserve( vert.size() );
456  tx.insert( tx.end(), vert.size(), 0. );
457  counts.reserve( vert.size() );
458  counts.insert( counts.end(), vert.size(), 0 );
459 
460  // record edges sizes on all polygons
461  typename std::vector<AimsVector<uint,D> >::const_iterator
462  ip, ep = poly.end(), jp;
463  float n, dn;
464 
465  for( ip=poly.begin(); ip!=ep; ++ip )
466  {
467  for( i=0; i<D; ++i )
468  {
469  // edge distance, accounted on both vertices of the edge
470  uint vi = (*ip)[i];
471  uint vj = (*ip)[ (i+1) % D ];
472  n = ( vert[ vi ] - vert[ vj ] ).norm();
473  dn = ( dvert[ vi ] - dvert[ vj ] ).norm();
474  if( dn == 0. )
475  n = 1.; // what to do else ? (leave inf ?)
476  else
477  n /= dn;
478  tx[ vi ] = std::max( tx[ vi ], n );
479  tx[ vj ] = std::max( tx[ vj ], n );
480  // count
481  ++counts[ vi ];
482  ++counts[ vj ];
483  }
484  }
485 
486  /*
487  // now average distances
488  std::vector<float>::iterator it, et = tx.end();
489  std::vector<unsigned>::const_iterator itc;
490  for( it=tx.begin(), itc=counts.begin(); it!=et; ++it, ++itc )
491  if( *itc != 0. )
492  *it /= float( *itc );
493  else
494  *it = 0.; // to avoid NaN
495  */
496  }
497 
498  return tex;
499  }
500 
501 
502  namespace internal
503  {
505  std::map<std::pair<uint,uint>, uint> & segments,
506  uint i, uint j,
507  const std::vector<Point3df> & vert,
508  std::vector<Point3df> & overt )
509  {
510  std::pair<uint,uint> seg = std::make_pair( i, j );
511  std::map<std::pair<uint,uint>, uint>::const_iterator
512  iseg = segments.find( seg );
513  uint iout;
514  if( iseg == segments.end() )
515  {
516  Point3df p = ( vert[i] + vert[j] ) / 2;
517  iout = overt.size();
518  overt.push_back( p );
519  segments[ seg ] = iout;
520  }
521  else
522  iout = iseg->second;
523  return iout;
524  }
525 
526  }
527 
528 
529  template <typename T>
532  const Texture<T> & tex, T region )
533  {
534  const std::vector<Point3df> & vert = mesh.vertex();
535  const std::vector<AimsVector<uint,3> > & poly = mesh.polygon();
537  std::map<std::pair<uint,uint>, uint> segments;
538  std::vector<AimsVector<uint,3> >::const_iterator ip, ep = poly.end();
539  uint i, j, k;
540  bool ii, jj, kk;
541  std::vector<Point3df> & overt = outmesh->vertex();
542  std::vector<AimsVector<uint,2> > & opoly = outmesh->polygon();
543 
544  for( ip=poly.begin(); ip!=ep; ++ip )
545  {
546  bool done = false;
547  i = (*ip)[0];
548  j = (*ip)[1];
549  k = (*ip)[2];
550  // order indices
551  if( i > j )
552  {
553  i = j;
554  j = (*ip)[0];
555  }
556  if( i > k )
557  {
558  k = i;
559  i = (*ip)[2];
560  }
561  if( j > k )
562  {
563  uint w = k;
564  k = j;
565  j = w;
566  }
567  // find boundaries in triangle
568  if( region >= 0 )
569  {
570  if( tex[i] == region )
571  ii = true;
572  else
573  ii = false;
574  if( tex[j] == region )
575  jj = true;
576  else
577  jj = false;
578  if( tex[k] == region )
579  kk = true;
580  else
581  kk = false;
582  }
583  else
584  {
585  if( tex[i] != tex[j] && tex[i] != tex[k] && tex[j] != tex[k] )
586  {
587  // all different
588  Point3df center = ( vert[i] + vert[j] + vert[k] ) / 3.;
589  uint iop = overt.size();
590  overt.push_back( center );
591  uint iout = internal::take_mid_point_and_insert( segments, i, j, vert,
592  overt );
593  opoly.push_back( AimsVector<uint,2>( iout, iop ) );
594  iout = internal::take_mid_point_and_insert( segments, i, k, vert,
595  overt );
596  opoly.push_back( AimsVector<uint,2>( iout, iop ) );
597  iout = internal::take_mid_point_and_insert( segments, j, k, vert,
598  overt );
599  opoly.push_back( AimsVector<uint,2>( iout, iop ) );
600  done = true;
601  }
602  else
603  {
604  ii = false;
605  if( tex[i] == tex[j] )
606  jj = false;
607  else
608  jj = true;
609  if( tex[i] == tex[k] )
610  kk = false;
611  else
612  kk = true;
613  }
614  }
615 
616  if( !done && ( ii != jj || ii != kk ) )
617  {
618  std::vector<uint> ipts;
619  if( ii != jj )
620  ipts.push_back( internal::take_mid_point_and_insert( segments, i, j,
621  vert, overt ) );
622  if( ii != kk )
623  ipts.push_back( internal::take_mid_point_and_insert( segments, i, k,
624  vert, overt ) );
625  if( jj != kk )
626  ipts.push_back( internal::take_mid_point_and_insert( segments, j, k,
627  vert, overt ) );
628  opoly.push_back( AimsVector<uint,2>( ipts[0], ipts[1] ) );
629  }
630  }
631  return outmesh;
632  }
633 
634 
635  template <typename T>
638  const TimeTexture<T> & tex, T region )
639  {
640  AimsSurfaceTriangle::const_iterator imesh, jmesh, emesh = mesh.end();
641  imesh = mesh.begin();
642  jmesh = imesh;
643  if( jmesh != emesh )
644  ++jmesh;
646  itex = tex.begin(), jtex=itex, etex = tex.end();
647  if( jtex != etex )
648  ++jtex;
650  while( imesh != emesh && itex != etex )
651  {
652  unsigned mtimestep = imesh->first;
653  unsigned ttimestep = itex->first;
654  AimsSurface<2, Void> *tmesh = meshTextureBoundary( imesh->second,
655  itex->second,
656  region );
657  (*outmesh)[ std::max( mtimestep, ttimestep ) ] = *tmesh;
658  delete tmesh;
659  if( jmesh == emesh && jtex == etex )
660  break;
661  if( jmesh != emesh && ( jtex == etex || jmesh->first < jtex->first ) )
662  {
663  imesh = jmesh;
664  ++jmesh;
665  }
666  else if( jtex != etex
667  && ( jmesh == emesh || jmesh->first > jtex->first ) )
668  {
669  itex = jtex;
670  ++jtex;
671  }
672  else
673  {
674  if( jmesh != emesh )
675  {
676  imesh = jmesh;
677  ++jmesh;
678  }
679  if( jtex != etex )
680  {
681  itex = jtex;
682  ++jtex;
683  }
684  }
685  }
686  return outmesh;
687  }
688 
689 
690  template <int D, typename T>
692  int timestep,
693  const Point3df & direction )
694  {
695  const std::vector<Point3df> & vert = mesh[timestep].vertex();
696  std::vector<AimsVector<uint, D> > & poly = mesh[timestep].polygon();
697  std::multimap<float, AimsVector<uint, D> > sorted;
698  typename std::vector<AimsVector<uint, D> >::iterator
699  ip, ep = poly.end();
700  typename std::multimap<float, AimsVector<uint, D> >::iterator
701  im, em = sorted.end();
702  int d;
703  Point3df center;
704 
705  // sort using a map
706  for( ip=poly.begin(); ip!=ep; ++ip )
707  {
708  center = vert[(*ip)[0]];
709  for( d=1; d<D; ++d )
710  center += vert[(*ip)[d]];
711  sorted.insert( std::make_pair( center.dot( direction ), *ip ) );
712  }
713 
714  // rewrite polygons
715  for( im=sorted.begin(), ip=poly.begin(); im!=em; ++im, ++ip )
716  *ip = im->second;
717  }
718 
719 
720  template <int D, typename T>
721  std::pair<carto::rc_ptr< AimsTimeSurface<D, Void> >,
724  {
728 
729  typename AimsTimeSurface<D, T>::const_iterator im, em = texmesh.end();
730  for( im=texmesh.begin(); im!=em; ++im )
731  {
732  AimsSurface<D> & m = (*mesh)[im->first];
733  Texture<T> & t = (*tex)[im->first];
734  m.vertex() = im->second.vertex();
735  m.normal() = im->second.normal();
736  m.polygon() = im->second.polygon();
737  t.data() = im->second.texture();
738  }
739 
740  mesh->header().copyProperties(
741  carto::Object::reference( texmesh.header() ) );
742  tex->header().copyProperties(
743  carto::Object::reference( texmesh.header() ) );
744 
745  return std::make_pair( mesh, tex );
746  }
747 
748 
749  template <int D, typename T>
752  const TimeTexture<T> & texture )
753  {
755  new AimsTimeSurface<D, T> );
756 
757  typename AimsTimeSurface<D, Void>::const_iterator im, em = mesh.end();
758  typename TimeTexture<T>::const_iterator it, et = texture.end();
759 
760  std::set<int> timesteps;
761  for( im=mesh.begin(); im!=em; ++im )
762  timesteps.insert( im->first );
763  for( it=texture.begin(); it!=et; ++it )
764  timesteps.insert( it->first );
765  std::set<int>::iterator is, es = timesteps.end();
766 
767  for( is=timesteps.begin(); is!=es; ++is )
768  {
769  im = mesh.lower_bound( *is );
770  if( im == em )
771  break;
772  it = texture.lower_bound( *is );
773 
774  AimsSurface<D, T> & m = (*texmesh)[*is];
775  m.vertex() = im->second.vertex();
776  m.normal() = im->second.normal();
777  m.polygon() = im->second.polygon();
778  if( it != et )
779  m.texture() = it->second.data();
780  }
781 
782  texmesh->header().copyProperties(
783  carto::Object::reference( mesh.header() ) );
784  texmesh->header().copyProperties(
785  carto::Object::reference( texture.header() ) );
786 
787  return texmesh;
788  }
789 
790 
791 }
792 
793 #endif
The template class to manage a mesh.
Definition: surface.h:69
const std::vector< Point3df > & normal() const
Get a const reference to the vector of normals.
Definition: surface.h:98
const std::vector< Point3df > & vertex() const
Get a const reference to the vector of vertices.
Definition: surface.h:93
const std::vector< T > & texture() const
Get a const reference to the vector of textures.
Definition: surface.h:103
const std::vector< AimsVector< uint, D > > & polygon() const
Get a const reference to the vector of polygons.
Definition: surface.h:108
The template class to manage a mesh with time if needed.
Definition: surface.h:317
void erase()
Clear all the meshes.
Definition: surface.h:505
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
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
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
const std::vector< Point3df > & normal() const
Get a const reference to the vector of normals of the 0 surface.
Definition: surface.h:350
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
int size() const
T dot(const AimsVector< T, D > &other) const
float norm() const
const std::vector< T > & data() const
Definition: texture.h:81
const aims::PythonHeader & header() const
Get the header.
Definition: texture.h:143
std::map< int, Texture< T > >::const_iterator const_iterator
Definition: texture.h:125
static void sortPolygonsAlongDirection(AimsTimeSurface< D, T > &mesh, int timestep, const Point3df &direction)
Sort polygons along a given direction.
static AimsTimeSurface< D, T > * meshExtract(const AimsTimeSurface< D, T > &mesh, const TimeTexture< int16_t > &tex, int16_t value, std::vector< size_t > **overtIndex=0)
Extracts a sub-mesh region from a label texture.
static void invertSurfacePolygons(AimsTimeSurface< D, T > &surface)
static TimeTexture< float > * meshEdgeLengthRatioTexture(const AimsTimeSurface< D, T > &nummesh, const AimsTimeSurface< D, T > &denommesh)
Calculate an edge length ratio in edges of two meshes with the same topology.
static std::vector< std::map< uint, float > > surfaceNeighbourDistance(const AimsTimeSurface< D, T > &surf)
static void meshTransform(AimsTimeSurface< D, T > &mesh, const Motion &trans)
Applies a transformation to a mesh.
static void meshMerge(AimsTimeSurface< D, T > &dst, const AimsTimeSurface< D, T > &add)
concatenates 2 meshes into one (adds the second to the first one)
static std::pair< carto::rc_ptr< AimsTimeSurface< D, Void > >, carto::rc_ptr< TimeTexture< T > > > splitTexturedMesh(const AimsTimeSurface< D, T > &texmesh)
Split a textured mesh into a mesh and a texture.
static carto::rc_ptr< AimsTimeSurface< D, T > > joinTexturedMesh(const AimsTimeSurface< D, Void > &mesh, const TimeTexture< T > &texture)
Join a mesh and a texture into a textured mesh.
static TimeTexture< float > * meshDensity(const AimsTimeSurface< D, T > &mesh, bool asDistance=false)
Calculate a mesh density: inverse of the average edges distance If asDistance is true,...
static std::vector< std::set< uint > > surfaceNeighbours(const AimsSurface< D, T > &surf)
static std::vector< std::set< uint > > surfaceNeighbours2ndOrder(const AimsTimeSurface< D, T > &surf)
static AimsSurface< 2, Void > * meshTextureBoundary(const AimsSurface< 3, Void > &mesh, const Texture< T > &tex, T region)
Extracts the boundary of region of value <region> of the input texture, on the mesh.
virtual void copyProperties(Object source)
Object reference(Object &value)
virtual void setProperty(const std::string &, Object)
Point3dd transform(double x, double y, double z) const
int nt
uint take_mid_point_and_insert(std::map< std::pair< uint, uint >, uint > &segments, uint i, uint j, const std::vector< Point3df > &vert, std::vector< Point3df > &overt)
The class for EcatSino data write operation.
Definition: borderfiller.h:13
AIMSDATA_API AimsTimeSurface< 3, Void > AimsSurfaceTriangle
Definition: surface.h:581
AIMSDATA_API float norm(const Tensor &thing)
Definition: tensor.h:141
unsigned int uint
float norm2(const AimsVector< T, D > &v1)