aimsalgo  5.1.2
Neuroimaging image processing
meshdistance_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_DISTANCEMAP_MESHDISTANCE_D_H
35 #define AIMS_DISTANCEMAP_MESHDISTANCE_D_H
36 
39 #include <map>
40 
41 template<class T>
43  const AimsSurface<3,Void> & mesh, const Texture<T> & inittex,
44  bool allowUnreached, float max_dist )
45 {
46  Texture<float> tex;
47  const std::vector<Point3df> & vert = mesh.vertex();
48  const std::vector< AimsVector<uint,3> > & poly = mesh.polygon();
49  unsigned i, n = vert.size();
50 
51  ASSERT( inittex.nItem() == n );
52  tex.reserve( n );
53 
54  // neighbours map
55 
56  std::map<unsigned, std::set<unsigned> > neighbours;
57  unsigned v1, v2, v3;
58 
59  for( i=0; i<poly.size(); ++i )
60  {
61  v1 = poly[i][0];
62  v2 = poly[i][1];
63  v3 = poly[i][2];
64  if( inittex.item(v1)!=MESHDISTANCE_FORBIDDEN
65  && inittex.item(v2)!=MESHDISTANCE_FORBIDDEN )
66  {
67  neighbours[v1].insert( v2 );
68  neighbours[v2].insert( v1 );
69  }
70  if( inittex.item(v1)!=MESHDISTANCE_FORBIDDEN
71  && inittex.item(v3)!=MESHDISTANCE_FORBIDDEN )
72  {
73  neighbours[v1].insert( v3 );
74  neighbours[v3].insert( v1 );
75  }
76  if( inittex.item(v2)!=MESHDISTANCE_FORBIDDEN
77  && inittex.item(v3)!=MESHDISTANCE_FORBIDDEN )
78  {
79  neighbours[v2].insert( v3 );
80  neighbours[v3].insert( v2 );
81  }
82  }
83 
84  // init texture
85 
86  for( i=0; i<n; ++i )
87  {
88  if( inittex.item(i) == 0 )
89  tex.push_back( FLT_MAX );
90  else if( inittex.item(i) == MESHDISTANCE_FORBIDDEN )
92  else
93  tex.push_back( 0 );
94  }
95 
96  std::multimap<float,unsigned> front1, front2;
97  std::multimap<float,unsigned> *cfront = &front1, *nfront = &front2, *tmpf;
98  std::multimap<float,unsigned>::iterator iv, fv;
99  std::set<unsigned> neigh;
100  std::set<unsigned>::iterator in, fn;
101  float d, d2, l, nd;
102  Point3df pos;
103 
104  // init first front
105 
106  for( i=0; i<n; ++i )
107  if( tex.item(i) == 0 )
108  front1.insert( std::pair<float,unsigned>( 0, i ) );
109 
110  // loop until current front is empty
111 
112  while( cfront->size() > 0 )
113  {
114  nfront->clear();
115  neigh.clear();
116 
117  for( iv=cfront->begin(), fv=cfront->end(); iv!=fv; ++iv )
118  {
119  i = (*iv).second;
120  d = (*iv).first;
121  for( in=neighbours[i].begin(), fn=neighbours[i].end(); in!=fn; ++in )
122  {
123  d2 = tex.item( *in );
124  pos = vert[i] - vert[*in];
125  l = sqrt( pos[0] * pos[0] + pos[1] * pos[1] + pos[2] * pos[2] );
126  nd = d + l;
127  if( d2 > nd && nd < max_dist )
128  {
129  tex.item( *in ) = nd;
130  neigh.insert( *in );
131  }
132  }
133  }
134 
135  for( in=neigh.begin(), fn=neigh.end(); in!=fn; ++in )
136  nfront->insert( std::pair<float,unsigned>( tex.item( *in ), *in ) );
137 
138  tmpf = cfront;
139  cfront = nfront;
140  nfront = tmpf;
141  }
142 
143 
144  if( !allowUnreached )
145  for( i=0; i<n; ++i )
146  if( tex.item(i) == FLT_MAX )
147  tex.item(i) = MESHDISTANCE_UNREACHED;
148 
149  return( tex );
150 }
151 
152 
153 namespace aims
154 {
155  namespace meshdistance
156  {
157 
158  template <typename T>
160  {
161  public:
162  static void resize( T & mat, size_t size1, size_t size2 = 0 )
163  {
164  }
165  };
166 
167  template <typename T>
168  class DistMapMatrixTraits<std::vector<T> >
169  {
170  public:
171  typedef T LineType;
172 
173  static void resize( std::vector<T> & mat, size_t size1,
174  size_t size2 = 0 )
175  {
176  mat.resize( size1 );
177  }
178 
179  static void storeLine( std::vector<T> & mat, size_t line,
180  const std::vector<float> & tex )
181  {
182  LineType & map = mat[line];
183  size_t i, n = tex.size();
184 
185  for( i=0; i<n; ++i )
187  }
188 
189  };
190 
191  template <typename T, typename U>
192  class DistMapMatrixTraits<std::map<T, U> >
193  {
194  public:
195  static void resize( T & mat, size_t size1, size_t size2 = 0 )
196  {
197  }
198 
199  static void storeElement( std::map<T, U> & map, T i, float value )
200  {
201  if( value != FLT_MAX )
202  map[i] = U( value );
203  }
204  };
205 
206  }
207 }
208 
209 
210 template <typename T, typename MapType>
211 void
213  MapType & distmaps,
214  const Texture<T> & inittex,
215  float max_dist )
216 {
217  const std::vector<Point3df> & vert = mesh.vertex();
218  const std::vector< AimsVector<uint,3> > & poly = mesh.polygon();
219  unsigned i, n = vert.size();
220  std::vector<float> tex, ctex( n );
221 
222  bool has_init = ( inittex.size() != 0 );
223  ASSERT( !has_init || inittex.nItem() == n );
225 
226  // neighbours map
227 
228  std::map<unsigned, std::set<unsigned> > neighbours;
229  unsigned v1, v2, v3;
230 
231  for( i=0; i<poly.size(); ++i )
232  {
233  v1 = poly[i][0];
234  v2 = poly[i][1];
235  v3 = poly[i][2];
236  if( !has_init || ( inittex[v1] != MESHDISTANCE_FORBIDDEN
237  && inittex[v2] != MESHDISTANCE_FORBIDDEN ) )
238  {
239  neighbours[v1].insert( v2 );
240  neighbours[v2].insert( v1 );
241  }
242  if( !has_init || ( inittex.item(v1) != MESHDISTANCE_FORBIDDEN
243  && inittex.item(v3) != MESHDISTANCE_FORBIDDEN ) )
244  {
245  neighbours[v1].insert( v3 );
246  neighbours[v3].insert( v1 );
247  }
248  if( !has_init || ( inittex.item(v2) != MESHDISTANCE_FORBIDDEN
249  && inittex.item(v3)!=MESHDISTANCE_FORBIDDEN ) )
250  {
251  neighbours[v2].insert( v3 );
252  neighbours[v3].insert( v2 );
253  }
254  }
255 
256  // init texture
257 
258  for( i=0; i<n; ++i )
259  {
260  if( !has_init || inittex.item(i) != MESHDISTANCE_FORBIDDEN )
261  ctex[i] = FLT_MAX;
262  else
263  ctex[i] = MESHDISTANCE_FORBIDDEN;
264  }
265 
266  size_t start; // start point for each map
267  for( start=0; start<n; ++start )
268  {
269  if( has_init && inittex[start] == MESHDISTANCE_FORBIDDEN )
270  continue; // skip forbidden points
271 
272  // re-init new map
273  tex = ctex;
274  tex[start] = 0; // with one starting point
275 
276  std::multimap<float,unsigned> front1, front2;
277  std::multimap<float,unsigned> *cfront = &front1, *nfront = &front2, *tmpf;
278  std::multimap<float,unsigned>::iterator iv, fv;
279  std::set<unsigned> neigh;
280  std::set<unsigned>::iterator in, fn;
281  float d, d2, l, nd;
282  Point3df pos;
283 
284  // init first front
285 
286  front1.insert( std::pair<float,unsigned>( 0., start ) );
287 
288  // loop until current front is empty
289 
290  while( cfront->size() > 0 )
291  {
292  nfront->clear();
293  neigh.clear();
294 
295  for( iv=cfront->begin(), fv=cfront->end(); iv!=fv; ++iv )
296  {
297  i = (*iv).second;
298  d = (*iv).first;
299  for( in=neighbours[i].begin(), fn=neighbours[i].end(); in!=fn; ++in )
300  {
301  d2 = tex[ *in ];
302  pos = vert[i] - vert[*in];
303  l = sqrt( pos[0] * pos[0] + pos[1] * pos[1] + pos[2] * pos[2] );
304  nd = d + l;
305  if( d2 > nd && nd < max_dist )
306  {
307  tex[ *in ] = nd;
308  neigh.insert( *in );
309  }
310  }
311  }
312 
313  for( in=neigh.begin(), fn=neigh.end(); in!=fn; ++in )
314  nfront->insert( std::pair<float,unsigned>( tex[ *in ], *in ) );
315 
316  tmpf = cfront;
317  cfront = nfront;
318  nfront = tmpf;
319  }
320 
321  // fill in the output sparse map
322  DistMapMatrixTraits<MapType>::storeLine( distmaps, start, tex );
323 
324  }
325 }
326 
327 
328 #endif
329 
#define ASSERT(EX)
const std::vector< Point3df > & vertex() const
const std::vector< AimsVector< uint, D > > & polygon() const
void reserve(size_t size)
size_t nItem() const
const T & item(int n) const
size_t size() const
void push_back(const T &item)
static void storeElement(std::map< T, U > &map, T i, float value)
static void resize(T &mat, size_t size1, size_t size2=0)
static void storeLine(std::vector< T > &mat, size_t line, const std::vector< float > &tex)
static void resize(std::vector< T > &mat, size_t size1, size_t size2=0)
static void resize(T &mat, size_t size1, size_t size2=0)
const short MESHDISTANCE_UNREACHED
Definition: meshvoronoi.h:85
void pairwiseDistanceMaps(const AimsSurface< 3, Void > &mesh, MapType &distmaps, const Texture< T > &inittex, float max_dist=FLT_MAX)
Computes a distance matrix over a mesh.
Texture< float > MeshDistance(const AimsSurface< 3, Void > &mesh, const Texture< T > &inittex, bool allowUnreached, float max_dist=FLT_MAX)
Computes a distance texture over a mesh.
const short MESHDISTANCE_FORBIDDEN
global variable...
Definition: meshvoronoi.h:84