34#ifndef AIMS_IO_GIFTIMESHFORMAT_D_H
35#define AIMS_IO_GIFTIMESHFORMAT_D_H
44#include <cartobase/thread/mutex.h>
53 template<
int D,
typename T>
54 void giftiReadTexture(AimsTimeSurface<D, T> & vol,
int texnum,
57 int vnum = da->dims[0];
59 std::vector<T> & tex = vol[texnum].
texture();
62 for (j = 0; j < vnum; ++j)
68 class GiftiReadExternalTexture:
public Process
71 GiftiReadExternalTexture( carto::Object textures, giiDataArray* da,
73 Process(), textures(textures), da(da), nt(nt), nts(nts)
77 carto::Object textures;
84 bool giftiReadExternalTexture(
Process & p,
const std::string &,
Finder &)
86 GiftiReadExternalTexture & gp
87 =
static_cast<GiftiReadExternalTexture &
> (p);
88 giiDataArray *da = gp.da;
89 int j, vnum = da->dims[0], nt = gp.nt;
90 carto::Object textures = gp.textures;
92 if ((
int) textures->size() > nt)
93 o = textures->getArrayItem(nt);
97 textures->insertArrayItem(-1, o);
100 = o->carto::GenericObject::value<TimeTexture<T> >();
102 std::vector<T> & tex = ttex[ttex.size() - 1].data();
104 for (j = 0; j < vnum; ++j)
113 void giftiReadTexture(AimsTimeSurface<D, Void> & ,
int ,
116 carto::Object textures;
119 textures = hdr.getProperty(
"textures");
126 int ndim = da->num_dim;
132 GiftiReadExternalTexture p(textures, da, nt, nts);
133 p.registerProcessType(
"Texture",
"FLOAT",
134 &giftiReadExternalTexture<float> );
135 p.registerProcessType(
"Texture",
"POINT2DF",
136 &giftiReadExternalTexture<Point2df> );
137 p.registerProcessType(
"Texture",
"S16",
138 &giftiReadExternalTexture<int16_t> );
139 p.registerProcessType(
"Texture",
"S32",
140 &giftiReadExternalTexture<int32_t> );
141 p.registerProcessType(
"Texture",
"U32",
142 &giftiReadExternalTexture<uint32_t> );
143 p.registerProcessType(
"Texture",
"VECTOR_OF_2_S16",
144 &giftiReadExternalTexture<Point2d> );
148 f.setDataType(dtype);
149 if (p.execute(f,
""))
151 hdr.setProperty(
"textures", textures);
157 template<
int D,
typename T>
159 D, T> & vol,
const carto::AllocatorContext & ,
162 setlocale( LC_NUMERIC,
"C" );
171 gifti_image *gim = gifti_read_image(hdr.
name().c_str(), 1);
179 int nda = gim->numDA, i;
180 int tmesh = -1, ttex = -1, tnorm = -1, tpoly = -1, nts = 0;
181 for (i = 0; i < nda; ++i)
183 giiDataArray *da = gim->darray[i];
186 gifti_free_image(gim);
191 case NIFTI_INTENT_POINTSET:
194 char *ts = gifti_get_meta_value(&da->meta,
"Timestep");
196 sscanf(ts,
"%d", &tmesh);
197 int vnum = da->dims[0];
201 if (da->ind_ord == GIFTI_IND_ORD_UNDEF)
202 std::cout <<
"GIFTI_IND_ORD_UNDEF" << std::endl;
204 if (da->ind_ord == GIFTI_IND_ORD_ROW_MAJOR)
205 std::cout <<
"GIFTI_IND_ORD_ROW_MAJOR" << std::endl;
207 if (da->ind_ord == GIFTI_IND_ORD_COL_MAJOR)
208 std::cout <<
"GIFTI_IND_ORD_COL_MAJOR " << vnum << std::endl;
211 std::vector<Point3df> & vert = vol[tmesh].
vertex();
215 if (da->ind_ord == GIFTI_IND_ORD_ROW_MAJOR || da->ind_ord == GIFTI_IND_ORD_UNDEF)
216 for (j = 0; j < vnum; ++j)
222 if (da->ind_ord == GIFTI_IND_ORD_COL_MAJOR)
223 for (j = 0; j < vnum; ++j)
230 case NIFTI_INTENT_VECTOR:
233 char *ts = gifti_get_meta_value(&da->meta,
"Timestep");
235 sscanf(ts,
"%d", &tnorm);
236 else if (tnorm < tmesh)
238 int vnum = da->dims[0];
240 std::vector<Point3df> &
norm = vol[tnorm].
normal();
244 if (da->ind_ord == GIFTI_IND_ORD_ROW_MAJOR || da->ind_ord == GIFTI_IND_ORD_UNDEF)
245 for (j = 0; j < vnum; ++j)
251 if (da->ind_ord == GIFTI_IND_ORD_COL_MAJOR)
252 for (j = 0; j < vnum; ++j)
260 case NIFTI_INTENT_TRIANGLE:
263 char *ts = gifti_get_meta_value(&da->meta,
"Timestep");
265 sscanf(ts,
"%d", &tpoly);
266 else if (tpoly < tmesh)
268 int vnum = da->dims[0];
270 std::vector<AimsVector<unsigned, D> > & poly = vol[tpoly].
polygon();
275 gifti_free_image( gim );
279 if (da->ind_ord == GIFTI_IND_ORD_ROW_MAJOR || da->ind_ord == GIFTI_IND_ORD_UNDEF)
280 for (j = 0; j < vnum; ++j)
284 for (k = 0; k < D; ++k)
289 if (da->ind_ord == GIFTI_IND_ORD_COL_MAJOR)
290 for (j = 0; j < vnum; ++j)
294 for (k = 0; k < D; ++k)
299 case NIFTI_INTENT_TIME_SERIES:
302 giftiReadTexture(vol, ttex, da, hdr, nts);
310 giftiReadTexture(vol, ttex, da, hdr, 0);
331 for (i = 0; i < tmesh; ++i)
334 std::vector<Point3df> & vert = surf.
vertex();
335 std::vector<AimsVector<uint, D> > & poly = surf.
polygon();
336 typename std::vector<AimsVector<uint, D> >
::iterator ip;
337 unsigned nvertex = vert.size();
338 for (ip = poly.begin(); ip != poly.end(); ++ip)
341 for (
int j = 0; j < D; ++j)
342 if (pol[j] >= nvertex)
347 std::cerr <<
"Broken mesh: polygon pointing to a "
348 <<
"vertex out of range" << std::endl;
357 if (surf.
normal().size() != vert.size())
362 gifti_free_image(gim);
368 template<
int D,
typename T>
373 setlocale( LC_NUMERIC,
"C" );
382 gifti_image *gim = hdr.giftiImageBase();
383 std::string fname = hdr.
name();
385 int hdrmeshda = 0, hdrnormda = 0, hdrpolyda = 0, hdrtexda = 0;
393 da_info = thdr.
getProperty(
"GIFTI_dataarrays_info");
396 for (; it->isValid(); it->next())
399 if (el->getProperty(
"encoding", encoding))
415 normal = (bool) n->getScalar();
417 if ((
int) a->getScalar() != 0)
419 encoding = (int) a->getScalar();
431 for( is=thing.begin(); is!=es; ++is, ++t )
436 const std::vector<Point3df> & vert = surf.
vertex();
438 gifti_add_empty_darray( gim, 1 );
439 giiDataArray * da = gim->darray[nda];
440 gifti_set_DA_defaults( da );
441 da->intent = NIFTI_INTENT_POINTSET;
442 da->datatype = NIFTI_TYPE_FLOAT32;
444 da->dims[0] = vert.size();
450 da->nvals = vert.size() * 3;
453 da->encoding = encoding;
458 gifti_alloc_DA_data( gim, &nda, 1 );
459 unsigned i, n = vert.size();
461 float *buf =
reinterpret_cast<float *
>( da->data );
464 buf[i*3] = vert[i][0];
465 buf[i*3+1] = vert[i][1];
466 buf[i*3+2] = vert[i][2];
472 std::ostringstream ts;
474 gifti_add_to_meta( &da->meta,
"Timestep", ts.str().c_str(), 1 );
497 = GiftiHeader::giftiFindHdrDA( hdrmeshda, da_info,
498 "NIFTI_INTENT_POINTSET" );
502 GiftiHeader::giftiCopyMetaToGii( dainf, da );
509 const std::vector<Point3df> &
norm = surf.
normal();
513 gifti_add_empty_darray( gim, 1 );
514 giiDataArray * da = gim->darray[nda];
515 gifti_set_DA_defaults( da );
516 da->intent = NIFTI_INTENT_VECTOR;
517 da->datatype = NIFTI_TYPE_FLOAT32;
519 da->dims[0] =
norm.size();
525 da->nvals =
norm.size() * 3;
528 da->encoding = encoding;
530 gifti_alloc_DA_data( gim, &nda, 1 );
531 unsigned i, n =
norm.size();
532 float *buf =
reinterpret_cast<float *
>( da->data );
535 buf[i*3] =
norm[i][0];
536 buf[i*3+1] =
norm[i][1];
537 buf[i*3+2] =
norm[i][2];
543 std::ostringstream ts;
545 gifti_add_to_meta( &da->meta,
"Timestep", ts.str().c_str(), 1 );
550 = GiftiHeader::giftiFindHdrDA( hdrnormda, da_info,
551 "NIFTI_INTENT_VECTOR" );
555 GiftiHeader::giftiCopyMetaToGii( dainf, da );
562 const std::vector<AimsVector<unsigned, D> > & poly
565 gifti_add_empty_darray( gim, 1 );
566 giiDataArray * da = gim->darray[nda];
567 gifti_set_DA_defaults( da );
568 da->intent = NIFTI_INTENT_TRIANGLE;
569 da->datatype = NIFTI_TYPE_INT32;
571 da->dims[0] = poly.size();
577 da->nvals = poly.size() * D;
580 da->encoding = encoding;
582 gifti_alloc_DA_data( gim, &nda, 1 );
583 unsigned i, j, n = poly.size();
584 int *buf =
reinterpret_cast<int *
>( da->data );
587 buf[i*D+j] = poly[i][j];
592 std::ostringstream ts;
594 gifti_add_to_meta( &da->meta,
"Timestep", ts.str().c_str(), 1 );
599 = GiftiHeader::giftiFindHdrDA( hdrpolyda, da_info,
600 "NIFTI_INTENT_TRIANGLE" );
604 GiftiHeader::giftiCopyMetaToGii( dainf, da );
608 const std::vector<T> & tex = surf.
texture();
609 hdr.giftiAddTexture( gim, tex );
613 = GiftiHeader::giftiFindHdrDA( hdrtexda, da_info,
"" );
617 GiftiHeader::giftiCopyMetaToGii( dainf,
618 gim->darray[gim->numDA-1] );
623 hdr.giftiAddExternalTextures( gim, hdrtexda, da_info );
626 hdr.giftiAddLabelTable( gim );
636 for( t=0; t<nda; ++t )
638 giiDataArray *da = gim->darray[t];
639 if( da->intent == NIFTI_INTENT_POINTSET
640 && ( first || da->numCS == 0 ) )
650 gifti_write_image( gim, fname.c_str(), 1 );
653 gifti_free_image( gim );
666 catch( std::exception & e )
The template class to manage a mesh.
const std::vector< Point3df > & normal() const
Get a const reference to the vector of normals.
const std::vector< AimsVector< uint, D > > & polygon() const
Get a const reference to the vector of polygons.
void updateNormals()
Update/Compute the normals.
const std::vector< T > & texture() const
Get a const reference to the vector of textures.
const std::vector< Point3df > & vertex() const
Get a const reference to the vector of vertices.
The template class to manage a mesh with time if needed.
void setHeader(const aims::PythonHeader &hdr)
Set the header.
const aims::PythonHeader & header() const
Get the header.
std::map< int, AimsSurface< D, T > >::const_iterator const_iterator
const std::vector< Point3df > & normal() const
Get a const reference to the vector of normals of the 0 surface.
const std::vector< AimsVector< uint, D > > & polygon() const
Get a const reference to the vector of polygons of the 0 surface.
const std::vector< T > & texture() const
Get a const reference to the vector of textures of the 0 surface.
const std::vector< Point3df > & vertex() const
Get a const reference to the vector of verteces of the surface of index 0.
Generic finder / checker for all data objects and file formats This will replace the old AimsFinder.
void setObjectType(const std::string &obj)
Link mechanism between the Finder and a process operating on arbitrary data types.
Object reference(Object &value)
virtual bool getProperty(const std::string &, Object &) const
virtual bool removeProperty(const std::string &)
virtual bool hasProperty(const std::string &) const
static void launchErrnoExcept(const std::string &filename="")
The class for EcatSino data write operation.
std::string giftiTextureDataType(int dtype, int &ndim, int *dims, int intent, int &ntime)
U convertedNiftiValue(void *data, int index, int dtype)
std::vector< Object > ObjectVector
AimsVector< float, 3 > Point3df
float norm(const AimsVector< T, D > &v1)