1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : MEDMEM_EnsightUtils.hxx
21 // Created : Tue May 27 12:24:11 2008
22 // Author : Edward AGAPOV (eap)
24 #ifndef MEDMEM_EnsightUtils_HeaderFile
25 #define MEDMEM_EnsightUtils_HeaderFile
27 #include "MEDMEM_GenDriver.hxx"
28 #include "MEDMEM_Exception.hxx"
29 #include "MEDMEM_DriverTools.hxx"
30 #include "MEDMEM_Mesh.hxx"
31 //#include "MEDMEM_Field.hxx"
45 // ==============================================================================
47 * \brief Functions to set writing format.
48 * Default format is EnSight6 ASCII
50 // ==============================================================================
52 enum EnSightFormat { ENSIGHT_6, ENSIGHT_GOLD };
54 void MEDMEM_EXPORT setEnSightFormatForWriting (EnSightFormat format, bool isBinary);
56 EnSightFormat getEnSightFormatForWriting();
57 bool isBinaryEnSightFormatForWriting();
59 // ==============================================================================
61 * \brief To raise or not if MEDMEM-EnSight incompatibility encounters or suspected
63 * Default is to raise.
64 * To ignore incompatibility is useful for debug of EnSigt reading and
65 * for suppressing exceptions in some suspicious cases, for example writing
66 * several meshes and fields.
67 * Incompatibility exception includes "EnSight-MEDMEM compatibility problem" string.
68 * Not all incompatibility exceptions can be suppressed.
70 // ==============================================================================
72 void MEDMEM_EXPORT setIgnoreIncompatibility(bool toIgnore=true);
76 class ENSIGHT_MESH_RDONLY_DRIVER;
77 class ENSIGHT_FIELD_RDONLY_DRIVER;
78 class ENSIGHT_MESH_WRONLY_DRIVER;
79 class ENSIGHT_FIELD_WRONLY_DRIVER;
82 // ==============================================================================
83 namespace MEDMEM_ENSIGHT { // INTERNAL MATTERS
84 // ==============================================================================
86 class _CaseFileDriver;
87 class _CaseFileDriver_User;
92 typedef std::set< _SubPartDesc > _SupportDesc;
94 using namespace MED_EN;
95 using namespace MEDMEM;
98 // ---------------------------------------------------------------
100 * \brief Prepend "EnSight-MEDMEM compatibility problem" to the text
103 STRING compatibilityPb(const string& exceptionText);
105 // ---------------------------------------------------------------
107 * \brief To ignore incompatibility or not
109 bool toIgnoreIncompatibility();
111 // ---------------------------------------------------------------
112 //!< search substring in a string
113 bool contains( const char* what, const char* inString );
115 // ---------------------------------------------------------------
117 * \brief EnSight element type name and an array to convert
118 * med connectivity to EnSight one
120 struct TEnSightElemType
123 vector<int> _medIndex;
124 medGeometryElement _medType;
126 // ---------------------------------------------------------------
128 * \brief Return EnSight type corresponding to med one
130 const TEnSightElemType& getEnSightType(medGeometryElement medType);
132 // ---------------------------------------------------------------
134 * \brief Return EnSight type having a given name
136 const TEnSightElemType& getEnSightType(const string& typeName);
138 // ---------------------------------------------------------------
140 * \brief Return true if typeName begins with "g_"
142 inline bool isGhostType(const string& typeName)
143 { return ( typeName[0] == 'g' && typeName[1] == '_'); }
145 // ---------------------------------------------------------------
147 * \brief Maximal EnSight line length
149 const int MAX_LINE_LENGTH = 80;
151 // ---------------------------------------------------------------
153 * \brief Maximal length of field name in EnSight
155 const int MAX_FIELD_NAME_LENGTH = 19;
157 // ---------------------------------------------------------------
159 * \brief Maximal length of field name in EnSight
161 const string ILLEGAL_FIELD_NAME_CHARACTERS = " !@#$^()[]*/+-"; // '.,' ????
163 // ---------------------------------------------------------------
165 * \brief Width of fields in ASCII file
167 const int INT_WIDTH_6 = 8;
168 const int INT_WIDTH_GOLD = 10;
169 const int FLT_WIDTH = 12;
171 // ---------------------------------------------------------------
173 * \brief EnSight space dimension
175 const int SPACE_DIM = 3;
177 // ---------------------------------------------------------------
179 * \brief Time step data boundaries in single-file mode
181 static const char* TIME_STEP_BEG = "BEGIN TIME STEP";
182 static const char* TIME_STEP_END = "END TIME STEP";
183 const size_t TIME_STEP_BEG_LEN = 15;
184 const size_t TIME_STEP_END_LEN = 13;
187 // ---------------------------------------------------------------
189 * \brief Cast value to float and protect from overflow
191 static inline float _toFloat (const double & value) {
192 if ( value > FLT_MAX ) return FLT_MAX;
193 if ( value < -FLT_MAX ) return -FLT_MAX;
194 if ( isnan( value )) throw MEDEXCEPTION(compatibilityPb("NaN value not allowed"));
195 return float( value );
197 static inline float _toFloat (const int & value) { return float( value ); }
198 static inline float _toFloat (const long & value) { return float( value ); }
200 // ==============================================================================
202 * \brief Reader/writer of EnSight Case file
204 * Apart from it's major job, it
205 * o assures cooperation of MED and Mesh/Field drivers so that the Case file created
206 * by MED driver is not overwritten by Mesh driver called by MED driver.
208 // ==============================================================================
210 class _CaseFileDriver
213 _CaseFileDriver(const string& fileName, const _CaseFileDriver_User* creator);
216 void read() throw (MEDEXCEPTION);
222 int getNbMeshes() const;
224 //!< sets all data necessary for meshDriver::read()
225 void setDataFileName(const int meshIndex, ENSIGHT_MESH_RDONLY_DRIVER* meshDriver);
231 int getNbVariables() const;
233 int getNbVarSteps(const int variableIndex);
235 //!< return variable index by variable name, return 0 if none found
236 int getVariableIndex(const string & varName) const;
238 //!< sets all data necessary for fieldDriver::read(), returns meshIndex
239 int setDataFileName(const int varIndex,
241 ENSIGHT_FIELD_RDONLY_DRIVER* fieldDriver);
247 //!< add a mesh to the Case file
248 void addMesh(const ENSIGHT_MESH_WRONLY_DRIVER* meshDriver);
250 //!< add a field to the Case file
251 void addField(const ENSIGHT_FIELD_WRONLY_DRIVER * fieldDriver);
253 //!< write and set necessary data to added drivers
254 void write() throw (MEDEXCEPTION);
258 //!< throw if Case file has not been read else return false
259 bool checkWasRead() const throw (MEDEXCEPTION);
261 //!< replace '*' in file name if any and return index in a file and time
262 int fixWildCardName(const int timeStep,
263 const std::string & ts,
264 const std::string & fs,
265 std::string & fileName,
268 // --------------------------------------------------------------------------------
270 // model: [ts] [fs] filename [change_coords_only]
271 // ts = time set number as specified in TIME section. This is optional.
272 // fs = corresponding file set number as specified in FILE section below.
273 // (Note, if you specify fs, then ts is no longer optional and must also be
275 // filename = The filename of the appropriate file.
276 // -> Model or measured filenames for a static geometry case, as well as match,
277 // boundary, and rigid_body filenames will not contain "*" wildcards.
278 // -> Model or measured filenames for a changing geometry case will
279 // contain "*" wildcards.
280 // change_coords_only = The option to indicate that the changing geometry (as
281 // indicated by wildcards in the filename) is coords only.
282 // Otherwise, changing geometry connectivity will be
285 string _timeSetNumber, _fileSetNumber; //!< ts, fs
286 string _fileName; //!< filename
287 string _change_coords_only;
289 // --------------------------------------------------------------------------------
291 // ts = The corresponding time set number (or index) as specified in TIME
292 // section below. This is only required for transient constants and
294 // fs = The corresponding file set number (or index) as specified in FILE
296 // (Note, if you specify fs, then ts is no longer optional and must
297 // also be specified.)
298 // description = The variable (GUI) name (ex. Pressure, Velocity, etc.)
299 // const_value(s) = The constant value. If constants change over time, then ns (see
300 // TIME section below) constant values of ts.
301 // cvfilename = The filename containing the constant values, one value per time step.
302 // filename = The filename of the variable file. Note: only transient filenames
303 // contain "*" wildcards.
304 // Re_fn = The filename for the file containing the real values of the complex
306 // Im_fn = The filename for the file containing the imaginary values of the
308 // freq = The corresponding harmonic frequency of the complex variable.
309 // For complex variables where harmonic frequency is undefined,
310 // simply use the text string: UNDEFINED.
312 string _type; //!< constant|scalar|etc.
313 string _name; //!< description
314 string _timeSetNumber, _fileSetNumber; //!< [ts], [fs]
315 string _fileNameOrData; //!< [cv]filename|Re_fn Im_fn freq|const_value(s)
317 // --------------------------------------------------------------------------------
319 // fs = file set number. This is the number referenced in the GEOMETRY
320 // and VARIABLE sections above.
321 // ns = number of transient steps
322 // fi = file index number in the file name (replaces "*" in the filenames)
325 std::list<int> _nbStepsInFile; //!< ns
326 std::list<std::string> _fileIndex; //!< fi
328 // --------------------------------------------------------------------------------
332 std::vector<std::string> _fileIndex; //!< fn
333 std::vector<std::string> _times; //!< times
335 bool operator==(const _TimeSet& ts) const
336 { return ( _fileIndex == ts._fileIndex && _times == ts._times ); }
341 std::string _fileName;
342 std::string _directory;
343 EnSightFormat _format;
345 std::map< int, _Variable> _variables; //!< map order number to variable data
346 std::map< int, _TimeSet > _timeSets; //!< map ts to time set data
347 std::map< int, _FileSet > _fileSets; //!< map fs to file set data
349 const _CaseFileDriver_User* _user; //!< mesh/field driver
351 std::list<ENSIGHT_MESH_WRONLY_DRIVER*> _meshDrivers; //!< added meshes
353 typedef std::map<std::string, std::list< ENSIGHT_FIELD_WRONLY_DRIVER* > > TFieldDriversByName;
354 TFieldDriversByName _fieldDrivers; //!< added field drivers groupped by name
356 //!< to block all calls from a mesh/field driver governed by med driver
360 // ==============================================================================
362 * \brief Base of all Ensight drivers.
363 * It stores data passed from case file
365 // ==============================================================================
367 class MEDMEM_EXPORT _CaseFileDriver_User: public GENDRIVER
371 _CaseFileDriver_User(const std::string& caseFileName="",
372 MED_EN::med_mode_acces mode=MED_EN::RDWR);
374 const std::string& getCaseFileName() const { return GENDRIVER::_fileName; }
376 const std::string& getDataFileName() const { return _dataFileName; }
378 bool isGoldFormat() const { return _isGoldFormat; }
380 //!< returns true if there are several meshes/fields in a data file
381 bool isSingleFileMode() const { return _singleFileMode; }
383 //!< index of meshes/fields in a data file, zero for static mesh/feild
384 int getIndexInDataFile() const { return _indexInDataFile; }
386 //!< true if there are time steps, i.e. getTime() has sense
387 bool isTransientMode() const { return _transientMode; }
390 double getTime() const { return atof(_time.c_str()); }
392 // -------------------------------
393 // pass mesh data to field driver
394 // -------------------------------
396 //!< for mesh driver to store data
397 void setInterData(_InterMed* imed);
399 //!< for field driver to get mesh data
400 _InterMed* getInterData();
402 _SubPart* getSubPart(const _SubPartDesc & descriptor) throw (MEDEXCEPTION);
404 _Support* getSupport(const _SupportDesc & descriptor,
405 const medEntityMesh entity) throw (MEDEXCEPTION);
409 //!< return part number to write support with, zero in failure case
410 int getPartNumber(const SUPPORT* support) const;
412 static bool canOpenFile(const string& fileName, med_mode_acces mode);
414 static void getSupportNodes(const SUPPORT* sup, map<int, int> & nodeIds);
416 //!< analyse if data file is binary
417 static bool isBinaryDataFile(const string& dataFileName);
419 static bool isTimeStepBeginning(const string& line)
420 { return ( line == TIME_STEP_BEG ); }
422 static bool isTimeStepEnd(const char* line)
423 { return ( strncmp( line, TIME_STEP_END, TIME_STEP_END_LEN ) == 0 ); }
425 static bool isToWriteEntity(const medEntityMesh entity, const GMESH* mesh);
427 ~_CaseFileDriver_User();
429 void merge( const GENDRIVER& driver);
433 friend class _CaseFileDriver;
435 // members set by _CaseFileDriver::setDataFileName(...) and _CaseFileDriver::write()
436 std::string _dataFileName;
438 bool _transientMode; //!< true if there are time steps
439 bool _singleFileMode; //!< only one or several meshes/fields in a data file
440 int _indexInDataFile; //!< which meshes/fields in a data file
441 std::string _time; //!< time of a step
443 _InterMed* _imed; //!< to be used by field driver
444 string _imedMapKey; //!< key in the map storing mesh data for usage by field drv
448 // ==============================================================================
450 * \brief Descriptor of the sub-part: part number and elem type or "block" etc.
452 // ==============================================================================
454 struct _SubPartDesc: public std::pair<int, std::string >
456 _SubPartDesc(int partNumber=-1,
457 const std::string& typeName="")
458 : std::pair<int, std::string > ( partNumber, typeName ) {}
460 const int& partNumber() const { return this->first; }
461 const string& typeName() const { return this->second; }
463 static _SubPartDesc globalCoordDesc() { return _SubPartDesc(-1,"coordinates"); }
466 std::ostream& operator << (std::ostream& os, const _SubPartDesc& desc);
468 // ==============================================================================
470 * \brief A type within EnSight part. It stores data needed by field driver to
471 * know nb of values of a geometric type and what place they get in MED group
473 // ==============================================================================
475 struct _SubPart: public _SubPartDesc
477 // _SubPart describes both nodes and elements since "block" describes the both.
479 // for cells: myNbCells and myCellGroupIndex
480 // for nodes: myNbNodes and myFirstNode
481 // GROUP of cells is created always,
482 // GROUP of nodes, only if nodal field support is required (see getSupport())
484 int myNbCells; //!< nb of cells
485 int myCellGroupIndex; //!< cell group id in _InterMed
486 _groupe::TMailleIter myFirstCell; //!< pointer to the first cell
488 int myNbNodes; //!< nb of nodes
489 mutable int myNodeGroupIndex; //!< node group id in _InterMed
490 _maille::TNoeud myFirstNode; //!< pointer to the first node
492 _SubPart(int partNumber=-1,
493 const std::string& typeName="")
494 : _SubPartDesc(partNumber,typeName),
495 myNbCells(0), myCellGroupIndex(-1),
496 myNbNodes(0), myNodeGroupIndex(-1)
499 _SubPartDesc getDescriptor() const { return _SubPartDesc( partNumber(), typeName() ); }
502 // ==============================================================================
504 * \brief EnSight variable support composed of _SubPart's
506 // ==============================================================================
510 _groupe * myCellGroup; //!< cell group in _InterMed
511 _groupe * myNodeGroup; //!< node group in _InterMed
513 _Support(): myCellGroup(0), myNodeGroup(0) {}
515 void setGroup( _groupe* g );
516 SUPPORT* medSupport( medEntityMesh entity );
518 int getIndex( const pair<const int,_noeud>& node);
519 int getIndex( const _groupe::TMaille& cell);
521 // medGeometryElement getType( const pair<const int,_noeud>& node);
522 // medGeometryElement getType( const _groupe::TMaille& cell);
525 // ==============================================================================
527 * \brief Structure to temporarily store data read from EnSight geom file
529 // ==============================================================================
531 struct _InterMed : public _intermediateMED
534 bool _isOwnMedMesh; //!< whether to delete _medMesh
535 int _nbUsers; //!< to know when to delete _medMesh
537 bool _needSubParts; //!< true if there are fields needing _SubPart data
539 map< _SubPartDesc, _SubPart > _subPartDescribed;
541 map< _SupportDesc, _Support > _supportDescribed;
543 void addSubPart(const _SubPart& subPart);
548 // ==============================================================================
550 * \brief Simple owner of C array
552 // ==============================================================================
554 template <typename T> struct _ValueOwner {
556 _ValueOwner(T* values):myValues(values) {}
557 ~_ValueOwner() { if ( myValues ) delete [] myValues; }
558 operator T*() { return myValues; }
560 _ValueOwner(const _ValueOwner& other) {} // forbidden
563 typedef _ValueOwner<char> TStrOwner;
564 typedef _ValueOwner<int> TIntOwner;
565 typedef _ValueOwner<double> TDblOwner;
566 typedef _ValueOwner<float> TFltOwner;
568 // ==============================================================================
570 * \brief Iterator on values of a component
572 // ==============================================================================
574 template <typename T> class _ValueIterator
580 _ValueIterator() // by default next() returns zero
581 : myPtr(zeroPtr()), myDelta( 0 ) {}
583 _ValueIterator(const T* values, int delta): myPtr(values-delta), myDelta(delta) {}
585 const T & next() { myPtr += myDelta; return *myPtr; }
587 static const T* zeroPtr() { static T a0 = 0; return &a0; }
590 // ==============================================================================
592 * \brief Reader of ASCII files
594 // ==============================================================================
596 class _ASCIIFileReader
599 _ASCIIFileReader(const string& fileName) throw (MEDEXCEPTION);
605 string getWord(); //!< never throws
607 int getInt() throw (MEDEXCEPTION) {
608 if ( eof() ) throw MEDEXCEPTION("Unexpected EOF");
609 return strtol(_ptr, &_ptr, 10);
611 float getReal() throw (MEDEXCEPTION) {
612 if ( eof() ) throw MEDEXCEPTION("Unexpected EOF");
615 return strtof(_ptr, &_ptr);
618 //!< needed after getWord(), getInt() or getReal() to get a next line
620 while (isspace(*_ptr)) if ((++_ptr)[-1]=='\n') break;
622 char* getLine() throw (MEDEXCEPTION);
624 const char* getCurrentPtr() const { return _ptr; }
626 bool lookAt( const char* text );
628 bool isTimeStepBeginning();
630 bool isTimeStepEnd();
632 //!< read out given data
633 void skip(int nbVals, int nbPerLine, int valWidth);
635 //!< read out width chars and nbLines line-ends
636 void skip(int width, int nbLines);
639 char* convertReals( const int nbValues,
640 const char* undefValue = 0,
641 set<int>* undefIndices = 0,
642 const vector<int>* partialIndices = 0,
643 const int nbPartialComponents = 0)
646 T* result = new T[ nbValues ];
648 if ( undefValue ) // fill undefIndices
650 undefIndices->clear();
651 float undef = atof( undefValue );
652 for ( int i = 0; i < nbValues; ++i, ++ptrT ) {
653 float value = getReal();
655 if ( value == undef )
656 undefIndices->insert( undefIndices->end(), i+1 );
659 else if ( partialIndices )
661 // partial variables are available in GOLD format only where
662 // values are in no-interlace
664 for ( int j = 1; j <= nbPartialComponents; ++j ) {
665 vector<int>::const_iterator i = partialIndices->begin(), iEnd = partialIndices->end();
667 result[ *i++ - shift ] = (T) getReal();
673 for ( int i = 0; i < nbValues; ++i, ++ptrT )
674 (*ptrT) = (T) getReal();
676 return (char*) result;
679 //static string strip(char* & str);
681 //!< divide a string into two parts
682 static int split(const string& str,
685 const char separator=' ',
686 const bool fromBack=false);
688 //!< divide a string into parts, return nb of parts
689 static int split(const string& str,
690 std::list<string> & parts,
691 const char separator=' ',
692 const bool fromBack=false);
694 //!< check if string contains only digits
695 static bool isDigit(const string& str, const bool real=false);
700 char* _start; // buffer start
701 char* _ptr; // beginning of not read portion
702 char* _eptr; // end of buffer contents
706 };// class _ASCIIFileReader
709 // ==============================================================================
711 * \brief Reader of binary files
713 // ==============================================================================
715 class _BinaryFileReader
718 _BinaryFileReader(const string& fileName) throw (MEDEXCEPTION);
720 ~_BinaryFileReader();
722 void rewind(); //!< rewind the file backward
724 void swapBytes() //!< turn on swapping bytes
725 { _mySwapBytes = true; }
727 int moreValuesAvailable() const; //!< size of not read file portion in sizeof(int)
731 void skip(int size) throw (MEDEXCEPTION);
733 void skipTimeStepBeginning() throw (MEDEXCEPTION);
735 char* getLine() throw (MEDEXCEPTION)
736 { return get<char>(80); }
738 int* getInt(int nb) throw (MEDEXCEPTION)
739 { return get<int>(nb,_mySwapBytes); }
741 float* getFlt(int nb) throw (MEDEXCEPTION)
742 { return get<float>(nb,_mySwapBytes); }
744 ssize_t getPosition() const { return _pos; }
747 char* convertReals( const int nbValues,
748 const char* undefValue = 0,
749 set<int>* undefIndices = 0,
750 const vector<int>* partialIndices = 0,
751 const int nbPartialComponents = 0 )
754 T* result = new T[ nbValues ];
755 T* ptrT = result, *endT = result + nbValues;
756 int nb = partialIndices ? partialIndices->size() * nbPartialComponents : nbValues;
757 TFltOwner fltData( getFlt( nb ));
758 float* ptrFlt = fltData;
759 if ( undefValue ) // fill undefIndices
761 undefIndices->clear();
762 float undef = atof( undefValue );
763 while ( ptrT < endT ) {
764 float value = *ptrFlt++;
766 if ( std::abs( value - undef ) <= FLT_MIN )
767 undefIndices->insert( undefIndices->end(), ptrT - result );
770 else if ( partialIndices )
772 // partial variables are available in GOLD format only where
773 // values are in no-interlace
775 for ( int j = 1; j <= nbPartialComponents; ++j ) {
776 vector<int>::const_iterator i = partialIndices->begin(), iEnd = partialIndices->end();
778 result[ *i++ - shift ] = (T) *ptrFlt++;
784 while ( ptrT < endT )
785 *ptrT++ = (T) *ptrFlt++;
787 return (char*) result;
791 int _file; //!< descriptor
792 MEDEXCEPTION _exception; //!< ready to raise exception
793 ssize_t _pos, _maxPos; //!< current position and end position
794 bool _mySwapBytes; //!< to swap bytes
796 //!< read any data from file
797 template <typename T> T* get(int nb, bool inverseBytes=false)
799 size_t bufSize = nb * sizeof( T );
800 if ( int(bufSize) > _maxPos - _pos )
802 T* buf = new T[ nb ];
805 ssize_t nBytesRead = ::read (_file, buf, bufSize );
807 if ( int(nBytesRead) < int(bufSize) ) {
811 if ( inverseBytes ) { // swap bytes
812 int* intBuf = ((int*) buf) - 1;
813 int* bufEnd = (int*)((char*) buf + nBytesRead);
814 while ( ++intBuf < bufEnd )
815 *intBuf = MEDMEM::swapBytes( *intBuf );
822 // ==============================================================================
824 * \brief Writer of binary files
826 // ==============================================================================
828 class _BinaryFileWriter
831 _BinaryFileWriter(const string& fileName) throw (MEDEXCEPTION);
833 ~_BinaryFileWriter();
836 void addString(const char* str) throw (MEDEXCEPTION);
839 void addString(const string& str) throw (MEDEXCEPTION)
840 { addString( str.c_str() ); }
842 //!< write an integer value
843 void addInt(const int value) throw (MEDEXCEPTION)
844 { add( &value, 1 ); }
846 //!< write integer values
847 void addInt(const int* data, int nbValues) throw (MEDEXCEPTION)
848 { add( data, nbValues ); }
850 //!< write integer values
851 void addInt(const vector< int >& data) throw (MEDEXCEPTION)
852 { add( &data[0], data.size() ); }
854 //!< write any data as floats
855 template <typename T>
856 void addReal(const T* data, int nbValues) throw (MEDEXCEPTION)
858 _RealData realData( data, nbValues );
859 add( realData.values(), nbValues );
862 //!< write any data as floats
863 template <class TValueIterator>
864 void addReal(vector< TValueIterator >& componentIt,
866 const medModeSwitch interlace) throw (MEDEXCEPTION)
868 _RealData realData( componentIt, nbValues, interlace );
869 add( realData.values(), nbValues * componentIt.size() );
874 int _file; //!< descriptor
875 MEDEXCEPTION _exception; //!< ready to raise exception
877 //!< write any data to file
878 template <typename T>
879 void add(const T* data, int nbValues) throw (MEDEXCEPTION)
883 ssize_t nbWritten = ::write( _file, (const void *) data, nbValues * sizeof(T));
884 if ( nbWritten < 0 ) throw _exception;
887 // ------------------------------------------------------------------------
889 * \brief Container of temporary data converting any data to floats
891 // ------------------------------------------------------------------------
893 PointerOf<float> _floatData;
895 //!< return pointer to float array
896 const float* values() { return _floatData; }
898 //!< convert nbValues to floats
899 template <typename T>
900 _RealData(const T* data, int nbValues)
902 if ( sizeof( T ) == sizeof( float ))
903 _floatData.set((const float*) data);
905 _floatData.set(nbValues);
906 float* floatPtr = _floatData;
907 const T *tPtr = data, *tEnd = data + nbValues;
908 while ( tPtr < tEnd )
909 *floatPtr++ = _toFloat( *tPtr++ );
913 //!< convert nbValues to floats in given interlace
914 template <class TValueIterator>
915 _RealData(vector< TValueIterator >& componentIt,
917 const medModeSwitch interlace)
919 int nbComponents = componentIt.size();
920 _floatData.set(nbValues * nbComponents);
921 float* floatPtr = _floatData;
922 if ( interlace == MED_FULL_INTERLACE && nbComponents > 1 ) {
923 for ( int i = 0; i < nbValues; ++i )
924 for ( int j = 0; j < nbComponents; ++j )
925 *floatPtr++ = _toFloat( componentIt[ j ].next() );
928 for ( int j = 0; j < nbComponents; ++j ) {
929 TValueIterator & values = componentIt[ j ];
930 for ( int i = 0; i < nbValues; ++i )
931 *floatPtr++ = _toFloat( values.next() );
935 }; // class _RealData
937 }; // class _BinaryFileWriter
939 }// namespace MEDMEM_ENSIGHT