mantaflow  0.10
A framework for fluid simulation
pconvert.h
Go to the documentation of this file.
1 
2 /******************************************************************************
3  *
4  * MantaFlow fluid solver framework
5  * Copyright 2011 Tobias Pfaff, Nils Thuerey
6  *
7  * This program is free software, distributed under the terms of the
8  * GNU General Public License (GPL)
9  * http://www.gnu.org/licenses
10  *
11  * Python argument wrappers and conversion tools
12  *
13  ******************************************************************************/
14 
15 // -----------------------------------------------------------------
16 // NOTE:
17 // Do not include this file in user code, include "manta.h" instead
18 // -----------------------------------------------------------------
19 
20 #ifdef _MANTA_H
21 #ifndef _PCONVERT_H
22 #define _PCONVERT_H
23 
24 #include <string>
25 #include <map>
26 #include <vector>
27 
28 namespace Manta {
29 template<class T> class Grid;
30 
31 
33 struct ArgLocker {
34  void add(PbClass* p);
35  ~ArgLocker();
36  std::vector<PbClass*> locks;
37 };
38 
39 PyObject* getPyNone();
40 
41 // for PbClass-derived classes
42 template<class T> T* fromPyPtr(PyObject* obj, std::vector<void*>* tmp) {
43  if (PbClass::isNullRef(obj))
44  return 0;
45  PbClass* pbo = Pb::objFromPy(obj);
46  const std::string& type = Namify<T>::S;
47  if (!pbo || !(pbo->canConvertTo(type)))
48  throw Error("can't convert argument to " + type+"*");
49  return (T*)(pbo);
50 }
51 
52 template<> float* fromPyPtr<float>(PyObject* obj, std::vector<void*>* tmp);
53 template<> double* fromPyPtr<double>(PyObject* obj, std::vector<void*>* tmp);
54 template<> int* fromPyPtr<int>(PyObject* obj, std::vector<void*>* tmp);
55 template<> std::string* fromPyPtr<std::string>(PyObject* obj, std::vector<void*>* tmp);
56 template<> bool* fromPyPtr<bool>(PyObject* obj, std::vector<void*>* tmp);
57 template<> Vec3* fromPyPtr<Vec3>(PyObject* obj, std::vector<void*>* tmp);
58 template<> Vec3i* fromPyPtr<Vec3i>(PyObject* obj, std::vector<void*>* tmp);
59 template<> Vec4* fromPyPtr<Vec4>(PyObject* obj, std::vector<void*>* tmp);
60 template<> Vec4i* fromPyPtr<Vec4i>(PyObject* obj, std::vector<void*>* tmp);
61 
62 PyObject* incref(PyObject* obj);
63 template<class T> PyObject* toPy(const T& v) {
64  PyObject* obj = v.getPyObject();
65  if (obj) {
66  return incref(obj);
67  }
68  T* co = new T (v);
69  const std::string& type = Namify<typename remove_pointers<T>::type>::S;
70  return Pb::copyObject(co,type);
71 }
72 template<class T> bool isPy(PyObject* obj) {
73  if (PbClass::isNullRef(obj))
74  return false;
75  PbClass* pbo = Pb::objFromPy(obj);
76  const std::string& type = Namify<typename remove_pointers<T>::type>::S;
77  return pbo && pbo->canConvertTo(type);
78 }
79 
80 template<class T> T fromPy(PyObject* obj) {
81  throw Error("Unknown type conversion. Did you pass a PbClass by value? Instead always pass grids/particlesystems/etc. by reference or using a pointer.");
82 }
83 
84 // builtin types
85 template<> float fromPy<float>(PyObject* obj);
86 template<> double fromPy<double>(PyObject* obj);
87 template<> int fromPy<int>(PyObject *obj);
88 template<> PyObject* fromPy<PyObject*>(PyObject *obj);
89 template<> std::string fromPy<std::string>(PyObject *obj);
90 template<> const char* fromPy<const char*>(PyObject *obj);
91 template<> bool fromPy<bool>(PyObject *obj);
92 template<> Vec3 fromPy<Vec3>(PyObject* obj);
93 template<> Vec3i fromPy<Vec3i>(PyObject* obj);
94 template<> Vec4 fromPy<Vec4>(PyObject* obj);
95 template<> Vec4i fromPy<Vec4i>(PyObject* obj);
96 template<> PbType fromPy<PbType>(PyObject* obj);
97 template<> PbTypeVec fromPy<PbTypeVec>(PyObject* obj);
98 
99 template<> PyObject* toPy<int>( const int& v);
100 template<> PyObject* toPy<std::string>( const std::string& val);
101 template<> PyObject* toPy<float>( const float& v);
102 template<> PyObject* toPy<double>( const double& v);
103 template<> PyObject* toPy<bool>( const bool& v);
104 template<> PyObject* toPy<Vec3i>( const Vec3i& v);
105 template<> PyObject* toPy<Vec3>( const Vec3& v);
106 template<> PyObject* toPy<Vec4i>( const Vec4i& v);
107 template<> PyObject* toPy<Vec4>( const Vec4& v);
108 typedef PbClass* PbClass_Ptr;
109 template<> PyObject* toPy<PbClass*>( const PbClass_Ptr & obj);
110 
111 template<> bool isPy<float>(PyObject* obj);
112 template<> bool isPy<double>(PyObject* obj);
113 template<> bool isPy<int>(PyObject *obj);
114 template<> bool isPy<PyObject*>(PyObject *obj);
115 template<> bool isPy<std::string>(PyObject *obj);
116 template<> bool isPy<const char*>(PyObject *obj);
117 template<> bool isPy<bool>(PyObject *obj);
118 template<> bool isPy<Vec3>(PyObject* obj);
119 template<> bool isPy<Vec3i>(PyObject* obj);
120 template<> bool isPy<Vec4>(PyObject* obj);
121 template<> bool isPy<Vec4i>(PyObject* obj);
122 template<> bool isPy<PbType>(PyObject* obj);
123 
125 class PbArgs {
126 public:
127  PbArgs(PyObject *linargs = NULL, PyObject* dict = NULL);
128  ~PbArgs();
129  void setup(PyObject *linargs = NULL, PyObject* dict = NULL);
130 
131  void check();
132  FluidSolver* obtainParent();
133 
134  inline int numLinArgs() { return mLinData.size(); }
135 
136  inline bool has(const std::string& key) {
137  return getItem(key, false) != NULL;
138  }
139  inline void deleteItem(const std::string& key) {
140  if( mData.find(key) != mData.end() )
141  mData.erase( mData.find(key) );
142  }
143 
144  inline PyObject* linArgs() { return mLinArgs; }
145  inline PyObject* kwds() { return mKwds; }
146 
147  void addLinArg(PyObject* obj);
148 
149  template<class T> inline void add(const std::string& key, T arg) {
150  DataElement el = { toPy(arg), false };
151  mData[key] = el;
152  }
153  template<class T> inline T get(const std::string& key, int number=-1, ArgLocker *lk=NULL) {
154  visit(number, key);
155  PyObject* o = getItem(key, false, lk);
156  if (o) return fromPy<T>(o);
157  o = getItem(number, false, lk);
158  if (o) return fromPy<T>(o);
159  errMsg ("Argument '" + key + "' is not defined.");
160  }
161  template<class T> inline T getOpt(const std::string& key, int number, T defarg, ArgLocker *lk=NULL) {
162  visit(number, key);
163  PyObject* o = getItem(key, false, lk);
164  if (o) return fromPy<T>(o);
165  if (number >= 0) o = getItem(number, false, lk);
166  return (o) ? fromPy<T>(o) : defarg;
167  }
168  template<class T> inline T* getPtrOpt(const std::string& key, int number, T* defarg, ArgLocker *lk=NULL) {
169  visit(number, key);
170  PyObject* o = getItem(key, false, lk);
171  if (o) return fromPyPtr<T>(o,&mTmpStorage);
172  if (number >= 0) o = getItem(number, false, lk);
173  return o ? fromPyPtr<T>(o,&mTmpStorage) : defarg;
174  }
175  template<class T> inline T* getPtr(const std::string& key, int number = -1, ArgLocker *lk=NULL) {
176  visit(number, key);
177  PyObject* o = getItem(key, false, lk);
178  if (o) return fromPyPtr<T>(o,&mTmpStorage);
179  o = getItem(number, false, lk);
180  if(o) return fromPyPtr<T>(o,&mTmpStorage);
181  errMsg ("Argument '" + key + "' is not defined.");
182  }
183 
184 
185  // automatic template type deduction
186  template<class T> bool typeCheck(int num, const std::string& name) {
187  PyObject* o = getItem(name, false, 0);
188  if (!o)
189  o = getItem(num, false, 0);
190  return o ? isPy<typename remove_pointers<T>::type>(o) : false;
191  }
192 
193  PbArgs& operator=(const PbArgs& a); // dummy
194  void copy(PbArgs& a);
195  void clear();
196  void visit(int num, const std::string& key);
197 
198  static PbArgs EMPTY;
199 
200 protected:
201  PyObject* getItem(const std::string& key, bool strict, ArgLocker* lk = NULL);
202  PyObject* getItem(size_t number, bool strict, ArgLocker* lk = NULL);
203 
204  struct DataElement {
205  PyObject *obj;
206  bool visited;
207  };
208  std::map<std::string, DataElement> mData;
209  std::vector<DataElement> mLinData;
210  PyObject* mLinArgs, *mKwds;
211  std::vector<void*> mTmpStorage;
212 };
213 
214 } // namespace
215 
216 #if NUMPY==1
217 #include "numpyWrap.h"
218 #endif
219 
220 #endif
221 #endif
222 
223 
Definition: commonkernels.h:22
Vector4D< int > Vec4i
3D vector class of type int
Definition: vector4d.h:364
Vector3D< int > Vec3i
3D vector class of type int
Definition: randomstream.h:548
Vector4D< Real > Vec4
3D vector class of type Real (typically float)
Definition: vector4d.h:361
Vector3D< Real > Vec3
3D vector class of type Real (typically float)
Definition: randomstream.h:545