1 /*============================================================================
2   MetaIO
3   Copyright 2000-2010 Insight Software Consortium
4 
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7 
8   This software is distributed WITHOUT ANY WARRANTY; without even the
9   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   See the License for more information.
11 ============================================================================*/
12 #ifdef _MSC_VER
13 #  pragma warning(disable : 4702)
14 #  pragma warning(disable : 4284)
15 #endif
16 
17 #include "metaTube.h"
18 
19 
20 #if (METAIO_USE_NAMESPACE)
21 namespace METAIO_NAMESPACE
22 {
23 #endif
24 
TubePnt(int dim)25 TubePnt::TubePnt(int dim)
26 {
27   m_NDims = static_cast<unsigned int>(dim);
28 
29   m_ID = -1;
30 
31   m_X = new float[m_NDims];
32   unsigned int i = 0;
33   for (i = 0; i < m_NDims; i++)
34   {
35     m_X[i] = 0;
36   }
37 
38   for (i = 0; i < 4; i++)
39   {
40     m_Color[i] = 1;
41   }
42 
43   m_Mark = false;
44 
45   m_T = new float[m_NDims];
46   m_V1 = new float[m_NDims];
47   m_V2 = new float[m_NDims];
48   for (unsigned int ii = 0; ii < m_NDims; ii++)
49   {
50     m_T[ii] = 0;
51     m_V1[ii] = 0;
52     m_V2[ii] = 0;
53   }
54   m_Alpha1 = 0;
55   m_Alpha2 = 0;
56   m_Alpha3 = 0;
57 
58   m_R = 0;
59   m_Medialness = 0;
60   m_Ridgeness = 0;
61   m_Branchness = 0;
62   m_Curvature = 0;
63   m_Levelness = 0;
64   m_Roundness = 0;
65   m_Intensity = 0;
66 
67   m_ExtraFields.clear();
68 }
69 
TubePnt(const TubePnt * _tubePnt)70 TubePnt::TubePnt(const TubePnt * _tubePnt)
71 {
72   TubePnt::CopyInfo(_tubePnt);
73 }
74 
~TubePnt()75 TubePnt::~TubePnt()
76 {
77   delete[] m_X;
78   delete[] m_T;
79   delete[] m_V1;
80   delete[] m_V2;
81 
82   m_ExtraFields.clear();
83 }
84 
85 void
CopyInfo(const TubePnt * _tubePnt)86 TubePnt::CopyInfo(const TubePnt * _tubePnt)
87 {
88   delete[] m_X;
89   delete[] m_T;
90   delete[] m_V1;
91   delete[] m_V2;
92 
93   m_ExtraFields.clear();
94 
95   m_NDims = _tubePnt->m_NDims;
96 
97   m_X = new float[m_NDims];
98   m_T = new float[m_NDims];
99   m_V1 = new float[m_NDims];
100   m_V2 = new float[m_NDims];
101   for (unsigned int i = 0; i < m_NDims; ++i)
102   {
103     m_X[i] = _tubePnt->m_X[i];
104     m_T[i] = _tubePnt->m_T[i];
105     m_V1[i] = _tubePnt->m_V1[i];
106     m_V2[i] = _tubePnt->m_V2[i];
107   }
108   m_Alpha1 = _tubePnt->m_Alpha1;
109   m_Alpha2 = _tubePnt->m_Alpha2;
110   m_Alpha3 = _tubePnt->m_Alpha3;
111   m_R = _tubePnt->m_R;
112   m_Medialness = _tubePnt->m_Medialness;
113   m_Ridgeness = _tubePnt->m_Ridgeness;
114   m_Branchness = _tubePnt->m_Branchness;
115   m_Curvature = _tubePnt->m_Curvature;
116   m_Levelness = _tubePnt->m_Levelness;
117   m_Roundness = _tubePnt->m_Roundness;
118   m_Intensity = _tubePnt->m_Intensity;
119 
120   for (unsigned int i = 0; i < 4; ++i)
121   {
122     m_Color[i] = _tubePnt->m_Color[i];
123   }
124   m_Mark = _tubePnt->m_Mark;
125 
126   auto it = _tubePnt->m_ExtraFields.begin();
127   auto itEnd = _tubePnt->m_ExtraFields.end();
128   while (it != itEnd)
129   {
130     m_ExtraFields.push_back(*it);
131     ++it;
132   }
133 }
134 const TubePnt::FieldListType &
GetExtraFields() const135 TubePnt::GetExtraFields() const
136 {
137   return m_ExtraFields;
138 }
139 
140 size_t
GetNumberOfExtraFields() const141 TubePnt::GetNumberOfExtraFields() const
142 {
143   return m_ExtraFields.size();
144 }
145 
146 void
SetNumberOfExtraFields(int size)147 TubePnt::SetNumberOfExtraFields(int size)
148 {
149   m_ExtraFields.resize(static_cast<unsigned long>(size));
150 }
151 
152 void
SetField(int indx,const char * name,float value)153 TubePnt::SetField(int indx, const char * name, float value)
154 {
155   FieldType field(name, value);
156   m_ExtraFields[indx] = field;
157 }
158 
159 void
SetField(const char * name,float value)160 TubePnt::SetField(const char * name, float value)
161 {
162   int indx = this->GetFieldIndex(name);
163   if (indx >= 0)
164   {
165     m_ExtraFields[indx].second = value;
166   }
167   else
168   {
169     this->AddField(name, value);
170   }
171 }
172 
173 void
AddField(const char * name,float value)174 TubePnt::AddField(const char * name, float value)
175 {
176   int indx = this->GetFieldIndex(name);
177   if (indx != -1)
178   {
179     m_ExtraFields[indx].second = value;
180   }
181   else
182   {
183     FieldType field(name, value);
184     m_ExtraFields.push_back(field);
185   }
186 }
187 
188 int
GetFieldIndex(const char * name) const189 TubePnt::GetFieldIndex(const char * name) const
190 {
191   unsigned int count = 0;
192   auto         it = m_ExtraFields.begin();
193   auto         itEnd = m_ExtraFields.end();
194   while (it != itEnd)
195   {
196     if (!strcmp((*it).first.c_str(), name))
197     {
198       return count;
199     }
200     ++it;
201     ++count;
202   }
203   return -1;
204 }
205 
206 float
GetField(int indx) const207 TubePnt::GetField(int indx) const
208 {
209   if (indx >= 0 && static_cast<size_t>(indx) < m_ExtraFields.size())
210   {
211     return m_ExtraFields[indx].second;
212   }
213   return -1;
214 }
215 
216 float
GetField(const char * name) const217 TubePnt::GetField(const char * name) const
218 {
219   auto it = m_ExtraFields.begin();
220   auto itEnd = m_ExtraFields.end();
221   while (it != itEnd)
222   {
223     if (!strcmp((*it).first.c_str(), name))
224     {
225       return (*it).second;
226     }
227     ++it;
228   }
229   return -1;
230 }
231 
232 /** MetaTube Constructors */
MetaTube()233 MetaTube::MetaTube()
234 {
235   META_DEBUG_PRINT( "MetaTube()" );
236   MetaTube::Clear();
237 }
238 
239 
MetaTube(const char * _headerName)240 MetaTube::MetaTube(const char * _headerName)
241   : MetaObject()
242 {
243   META_DEBUG_PRINT( "MetaTube()" );
244   MetaTube::Clear();
245   MetaTube::Read(_headerName);
246 }
247 
248 
MetaTube(const MetaTube * Tube)249 MetaTube::MetaTube(const MetaTube * Tube)
250   : MetaObject()
251 {
252   META_DEBUG_PRINT( "MetaTube()" );
253   MetaTube::Clear();
254   CopyInfo(Tube);
255 }
256 
257 
MetaTube(unsigned int dim)258 MetaTube::MetaTube(unsigned int dim)
259   : MetaObject(dim)
260 {
261   META_DEBUG_PRINT( "MetaTube()" );
262   MetaTube::Clear();
263 }
264 
265 /** Destructor */
~MetaTube()266 MetaTube::~MetaTube()
267 {
268   // Delete the list of pointers to PointObject.
269   auto it = m_PointList.begin();
270   while (it != m_PointList.end())
271   {
272     TubePnt * pnt = *it;
273     ++it;
274     delete pnt;
275   }
276   m_PointList.clear();
277   MetaObject::M_Destroy();
278 }
279 
280 //
281 void
PrintInfo() const282 MetaTube::PrintInfo() const
283 {
284   MetaObject::PrintInfo();
285 
286   std::cout << "PointDim = " << m_PointDim << std::endl;
287 
288   std::cout << "NPoints = " << m_NPoints << std::endl;
289 
290   char str[255];
291   MET_TypeToString(m_ElementType, str);
292   std::cout << "ElementType = " << str << std::endl;
293 
294   std::cout << "ParentPoint = " << m_ParentPoint << std::endl;
295 
296   if (m_Root)
297   {
298     std::cout << "Root = "
299               << "True" << std::endl;
300   }
301   else
302   {
303     std::cout << "Root = "
304               << "False" << std::endl;
305   }
306 
307   std::cout << "Artery = " << m_Artery << std::endl;
308 }
309 
310 void
CopyInfo(const MetaTube * _object)311 MetaTube::CopyInfo(const MetaTube * _object)
312 {
313   Clear();
314 
315   MetaObject::CopyInfo(_object);
316 
317   auto it = _object->GetPoints().begin();
318   while (it != _object->GetPoints().end())
319   {
320     auto * pnt = new TubePnt(*it);
321     m_PointList.push_back(pnt);
322     ++it;
323   }
324 
325   m_ParentPoint = _object->ParentPoint();
326   m_Artery = _object->Artery();
327   m_Root = _object->Root();
328 }
329 
330 /** Clear Tube information */
331 void
Clear()332 MetaTube::Clear()
333 {
334   META_DEBUG_PRINT( "MetaTube: Clear" );
335 
336   MetaObject::Clear();
337 
338   strcpy(m_ObjectTypeName, "Tube");
339   strcpy(m_ObjectSubTypeName, "");
340 
341   m_ElementType = MET_FLOAT;
342 
343   m_ParentPoint = -1;
344   m_Root = false;
345   m_Artery = true;
346 
347   // Delete the list of pointers to PointObjects.
348   auto it = m_PointList.begin();
349   while (it != m_PointList.end())
350   {
351     TubePnt * pnt = *it;
352     ++it;
353     delete pnt;
354   }
355   m_PointList.clear();
356 
357   m_NPoints = 0;
358   if (m_NDims == 2)
359   {
360     m_PointDim = "id x y red green blue alpha mark r rn mn bn cv lv ro in tx ty v1x v1y a1 a2";
361   }
362   else
363   {
364     m_PointDim = "id x y z red green blue alpha mark r rn mn bn cv lv ro in tx ty tz v1x v1y v1z v2x v2y v2z a1 a2 a3";
365   }
366 }
367 
368 const char *
PointDim() const369 MetaTube::PointDim() const
370 {
371   return m_PointDim.c_str();
372 }
373 
374 void
PointDim(const char * pntDim)375 MetaTube::PointDim(const char * pntDim)
376 {
377   m_PointDim = pntDim;
378 }
379 
380 void
NPoints(int npnt)381 MetaTube::NPoints(int npnt)
382 {
383   m_NPoints = npnt;
384 }
385 
386 int
NPoints() const387 MetaTube::NPoints() const
388 {
389   return m_NPoints;
390 }
391 
392 /** Set Read fields */
393 void
M_SetupReadFields()394 MetaTube::M_SetupReadFields()
395 {
396   META_DEBUG_PRINT( "MetaTube: M_SetupReadFields" );
397 
398   MetaObject::M_SetupReadFields();
399 
400   MET_FieldRecordType * mF;
401 
402   mF = new MET_FieldRecordType;
403   MET_InitReadField(mF, "ParentPoint", MET_INT, false);
404   m_Fields.push_back(mF);
405 
406   mF = new MET_FieldRecordType;
407   MET_InitReadField(mF, "Root", MET_STRING, false);
408   m_Fields.push_back(mF);
409 
410   mF = new MET_FieldRecordType;
411   MET_InitReadField(mF, "Artery", MET_STRING, false);
412   m_Fields.push_back(mF);
413 
414   mF = new MET_FieldRecordType;
415   MET_InitReadField(mF, "ElementType", MET_STRING, false);
416   m_Fields.push_back(mF);
417 
418   mF = new MET_FieldRecordType;
419   MET_InitReadField(mF, "PointDim", MET_STRING, true);
420   m_Fields.push_back(mF);
421 
422   mF = new MET_FieldRecordType;
423   MET_InitReadField(mF, "NPoints", MET_INT, true);
424   m_Fields.push_back(mF);
425 
426   mF = new MET_FieldRecordType;
427   MET_InitReadField(mF, "Points", MET_NONE, true);
428   mF->terminateRead = true;
429   m_Fields.push_back(mF);
430 }
431 
432 void
M_SetupWriteFields()433 MetaTube::M_SetupWriteFields()
434 {
435   MetaObject::M_SetupWriteFields();
436 
437   MET_FieldRecordType * mF;
438 
439   if (m_ParentPoint >= 0 && m_ParentID >= 0)
440   {
441     mF = new MET_FieldRecordType;
442     MET_InitWriteField(mF, "ParentPoint", MET_INT, m_ParentPoint);
443     m_Fields.push_back(mF);
444   }
445 
446   if (m_Root)
447   {
448     mF = new MET_FieldRecordType;
449     MET_InitWriteField(mF, "Root", MET_STRING, strlen("True"), "True");
450     m_Fields.push_back(mF);
451   }
452   else
453   {
454     mF = new MET_FieldRecordType;
455     MET_InitWriteField(mF, "Root", MET_STRING, strlen("False"), "False");
456     m_Fields.push_back(mF);
457   }
458 
459   if (m_Artery)
460   {
461     mF = new MET_FieldRecordType;
462     MET_InitWriteField(mF, "Artery", MET_STRING, strlen("True"), "True");
463     m_Fields.push_back(mF);
464   }
465   else
466   {
467     mF = new MET_FieldRecordType;
468     MET_InitWriteField(mF, "Artery", MET_STRING, strlen("False"), "False");
469     m_Fields.push_back(mF);
470   }
471 
472   if (m_NDims == 2)
473   {
474     m_PointDim = "id x y red green blue alpha mark r rn mn bn cv lv ro in tx ty v1x v1y a1 a2";
475   }
476   else
477   {
478     m_PointDim = "id x y z red green blue alpha mark r rn mn bn cv lv ro in tx ty tz v1x v1y v1z v2x v2y v2z a1 a2 a3";
479   }
480 
481   // All the points in the tube have the same number of fields
482   const TubePnt::FieldListType & extraList = (*(m_PointList.begin()))->GetExtraFields();
483   auto                           itFields = extraList.begin();
484   auto                           itFieldsEnd = extraList.end();
485   while (itFields != itFieldsEnd)
486   {
487     m_PointDim += " ";
488     m_PointDim += (*itFields).first;
489     ++itFields;
490   }
491 
492   mF = new MET_FieldRecordType;
493   MET_InitWriteField(mF, "PointDim", MET_STRING, m_PointDim.size(), m_PointDim.c_str());
494   m_Fields.push_back(mF);
495 
496   m_NPoints = static_cast<int>(m_PointList.size());
497   mF = new MET_FieldRecordType;
498   MET_InitWriteField(mF, "NPoints", MET_INT, m_NPoints);
499   m_Fields.push_back(mF);
500 
501   mF = new MET_FieldRecordType;
502   MET_InitWriteField(mF, "Points", MET_NONE);
503   m_Fields.push_back(mF);
504 }
505 
506 /** Return the position given the name of the field */
507 int
M_GetPosition(const char * name,std::vector<bool> & used) const508 MetaTube::M_GetPosition(const char * name, std::vector<bool> & used) const
509 {
510   auto it = m_Positions.begin();
511   auto itUsed = used.begin();
512   auto itEnd = m_Positions.end();
513   while (it != itEnd)
514   {
515     if (!strcmp((*it).first.c_str(), name))
516     {
517       *itUsed = true;
518       return (*it).second;
519     }
520     ++it;
521     ++itUsed;
522   }
523 
524   return -1;
525 }
526 
527 void
M_SetFloatIntoBinaryData(float val,char * _data,int i) const528 MetaTube::M_SetFloatIntoBinaryData(float val, char * _data, int i) const
529 {
530   MET_SwapByteIfSystemMSB(&val, MET_FLOAT);
531   MET_DoubleToValue(static_cast<double>(val), m_ElementType, _data, i);
532 }
533 
534 float
M_GetFloatFromBinaryData(size_t pos,const char * _data,size_t readSize)535 MetaTube::M_GetFloatFromBinaryData(size_t pos, const char * _data, size_t readSize)
536 {
537   if (pos < readSize)
538   {
539     float        tf;
540     char * const num = reinterpret_cast<char *>(&tf);
541     size_t       posChar = pos * sizeof(float);
542     for (size_t k = 0; k < sizeof(float) && posChar + k < readSize; k++)
543     {
544       num[k] = _data[posChar + k];
545     }
546     MET_SwapByteIfSystemMSB(&tf, MET_FLOAT);
547     return tf;
548   }
549   return -1;
550 }
551 
552 bool
M_Read()553 MetaTube::M_Read()
554 {
555   META_DEBUG_PRINT( "MetaTube: M_Read: Loading Header" );
556 
557   if (!MetaObject::M_Read())
558   {
559     std::cout << "MetaTube: M_Read: Error parsing file" << std::endl;
560     return false;
561   }
562 
563   META_DEBUG_PRINT( "MetaTube: M_Read: Parsing Header" );
564 
565   MET_FieldRecordType * mF;
566 
567   mF = MET_GetFieldRecord("ParentPoint", &m_Fields);
568   if (mF && mF->defined)
569   {
570     m_ParentPoint = static_cast<int>(mF->value[0]);
571   }
572 
573   m_Root = false;
574   mF = MET_GetFieldRecord("Root", &m_Fields);
575   if (mF && mF->defined)
576   {
577     if (*(reinterpret_cast<char *>(mF->value)) == 'T' || *(reinterpret_cast<char *>(mF->value)) == 't' || *(reinterpret_cast<char *>(mF->value)) == '1')
578     {
579       m_Root = true;
580     }
581     else
582     {
583       m_Root = false;
584     }
585   }
586 
587   m_Artery = true;
588   mF = MET_GetFieldRecord("Artery", &m_Fields);
589   if (mF && mF->defined)
590   {
591     if (*(reinterpret_cast<char *>(mF->value)) == 'T' || *(reinterpret_cast<char *>(mF->value)) == 't')
592     {
593       m_Artery = true;
594     }
595     else
596     {
597       m_Artery = false;
598     }
599   }
600 
601   mF = MET_GetFieldRecord("NPoints", &m_Fields);
602   if (mF->defined)
603   {
604     m_NPoints = static_cast<int>(mF->value[0]);
605   }
606 
607   mF = MET_GetFieldRecord("ElementType", &m_Fields);
608   if (mF && mF->defined)
609   {
610     MET_StringToType(reinterpret_cast<char *>(mF->value), &m_ElementType);
611   }
612 
613   mF = MET_GetFieldRecord("PointDim", &m_Fields);
614   if (mF->defined)
615   {
616     m_PointDim = reinterpret_cast<char *>(mF->value);
617   }
618 
619 
620   int     pntDim;
621   char ** pntVal = nullptr;
622   char    pointDim[4096];
623 
624   for (unsigned t = 0; t < this->m_PointDim.size(); t++)
625   {
626     pointDim[t] = this->m_PointDim[t];
627   }
628   pointDim[m_PointDim.size()] = '\0';
629 
630   MET_StringToWordArray(pointDim, &pntDim, &pntVal);
631 
632   META_DEBUG_PRINT( "MetaTube: Parsing point dim" );
633 
634   m_Positions.clear();
635   std::vector<bool> positionUsed;
636   for (int i = 0; i < pntDim; i++)
637   {
638     PositionType p(pntVal[i], static_cast<const unsigned int &>(i));
639     m_Positions.push_back(p);
640     positionUsed.push_back(false);
641   }
642 
643   for (int i = 0; i < pntDim; i++)
644   {
645     delete[] pntVal[i];
646   }
647   delete[] pntVal;
648 
649   float v[100];
650 
651   if (m_Event)
652   {
653     m_Event->StartReading(static_cast<unsigned int>(m_NPoints));
654   }
655 
656   int posId = M_GetPosition("id", positionUsed);
657   int posX = M_GetPosition("x", positionUsed);
658   int posY = M_GetPosition("y", positionUsed);
659   int posZ = M_GetPosition("z", positionUsed);
660   int posRed = M_GetPosition("red", positionUsed);
661   int posGreen = M_GetPosition("green", positionUsed);
662   int posBlue = M_GetPosition("blue", positionUsed);
663   int posAlpha = M_GetPosition("alpha", positionUsed);
664   int posMark = M_GetPosition("mark", positionUsed);
665   if (posMark == -1)
666   {
667     posMark = M_GetPosition("mk", positionUsed);
668   }
669   int posR = M_GetPosition("r", positionUsed);
670   if (posR == -1)
671   {
672     posR = M_GetPosition("R", positionUsed);
673   }
674   if (posR == -1)
675   {
676     posR = M_GetPosition("radius", positionUsed);
677   }
678   if (posR == -1)
679   {
680     posR = M_GetPosition("Radius", positionUsed);
681   }
682   if (posR == -1)
683   {
684     posR = M_GetPosition("rad", positionUsed);
685   }
686   if (posR == -1)
687   {
688     posR = M_GetPosition("Rad", positionUsed);
689   }
690   if (posR == -1)
691   {
692     posR = M_GetPosition("s", positionUsed);
693   }
694   if (posR == -1)
695   {
696     posR = M_GetPosition("S", positionUsed);
697   }
698   int posRn = M_GetPosition("rn", positionUsed);
699   int posMn = M_GetPosition("mn", positionUsed);
700   int posBn = M_GetPosition("bn", positionUsed);
701   int posCv = M_GetPosition("cv", positionUsed);
702   int posLv = M_GetPosition("lv", positionUsed);
703   int posRo = M_GetPosition("ro", positionUsed);
704   int posIn = M_GetPosition("in", positionUsed);
705   int posTx = M_GetPosition("tx", positionUsed);
706   int posTy = M_GetPosition("ty", positionUsed);
707   int posTz = M_GetPosition("tz", positionUsed);
708   int posV1x = M_GetPosition("v1x", positionUsed);
709   int posV1y = M_GetPosition("v1y", positionUsed);
710   int posV1z = M_GetPosition("v1z", positionUsed);
711   int posV2x = M_GetPosition("v2x", positionUsed);
712   int posV2y = M_GetPosition("v2y", positionUsed);
713   int posV2z = M_GetPosition("v2z", positionUsed);
714   int posA1 = M_GetPosition("a1", positionUsed);
715   int posA2 = M_GetPosition("a2", positionUsed);
716   int posA3 = M_GetPosition("a3", positionUsed);
717 
718   if (m_BinaryData)
719   {
720     int elementSize;
721     MET_SizeOfType(m_ElementType, &elementSize);
722     int readSize = m_NPoints * pntDim * elementSize;
723 
724     char * _data = new char[readSize];
725     m_ReadStream->read(_data, readSize);
726 
727     int gc = static_cast<int>(m_ReadStream->gcount());
728     if (gc != readSize)
729     {
730       std::cout << "MetaLine: m_Read: data not read completely" << std::endl;
731       std::cout << "   ideal = " << readSize << " : actual = " << gc << std::endl;
732       delete[] _data;
733       return false;
734     }
735 
736     for (int j = 0; j < m_NPoints; j++)
737     {
738       auto * pnt = new TubePnt(m_NDims);
739 
740       auto pntPos = static_cast<size_t>(j * pntDim);
741 
742       if (posId >= 0)
743       {
744         pnt->m_ID = static_cast<int>(M_GetFloatFromBinaryData(pntPos + posId, _data, static_cast<size_t>(readSize)));
745       }
746       if (posX >= 0)
747       {
748         pnt->m_X[0] = M_GetFloatFromBinaryData(pntPos + posX, _data, static_cast<size_t>(readSize));
749       }
750       if (posY >= 0)
751       {
752         pnt->m_X[1] = M_GetFloatFromBinaryData(pntPos + posY, _data, static_cast<size_t>(readSize));
753       }
754       if (m_NDims > 2 && posZ >= 0)
755       {
756         pnt->m_X[2] = M_GetFloatFromBinaryData(pntPos + posZ, _data, static_cast<size_t>(readSize));
757       }
758       if (posRed >= 0)
759       {
760         pnt->m_Color[0] = M_GetFloatFromBinaryData(pntPos + posRed, _data, static_cast<size_t>(readSize));
761       }
762       if (posGreen >= 0)
763       {
764         pnt->m_Color[1] = M_GetFloatFromBinaryData(pntPos + posGreen, _data, static_cast<size_t>(readSize));
765       }
766       if (posBlue >= 0)
767       {
768         pnt->m_Color[2] = M_GetFloatFromBinaryData(pntPos + posBlue, _data, static_cast<size_t>(readSize));
769       }
770       if (posAlpha >= 0)
771       {
772         pnt->m_Color[3] = M_GetFloatFromBinaryData(pntPos + posAlpha, _data, static_cast<size_t>(readSize));
773       }
774       if (posMark >= 0)
775       {
776         if (M_GetFloatFromBinaryData(pntPos + posMark, _data, static_cast<size_t>(readSize)) != 0)
777         {
778           pnt->m_Mark = true;
779         }
780         else
781         {
782           pnt->m_Mark = false;
783         }
784       }
785       if (posR != -1)
786       {
787         pnt->m_R = M_GetFloatFromBinaryData(pntPos + posR, _data, static_cast<size_t>(readSize));
788       }
789       if (posMn != -1)
790       {
791         pnt->m_Medialness = M_GetFloatFromBinaryData(pntPos + posMn, _data, static_cast<size_t>(readSize));
792       }
793       if (posRn != -1)
794       {
795         pnt->m_Ridgeness = M_GetFloatFromBinaryData(pntPos + posRn, _data, static_cast<size_t>(readSize));
796       }
797       if (posBn != -1)
798       {
799         pnt->m_Branchness = M_GetFloatFromBinaryData(pntPos + posBn, _data, static_cast<size_t>(readSize));
800       }
801       if (posCv != -1)
802       {
803         pnt->m_Curvature = M_GetFloatFromBinaryData(pntPos + posCv, _data, static_cast<size_t>(readSize));
804       }
805       if (posLv != -1)
806       {
807         pnt->m_Levelness = M_GetFloatFromBinaryData(pntPos + posLv, _data, static_cast<size_t>(readSize));
808       }
809       if (posRo != -1)
810       {
811         pnt->m_Roundness = M_GetFloatFromBinaryData(pntPos + posRo, _data, static_cast<size_t>(readSize));
812       }
813       if (posIn != -1)
814       {
815         pnt->m_Intensity = M_GetFloatFromBinaryData(pntPos + posIn, _data, static_cast<size_t>(readSize));
816       }
817       if (posTx != -1)
818       {
819         pnt->m_T[0] = M_GetFloatFromBinaryData(pntPos + posTx, _data, static_cast<size_t>(readSize));
820       }
821       if (posTy != -1)
822       {
823         pnt->m_T[1] = M_GetFloatFromBinaryData(pntPos + posTy, _data, static_cast<size_t>(readSize));
824       }
825       if (m_NDims > 2 && posTz != -1)
826       {
827         pnt->m_T[2] = M_GetFloatFromBinaryData(pntPos + posTz, _data, static_cast<size_t>(readSize));
828       }
829       if (posV1x != -1)
830       {
831         pnt->m_V1[0] = M_GetFloatFromBinaryData(pntPos + posV1x, _data, static_cast<size_t>(readSize));
832       }
833       if (posV1y != -1)
834       {
835         pnt->m_V1[1] = M_GetFloatFromBinaryData(pntPos + posV1y, _data, static_cast<size_t>(readSize));
836       }
837       if (m_NDims > 2 && posV1z != -1)
838       {
839         pnt->m_V1[2] = M_GetFloatFromBinaryData(pntPos + posV1z, _data, static_cast<size_t>(readSize));
840       }
841       if (posV2x != -1)
842       {
843         pnt->m_V2[0] = M_GetFloatFromBinaryData(pntPos + posV2x, _data, static_cast<size_t>(readSize));
844       }
845       if (posV2y != -1)
846       {
847         pnt->m_V2[1] = M_GetFloatFromBinaryData(pntPos + posV2y, _data, static_cast<size_t>(readSize));
848       }
849       if (m_NDims > 2 && posV2z != -1)
850       {
851         pnt->m_V2[2] = M_GetFloatFromBinaryData(pntPos + posV2z, _data, static_cast<size_t>(readSize));
852       }
853       if (posA1 != -1)
854       {
855         pnt->m_Alpha1 = M_GetFloatFromBinaryData(pntPos + posA1, _data, static_cast<size_t>(readSize));
856       }
857       if (posA2 != -1)
858       {
859         pnt->m_Alpha2 = M_GetFloatFromBinaryData(pntPos + posA2, _data, static_cast<size_t>(readSize));
860       }
861       if (posA3 != -1)
862       {
863         pnt->m_Alpha3 = M_GetFloatFromBinaryData(pntPos + posA3, _data, static_cast<size_t>(readSize));
864       }
865 
866       std::vector<PositionType>::const_iterator itFields = m_Positions.begin();
867       auto                                      itUsed = positionUsed.begin();
868       std::vector<PositionType>::const_iterator itFieldsEnd = m_Positions.end();
869       while (itFields != itFieldsEnd)
870       {
871         if (!(*itUsed))
872         {
873           int pos = M_GetPosition((*itFields).first.c_str(), positionUsed);
874           (*itUsed) = false;
875           if (pos >= 0)
876           {
877             float tf = M_GetFloatFromBinaryData(pntPos + pos, _data, static_cast<size_t>(readSize));
878             pnt->AddField((*itFields).first.c_str(), tf);
879           }
880         }
881         ++itFields;
882         ++itUsed;
883       }
884 
885       m_PointList.push_back(pnt);
886     }
887     char c = ' ';
888     while ((c != '\n') && (!m_ReadStream->eof()))
889     {
890       c = static_cast<char>(m_ReadStream->get());
891       // to avoid unrecognize charactere
892     }
893     delete[] _data;
894   }
895   else
896   {
897     for (int j = 0; j < m_NPoints; j++)
898     {
899       if (m_Event)
900       {
901         m_Event->SetCurrentIteration(static_cast<unsigned int>(j + 1));
902       }
903 
904       for (int k = 0; k < pntDim; k++)
905       {
906         *m_ReadStream >> v[k];
907         m_ReadStream->get();
908       }
909 
910       auto * pnt = new TubePnt(m_NDims);
911 
912       if (posId >= 0)
913       {
914         pnt->m_ID = static_cast<int>(v[posId]);
915       }
916       if (posX >= 0)
917       {
918         pnt->m_X[0] = v[posX];
919       }
920       if (posY >= 0)
921       {
922         pnt->m_X[1] = v[posY];
923       }
924       if (m_NDims > 2 && posZ >= 0)
925       {
926         pnt->m_X[2] = v[posZ];
927       }
928       if (posRed >= 0)
929       {
930         pnt->m_Color[0] = v[posRed];
931       }
932       if (posGreen >= 0)
933       {
934         pnt->m_Color[1] = v[posGreen];
935       }
936       if (posBlue >= 0)
937       {
938         pnt->m_Color[2] = v[posBlue];
939       }
940       if (posAlpha >= 0)
941       {
942         pnt->m_Color[3] = v[posAlpha];
943       }
944       if (posMark >= 0)
945       {
946         pnt->m_Mark = (v[posMark] != 0) ? true : false;
947       }
948       if (posR >= 0)
949       {
950         pnt->m_R = v[posR];
951       }
952       if (posRn >= 0)
953       {
954         pnt->m_Ridgeness = v[posRn];
955       }
956       if (posMn >= 0)
957       {
958         pnt->m_Medialness = v[posMn];
959       }
960       if (posBn >= 0)
961       {
962         pnt->m_Branchness = v[posBn];
963       }
964       if (posCv >= 0)
965       {
966         pnt->m_Curvature = v[posCv];
967       }
968       if (posLv >= 0)
969       {
970         pnt->m_Levelness = v[posLv];
971       }
972       if (posRo >= 0)
973       {
974         pnt->m_Roundness = v[posRo];
975       }
976       if (posIn >= 0)
977       {
978         pnt->m_Intensity = v[posIn];
979       }
980       if (posTx >= 0)
981       {
982         pnt->m_T[0] = v[posTx];
983       }
984       if (posTy >= 0)
985       {
986         pnt->m_T[1] = v[posTy];
987       }
988       if (m_NDims > 2 && posTz >= 0)
989       {
990         pnt->m_T[2] = v[posTz];
991       }
992       if (posV1x >= 0)
993       {
994         pnt->m_V1[0] = v[posV1x];
995       }
996       if (posV1y >= 0)
997       {
998         pnt->m_V1[1] = v[posV1y];
999       }
1000       if (m_NDims > 2 && posV1z >= 0)
1001       {
1002         pnt->m_V1[2] = v[posV1z];
1003       }
1004       if (posV2x >= 0)
1005       {
1006         pnt->m_V2[0] = v[posV2x];
1007       }
1008       if (posV2y >= 0)
1009       {
1010         pnt->m_V2[1] = v[posV2y];
1011       }
1012       if (m_NDims > 2 && posV2z >= 0)
1013       {
1014         pnt->m_V2[2] = v[posV2z];
1015       }
1016       if (posA1 >= 0)
1017       {
1018         pnt->m_Alpha1 = v[posA1];
1019       }
1020       if (posA2 >= 0)
1021       {
1022         pnt->m_Alpha2 = v[posA2];
1023       }
1024       if (posA3 >= 0)
1025       {
1026         pnt->m_Alpha3 = v[posA3];
1027       }
1028 
1029       std::vector<PositionType>::const_iterator itFields = m_Positions.begin();
1030       auto                                      itUsed = positionUsed.begin();
1031       std::vector<PositionType>::const_iterator itFieldsEnd = m_Positions.end();
1032       while (itFields != itFieldsEnd)
1033       {
1034         if (!(*itUsed))
1035         {
1036           std::string fldstr = (*itFields).first;
1037           pnt->AddField(fldstr.c_str(), v[this->M_GetPosition(fldstr.c_str(), positionUsed)]);
1038           (*itUsed) = false;
1039         }
1040         ++itFields;
1041         ++itUsed;
1042       }
1043 
1044       m_PointList.push_back(pnt);
1045     }
1046 
1047     const std::string objectType = MET_ReadType(*m_ReadStream);
1048     if (objectType.empty())
1049     {
1050       // to avoid unrecognized characters
1051       char c = ' ';
1052       while ((c != '\n') && (m_ReadStream->good()))
1053       {
1054         c = static_cast<char>(m_ReadStream->get());
1055       }
1056     }
1057   }
1058 
1059   if (m_Event)
1060   {
1061     m_Event->StopReading();
1062   }
1063 
1064   return true;
1065 }
1066 
1067 bool
M_Write()1068 MetaTube::M_Write()
1069 {
1070   if (!MetaObject::M_Write())
1071   {
1072     std::cout << "MetaTube: M_Write: Error parsing file" << std::endl;
1073     return false;
1074   }
1075 
1076   int     pntDim;
1077   char ** pntVal = nullptr;
1078   char    pointDim[4096];
1079 
1080   for (unsigned t = 0; t < this->m_PointDim.size(); t++)
1081   {
1082     pointDim[t] = this->m_PointDim[t];
1083   }
1084   pointDim[m_PointDim.size()] = '\0';
1085 
1086   MET_StringToWordArray(pointDim, &pntDim, &pntVal);
1087 
1088   META_DEBUG_PRINT( "MetaTube: Parsing point dim" );
1089 
1090   m_Positions.clear();
1091   std::vector<bool> positionUsed;
1092   for (int i = 0; i < pntDim; i++)
1093   {
1094     PositionType p(pntVal[i], static_cast<const unsigned int &>(i));
1095     m_Positions.push_back(p);
1096     positionUsed.push_back(false);
1097   }
1098 
1099   for (int i = 0; i < pntDim; i++)
1100   {
1101     delete[] pntVal[i];
1102   }
1103   delete[] pntVal;
1104 
1105   int posId = M_GetPosition("id", positionUsed);
1106   int posX = M_GetPosition("x", positionUsed);
1107   int posY = M_GetPosition("y", positionUsed);
1108   int posZ = M_GetPosition("z", positionUsed);
1109   int posRed = M_GetPosition("red", positionUsed);
1110   int posGreen = M_GetPosition("green", positionUsed);
1111   int posBlue = M_GetPosition("blue", positionUsed);
1112   int posAlpha = M_GetPosition("alpha", positionUsed);
1113   int posMark = M_GetPosition("mark", positionUsed);
1114   if (posMark == -1)
1115   {
1116     posMark = M_GetPosition("mk", positionUsed);
1117   }
1118   int posR = M_GetPosition("r", positionUsed);
1119   if (posR == -1)
1120   {
1121     posR = M_GetPosition("R", positionUsed);
1122   }
1123   if (posR == -1)
1124   {
1125     posR = M_GetPosition("radius", positionUsed);
1126   }
1127   if (posR == -1)
1128   {
1129     posR = M_GetPosition("Radius", positionUsed);
1130   }
1131   if (posR == -1)
1132   {
1133     posR = M_GetPosition("rad", positionUsed);
1134   }
1135   if (posR == -1)
1136   {
1137     posR = M_GetPosition("Rad", positionUsed);
1138   }
1139   if (posR == -1)
1140   {
1141     posR = M_GetPosition("s", positionUsed);
1142   }
1143   if (posR == -1)
1144   {
1145     posR = M_GetPosition("S", positionUsed);
1146   }
1147   int posRn = M_GetPosition("rn", positionUsed);
1148   int posMn = M_GetPosition("mn", positionUsed);
1149   int posBn = M_GetPosition("bn", positionUsed);
1150   int posCv = M_GetPosition("cv", positionUsed);
1151   int posLv = M_GetPosition("lv", positionUsed);
1152   int posRo = M_GetPosition("ro", positionUsed);
1153   int posIn = M_GetPosition("in", positionUsed);
1154   int posTx = M_GetPosition("tx", positionUsed);
1155   int posTy = M_GetPosition("ty", positionUsed);
1156   int posTz = M_GetPosition("tz", positionUsed);
1157   int posV1x = M_GetPosition("v1x", positionUsed);
1158   int posV1y = M_GetPosition("v1y", positionUsed);
1159   int posV1z = M_GetPosition("v1z", positionUsed);
1160   int posV2x = M_GetPosition("v2x", positionUsed);
1161   int posV2y = M_GetPosition("v2y", positionUsed);
1162   int posV2z = M_GetPosition("v2z", positionUsed);
1163   int posA1 = M_GetPosition("a1", positionUsed);
1164   int posA2 = M_GetPosition("a2", positionUsed);
1165   int posA3 = M_GetPosition("a3", positionUsed);
1166 
1167   int                                       extraCount = 0;
1168   std::vector<PositionType>::const_iterator itFields = m_Positions.begin();
1169   auto                                      itUsed = positionUsed.begin();
1170   std::vector<PositionType>::const_iterator itFieldsEnd = m_Positions.end();
1171   while (itFields != itFieldsEnd)
1172   {
1173     if (!(*itUsed))
1174     {
1175       ++extraCount;
1176     }
1177     ++itFields;
1178     ++itUsed;
1179   }
1180 
1181 
1182   if (m_BinaryData)
1183   {
1184     auto it = m_PointList.begin();
1185     auto itEnd = m_PointList.end();
1186 
1187     int elementSize;
1188     MET_SizeOfType(m_ElementType, &elementSize);
1189 
1190     // Allocates memory specifically needed to hold a TubePoint
1191     int    dataSize = (m_NDims * (2 + m_NDims) + 14 + extraCount) * m_NPoints * elementSize;
1192     char * data = new char[dataSize];
1193     // NDIMS * 2: x, alpha
1194     // NDims * NDims: t, v1, [v2]
1195     // 14: id, red, green, blue, alpha, mark, r, rn, mn, bn, cv, lv, ro, in
1196     int dataPos = 0;
1197     while (it != itEnd)
1198     {
1199       std::vector<PositionType>::const_iterator l_itFields = m_Positions.begin();
1200       std::vector<PositionType>::const_iterator l_itFieldsEnd = m_Positions.end();
1201       while (l_itFields != l_itFieldsEnd)
1202       {
1203         if (l_itFields->second == posId)
1204         {
1205           M_SetFloatIntoBinaryData(static_cast<float>((*it)->m_ID), data, dataPos++);
1206         }
1207         else if (l_itFields->second == posX)
1208         {
1209           M_SetFloatIntoBinaryData((*it)->m_X[0], data, dataPos++);
1210         }
1211         else if (l_itFields->second == posY)
1212         {
1213           M_SetFloatIntoBinaryData((*it)->m_X[1], data, dataPos++);
1214         }
1215         else if (m_NDims > 2 && l_itFields->second == posZ)
1216         {
1217           M_SetFloatIntoBinaryData((*it)->m_X[2], data, dataPos++);
1218         }
1219         else if (l_itFields->second == posRed)
1220         {
1221           M_SetFloatIntoBinaryData((*it)->m_Color[0], data, dataPos++);
1222         }
1223         else if (l_itFields->second == posGreen)
1224         {
1225           M_SetFloatIntoBinaryData((*it)->m_Color[1], data, dataPos++);
1226         }
1227         else if (l_itFields->second == posBlue)
1228         {
1229           M_SetFloatIntoBinaryData((*it)->m_Color[2], data, dataPos++);
1230         }
1231         else if (l_itFields->second == posAlpha)
1232         {
1233           M_SetFloatIntoBinaryData((*it)->m_Color[3], data, dataPos++);
1234         }
1235         else if (l_itFields->second == posR)
1236         {
1237           M_SetFloatIntoBinaryData((*it)->m_R, data, dataPos++);
1238         }
1239         else if (l_itFields->second == posRn)
1240         {
1241           M_SetFloatIntoBinaryData((*it)->m_Ridgeness, data, dataPos++);
1242         }
1243         else if (l_itFields->second == posMn)
1244         {
1245           M_SetFloatIntoBinaryData((*it)->m_Medialness, data, dataPos++);
1246         }
1247         else if (l_itFields->second == posBn)
1248         {
1249           M_SetFloatIntoBinaryData((*it)->m_Branchness, data, dataPos++);
1250         }
1251         else if (l_itFields->second == posCv)
1252         {
1253           M_SetFloatIntoBinaryData((*it)->m_Curvature, data, dataPos++);
1254         }
1255         else if (l_itFields->second == posRo)
1256         {
1257           M_SetFloatIntoBinaryData((*it)->m_Roundness, data, dataPos++);
1258         }
1259         else if (l_itFields->second == posLv)
1260         {
1261           M_SetFloatIntoBinaryData((*it)->m_Levelness, data, dataPos++);
1262         }
1263         else if (l_itFields->second == posIn)
1264         {
1265           M_SetFloatIntoBinaryData((*it)->m_Intensity, data, dataPos++);
1266         }
1267         else if (l_itFields->second == posMark)
1268         {
1269           M_SetFloatIntoBinaryData((*it)->m_Mark ? 1.0f : 0.0f, data, dataPos++);
1270         }
1271         else if (l_itFields->second == posTx)
1272         {
1273           M_SetFloatIntoBinaryData((*it)->m_T[0], data, dataPos++);
1274         }
1275         else if (l_itFields->second == posTy)
1276         {
1277           M_SetFloatIntoBinaryData((*it)->m_T[1], data, dataPos++);
1278         }
1279         else if (m_NDims > 2 && l_itFields->second == posTz)
1280         {
1281           M_SetFloatIntoBinaryData((*it)->m_T[2], data, dataPos++);
1282         }
1283         else if (l_itFields->second == posV1x)
1284         {
1285           M_SetFloatIntoBinaryData((*it)->m_V1[0], data, dataPos++);
1286         }
1287         else if (l_itFields->second == posV1y)
1288         {
1289           M_SetFloatIntoBinaryData((*it)->m_V1[1], data, dataPos++);
1290         }
1291         else if (m_NDims > 2 && l_itFields->second == posV1z)
1292         {
1293           M_SetFloatIntoBinaryData((*it)->m_V1[2], data, dataPos++);
1294         }
1295         else if (l_itFields->second == posV2x)
1296         {
1297           M_SetFloatIntoBinaryData((*it)->m_V2[0], data, dataPos++);
1298         }
1299         else if (l_itFields->second == posV2y)
1300         {
1301           M_SetFloatIntoBinaryData((*it)->m_V2[1], data, dataPos++);
1302         }
1303         else if (m_NDims > 2 && l_itFields->second == posV2z)
1304         {
1305           M_SetFloatIntoBinaryData((*it)->m_V2[2], data, dataPos++);
1306         }
1307         else if (l_itFields->second == posA1)
1308         {
1309           M_SetFloatIntoBinaryData((*it)->m_Alpha1, data, dataPos++);
1310         }
1311         else if (l_itFields->second == posA2)
1312         {
1313           M_SetFloatIntoBinaryData((*it)->m_Alpha2, data, dataPos++);
1314         }
1315         else if (l_itFields->second == posA3)
1316         {
1317           M_SetFloatIntoBinaryData((*it)->m_Alpha3, data, dataPos++);
1318         }
1319         else
1320         {
1321           int indx = (*it)->GetFieldIndex(l_itFields->first.c_str());
1322           if (indx >= 0)
1323           {
1324             M_SetFloatIntoBinaryData((*it)->GetField(indx), data, dataPos++);
1325           }
1326           else
1327           {
1328             std::cerr << "Cannot find value for field " << l_itFields->first << std::endl;
1329           }
1330         }
1331         ++l_itFields;
1332       }
1333 
1334       ++it;
1335     }
1336 
1337     m_WriteStream->write(data, dataSize);
1338     m_WriteStream->write("\n", 1);
1339 
1340     delete[] data;
1341   }
1342   else
1343   {
1344     PointListType::const_iterator it = m_PointList.begin();
1345     PointListType::const_iterator itEnd = m_PointList.end();
1346 
1347     int dataPos = 0;
1348     while (it != itEnd)
1349     {
1350       std::vector<PositionType>::const_iterator l_itFields = m_Positions.begin();
1351       std::vector<PositionType>::const_iterator l_itFieldsEnd = m_Positions.end();
1352       while (l_itFields != l_itFieldsEnd)
1353       {
1354         if (l_itFields->second == posId)
1355         {
1356           *m_WriteStream << (*it)->m_ID << " ";
1357           dataPos++;
1358         }
1359         else if (l_itFields->second == posX)
1360         {
1361           *m_WriteStream << (*it)->m_X[0] << " ";
1362           dataPos++;
1363         }
1364         else if (l_itFields->second == posY)
1365         {
1366           *m_WriteStream << (*it)->m_X[1] << " ";
1367           dataPos++;
1368         }
1369         else if (m_NDims > 2 && l_itFields->second == posZ)
1370         {
1371           *m_WriteStream << (*it)->m_X[2] << " ";
1372           dataPos++;
1373         }
1374         else if (l_itFields->second == posRed)
1375         {
1376           *m_WriteStream << (*it)->m_Color[0] << " ";
1377           dataPos++;
1378         }
1379         else if (l_itFields->second == posGreen)
1380         {
1381           *m_WriteStream << (*it)->m_Color[1] << " ";
1382           dataPos++;
1383         }
1384         else if (l_itFields->second == posBlue)
1385         {
1386           *m_WriteStream << (*it)->m_Color[2] << " ";
1387           dataPos++;
1388         }
1389         else if (l_itFields->second == posAlpha)
1390         {
1391           *m_WriteStream << (*it)->m_Color[3] << " ";
1392           dataPos++;
1393         }
1394         else if (l_itFields->second == posR)
1395         {
1396           *m_WriteStream << (*it)->m_R << " ";
1397           dataPos++;
1398         }
1399         else if (l_itFields->second == posRn)
1400         {
1401           *m_WriteStream << (*it)->m_Ridgeness << " ";
1402           dataPos++;
1403         }
1404         else if (l_itFields->second == posMn)
1405         {
1406           *m_WriteStream << (*it)->m_Medialness << " ";
1407           dataPos++;
1408         }
1409         else if (l_itFields->second == posBn)
1410         {
1411           *m_WriteStream << (*it)->m_Branchness << " ";
1412           dataPos++;
1413         }
1414         else if (l_itFields->second == posCv)
1415         {
1416           *m_WriteStream << (*it)->m_Curvature << " ";
1417           dataPos++;
1418         }
1419         else if (l_itFields->second == posRo)
1420         {
1421           *m_WriteStream << (*it)->m_Roundness << " ";
1422           dataPos++;
1423         }
1424         else if (l_itFields->second == posLv)
1425         {
1426           *m_WriteStream << (*it)->m_Levelness << " ";
1427           dataPos++;
1428         }
1429         else if (l_itFields->second == posIn)
1430         {
1431           *m_WriteStream << (*it)->m_Intensity << " ";
1432           dataPos++;
1433         }
1434         else if (l_itFields->second == posMark)
1435         {
1436           if ((*it)->m_Mark)
1437           {
1438             *m_WriteStream << "1 ";
1439           }
1440           else
1441           {
1442             *m_WriteStream << "0 ";
1443           }
1444           dataPos++;
1445         }
1446         else if (l_itFields->second == posTx)
1447         {
1448           *m_WriteStream << (*it)->m_T[0] << " ";
1449           dataPos++;
1450         }
1451         else if (l_itFields->second == posTy)
1452         {
1453           *m_WriteStream << (*it)->m_T[1] << " ";
1454           dataPos++;
1455         }
1456         else if (m_NDims > 2 && l_itFields->second == posTz)
1457         {
1458           *m_WriteStream << (*it)->m_T[2] << " ";
1459           dataPos++;
1460         }
1461         else if (l_itFields->second == posV1x)
1462         {
1463           *m_WriteStream << (*it)->m_V1[0] << " ";
1464           dataPos++;
1465         }
1466         else if (l_itFields->second == posV1y)
1467         {
1468           *m_WriteStream << (*it)->m_V1[1] << " ";
1469           dataPos++;
1470         }
1471         else if (m_NDims > 2 && l_itFields->second == posV1z)
1472         {
1473           *m_WriteStream << (*it)->m_V1[2] << " ";
1474           dataPos++;
1475         }
1476         else if (l_itFields->second == posV2x)
1477         {
1478           *m_WriteStream << (*it)->m_V2[0] << " ";
1479           dataPos++;
1480         }
1481         else if (l_itFields->second == posV2y)
1482         {
1483           *m_WriteStream << (*it)->m_V2[1] << " ";
1484           dataPos++;
1485         }
1486         else if (m_NDims > 2 && l_itFields->second == posV2z)
1487         {
1488           *m_WriteStream << (*it)->m_V2[2] << " ";
1489           dataPos++;
1490         }
1491         else if (l_itFields->second == posA1)
1492         {
1493           *m_WriteStream << (*it)->m_Alpha1 << " ";
1494           dataPos++;
1495         }
1496         else if (l_itFields->second == posA2)
1497         {
1498           *m_WriteStream << (*it)->m_Alpha2 << " ";
1499           dataPos++;
1500         }
1501         else if (l_itFields->second == posA3)
1502         {
1503           *m_WriteStream << (*it)->m_Alpha3 << " ";
1504           dataPos++;
1505         }
1506         else
1507         {
1508           int indx = (*it)->GetFieldIndex(l_itFields->first.c_str());
1509           if (indx >= 0)
1510           {
1511             *m_WriteStream << (*it)->GetField(indx) << " ";
1512             dataPos++;
1513           }
1514           else
1515           {
1516             std::cerr << "Cannot find value for field " << l_itFields->first << std::endl;
1517           }
1518         }
1519         ++l_itFields;
1520       }
1521 
1522       *m_WriteStream << std::endl;
1523       ++it;
1524     }
1525   }
1526   return true;
1527 }
1528 
1529 #if (METAIO_USE_NAMESPACE)
1530 };
1531 #endif
1532