From abb7185fc68e142a147547932b2419db68682e1a Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me?= Date: Sun, 18 Oct 2020 18:02:03 +0200 Subject: [PATCH] Remove BuildPlugin_Interp and add a test (Maxt > Mint) --- src/BuildPlugin/BuildPlugin_EvalListener.cpp | 4 +- src/BuildPlugin/BuildPlugin_EvalListener.h | 4 +- src/BuildPlugin/BuildPlugin_Interpolation.cpp | 29 +- src/BuildPlugin/BuildPlugin_Interpolation.h | 7 - src/BuildPlugin/BuildPlugin_PyInterp.cpp | 268 ------------------ src/BuildPlugin/BuildPlugin_PyInterp.h | 65 ----- src/BuildPlugin/CMakeLists.txt | 3 +- src/BuildPlugin/interpolation_widget.xml | 10 +- 8 files changed, 26 insertions(+), 364 deletions(-) delete mode 100644 src/BuildPlugin/BuildPlugin_PyInterp.cpp delete mode 100644 src/BuildPlugin/BuildPlugin_PyInterp.h diff --git a/src/BuildPlugin/BuildPlugin_EvalListener.cpp b/src/BuildPlugin/BuildPlugin_EvalListener.cpp index 335995622..96c552f89 100644 --- a/src/BuildPlugin/BuildPlugin_EvalListener.cpp +++ b/src/BuildPlugin/BuildPlugin_EvalListener.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #include @@ -74,7 +74,7 @@ BuildPlugin_EvalListener::BuildPlugin_EvalListener() aLoop->registerListener(this, ModelAPI_BuildEvalMessage::eventId(), NULL, true); aLoop->registerListener(this, ModelAPI_ComputePositionsMessage::eventId(), NULL, true); - myInterp = std::shared_ptr(new BuildPlugin_PyInterp()); + myInterp = std::shared_ptr(new InitializationPlugin_PyInterp()); myInterp->initialize(); } diff --git a/src/BuildPlugin/BuildPlugin_EvalListener.h b/src/BuildPlugin/BuildPlugin_EvalListener.h index ab558a356..3951559eb 100644 --- a/src/BuildPlugin/BuildPlugin_EvalListener.h +++ b/src/BuildPlugin/BuildPlugin_EvalListener.h @@ -27,7 +27,7 @@ class ModelAPI_Attribute; class ModelAPI_Document; class ModelAPI_Feature; class ModelAPI_ResultParameter; -class BuildPlugin_PyInterp; +class InitializationPlugin_PyInterp; /** * \class BuildPlugin_EvalListener @@ -64,7 +64,7 @@ class BuildPlugin_EvalListener : public Events_Listener void processEvaluationEvent(const std::shared_ptr& theMessage); private: - std::shared_ptr myInterp; + std::shared_ptr myInterp; }; #endif /* SRC_BUILDPLUGIN_EVALLISTENER_H_ */ diff --git a/src/BuildPlugin/BuildPlugin_Interpolation.cpp b/src/BuildPlugin/BuildPlugin_Interpolation.cpp index 2fd4d48bc..433a92d02 100644 --- a/src/BuildPlugin/BuildPlugin_Interpolation.cpp +++ b/src/BuildPlugin/BuildPlugin_Interpolation.cpp @@ -76,7 +76,6 @@ void BuildPlugin_Interpolation::initAttributes() data()->addAttribute(CREATION_METHODE_BY_SELECTION_ID(), ModelAPI_AttributeString::typeId()); data()->addAttribute(CREATION_METHODE_ANALYTICAL_ID(), ModelAPI_AttributeString::typeId()); data()->addAttribute(CREATION_METHODE_ANALYTICAL_ID(), ModelAPI_AttributeString::typeId()); - data()->addAttribute(EXPRESSION_ID(), ModelAPI_AttributeString::typeId()); data()->addAttribute(EXPRESSION_ERROR_ID(), ModelAPI_AttributeString::typeId()); data()->addAttribute(VARIABLE_ID(), ModelAPI_AttributeString::typeId()); data()->addAttribute(VALUE_ID(), ModelAPI_AttributeTables::typeId()); @@ -94,20 +93,23 @@ void BuildPlugin_Interpolation::initAttributes() CREATION_METHODE_ANALYTICAL_ID()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATION_METHODE_BY_SELECTION_ID()); - ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXPRESSION_ID()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), VARIABLE_ID()); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), VALUE_ID()); data()->addAttribute(ARGUMENTS_ID(), ModelAPI_AttributeRefList::typeId()); data()->reflist(ARGUMENTS_ID())->setIsArgument(false); ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), ARGUMENTS_ID()); - string(XT_ID())->setValue("t"); - string(YT_ID())->setValue("t"); - string(ZT_ID())->setValue("t"); - real(MINT_ID())->setValue(0); - real(MAXT_ID())->setValue(100); - integer(NUMSTEP_ID())->setValue(10); - updateCoods(); + if( string( XT_ID())->value() == "" + && string( YT_ID())->value() == "" + && string( ZT_ID())->value() == "") + { + string(XT_ID())->setValue("t"); + string(YT_ID())->setValue("t"); + string(ZT_ID())->setValue("t"); + real(MINT_ID())->setValue(0); + real(MAXT_ID())->setValue(100); + integer(NUMSTEP_ID())->setValue(10); + } } void BuildPlugin_Interpolation::attributeChanged(const std::string& theID) @@ -133,6 +135,11 @@ void BuildPlugin_Interpolation::updateCoods() double aMint = real(MINT_ID())->value(); double aMaxt = real(MAXT_ID())->value(); int aNbrStep = integer(NUMSTEP_ID())->value(); + + if ( aMaxt < aMint ) { + setError("The minimum value of the parameter must be less than maximum value !!!" ); + } + double scale = (aMaxt - aMint )/aNbrStep; string(VARIABLE_ID())->setValue("t"); @@ -257,7 +264,7 @@ void BuildPlugin_Interpolation::execute() //y value = table->value(step, 2); coodPoint.push_back( value.myDouble ); - // + //Z value = table->value(step, 3); coodPoint.push_back( value.myDouble ); @@ -280,7 +287,7 @@ void BuildPlugin_Interpolation::execute() // Create curve from points GeomEdgePtr anEdge = - GeomAlgoAPI_CurveBuilder::edge(aPoints, false, true,GeomDirPtr(),GeomDirPtr()); + GeomAlgoAPI_CurveBuilder::edge(aPoints, false, false,GeomDirPtr(),GeomDirPtr()); if (!anEdge.get()) { setError("Error: Result curve is empty."); return; diff --git a/src/BuildPlugin/BuildPlugin_Interpolation.h b/src/BuildPlugin/BuildPlugin_Interpolation.h index 4859364cf..e921ae5ac 100644 --- a/src/BuildPlugin/BuildPlugin_Interpolation.h +++ b/src/BuildPlugin/BuildPlugin_Interpolation.h @@ -149,13 +149,6 @@ public: return MY_VALUE_ID; } - /// attribute of parameter expression - inline static const std::string& EXPRESSION_ID() - { - static const std::string MY_EXPRESSION_ID("expression"); - return MY_EXPRESSION_ID; - } - /// attribute of parameter expression error inline static const std::string& EXPRESSION_ERROR_ID() { diff --git a/src/BuildPlugin/BuildPlugin_PyInterp.cpp b/src/BuildPlugin/BuildPlugin_PyInterp.cpp deleted file mode 100644 index ae85fd5f6..000000000 --- a/src/BuildPlugin/BuildPlugin_PyInterp.cpp +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright (C) 2014-2020 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include - -#include - -#include -#include -#include - -BuildPlugin_PyInterp::BuildPlugin_PyInterp() -: PyInterp_Interp() -{ -} - -BuildPlugin_PyInterp::~BuildPlugin_PyInterp() -{ -} - -const char* aSearchCode = - "import ast\n" - "class FindName(ast.NodeVisitor):\n" - " def __init__(self, name):\n" - " self.name = name\n" - " def visit_Name(self, node):\n" - " if node.id == self.name:\n" - " positions.append((node.lineno, node.col_offset))\n" - "FindName(name).visit(ast.parse(expression))"; - -// make the expression be correct for the python interpreter even for the -// beta=alfa*2 expressions -static std::wstring adjustExpression(const std::wstring& theExpression) { - std::wstring anExpression = theExpression; - if (!anExpression.empty() && anExpression.back() == L'=') { - anExpression = anExpression.substr(0, anExpression.length() - 1); - } - return anExpression; -} - -std::list > -BuildPlugin_PyInterp::positions(const std::wstring& theExpression, - const std::wstring& theName) -{ - PyLockWrapper lck; // Acquire GIL until the end of the method - - std::list > aResult; - - // prepare a context - PyObject* aContext = PyDict_New(); - PyDict_SetItemString(aContext, "__builtins__", PyEval_GetBuiltins()); - - std::wstring anExpression = adjustExpression(theExpression); - // extend aContext with variables - PyDict_SetItemString(aContext, "expression", - PyUnicode_FromWideChar(anExpression.c_str(), anExpression.size())); - PyDict_SetItemString(aContext, "name", PyUnicode_FromWideChar(theName.c_str(), theName.size())); - PyDict_SetItemString(aContext, "positions", Py_BuildValue("[]")); - - // run the search code - PyObject* aExecResult = PyRun_String(aSearchCode, Py_file_input, aContext, aContext); - Py_XDECREF(aExecResult); - - // receive results from context - PyObject* aPositions = PyDict_GetItemString(aContext, "positions"); - for (int anIndex = 0; anIndex < PyList_Size(aPositions); ++anIndex) { - PyObject* aPosition = PyList_GetItem(aPositions, anIndex); - PyObject* aLineNo = PyTuple_GetItem(aPosition, 0); - PyObject* aColOffset = PyTuple_GetItem(aPosition, 1); - - aResult.push_back( - std::pair((int)PyLong_AsLong(aLineNo), - (int)PyLong_AsLong(aColOffset))); - } - - // TODO(spo): after this refCount of the variable is not 0. Is there memory leak? - Py_DECREF(aContext); - - return aResult; -} - - -std::list BuildPlugin_PyInterp::compile(const std::wstring& theExpression) -{ - PyLockWrapper lck; // Acquire GIL until the end of the method - std::list aResult; - PyObject *aCodeopModule = PyImport_AddModule("codeop"); - if(!aCodeopModule) { // Fatal error. No way to go on. - PyErr_Print(); - return aResult; - } - // support "variable_name=" expression as "variable_name" - std::wstring anExpression = adjustExpression(theExpression); - - PyObject *aCodePyObj = - PyObject_CallMethod(aCodeopModule, (char*)"compile_command", (char*)"(s)", - Locale::Convert::toString(anExpression).c_str()); - - if(!aCodePyObj || aCodePyObj == Py_None || !PyCode_Check(aCodePyObj)) { - Py_XDECREF(aCodePyObj); - return aResult; - } - - PyCodeObject* aCodeObj = (PyCodeObject*) aCodePyObj; - std::string aCodeName(PyBytes_AsString(aCodeObj->co_code)); - // co_names should be tuple, but can be changed in modern versions of python (>2.7.3) - if(!PyTuple_Check(aCodeObj->co_names)) { - return aResult; - } - - size_t params_size = PyTuple_Size(aCodeObj->co_names); - if (params_size > 0) { - for (size_t i = 0; i < params_size; i++) { - PyObject* aParamObj = PyTuple_GetItem(aCodeObj->co_names, i); - PyObject* aParamObjStr = PyObject_Str(aParamObj); - Py_ssize_t aSize; - std::wstring aParamName(PyUnicode_AsWideCharString(aParamObjStr, &aSize)); - aResult.push_back(aParamName); - Py_XDECREF(aParamObjStr); - } - } - Py_XDECREF(aCodeObj); - return aResult; -} - -void BuildPlugin_PyInterp::extendLocalContext(const std::list& theParameters) -{ - PyLockWrapper lck; // Acquire GIL until the end of the method - if (theParameters.empty()) - return; - std::list::const_iterator it = theParameters.begin(); - for ( ; it != theParameters.cend(); it++) { - std::string aParamValue = Locale::Convert::toString(*it); - simpleRun(aParamValue.c_str(), false); - } -} - -void BuildPlugin_PyInterp::clearLocalContext() -{ - PyLockWrapper lck; - PyDict_Clear(_local_context); -} - -double BuildPlugin_PyInterp::evaluate(const std::wstring& theExpression, - std::string& theError) -{ - // support "variable_name=" expression as "variable_name" - std::wstring anExpression = adjustExpression(theExpression); - - PyLockWrapper lck; // Acquire GIL until the end of the method - PyCompilerFlags aFlags = {CO_FUTURE_DIVISION}; - aFlags.cf_flags = CO_FUTURE_DIVISION; - PyCodeObject* anExprCode = (PyCodeObject *) Py_CompileStringFlags( - Locale::Convert::toString(anExpression).c_str(), - "", Py_eval_input, &aFlags); - if(!anExprCode) { - theError = errorMessage(); - Py_XDECREF(anExprCode); - return 0.; - } - - PyObject* anEvalResult = PyEval_EvalCode((PyObject *)anExprCode, _global_context, _local_context); - if(!anEvalResult) { - theError = errorMessage(); - Py_XDECREF(anExprCode); - Py_XDECREF(anEvalResult); - return 0.; - } - - PyObject* anEvalStrObj = PyObject_Str(anEvalResult); - std::string anEvalStr(PyUnicode_AsUTF8(anEvalStrObj)); - Py_XDECREF(anExprCode); - Py_XDECREF(anEvalResult); - Py_XDECREF(anEvalStrObj); - double result = 0.; - try { - // set locale due to the #2485 - std::string aCurLocale = std::setlocale(LC_NUMERIC, 0); - std::setlocale(LC_NUMERIC, "C"); - result = std::stod(anEvalStr); - std::setlocale(LC_NUMERIC, aCurLocale.c_str()); - } - catch (const std::invalid_argument&) { - theError = "Unable to eval " + anEvalStr; - } - - return result; -} - -std::string BuildPlugin_PyInterp::errorMessage() -{ - std::string aPyError; - if (PyErr_Occurred()) { - PyObject *pstr, *ptype, *pvalue, *ptraceback; - PyErr_Fetch(&ptype, &pvalue, &ptraceback); - PyErr_NormalizeException(&ptype, &pvalue, &ptraceback); - pstr = PyObject_Str(pvalue); - aPyError = std::string(PyUnicode_AsUTF8(pstr)); - Py_XDECREF(pstr); - Py_XDECREF(ptype); - Py_XDECREF(pvalue); - Py_XDECREF(ptraceback); - } - return aPyError; -} - -bool BuildPlugin_PyInterp::initContext() -{ - PyObject *m = PyImport_AddModule("__main__"); // interpreter main module (module context) - if(!m){ - PyErr_Print(); - return false; - } - _global_context = PyModule_GetDict(m); // get interpreter global variable context - Py_INCREF(_global_context); - _local_context = PyDict_New(); - Py_INCREF(_local_context); - - // to avoid "help()" hang in the python console - const static char* aHelpTxt = "def help(): print(\"Available modules:\\n" - " salome.shaper.model : higher level access to features and data model\\n" - " BuildAPI : Build plugin features allowing to build shapes\\n" - " ConfigAPI : configuration management: preferences and XML properties\\n" - " ConstructionAPI : Construction plugin for auxiliary features creation\\n" - " EventsAPI : application events receiving and emitting manager\\n" - " ExchangeAPI : Exchange plugin with import/export features\\n" - " FeaturesAPI : Features plugin with general 3D features\\n" - " GeomAlgoAPI : geometrical algorithms\\n" - " GeomAPI : geometrical data structures\\n" - " GeomDataAPI : specific geometrical data structures stored in the data model\\n" - " ModelAPI : general low-level interface to access data model\\n" - " ModelHighAPI : general high-level interface to access data model\\n" - " ParametersAPI : Parameters plugin for parameters feature management\\n" - " PartSetAPI : PartSet plugin for management Parts features\\n" - " SketchAPI : Sketch plugin with all sketch features\")"; - - PyRun_SimpleString(aHelpTxt); - - return PyRun_SimpleString("from math import *") == 0; -} - -void BuildPlugin_PyInterp::closeContext() -{ - Py_XDECREF(_local_context); - PyInterp_Interp::closeContext(); -} - -bool BuildPlugin_PyInterp::runString(std::string theString) -{ - PyLockWrapper lck; // Acquire GIL until the end of the method - return PyRun_SimpleString(theString.c_str()); -} diff --git a/src/BuildPlugin/BuildPlugin_PyInterp.h b/src/BuildPlugin/BuildPlugin_PyInterp.h deleted file mode 100644 index b5b8e14a8..000000000 --- a/src/BuildPlugin/BuildPlugin_PyInterp.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2014-2020 CEA/DEN, EDF R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef BUILDPLUGIN_PYINTERP_H_ -#define BUILDPLUGIN_PYINTERP_H_ - -#include -#include - -#include -#include -#include - -/** - * \class BuildPlugin_PyInterp - * \ingroup Plugins - * \brief Helper class for using Python interpreter. - */ -class BUILDPLUGIN_EXPORT BuildPlugin_PyInterp : public PyInterp_Interp -{ - public: - BuildPlugin_PyInterp(); - virtual ~BuildPlugin_PyInterp(); - - /// Returns a list of positions for theName in theExpression. - std::list > positions(const std::wstring& theExpression, - const std::wstring& theName); - /// Compiles theExpression and returns a list of parameters used in theExpression. - std::list compile(const std::wstring& theExpression); - /// Extends local context with the list of parameters. - void extendLocalContext(const std::list& theParameters); - /// Clears local context. - void clearLocalContext(); - /// Evaluates theExpression and returns its value. - double evaluate(const std::wstring& theExpression, std::string& theError); - - /// Runs the string command in the python interpreter. Returns true if no error is in result. - bool runString(std::string theString); - - protected: - /// Returns error message. - std::string errorMessage(); - /// Overrides PyInterp_Interp. - virtual bool initContext(); - /// Reimplemented from PyInterp_Interp::closeContext(). - virtual void closeContext(); -}; - -#endif /* BUILDPLUGIN_PYINTERP_H_ */ diff --git a/src/BuildPlugin/CMakeLists.txt b/src/BuildPlugin/CMakeLists.txt index 929c321c6..f5f04f61e 100644 --- a/src/BuildPlugin/CMakeLists.txt +++ b/src/BuildPlugin/CMakeLists.txt @@ -29,6 +29,7 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events ${PROJECT_SOURCE_DIR}/src/GeomDataAPI ${PROJECT_SOURCE_DIR}/src/GeomValidators ${PROJECT_SOURCE_DIR}/src/SketchPlugin + ${PROJECT_SOURCE_DIR}/src/InitializationPlugin ${SUIT_INCLUDE} ${PYTHON_INCLUDE_DIR} ) @@ -51,7 +52,6 @@ SET(PROJECT_HEADERS BuildPlugin_Filling.h BuildPlugin_Validators.h BuildPlugin_EvalListener.h - BuildPlugin_PyInterp.h ) SET(PROJECT_SOURCES @@ -71,7 +71,6 @@ SET(PROJECT_SOURCES BuildPlugin_Filling.cpp BuildPlugin_Validators.cpp BuildPlugin_EvalListener.cpp - BuildPlugin_PyInterp.cpp ) SET(XML_RESOURCES diff --git a/src/BuildPlugin/interpolation_widget.xml b/src/BuildPlugin/interpolation_widget.xml index 7294fc5d5..21ccd2c84 100644 --- a/src/BuildPlugin/interpolation_widget.xml +++ b/src/BuildPlugin/interpolation_widget.xml @@ -39,26 +39,22 @@ tooltip="???" icon="icons/Build/feature_interpolation_analytical.png"> - + - + - + - -