Salome HOME
Add test for .mesh file format
[tools/medcoupling.git] / src / MEDLoader / Swig / MEDLoaderTypemaps.i
1 // Copyright (C) 2007-2024  CEA, EDF
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, or (at your option) any later version.
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 // Author : Anthony Geay (EDF R&D)
20
21 #include <vector>
22 #include <iterator>
23
24 class MEDVectorMIIterator : public std::iterator< std::input_iterator_tag, long, long, const std::pair<int,mcIdType> *, std::pair<int,mcIdType> >
25 {
26   long _num = 0;
27   std::vector< std::pair<mcIdType,mcIdType> > _data;
28 public:
29   explicit MEDVectorMIIterator(long num , std::vector< std::pair<mcIdType,mcIdType> > data) : _num(num),_data(data) {}
30   MEDVectorMIIterator& operator++() { ++_num; return *this;}
31   bool operator==(const MEDVectorMIIterator& other) const {return _num == other._num;}
32   bool operator!=(const MEDVectorMIIterator& other) const {return !(*this == other);}
33   reference operator*() const {return {(int)_data[_num].first,_data[_num].second}; }
34 };
35
36 class MEDVectorVectorMIIterator : public std::iterator< std::input_iterator_tag, long, long, const std::vector< std::pair<int,mcIdType> >*, std::vector< std::pair<int,mcIdType> > >
37 {
38   long _num = 0;
39   std::vector< std::vector< std::pair<mcIdType,mcIdType> > > _data;
40 public:
41   explicit MEDVectorVectorMIIterator(long num , std::vector< std::vector< std::pair<mcIdType,mcIdType> > > data) : _num(num),_data(data) {}
42   MEDVectorVectorMIIterator& operator++() { ++_num; return *this;}
43   bool operator==(const MEDVectorVectorMIIterator& other) const {return _num == other._num;}
44   bool operator!=(const MEDVectorVectorMIIterator& other) const {return !(*this == other);}
45   reference operator*() const { auto data = _data[_num]; return reference(MEDVectorMIIterator(0,data),MEDVectorMIIterator(data.size(),data)); }
46 };
47
48 static PyObject *convertMEDFileMesh(MEDCoupling::MEDFileMesh* mesh, int owner)
49 {
50   PyObject *ret=0;
51   if(!mesh)
52     {
53       Py_XINCREF(Py_None);
54       return Py_None;
55     }
56   if(dynamic_cast<MEDCoupling::MEDFileUMesh *>(mesh))
57     ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_MEDCoupling__MEDFileUMesh,owner);
58   if(dynamic_cast<MEDCoupling::MEDFileCMesh *>(mesh))
59     ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_MEDCoupling__MEDFileCMesh,owner);
60   if(dynamic_cast<MEDCoupling::MEDFileCurveLinearMesh *>(mesh))
61     ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_MEDCoupling__MEDFileCurveLinearMesh,owner);
62   if(!ret)
63     throw INTERP_KERNEL::Exception("Not recognized type of MEDFileMesh on downcast !");
64   return ret;
65 }
66
67 static PyObject *convertMEDFileParameter1TS(MEDCoupling::MEDFileParameter1TS* p1ts, int owner)
68 {
69   PyObject *ret=0;
70   if(!p1ts)
71     {
72       Py_XINCREF(Py_None);
73       return Py_None;
74     }
75   if(dynamic_cast<MEDFileParameterDouble1TS *>(p1ts))
76     ret=SWIG_NewPointerObj((void*)p1ts,SWIGTYPE_p_MEDCoupling__MEDFileParameterDouble1TS,owner);
77   if(dynamic_cast<MEDFileParameterDouble1TSWTI *>(p1ts))
78     ret=SWIG_NewPointerObj((void*)p1ts,SWIGTYPE_p_MEDCoupling__MEDFileParameterDouble1TSWTI,owner);
79   if(!ret)
80     throw INTERP_KERNEL::Exception("Not recognized type of MEDFileParameter1TS on downcast !");
81   return ret;
82 }
83
84 static PyObject *convertMEDFileField1TS(MEDCoupling::MEDFileAnyTypeField1TS *p, int owner)
85 {
86   PyObject *ret=0;
87   if(!p)
88     {
89       Py_XINCREF(Py_None);
90       return Py_None;
91     }
92   if(dynamic_cast<MEDFileField1TS *>(p))
93     ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_MEDCoupling__MEDFileField1TS,owner);
94   if(dynamic_cast<MEDFileInt32Field1TS *>(p))
95     ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_MEDCoupling__MEDFileInt32Field1TS,owner);
96   if(dynamic_cast<MEDFileInt64Field1TS *>(p))
97     ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_MEDCoupling__MEDFileInt64Field1TS,owner);
98   if(dynamic_cast<MEDFileFloatField1TS *>(p))
99     ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_MEDCoupling__MEDFileFloatField1TS,owner);
100   if(!ret)
101     throw INTERP_KERNEL::Exception("Not recognized type of MEDFileAnyTypeField1TS on downcast !");
102   return ret;
103 }
104
105 static PyObject *convertMEDFileFieldMultiTS(MEDCoupling::MEDFileAnyTypeFieldMultiTS *p, int owner)
106 {
107   PyObject *ret=0;
108   if(!p)
109     {
110       Py_XINCREF(Py_None);
111       return Py_None;
112     }
113   if(dynamic_cast<MEDFileFieldMultiTS *>(p))
114     ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_MEDCoupling__MEDFileFieldMultiTS,owner);
115   if(dynamic_cast<MEDFileInt32FieldMultiTS *>(p))
116     ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_MEDCoupling__MEDFileInt32FieldMultiTS,owner);
117   if(dynamic_cast<MEDFileInt64FieldMultiTS *>(p))
118     ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_MEDCoupling__MEDFileInt64FieldMultiTS,owner);
119   if(dynamic_cast<MEDFileFloatFieldMultiTS *>(p))
120     ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_MEDCoupling__MEDFileFloatFieldMultiTS,owner);
121   if(!ret)
122     throw INTERP_KERNEL::Exception("Not recognized type of MEDFileAnyTypeFieldMultiTS on downcast !");
123   return ret;
124 }
125
126 static PyObject *convertMEDMeshMultiLev(MEDCoupling::MEDMeshMultiLev *p, int owner)
127 {
128   PyObject *ret=0;
129   if(!p)
130     {
131       Py_XINCREF(Py_None);
132       return Py_None;
133     }
134   if(dynamic_cast<MEDUMeshMultiLev *>(p))
135     ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_MEDCoupling__MEDUMeshMultiLev,owner);
136   if(dynamic_cast<MEDCMeshMultiLev *>(p))
137     ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_MEDCoupling__MEDCMeshMultiLev,owner);
138   if(dynamic_cast<MEDCurveLinearMeshMultiLev *>(p))
139     ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_MEDCoupling__MEDCurveLinearMeshMultiLev,owner);
140   if(!ret)
141     throw INTERP_KERNEL::Exception("Not recognized type of MEDMeshMultiLev on downcast !");
142   return ret;
143 }
144
145 static std::vector<std::pair<int,int> > convertTimePairIdsFromPy(PyObject *pyLi)
146 {
147   std::vector<std::pair<int,int> > ret;
148   if(PyList_Check(pyLi))
149     {
150       std::size_t size=PyList_Size(pyLi);
151       ret.resize(size);
152       for(std::size_t i=0;i<size;i++)
153         {
154           PyObject *o=PyList_GetItem(pyLi,i);
155           if(PyTuple_Check(o))
156             {
157               std::pair<int,int> p;
158               std::size_t size2=PyTuple_Size(o);
159               if(size2!=2)
160                 throw INTERP_KERNEL::Exception("tuples in list must be of size 2 (dt,it) !");
161               PyObject *o0=PyTuple_GetItem(o,0);
162               if(PyInt_Check(o0))
163                 p.first=(int)PyInt_AS_LONG(o0);
164               else
165                 throw INTERP_KERNEL::Exception("First elem of tuples in list must be integer : dt !");
166               PyObject *o1=PyTuple_GetItem(o,1);
167               if(PyInt_Check(o1))
168                 p.second=(int)PyInt_AS_LONG(o1);
169               else
170                 throw INTERP_KERNEL::Exception("Second elem of tuples in list must be integer : dt !");
171               ret[i]=p;
172             }
173           else
174             throw INTERP_KERNEL::Exception("list must contain tuples only");
175         }
176     }
177   else
178     throw INTERP_KERNEL::Exception("convertTimePairIdsFromPy : not a list");
179   return ret;
180 }
181
182 static std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > convertVecPairIntToVecPairTOFCT(const std::vector<std::pair<int,int> >& tmp)
183 {
184   std::size_t sz(tmp.size());
185   std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > entitiesCpp(sz);
186   for(std::size_t i=0;i<sz;i++)
187     {
188       entitiesCpp[i].first=(TypeOfField)tmp[i].first;
189       entitiesCpp[i].second=(INTERP_KERNEL::NormalizedCellType)tmp[i].second;
190     }
191   return entitiesCpp;
192 }
193
194 static void converPyListToVecString(PyObject *pyLi, std::vector<std::string>& v)
195 {
196   static const char msg0[]="In list passed in argument some elements are NOT strings ! Expected a list containing only strings !";
197   static const char msg1[]="In tuple passed in argument some elements are NOT strings ! Expected a list containing only strings !";
198   static const char msg2[]="Unrecognized python argument : expected a list of string or tuple of string or string !";
199   if(PyList_Check(pyLi))
200     {
201       std::size_t size=PyList_Size(pyLi);
202       v.resize(size);
203       for(std::size_t i=0;i<size;i++)
204         {
205           PyObject *o=PyList_GetItem(pyLi,i);
206           v[i]=convertPyObjectToStr(o,msg0);
207         }
208       return ;
209     }
210   else if(PyTuple_Check(pyLi))
211     {
212       std::size_t size=PyTuple_Size(pyLi);
213       v.resize(size);
214       for(std::size_t i=0;i<size;i++)
215         {
216           PyObject *o=PyTuple_GetItem(pyLi,i);
217           v[i]=convertPyObjectToStr(o,msg1);
218         }
219       return ;
220     }
221   v.resize(1);
222   v[0]=convertPyObjectToStr(pyLi,msg2);
223 }
224
225 static PyObject *convertFieldDoubleVecToPy(const std::vector<MEDCoupling::MEDCouplingFieldDouble *>& li)
226 {
227   std::size_t sz=li.size();
228   PyObject *ret=PyList_New(sz);
229   for(std::size_t i=0;i<sz;i++)
230     {
231       PyObject *o=SWIG_NewPointerObj((void*)li[i],SWIGTYPE_p_MEDCoupling__MEDCouplingFieldDouble,SWIG_POINTER_OWN | 0);
232       PyList_SetItem(ret,i,o);
233     }
234   return ret;
235 }
236
237 template< class T >
238 PyObject *convertVecPairIntToPy(const std::vector< std::pair<int,T> >& vec)
239 {
240   PyObject *ret(PyList_New(vec.size()));
241   int rk=0;
242   for(typename std::vector< std::pair<int,T> >::const_iterator iter=vec.begin();iter!=vec.end();iter++,rk++)
243     {
244       PyObject *elt=PyTuple_New(2);
245       PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first));
246       PyTuple_SetItem(elt,1,PyInt_FromLong((*iter).second));
247       PyList_SetItem(ret,rk,elt);
248     }
249   return ret;
250 }
251
252 PyObject *convertVecPairVecStToPy(const std::vector< std::pair<std::vector<std::string>, std::string > >& vec)
253 {
254   std::size_t sz=vec.size();
255   PyObject *ret=PyList_New(sz);
256   for(std::size_t i=0;i<sz;i++)
257     {
258       PyObject *t=PyTuple_New(2);
259       int sz2=(int)vec[i].first.size();
260       PyObject *ll=PyList_New(sz2);
261       for(int j=0;j<sz2;j++)
262         PyList_SetItem(ll,j,PyString_FromString(vec[i].first[j].c_str()));
263       PyTuple_SetItem(t,0,ll);
264       PyTuple_SetItem(t,1,PyString_FromString(vec[i].second.c_str()));
265       PyList_SetItem(ret,i,t);
266     }
267   return ret;
268 }
269
270 PyObject *convertVectPairStToPy(const std::vector< std::pair<std::string, std::string > >& vec)
271 {
272   std::size_t sz=vec.size();
273   PyObject *ret=PyList_New(sz);
274   for(std::size_t i=0;i<sz;i++)
275     {
276       PyObject *t=PyTuple_New(2);
277       PyTuple_SetItem(t,0,PyString_FromString(vec[i].first.c_str()));
278       PyTuple_SetItem(t,1,PyString_FromString(vec[i].second.c_str()));
279       PyList_SetItem(ret,i,t);
280     }
281   return ret;
282 }
283
284 std::vector< std::pair<std::string, std::string > > convertVecPairStStFromPy(PyObject *pyLi)
285 {
286   std::vector< std::pair<std::string, std::string > > ret;
287   const char *msg="convertVecPairStStFromPy : Expecting PyList of Tuples of size 2 ! The first elt in tuple is one string and the 2nd one a string !";
288   if(PyList_Check(pyLi))
289     {
290       std::size_t size=PyList_Size(pyLi);
291       ret.resize(size);
292       for(std::size_t i=0;i<size;i++)
293         {
294           PyObject *o=PyList_GetItem(pyLi,i);
295           if(PyTuple_Check(o))
296             {
297               std::pair<std::string, std::string> p;
298               std::size_t size2=PyTuple_Size(o);
299               if(size2!=2)
300                 throw INTERP_KERNEL::Exception(msg);
301               PyObject *o0=PyTuple_GetItem(o,0);
302               p.first=convertPyObjectToStr(o0,msg);
303               PyObject *o1=PyTuple_GetItem(o,1);
304               p.second=convertPyObjectToStr(o1,msg);
305               ret[i]=p;
306             }
307           else
308             throw INTERP_KERNEL::Exception(msg);
309         }
310       return ret;
311     }
312   throw INTERP_KERNEL::Exception(msg);
313 }
314
315 std::vector< std::pair<std::vector<std::string>, std::string > > convertVecPairVecStFromPy(PyObject *pyLi)
316 {
317   std::vector< std::pair<std::vector<std::string>, std::string > > ret;
318   const char *msg="convertVecPairVecStFromPy : Expecting PyList of Tuples of size 2 ! The first elt in tuple is a list of strings and the 2nd one a string !";
319   if(PyList_Check(pyLi))
320     {
321       std::size_t size=PyList_Size(pyLi);
322       ret.resize(size);
323       for(std::size_t i=0;i<size;i++)
324         {
325           PyObject *o=PyList_GetItem(pyLi,i);
326           if(PyTuple_Check(o))
327             {
328               std::pair<std::vector<std::string>, std::string> p;
329               std::size_t size2=PyTuple_Size(o);
330               if(size2!=2)
331                 throw INTERP_KERNEL::Exception(msg);
332               PyObject *o0=PyTuple_GetItem(o,0);
333               if(PyList_Check(o0))
334                 {
335                   std::size_t size3=PyList_Size(o0);
336                   p.first.resize(size3);
337                   for(std::size_t j=0;j<size3;j++)
338                     {
339                       PyObject *o0j=PyList_GetItem(o0,j);
340                       p.first[j]=convertPyObjectToStr(o0j,msg);
341                     }
342                 }
343               else
344                 throw INTERP_KERNEL::Exception(msg);
345               PyObject *o1=PyTuple_GetItem(o,1);
346               p.second=convertPyObjectToStr(o1,msg);
347               ret[i]=p;
348             }
349           else
350             throw INTERP_KERNEL::Exception(msg);
351         }
352       return ret;
353     }
354   throw INTERP_KERNEL::Exception(msg);
355 }
356
357 /*!
358  * Called by MEDFileAnyTypeFieldMultiTS::__getitem__ when \a elt0 is neither a list nor a slice.
359  * In this case a MEDFileAnyTypeField1TS object is returned.
360  */
361 int MEDFileAnyTypeFieldMultiTSgetitemSingleTS__(const MEDFileAnyTypeFieldMultiTS *self, PyObject *elt0)
362 {
363   if(elt0 && PyInt_Check(elt0))
364     {//fmts[3]
365       return InterpreteNegativeInt(PyInt_AS_LONG(elt0),self->getNumberOfTS());
366     }
367   else if(elt0 && PyTuple_Check(elt0))
368     {
369       if(PyTuple_Size(elt0)==2)
370         {
371           PyObject *o0=PyTuple_GetItem(elt0,0);
372           PyObject *o1=PyTuple_GetItem(elt0,1);
373           if(PyInt_Check(o0) && PyInt_Check(o1))
374             {//fmts(1,-1)
375               int iter=(int)PyInt_AS_LONG(o0);
376               int order=(int)PyInt_AS_LONG(o1);
377               return self->getPosOfTimeStep(iter,order);
378             }
379           else
380             throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input param ! input is a tuple of size 2 but two integers are expected in this tuple to request a time steps !");
381         }
382       else
383         throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input param ! input is a tuple of size != 2 ! two integers are expected in this tuple to request a time steps !");
384     }
385   else if(elt0 && PyFloat_Check(elt0))
386     {
387       double val=PyFloat_AS_DOUBLE(elt0);
388       return self->getPosGivenTime(val);
389     }
390   else
391     throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input params ! expected fmts[int], fmts[int,int], or fmts[double] to request one time step ! To request a series of time steps invoke fmts[slice], fmts[list of int], fmts[list of double], or fmts[list of int,int] !");
392 }
393
394 /*!
395  * Called by MEDFileAnyTypeFieldMultiTS::__getitem__ when \a obj is neither a list nor a slice.
396  * In this case a MEDFileAnyTypeField1TS object is returned.
397  */
398 int MEDFileFieldsgetitemSingleTS__(const MEDFileFields *self, PyObject *obj)
399 {
400   static const char msg[]="MEDFileFields::__getitem__ : only integer or string with fieldname supported !";
401   if(PyInt_Check(obj))
402     {
403       return InterpreteNegativeInt(PyInt_AS_LONG(obj),self->getNumberOfFields());
404     }
405   return self->getPosFromFieldName(convertPyObjectToStr(obj,msg));
406 }
407
408 void convertToMapIntDataArrayInt(PyObject *pyMap, std::map<int, MCAuto<DataArrayIdType> >& cppMap)
409 {
410   if(!PyDict_Check(pyMap))
411     throw INTERP_KERNEL::Exception("convertToMapIntDataArrayInt : input is not a python map !");
412   PyObject *key, *value;
413   Py_ssize_t pos(0);
414   cppMap.clear();
415   while (PyDict_Next(pyMap,&pos,&key,&value))
416     {
417       if(!PyInt_Check(key))
418         throw INTERP_KERNEL::Exception("convertToMapIntDataArrayInt : keys in map must be PyInt !");
419       int k((int)PyInt_AS_LONG(key));
420       void *argp(0);
421       int status(SWIG_ConvertPtr(value,&argp,SWIGTITraits<mcIdType>::TI,0|0));
422       if(!SWIG_IsOK(status))
423         {
424           std::ostringstream oss; oss << "convertToMapIntDataArrayInt : values in map must be DataArrayInt !";
425           throw INTERP_KERNEL::Exception(oss.str().c_str());
426         }
427       DataArrayIdType *arg(reinterpret_cast<DataArrayIdType*>(argp));
428       MCAuto<DataArrayIdType> arg2(arg);
429       if(arg)
430         arg->incrRef();
431       cppMap[k]=arg2;
432     }
433 }
434
435 template<class T>
436 PyObject *MEDFileField1TS_getFieldWithProfile(const typename MLFieldTraits<T>::F1TSType *self, TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh) 
437 {
438   DataArrayIdType *ret1(NULL);
439   typename MEDCoupling::Traits<T>::ArrayType *ret0(self->getFieldWithProfile(type,meshDimRelToMax,mesh,ret1));
440   PyObject *ret(PyTuple_New(2));
441   PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTITraits<T>::TI, SWIG_POINTER_OWN | 0 ));
442   PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTITraits<mcIdType>::TI, SWIG_POINTER_OWN | 0 ));
443   return ret;
444 }
445
446 template<class T>
447 PyObject *MEDFileField1TS_getUndergroundDataArrayExt(const typename MLFieldTraits<T>::F1TSType *self)
448 {
449   std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<mcIdType,mcIdType> > > elt1Cpp;
450   typename MEDCoupling::Traits<T>::ArrayType *elt0=self->getUndergroundDataArrayExt(elt1Cpp);
451   if(elt0)
452     elt0->incrRef();
453   PyObject *ret=PyTuple_New(2);
454   PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(elt0),SWIGTITraits<T>::TI, SWIG_POINTER_OWN | 0 ));
455   std::size_t sz=elt1Cpp.size();
456   PyObject *elt=PyList_New(sz);
457   for(std::size_t i=0;i<sz;i++)
458     {
459       PyObject *elt1=PyTuple_New(2);
460       PyObject *elt2=PyTuple_New(2);
461       PyTuple_SetItem(elt2,0,SWIG_From_int((int)elt1Cpp[i].first.first));
462       PyTuple_SetItem(elt2,1,SWIG_From_int(elt1Cpp[i].first.second));
463       PyObject *elt3=PyTuple_New(2);
464       PyTuple_SetItem(elt3,0,PyInt_FromLong(elt1Cpp[i].second.first));
465       PyTuple_SetItem(elt3,1,PyInt_FromLong(elt1Cpp[i].second.second));
466       PyTuple_SetItem(elt1,0,elt2);
467       PyTuple_SetItem(elt1,1,elt3);
468       PyList_SetItem(elt,i,elt1);
469     }
470   PyTuple_SetItem(ret,1,elt);
471   return ret;
472 }