aimsdata  5.0.5
Neuroimaging data handling
tex2graph_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 /*
35  * Texture class
36  */
37 #ifndef AIMS_MESH_TEX2GRAPH_D_H
38 #define AIMS_MESH_TEX2GRAPH_D_H
39 
40 #include <aims/mesh/tex2graph.h>
41 #include <graph/graph/graph.h>
42 #include <cartobase/smart/rcptr.h>
43 #include <aims/graph/graphmanip.h>
44 #include <stdio.h>
45 
46 namespace aims
47 {
48 
49 
50  template <class T>
52  {
53  }
54 
55  template <class T>
56  inline int Tex2Graph<T>::getIndex(const T & label)
57  {
58  return (int) label;
59 
60  }
61 
62  template <>
63  inline int Tex2Graph<std::set<short> >::getIndex(const std::set<short> & label)
64  {
65  return label2index[label];
66  }
67 
68 
69 
70  template <>
71  inline void Tex2Graph<std::set<short> >::fillLabel2index(const Texture<std::set<short> > & tex)
72  {
73  std::set<std::set<short> > all_lab;
74  std::set<std::set<short> >::iterator bl,fl;
75  int inc = 0, n = tex.nItem();
76 
77  for( int i=0; i<n; ++i )
78  all_lab.insert( tex.item(i) );
79 
80  for (bl=all_lab.begin(), fl=all_lab.end(); bl != fl; ++bl,++inc)
81  label2index[*bl] = inc;
82  }
83 
84  template <class T>
85  inline void Tex2Graph<T>::makeGraph( Graph & g, const AimsSurfaceTriangle & initmesh,
86  const Texture<T> & tex,
87  const std::map<T,std::string> & lab2name, float epsilon )
88  {
89 
90  T lab;
91  std::map<T,Vertex*> nodeLabels;
92  typename std::map<T,std::set<unsigned> >::iterator il,el;
93  std::map<T,std::set<unsigned> > triLabels;
94  std::set<unsigned>::iterator it,et;
95  Vertex *v;
96  const std::vector< AimsVector<uint, 3 > > & initpoly = initmesh.polygon();
97  unsigned n = tex.nItem(), i, m = initpoly.size();
98  typename std::map <T,std::string>::const_iterator iname,ename = lab2name.end();
99 
100  if ( n != initmesh.vertex().size() )
101  throw std::logic_error("Mesh and texture must have the same size");
102 
103 
104  AimsSurfaceTriangle mesh = initmesh;
105  std::vector<Point3df> &vert = mesh.vertex();
106  std::vector<Point3df> &normal = mesh.normal();
107  std::vector< AimsVector<uint, 3 > > &poly = mesh.polygon();
108 
109  for (i=0; i<n; ++i)
110  {
111  vert[i][0] = vert[i][0] + epsilon * normal[i][0];
112  vert[i][1] = vert[i][1] + epsilon * normal[i][1];
113  vert[i][2] = vert[i][2] + epsilon * normal[i][2];
114  }
115 
116  std::vector<float> vs;
117  vs.push_back( 1 );
118  vs.push_back( 1 );
119  vs.push_back( 1 );
120  g.setProperty( "voxel_size", vs );
121  g.setProperty( "filename_base", "*" );
122 
123  std::vector<int> bbmin(3), bbmax(3);
124  bool first = true;
125  std::string name;
126  typename std::set<T>::iterator bl,fl;
127 
128  fillLabel2index(tex);
129 
130  for( i=0; i<n; ++i )
131  {
132  lab = tex.item(i);
133 
134  if ( nodeLabels.find( lab ) == nodeLabels.end() )
135  {
136  v = g.addVertex( "roi" );
137  //v->setProperty( "roi_label", (int) lab );
138  v->setProperty( "roi_label", getIndex(lab) );
139  iname = lab2name.find(lab);
140  if (iname != ename)
141  {
142  name = iname->second ;
143  v->setProperty( "name", name );
144  }
145  else
146  {
147  std::cerr << "Cannot translate a label " << std::endl ;
148  v->setProperty( "name", (std::string)"unknown" );
149  }
150  nodeLabels[lab] = v;
151 
152 
153  }
154  const Point3df & pt = mesh.vertex()[i];
155  if( first )
156  {
157  bbmin[0] = bbmax[0] = (int) rint( pt[0] );
158  bbmin[1] = bbmax[1] = (int) rint( pt[1] );
159  bbmin[2] = bbmax[2] = (int) rint( pt[2] );
160  first = false;
161  }
162  else
163  {
164  if( pt[0] < bbmin[0] )
165  bbmin[0] = (int) rint( pt[0] );
166  if( pt[1] < bbmin[1] )
167  bbmin[1] = (int) rint( pt[1] );
168  if( pt[2] < bbmin[2] )
169  bbmin[2] = (int) rint( pt[2] );
170  if( pt[0] > bbmax[0] )
171  bbmax[0] = (int) rint( pt[0] );
172  if( pt[1] > bbmax[1] )
173  bbmax[1] = (int) rint( pt[1] );
174  if( pt[2] > bbmax[2] )
175  bbmax[2] = (int) rint( pt[2] );
176  }
177  }
178 
179  g.setProperty( "boundingbox_min", bbmin );
180  g.setProperty( "boundingbox_max", bbmax );
181 
182 
183  for ( i=0; i<m; ++i )
184  {
185  if ( tex.item(poly[i][0]) == tex.item(poly[i][1]) &&
186  tex.item(poly[i][2]) == tex.item(poly[i][1]) )
187  triLabels[tex.item(poly[i][0])].insert(i);
188  }
189 
190  for ( il = triLabels.begin(), el = triLabels.end(); il != el; ++il )
191  {
192  uint ind=0,a,b,c;
193  std::map<uint,uint> conversion;
194  std::map<uint,uint>::iterator ic;
195  AimsVector<uint,3> tri;
196 
198 
199  for (it = il->second.begin(), et = il->second.end(); it != et; ++it)
200  {
201  tri = poly[*it];
202  if ( (ic=conversion.find( tri[0] )) == conversion.end() )
203  {
204  conversion[tri[0] ] = ind;
205  a=ind;
206  ++ind;
207  surface->vertex().push_back(mesh.vertex()[tri[0] ] );
208  }
209  else
210  a =ic->second;
211 
212  if ( (ic=conversion.find(tri[1] )) == conversion.end() )
213  {
214  conversion[tri[1] ] = ind;
215  b=ind;
216  ++ind;
217  surface->vertex().push_back(mesh.vertex()[tri[1] ] );
218  }
219  else
220  b = ic->second;
221 
222  if ( (ic=conversion.find( tri[2] )) == conversion.end() )
223  {
224  conversion[ tri[2] ] = ind;
225  c=ind;
226  ++ind;
227  surface->vertex().push_back(mesh.vertex()[tri[2] ] );
228  }
229  else
230  c = ic->second;
231  surface->polygon().push_back(AimsVector<uint,3>(a,b,c) );
232  }
233 
234  v = nodeLabels[il->first];
235  surface->updateNormals();
236  GraphManip::storeAims( g, v, "aims_Tmtktri", surface );
237  v->setProperty("aims_Tmtktri",surface);
238  }
239 
240  }
241 
242 
243  template <class T>
244  inline void Tex2Graph<T>::makeGraph( Graph & g, const AimsSurfaceTriangle & initmesh,
245  const Texture<T> & tex, float epsilon )
246  {
247  T lab;
248  std::map<T,Vertex*> nodeLabels;
249  typename std::map<T,std::set<unsigned> >::iterator il,el;
250  std::map<T,std::set<unsigned> > triLabels;
251  std::set<unsigned>::iterator it,et;
252  Vertex *v;
253  const std::vector< AimsVector<uint, 3 > > & initpoly = initmesh.polygon();
254  unsigned n = tex.nItem(), i, m = initpoly.size();
255 
256  if ( n != initmesh.vertex().size() )
257  throw std::logic_error("Mesh and texture must have the same size");
258 
259  AimsSurfaceTriangle mesh = initmesh;
260  std::vector<Point3df> &vert = mesh.vertex() ;
261  std::vector<Point3df> &normal = mesh.normal();
262  std::vector< AimsVector<uint, 3 > > &poly = mesh.polygon();
263 
264  for (i=0; i<n; ++i)
265  {
266  vert[i][0] = vert[i][0] + epsilon * normal[i][0];
267  vert[i][1] = vert[i][1] + epsilon * normal[i][1];
268  vert[i][2] = vert[i][2] + epsilon * normal[i][2];
269  }
270 
271  std::vector<float> vs;
272  vs.push_back( 1 );
273  vs.push_back( 1 );
274  vs.push_back( 1 );
275  g.setProperty( "voxel_size", vs );
276  g.setProperty( "filename_base", "*" );
277 
278  std::vector<int> bbmin(3), bbmax(3);
279  bool first = true;
280  char name[10];
281 
282  fillLabel2index(tex);
283 
284 
285  for( i=0; i<n; ++i )
286  {
287  lab = tex.item(i);
288  if ( nodeLabels.find( lab ) == nodeLabels.end() )
289  {
290  v = g.addVertex( "roi" );
291  v->setProperty( "roi_label", getIndex(lab) );
292  sprintf( name, "%d", getIndex(lab) );
293  v->setProperty( "name", "label_"+std::string( name ) );
294  nodeLabels[lab] = v;
295  }
296  const Point3df & pt = mesh.vertex()[i];
297  if( first )
298  {
299  bbmin[0] = bbmax[0] = (int) rint( pt[0] );
300  bbmin[1] = bbmax[1] = (int) rint( pt[1] );
301  bbmin[2] = bbmax[2] = (int) rint( pt[2] );
302  first = false;
303  }
304  else
305  {
306  if( pt[0] < bbmin[0] )
307  bbmin[0] = (int) rint( pt[0] );
308  if( pt[1] < bbmin[1] )
309  bbmin[1] = (int) rint( pt[1] );
310  if( pt[2] < bbmin[2] )
311  bbmin[2] = (int) rint( pt[2] );
312  if( pt[0] > bbmax[0] )
313  bbmax[0] = (int) rint( pt[0] );
314  if( pt[1] > bbmax[1] )
315  bbmax[1] = (int) rint( pt[1] );
316  if( pt[2] > bbmax[2] )
317  bbmax[2] = (int) rint( pt[2] );
318  }
319  }
320 
321  g.setProperty( "boundingbox_min", bbmin );
322  g.setProperty( "boundingbox_max", bbmax );
323 
324  for ( i=0; i<m; ++i )
325  {
326  if ( tex.item(poly[i][0]) == tex.item(poly[i][1]) &&
327  tex.item(poly[i][2]) == tex.item(poly[i][1]) )
328  triLabels[tex.item(poly[i][0])].insert(i);
329  }
330 
331  for ( il = triLabels.begin(), el = triLabels.end(); il != el; ++il )
332  {
333  uint ind=0,a,b,c;
334  std::map<uint,uint> conversion;
335  std::map<uint,uint>::iterator ic;
336  AimsVector<uint,3> tri;
338  for (it = il->second.begin(), et = il->second.end(); it != et; ++it)
339  {
340  tri = poly[*it];
341  if ( (ic=conversion.find( tri[0] )) == conversion.end() )
342  {
343  conversion[tri[0] ] = ind;
344  a=ind;
345  ++ind;
346  surface->vertex().push_back(mesh.vertex()[tri[0] ] );
347  surface->normal().push_back(mesh.normal()[tri[0] ] );
348  }
349  else
350  a =ic->second;
351 
352  if ( (ic=conversion.find(tri[1] )) == conversion.end() )
353  {
354  conversion[tri[1] ] = ind;
355  b=ind;
356  ++ind;
357  surface->vertex().push_back(mesh.vertex()[tri[1] ] );
358  surface->normal().push_back(mesh.normal()[tri[1] ] );
359  }
360  else
361  b = ic->second;
362 
363  if ( (ic=conversion.find( tri[2] )) == conversion.end() )
364  {
365  conversion[ tri[2] ] = ind;
366  c=ind;
367  ++ind;
368  surface->vertex().push_back(mesh.vertex()[tri[2] ] );
369  surface->normal().push_back(mesh.normal()[tri[2] ] );
370  }
371  else
372  c = ic->second;
373  surface->polygon().push_back(AimsVector<uint,3>(a,b,c) );
374  v = nodeLabels[il->first];
375  v->setProperty("aims_Tmtktri",surface);
376  }
377  }
378 
380  objmap( new std::map<std::string,std::map<std::string,GraphElementCode> > );
381  GraphElementCode &gec = (*objmap)["roi"]["Tmtktri"];
382  gec.id = "Tmtktri";
383  gec.attribute = "aims_Tmtktri";
384  gec.objectType = "Mesh";
385  gec.dataType = "VOID";
386  gec.syntax = "roi";
387  gec.local_file_attribute = "Tmtktri_filename";
388  gec.global_index_attribute = "Tmtktri_label";
389  gec.global_filename = "patch.mesh";
390  //gec.global = false;
391  g.setProperty("aims_objects_table",objmap);
392  }
393 
394 
395 }
396 
397 
398 
399 #endif
Vertex * addVertex(const std::string &s="")
std::string local_file_attribute
Definition: graphmanip.h:90
size_t nItem() const
Definition: texture.h:70
AIMSDATA_API AimsTimeSurface< 3, Void > AimsSurfaceTriangle
Definition: surface.h:547
std::string syntax
syntactic attribute of attributed objects
Definition: graphmanip.h:95
const T & item(int n) const
Definition: texture.h:72
std::string dataType
data type as in Aims Finder: "S16", "U8", "FLOAT", ...
Definition: graphmanip.h:88
Describe how Aims objects are stored in graph objects.
Definition: graphmanip.h:64
std::string global_index_attribute
Definition: graphmanip.h:91
The class for EcatSino data write operation.
Definition: border.h:44
std::string attribute
attribute found in graph objects, this attribute is a reference-counting pointer (carto::rc_ptr<T>) t...
Definition: graphmanip.h:84
void fillLabel2index(const Texture< T > &)
Definition: tex2graph_d.h:51
void makeGraph(Graph &g, const AimsSurfaceTriangle &mesh, const Texture< T > &tex, float epsilon=0.01)
Fills graph g from texture of labels tex on the mesh mesh.
Definition: tex2graph_d.h:244
int getIndex(const T &label)
Definition: tex2graph_d.h:56
std::string objectType
object type as in aims Finder: "Volume", "Bucket", "Mesh", ...
Definition: graphmanip.h:86
unsigned int uint
std::string id
ID for object: filename (globals) or attribute for filename (locals)
Definition: graphmanip.h:80
std::string global_filename
Definition: graphmanip.h:92
static void storeAims(Graph &graph, GraphObject *vertex, const std::string &attribute, carto::rc_ptr< T > obj)
This template function stores the given object in the given Vertex / Edge of the graph and takes care...
Definition: graphmanip_d.h:46