1 // Copyright (C) 2007-2016 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, or (at your option) any later version.
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 * ==================================*/
40 PyStdOut_dealloc(PyStdOut *self)
46 PyStdOut_write(PyStdOut *self, PyObject *args)
49 if (!PyArg_ParseTuple(args, "s",&c))
52 *(self->out)=*(self->out)+c;
58 static PyMethodDef PyStdOut_methods[] = {
59 {"write", (PyCFunction)PyStdOut_write, METH_VARARGS,
60 PyDoc_STR("write(string) -> None")},
61 {NULL, NULL} /* sentinel */
64 static PyMemberDef PyStdOut_memberlist[] = {
65 {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0,
66 (char*)"flag indicating that a space needs to be printed; used by print"},
70 static PyTypeObject PyStdOut_Type = {
71 /* The ob_type field must be initialized in the module init function
72 * to be portable to Windows without using C++. */
73 PyVarObject_HEAD_INIT(NULL, 0)
76 sizeof(PyStdOut), /*tp_basicsize*/
79 (destructor)PyStdOut_dealloc, /*tp_dealloc*/
91 PyObject_GenericGetAttr, /*tp_getattro*/
92 /* softspace is writable: we must supply tp_setattro */
93 PyObject_GenericSetAttr, /* tp_setattro */
95 Py_TPFLAGS_DEFAULT, /*tp_flags*/
100 0, /*tp_weaklistoffset*/
103 PyStdOut_methods, /*tp_methods*/
104 PyStdOut_memberlist, /*tp_members*/
122 0, /*tp_version_tag*/
126 PyObject * newPyStdOut( std::string& out )
128 PyStdOut* self = PyObject_New(PyStdOut, &PyStdOut_Type);
133 return (PyObject*)self;
137 ////////////////////////END PYTHON///////////////////////////
140 //! The only one instance of Parser
141 Plot2d_AnalyticalParser* Plot2d_AnalyticalParser::myParser = 0;
144 QString Plot2d_AnalyticalParser::myScript = QString("");
147 \brief Return the only instance of the Plot2d_AnalyticalParser
148 \return instance of the Plot2d_AnalyticalParser
150 Plot2d_AnalyticalParser* Plot2d_AnalyticalParser::parser()
153 myParser = new Plot2d_AnalyticalParser();
160 Construct the Parser and initialize python interpritator.
162 Plot2d_AnalyticalParser::Plot2d_AnalyticalParser()
164 /* Initialize the Python interpreter */
165 if (Py_IsInitialized()) {
166 PyGILState_STATE gstate = PyGILState_Ensure();
167 myMainMod = PyImport_AddModule("__main__");
168 myMainDict = PyModule_GetDict(myMainMod);
169 PyGILState_Release(gstate);
174 int Plot2d_AnalyticalParser::calculate( const QString& theExpr,
181 QString aPyScript = myScript;
182 aPyScript = aPyScript.arg(theExpr);
184 PyGILState_STATE gstate = PyGILState_Ensure();
185 PyObject* obj = PyRun_String(qPrintable(aPyScript), Py_file_input, myMainDict, NULL);
189 PyGILState_Release(gstate);
196 PyObject* func = NULL;
197 PyObject* f_y = NULL;
199 if(PyObject_HasAttrString(myMainMod, "Y")) {
200 f_y = PyObject_GetAttrString(myMainMod, "Y");
203 if(PyObject_HasAttrString(myMainMod, "coordCalculator")) {
204 func = PyObject_GetAttrString(myMainMod, "coordCalculator");
207 if( f_y == NULL || func == NULL ) {
209 std::string err_description="";
210 PyObject* new_stderr = newPyStdOut(err_description);
211 PyObject* old_stderr = PySys_GetObject((char*)"stderr");
212 Py_INCREF(old_stderr);
213 PySys_SetObject((char*)"stderr", new_stderr);
215 PySys_SetObject((char*)"stderr", old_stderr);
216 Py_DECREF(new_stderr);
217 PyGILState_Release(gstate);
221 PyObject* coords = PyObject_CallFunction(func,(char*)"(d, d, i)", theMin, theMax, theNbStep );
225 std::string err_description="";
226 PyObject* new_stderr = newPyStdOut(err_description);
227 PyObject* old_stderr = PySys_GetObject((char*)"stderr");
228 Py_INCREF(old_stderr);
229 PySys_SetObject((char*)"stderr", new_stderr);
231 PySys_SetObject((char*)"stderr", old_stderr);
232 Py_DECREF(new_stderr);
233 PyGILState_Release(gstate);
237 Py_ssize_t size = PyList_Size( coords );
245 *theX = new double[size];
246 *theY = new double[size];
248 for ( Py_ssize_t i = 0; i< size; ++i ) {
249 PyObject* coord = PyList_GetItem( coords, i );
250 (*theX)[i] = PyFloat_AsDouble(PyList_GetItem(coord, 0));
251 (*theY)[i] = PyFloat_AsDouble(PyList_GetItem(coord, 1));
254 PyGILState_Release(gstate);
259 \brief Initialize python script.
261 void Plot2d_AnalyticalParser::initScript() {
263 myScript += "from math import *\n";
264 myScript += "def Y(x):\n";
265 myScript += "\treturn %1\n";
267 myScript += "def coordCalculator(xmin, xmax, nstep):\n";
268 myScript += "\tcoords = []\n";
269 myScript += "\txstep = (xmax - xmin) / nstep\n";
270 myScript += "\tn = 0\n";
271 myScript += "\twhile n <= nstep :\n";
272 myScript += "\t\tx = xmin + n*xstep\n";
273 myScript += "\t\ttry:\n";
274 myScript += "\t\t\ty = Y(x)\n";
275 myScript += "\t\t\tcoords.append([x,y])\n";
276 myScript += "\t\texcept (ValueError, ZeroDivisionError):\n";
277 myScript += "\t\t\tpass\n";
278 myScript += "\t\tn = n+1\n";
279 myScript += "\treturn coords\n";