diff --git a/Mesh/FieldPython.h b/Mesh/FieldPython.h new file mode 100644 index 0000000000000000000000000000000000000000..f6ca53c1b47ed1fb3df6a0e7cd97ca37d17d6a80 --- /dev/null +++ b/Mesh/FieldPython.h @@ -0,0 +1,59 @@ +#ifndef _FIELD_PYTHON_H_ +#define _FIELD_PYTHON_H_ + +#include "Field.h" +#include "Python.h" +class FieldPython : public Field +{ + PyObject *_callback; + + public: + const char *getName() + { + return "Python"; + } + + std::string getDescription() + { + return "simple call to a python function"; + } + + FieldPython(PyObject *cb, PyObject *arg = NULL) + { + _callback = cb; + Py_INCREF(_callback); + } + + ~FieldPython() + { + Py_DECREF(_callback); + } + + double operator() (double x, double y, double z, GEntity *ge=0) + { + PyObject *pyge = SWIG_NewPointerObj((void*) ge, SWIGTYPE_p_GEntity, 0); + PyObject *args = Py_BuildValue("(dddO)", x, y, z, pyge); + PyObject *result = PyEval_CallObject(_callback, args); + Py_DECREF(args); + if (result) { + double r = PyFloat_AsDouble(result); + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + Msg::Error("Result of python function of field %i cannot be interpreted as a float.", id); + r = MAX_LC; + } + Py_DECREF(result); + return r; + } + else { + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + } + Msg::Error("An error occurs while evaluating python function of field %i.", id); + return MAX_LC; + } + } +}; +#endif diff --git a/wrappers/gmshpy/gmshMesh.i b/wrappers/gmshpy/gmshMesh.i index 0e3c66d39b624592bc7db6437d0cf62c1f465a8e..38836cae212845de6e35522d230b32a3a1f9c853 100644 --- a/wrappers/gmshpy/gmshMesh.i +++ b/wrappers/gmshpy/gmshMesh.i @@ -21,6 +21,7 @@ #include "meshPartition.h" #endif #include "Field.h" + #include "FieldPython.h" #include "meshMetric.h" #if defined(HAVE_ANN) #include "CenterlineField.h" @@ -58,6 +59,21 @@ namespace std { %include "meshPartition.h" #endif %include "Field.h" +%extend FieldManager { + int addPythonField(PyObject *callback, int id = -1) { + if (id == -1) { + id = $self->newId(); + } + if($self->find(id) != $self->end()) { + Msg::Error("Field id %i is already defined", id); + return -1; + } + Field *f = new FieldPython(callback); + f->id = id; + $self->operator[](id) = f; + return id; + } +} %include "meshMetric.h" #if defined(HAVE_ANN) %include "CenterlineField.h"