1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : Plot2d_AnalyticalParser.cxx
23 // Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
24 #include "Plot2d_AnalyticalParser.h"
25 #include <structmember.h>
28 /* ==================================
29 * =========== PYTHON ==============
30 * ==================================*/
39 PyStdOut_dealloc(PyStdOut *self)
45 PyStdOut_write(PyStdOut *self, PyObject *args)
49 if (!PyArg_ParseTuple(args, "t#:write",&c, &l))
53 *(self->out)=*(self->out)+c;
59 static PyMethodDef PyStdOut_methods[] = {
60 {"write", (PyCFunction)PyStdOut_write, METH_VARARGS,
61 PyDoc_STR("write(string) -> None")},
62 {NULL, NULL} /* sentinel */
65 static PyMemberDef PyStdOut_memberlist[] = {
66 {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0,
67 (char*)"flag indicating that a space needs to be printed; used by print"},
71 static PyTypeObject PyStdOut_Type = {
72 /* The ob_type field must be initialized in the module init function
73 * to be portable to Windows without using C++. */
74 PyObject_HEAD_INIT(NULL)
77 sizeof(PyStdOut), /*tp_basicsize*/
80 (destructor)PyStdOut_dealloc, /*tp_dealloc*/
92 PyObject_GenericGetAttr, /*tp_getattro*/
93 /* softspace is writable: we must supply tp_setattro */
94 PyObject_GenericSetAttr, /* tp_setattro */
96 Py_TPFLAGS_DEFAULT, /*tp_flags*/
100 0, /*tp_richcompare*/
101 0, /*tp_weaklistoffset*/
104 PyStdOut_methods, /*tp_methods*/
105 PyStdOut_memberlist, /*tp_members*/
119 PyObject * newPyStdOut( std::string& out )
122 self = PyObject_New(PyStdOut, &PyStdOut_Type);
127 return (PyObject*)self;
131 ////////////////////////END PYTHON///////////////////////////
134 //! The only one instance of Parser
135 Plot2d_AnalyticalParser* Plot2d_AnalyticalParser::myParser = 0;
138 QString Plot2d_AnalyticalParser::myScript = QString("");
141 \brief Return the only instance of the Plot2d_AnalyticalParser
142 \return instance of the Plot2d_AnalyticalParser
144 Plot2d_AnalyticalParser* Plot2d_AnalyticalParser::parser()
147 myParser = new Plot2d_AnalyticalParser();
154 Construct the Parser and initialize python interpritator.
156 Plot2d_AnalyticalParser::Plot2d_AnalyticalParser()
158 /* Initialize the Python interpreter */
159 if (Py_IsInitialized()) {
160 PyGILState_STATE gstate = PyGILState_Ensure();
161 myMainMod = PyImport_AddModule("__main__");
162 myMainDict = PyModule_GetDict(myMainMod);
163 PyGILState_Release(gstate);
168 int Plot2d_AnalyticalParser::calculate( const QString& theExpr,
175 QString aPyScript = myScript;
176 aPyScript = aPyScript.arg(theExpr);
178 PyGILState_STATE gstate = PyGILState_Ensure();
179 PyObject* obj = PyRun_String(qPrintable(aPyScript), Py_file_input, myMainDict, NULL);
183 PyGILState_Release(gstate);
190 PyObject* func = NULL;
191 PyObject* f_y = NULL;
193 if(PyObject_HasAttrString(myMainMod, "Y")) {
194 f_y = PyObject_GetAttrString(myMainMod, "Y");
197 if(PyObject_HasAttrString(myMainMod, "coordCalculator")) {
198 func = PyObject_GetAttrString(myMainMod, "coordCalculator");
201 PyObject* new_stderr = NULL;
203 if( f_y == NULL || func == NULL ) {
205 std::string err_description="";
206 new_stderr = newPyStdOut(err_description);
207 PySys_SetObject((char*)"stderr", new_stderr);
209 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
210 Py_DECREF(new_stderr);
211 PyGILState_Release(gstate);
216 coords = PyObject_CallFunction(func,(char*)"(d, d, i)", theMin, theMax, theNbStep );
222 std::string err_description="";
223 new_stderr = newPyStdOut(err_description);
224 PySys_SetObject((char*)"stderr", new_stderr);
226 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
227 Py_DECREF(new_stderr);
228 PyGILState_Release(gstate);
232 Py_ssize_t size = PyList_Size( coords );
240 *theX = new double[size];
241 *theY = new double[size];
243 for ( Py_ssize_t i = 0; i< size; ++i ) {
244 PyObject* coord = PyList_GetItem( coords, i );
245 (*theX)[i] = PyFloat_AsDouble(PyList_GetItem(coord, 0));
246 (*theY)[i] = PyFloat_AsDouble(PyList_GetItem(coord, 1));
249 PyGILState_Release(gstate);
254 \brief Initialize python script.
256 void Plot2d_AnalyticalParser::initScript() {
258 myScript += "from math import * \n";
259 myScript += "def Y(x): \n";
260 myScript += " return ";
263 myScript += "def coordCalculator(xmin, xmax, nstep): \n";
264 myScript += " coords = [] \n";
265 myScript += " xstep = (xmax - xmin) / nstep \n";
266 myScript += " n = 0 \n";
267 myScript += " while n <= nstep : \n";
268 myScript += " x = xmin + n*xstep \n";
269 myScript += " try: \n";
270 myScript += " y = Y(x) \n";
271 myScript += " coords.append([x,y]) \n";
272 myScript += " except ValueError, ZeroDivisionError: \n";
273 myScript += " pass \n";
274 myScript += " n = n+1 \n";
275 myScript += " return coords \n";