aimsalgo 6.0.0
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
41template<class T>
43 const AimsSurface<3,Void> & mesh, const Texture<T> & inittex,
44 bool allowUnreached, float max_dist )
45{
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 )
148
149 return( tex );
150}
151
152
153namespace 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
210template <typename T, typename MapType>
211void
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< AimsVector< uint, D > > & polygon() const
const std::vector< Point3df > & vertex() 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
STL namespace.
AimsVector< float, 3 > Point3df