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);
332 for( im=vol.begin(); im!=em; ++im )
336 std::vector<Point3df> & vert = surf.
vertex();
337 std::vector<AimsVector<uint, D> > & poly = surf.
polygon();
338 typename std::vector<AimsVector<uint, D> >
::iterator ip;
339 unsigned nvertex = vert.size();
340 for (ip = poly.begin(); ip != poly.end(); ++ip)
343 for (
int j = 0; j < D; ++j)
344 if (pol[j] >= nvertex)
349 std::cerr <<
"Broken mesh: polygon pointing to a "
350 <<
"vertex out of range" << std::endl;
359 if (surf.
normal().size() != vert.size())
364 gifti_free_image(gim);
370 template<
int D,
typename T>
375 setlocale( LC_NUMERIC,
"C" );
384 gifti_image *gim = hdr.giftiImageBase();
385 std::string fname = hdr.
name();
387 int hdrmeshda = 0, hdrnormda = 0, hdrpolyda = 0, hdrtexda = 0;
395 da_info = thdr.
getProperty(
"GIFTI_dataarrays_info");
398 for (; it->isValid(); it->next())
401 if (el->getProperty(
"encoding", encoding))
417 normal = (bool) n->getScalar();
419 if ((
int) a->getScalar() != 0)
421 encoding = (int) a->getScalar();
433 for( is=thing.begin(); is!=es; ++is, ++t )
438 const std::vector<Point3df> & vert = surf.
vertex();
440 gifti_add_empty_darray( gim, 1 );
441 giiDataArray * da = gim->darray[nda];
442 gifti_set_DA_defaults( da );
443 da->intent = NIFTI_INTENT_POINTSET;
444 da->datatype = NIFTI_TYPE_FLOAT32;
446 da->dims[0] = vert.size();
452 da->nvals = vert.size() * 3;
455 da->encoding = encoding;
460 gifti_alloc_DA_data( gim, &nda, 1 );
461 unsigned i, n = vert.size();
463 float *buf =
reinterpret_cast<float *
>( da->data );
466 buf[i*3] = vert[i][0];
467 buf[i*3+1] = vert[i][1];
468 buf[i*3+2] = vert[i][2];
474 std::ostringstream ts;
476 gifti_add_to_meta( &da->meta,
"Timestep", ts.str().c_str(), 1 );
502 = GiftiHeader::giftiFindHdrDA( hdrmeshda, da_info,
503 "NIFTI_INTENT_POINTSET" );
507 GiftiHeader::giftiCopyMetaToGii( dainf, da );
514 const std::vector<Point3df> &
norm = surf.
normal();
518 gifti_add_empty_darray( gim, 1 );
519 giiDataArray * da = gim->darray[nda];
520 gifti_set_DA_defaults( da );
521 da->intent = NIFTI_INTENT_VECTOR;
522 da->datatype = NIFTI_TYPE_FLOAT32;
524 da->dims[0] =
norm.size();
530 da->nvals =
norm.size() * 3;
533 da->encoding = encoding;
535 gifti_alloc_DA_data( gim, &nda, 1 );
536 unsigned i, n =
norm.size();
537 float *buf =
reinterpret_cast<float *
>( da->data );
540 buf[i*3] =
norm[i][0];
541 buf[i*3+1] =
norm[i][1];
542 buf[i*3+2] =
norm[i][2];
548 std::ostringstream ts;
550 gifti_add_to_meta( &da->meta,
"Timestep", ts.str().c_str(), 1 );
555 = GiftiHeader::giftiFindHdrDA( hdrnormda, da_info,
556 "NIFTI_INTENT_VECTOR" );
560 GiftiHeader::giftiCopyMetaToGii( dainf, da );
567 const std::vector<AimsVector<unsigned, D> > & poly
570 gifti_add_empty_darray( gim, 1 );
571 giiDataArray * da = gim->darray[nda];
572 gifti_set_DA_defaults( da );
573 da->intent = NIFTI_INTENT_TRIANGLE;
574 da->datatype = NIFTI_TYPE_INT32;
576 da->dims[0] = poly.size();
582 da->nvals = poly.size() * D;
585 da->encoding = encoding;
587 gifti_alloc_DA_data( gim, &nda, 1 );
588 unsigned i, j, n = poly.size();
589 int *buf =
reinterpret_cast<int *
>( da->data );
592 buf[i*D+j] = poly[i][j];
597 std::ostringstream ts;
599 gifti_add_to_meta( &da->meta,
"Timestep", ts.str().c_str(), 1 );
604 = GiftiHeader::giftiFindHdrDA( hdrpolyda, da_info,
605 "NIFTI_INTENT_TRIANGLE" );
609 GiftiHeader::giftiCopyMetaToGii( dainf, da );
613 const std::vector<T> & tex = surf.
texture();
614 hdr.giftiAddTexture( gim, tex );
618 = GiftiHeader::giftiFindHdrDA( hdrtexda, da_info,
"" );
622 GiftiHeader::giftiCopyMetaToGii( dainf,
623 gim->darray[gim->numDA-1] );
628 hdr.giftiAddExternalTextures( gim, hdrtexda, da_info );
631 hdr.giftiAddLabelTable( gim );
641 for( t=0; t<nda; ++t )
643 giiDataArray *da = gim->darray[t];
644 if( da->intent == NIFTI_INTENT_POINTSET
645 && ( first || da->numCS == 0 ) )
655 gifti_write_image( gim, fname.c_str(), 1 );
658 gifti_free_image( gim );
671 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.
std::map< int, AimsSurface< D, T > >::iterator iterator
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)