Salome HOME
Merge from V6_main 01/04/2013
[modules/paravis.git] / src / Plugins / MedReader / IO / vtkMedUtilities.h
1 // Copyright (C) 2010-2013  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #ifndef _vtkMedUtilities_h_
21 #define _vtkMedUtilities_h_
22
23 #include "vtkObject.h"
24 #include "vtkSmartPointer.h"
25 #include "vtkMultiBlockDataSet.h"
26 #include "vtkStringArray.h"
27 #include "vtkMedSetGet.h"
28 #include "vtkMed.h"
29 #include "vtkMedReader.h"
30
31 #include <utility>
32 #include <string>
33 #include <vector>
34 #include <list>
35 #include <set>
36 #include <map>
37
38 class vtkDataArray;
39 class vtkMedMesh;
40 class vtkMedFamily;
41 class vtkMedGroup;
42 class vtkIdList;
43 class vtkMutableDirectedGraph;
44 class vtkInformationIntegerKey;
45 class vtkInformationObjectBaseKey;
46
47 //BTX
48 class vtkMedComputeStep
49 {
50 public :
51   med_int IterationIt;
52   med_int TimeIt;
53   med_float TimeOrFrequency;
54
55   vtkMedComputeStep()
56     {
57     this->IterationIt = MED_NO_IT;
58     this->TimeIt = MED_NO_DT;
59     this->TimeOrFrequency = MED_UNDEF_DT;
60     }
61 };
62
63 bool operator==(const vtkMedComputeStep& cs0, const vtkMedComputeStep& cs1);
64 bool operator!=(const vtkMedComputeStep& cs0, const vtkMedComputeStep& cs1);
65 bool operator<(const vtkMedComputeStep& cs0, const vtkMedComputeStep& cs1);
66
67 class vtkMedEntity
68 {
69 public :
70
71   vtkMedEntity() : EntityType(MED_NODE),
72                      GeometryType(MED_NONE)
73     {
74     }
75
76   vtkMedEntity(med_entity_type type, med_geometry_type geometry) :
77       EntityType(type),
78       GeometryType(geometry)
79     {
80     }
81
82   ~vtkMedEntity()
83     {
84     }
85
86   vtkMedEntity(const vtkMedEntity& entity) :
87       EntityType(entity.EntityType),
88       GeometryType(entity.GeometryType)
89     {
90     this->GeometryName = entity.GeometryName;
91     }
92
93   void operator=(const vtkMedEntity& entity)
94     {
95     this->EntityType = entity.EntityType;
96     this->GeometryType = entity.GeometryType;
97     this->GeometryName = entity.GeometryName;
98     }
99
100   med_entity_type EntityType;
101   med_geometry_type GeometryType;
102   std::string GeometryName;
103 };
104
105 bool operator==(const vtkMedEntity& cs0, const vtkMedEntity& cs1);
106 bool operator!=(const vtkMedEntity& cs0, const vtkMedEntity& cs1);
107 bool operator<(const vtkMedEntity& cs0, const vtkMedEntity& cs1);
108 //ETX
109
110 class VTK_EXPORT vtkMedUtilities
111 {
112 public:
113   static vtkInformationIntegerKey* ELNO();
114   static vtkInformationIntegerKey* ELGA();
115   static vtkInformationStringVectorKey* BLOCK_NAME();
116   static vtkInformationObjectBaseKey* STRUCT_ELEMENT();
117   static vtkInformationIntegerKey* STRUCT_ELEMENT_INDEX();
118
119   // Description:
120   // return an array to store the coordinates of nodes.
121   // the  type of the elements is the same as the one in the med file
122   static vtkDataArray* NewCoordArray();
123
124   // Description:
125   // returns an array to store data of a given type.
126   // the type corresponds to med types.
127   static vtkDataArray* NewArray(med_field_type type);
128   static vtkAbstractArray* NewArray(med_attribute_type type);
129
130   //BTX
131   enum
132   {
133     OnPoint, OnCell
134   };
135   //ETX
136
137   //BTX
138   // Description:
139   // returns a name for the given med_geometry_type
140   static const char* GeometryName(med_geometry_type geometry);
141
142   // Description:
143   // returns a name for the given med_geometry_type
144   static const char* EntityName(med_entity_type type);
145
146   // Description:
147   // returns a name for the given med_connectivity_mode
148   static const char* ConnectivityName(med_connectivity_mode conn);
149
150   static const std::string SimplifyName(const char* medName);
151
152   static const std::string FamilyKey(const char* meshName, int pointOrCell,
153       const char* familyName);
154   static const std::string GroupKey(const char* meshName, int pointOrCell,
155       const char* groupName);
156
157   static const std::string EntityKey(const vtkMedEntity&);
158
159   static int GetNumberOfPoint(med_geometry_type geometry);
160   static int GetDimension(med_geometry_type geometry);
161
162   // returns the VTK cell type (as described in the vtkCellType.h file)
163   // corresponding to the given med_geometry_type
164   static int GetVTKCellType(med_geometry_type geometry);
165
166   // returns the number of sub entity : the number of faces for cells,
167   // the number of edges for faces, the number of nodes for edges
168   static int GetNumberOfSubEntity(med_geometry_type geometry);
169
170   // returns the number of Nodes
171   static int GetNumberOfNodes(med_geometry_type geometry);
172   //ETX
173
174   static med_entity_type GetSubType(med_entity_type type);
175   static med_geometry_type GetSubGeometry(med_geometry_type geometry,
176       int index);
177
178   static int GetParentNodeIndex(med_geometry_type parentGeometry,
179       int subEntityIndex, int subEntityNodeIndex);
180
181   // Description :
182   // Project the ids gathered in the sub entity to the parent entity.
183   // used for MED_DESC connectivity.
184   // Rem : no check is performed, and do not work for
185   // MED_POLYHEDRE and MED_POLYGON
186   static void ProjectConnectivity(med_geometry_type parentGeometry,
187       vtkIdList* parentIds, vtkIdList* subEntityIds, int subEntityIndex,
188       bool invert);
189
190   static char Separator;
191
192   static const char* NoGroupName;
193   static const char* OnCellName;
194   static const char* OnPointName;
195
196   //BTX
197   static void SplitGroupKey(const char* name, /*vtkstd::*/std::string& mesh,
198       /*vtkstd::*/std::string& entity, /*vtkstd::*/std::string& group);
199
200   static std::string GetModeKey(int index, double frequency, int maxindex);
201   static int  GetModeFromKey(const char*, int& index, double& frequency);
202
203   static int MedToVTKIndex(int vtktype, int node);
204
205   static vtkMultiBlockDataSet* GetParent(vtkMultiBlockDataSet* root,
206                                   vtkStringArray* path);
207
208   // Description:
209   // Format the id list so that it respects the VTK format for polyhedrons :
210   // numfaces, npts_face0, pt0, ... npts_face1, pt1 ....
211   static int  FormatPolyhedronForVTK(vtkMedFamilyOnEntityOnProfile*,
212                                vtkIdType, vtkIdList*);
213
214   static int SizeOf(med_attribute_type type);
215   //ETX
216 };
217
218 //BTX
219
220 template<class T>
221 class vtkObjectVector: public std::vector<vtkSmartPointer<T> >
222 {
223 };
224
225 template<class T>
226 class vtkMedComputeStepMap: public
227     std::map<med_int, std::map<med_int, vtkSmartPointer<T> > >
228 {
229 public :
230   void  AddObject(const vtkMedComputeStep& cs, T* obj)
231     {
232     (*this)[cs.TimeIt][cs.IterationIt] = obj;
233     this->TimeIt[cs.TimeOrFrequency] = cs.TimeIt;
234     }
235
236   T* GetObject(const vtkMedComputeStep& cs)
237     {
238     if(this->find(cs.TimeIt) == this->end())
239       return NULL;
240
241     std::map<med_int, vtkSmartPointer<T> >& itmap = (*this)[cs.TimeIt];
242
243     if(itmap.find(cs.IterationIt) == itmap.end())
244       return NULL;
245
246     return itmap[cs.IterationIt];
247     }
248
249   med_int GetNumberOfObject()
250     {
251     med_int nb = 0;
252     typename vtkMedComputeStepMap<T>::iterator it = this->begin();
253     while(it != this->end())
254       {
255       nb += it->second.size();
256       it++;
257       }
258     return nb;
259     }
260
261   T* GetObject(med_int id)
262     {
263     med_int nb = 0;
264     if(id < 0)
265       return NULL;
266
267     typename vtkMedComputeStepMap<T>::iterator it = this->begin();
268     while(it != this->end())
269       {
270       std::map<med_int, vtkSmartPointer<T> >& itmap = it->second;
271       nb += itmap.size();
272       if(id < nb)
273         {
274         typename std::map<med_int, vtkSmartPointer<T> >::iterator iterationit =
275             itmap.begin();
276         for(int ii=0; ii<nb-id-1; ii++)
277           iterationit++;
278         return iterationit->second;
279         }
280       it++;
281       }
282     return NULL;
283     }
284
285   T* FindObject(const vtkMedComputeStep& cs, int strategy)
286     {
287     // first test if the given compute step is present
288     T* obj = this->GetObject(cs);
289     if(obj != NULL)
290       return obj;
291
292     if(this->size() == 0)
293       return NULL;
294
295     // let us first find the iterator that corresponds to the given time
296     med_int timeit = this->FindTimeIterator(cs.TimeOrFrequency, cs.TimeIt);
297
298     std::map<med_int, vtkSmartPointer<T> >& itmap =
299         (*this)[timeit];
300
301     if(itmap.size() == 0)
302       return NULL;
303
304     if(strategy == vtkMedReader::PhysicalTime
305        || strategy == vtkMedReader::Modes)
306       {
307       // in this strategies, we return the last iteration for each time.
308       return itmap.rbegin()->second;
309       }
310     else if(strategy == vtkMedReader::Iteration)
311       {
312       // in this case, we look for the real iteration
313       typename std::map<med_int, vtkSmartPointer<T> >::iterator iterationit
314           = itmap.lower_bound(cs.IterationIt);
315
316       // if this is not exactly the same step and if this is not the first
317       // step, rool back one step to choose the one just before the asked time.
318       if(iterationit->first != cs.IterationIt && iterationit != itmap.begin())
319         iterationit--;
320
321       // the time iterator asked for is higher than all times,
322       // let us pick the last one.
323       if(iterationit == itmap.end())
324         iterationit--;
325
326       return iterationit->second;
327       }
328     }
329
330   void  GatherTimes(std::set<med_float>& times)
331     {
332     typename std::map<med_float, med_int>::iterator it
333         = this->TimeIt.begin();
334     while(it != this->TimeIt.end())
335       {
336       times.insert(it->first);
337       it++;
338       }
339     }
340
341   void  GatherIterations(med_float time, std::set<med_int>& iterations)
342     {
343     med_int timeit = this->FindTimeIterator(time, -1);
344     if(timeit == -1)
345       return;
346
347     std::map<med_int, vtkSmartPointer<T> >& itmap =
348         (*this)[timeit];
349
350     typename std::map<med_int, vtkSmartPointer<T> >::iterator it =
351         itmap.begin();
352
353     while(it != itmap.end())
354       {
355       iterations.insert(it->first);
356       it++;
357       }
358     }
359
360 protected :
361
362   med_int FindTimeIterator(med_float time, med_int defaultit)
363     {
364     if(this->TimeIt.size() == 0)
365       return defaultit;
366
367     typename std::map<med_float, med_int>::iterator it
368         = this->TimeIt.lower_bound(time);
369
370     // if this is not exactly the same step and if this is not the first step,
371     // rool back one step to choose the one just before the asked time.
372     if(it->first != time && it != this->TimeIt.begin())
373       it--;
374
375     // if the time iterator asked for is higher than all times,
376     // let us pick the last one.
377     if(it == this->TimeIt.end())
378       it--;
379
380     return it->second;
381     }
382
383   std::map<med_float, med_int> TimeIt;
384 };
385
386 template<class T>
387 class vtkList: public std::list<T>
388 {
389 };
390
391 template<class T1, class T2>
392 struct IsSameTraits
393 {
394   static const bool IsSame()
395   {
396     return false;
397   }
398 };
399
400 template<class T1>
401 struct IsSameTraits<T1, T1>
402 {
403   static const bool IsSame()
404   {
405     return true;
406   }
407 };
408
409 #define PRINT_IVAR(os, indent, name) \
410   os << indent << #name << " : "  << name << endl;
411
412 #define PRINT_STRING(os, indent, name) \
413   os << indent << #name << " : "  << ( name ? name : "(void)") << endl;
414
415 #define PRINT_OBJECT(os, indent, name) \
416   os << indent << #name << " : " ;\
417   if(name != NULL) \
418   {\
419     os << endl;\
420     name->PrintSelf(os, indent.GetNextIndent());\
421   }\
422   else os << "(NULL)" << endl;
423
424 #define PRINT_VECTOR(os, indent, name, size) \
425 {\
426   os << indent << #name << " : (";\
427   for(vtkIdType _index = 0; _index<size; _index++)\
428     {\
429     os << name[_index];\
430     if(_index < size-1)\
431       os << ", ";\
432     }\
433   os << ")" << endl;\
434 }
435
436 #define PRINT_OBJECT_VECTOR(os, indent, name) \
437 {\
438   os << indent << #name;\
439   os << endl;\
440   vtkIdType _size = name->size();\
441   for(vtkIdType _index = 0; _index < _size; _index++)\
442   {\
443   os << indent << #name << _index << " : " << endl;\
444   if(name->at(_index) != NULL)\
445     name->at(_index)->PrintSelf(os, indent.GetNextIndent());\
446   else\
447     os << indent.GetNextIndent() << "(NULL)" << endl;\
448   }\
449 }
450
451 #define PRINT_STRING_VECTOR(os, indent, name)\
452 {\
453   os << indent << #name << ": ";\
454   for(int _comp = 0; _comp<this->name->size(); _comp++)\
455     {\
456     os << this->name->at(_comp)->GetString();\
457     if(_comp < this->name->size()-1)\
458       os << ", ";\
459     }\
460   os << endl;\
461 }
462
463 #define PRINT_MED_STRING(os, indent, name)\
464   os << indent << #name << ": " << this->name->GetString() << endl; \
465
466 //ETX
467
468 #endif