## Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+UNSET(PYTHON_INCLUDE_DIRS)
+UNSET(PYTHON_LIBRARIES)
IF(WIN32)
IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
ENDIF()
IF(WIN32)
- FILE(TO_CMAKE_PATH "$ENV{PYTHONHOME}/libs/${PYTHON_LIBRARY_FILE}" PYTHON_LIBRARY)
+ FILE(TO_CMAKE_PATH "$ENV{PYTHONHOME}/libs/${PYTHON_LIBRARY_FILE}" PATH_PYTHON_LIBRARY)
ElSE()
- FILE(TO_CMAKE_PATH "$ENV{PYTHONHOME}/lib/${PYTHON_LIBRARY_FILE}" PYTHON_LIBRARY)
+ FILE(TO_CMAKE_PATH "$ENV{PYTHONHOME}/lib/${PYTHON_LIBRARY_FILE}" PATH_PYTHON_LIBRARY)
ENDIF()
+FILE(TO_CMAKE_PATH $ENV{PYTHON_INCLUDE} PATH_PYTHON_INCLUDE_DIR)
+
+SET(PYTHON_INCLUDE_DIR ${PATH_PYTHON_INCLUDE_DIR} CACHE PATH "path to where Python.h is found" FORCE)
+SET(PYTHON_LIBRARY ${PATH_PYTHON_LIBRARY} CACHE FILEPATH "path to the python library" FORCE)
-FILE(TO_CMAKE_PATH $ENV{PYTHON_INCLUDE} PYTHON_INCLUDE_DIR)
FIND_PACKAGE(PythonLibs REQUIRED)
FIND_PACKAGE(PythonInterp REQUIRED)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_DIR})
-#MESSAGE(STATUS "PYTHON_LIBRARIES: " ${PYTHON_LIBRARIES})
-#MESSAGE(STATUS "PYTHON_INCLUDE_DIR: " ${PYTHON_INCLUDE_DIR})
INCLUDE(XMLProcessing)
INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/src/Events
- ${PYTHON_INCLUDE_DIRS})
+ ${PYTHON_INCLUDE_DIR})
SET(PROJECT_HEADERS
Config_def.h
SET_TARGET_PROPERTIES(ModelAPI PROPERTIES LINKER_LANGUAGE CXX)
TARGET_LINK_LIBRARIES(ModelAPI ${PROJECT_LIBRARIES})
-INCLUDE_DIRECTORIES(
- ../Config
- ../Events
- ../GeomAPI
- ../GeomAlgoAPI
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Config
+ ${PROJECT_SOURCE_DIR}/src/Events
+ ${PROJECT_SOURCE_DIR}/src/GeomAPI
+ ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI
)
INCLUDE(Common)
-
-INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events
- ${PROJECT_SOURCE_DIR}/src/Config
- ${PROJECT_SOURCE_DIR}/src/ModelAPI
-)
+INCLUDE(FindPython)
SET(PROJECT_HEADERS
ParametersPlugin.h
ParametersPlugin_Plugin.h
ParametersPlugin_Parameter.h
+ ParametersPlugin_PyInterp.h
)
SET(PROJECT_SOURCES
ParametersPlugin_Plugin.cpp
ParametersPlugin_Parameter.cpp
+ ParametersPlugin_PyInterp.cpp
)
SET(XML_RESOURCES
plugin-Parameters.xml
)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events
+ ${PROJECT_SOURCE_DIR}/src/Config
+ ${PROJECT_SOURCE_DIR}/src/ModelAPI
+ ${PROJECT_SOURCE_DIR}/src/GeomAPI
+ ${SUIT_INCLUDE}
+ ${PYTHON_INCLUDE_DIR}
+)
+
+MESSAGE(STATUS "PYTHON_LIBRARIES (ParametersPlugin): ${PYTHON_LIBRARIES}")
+
SET(PROJECT_LIBRARIES
Events
Config
ModelAPI
+ ${PyInterp}
+ ${PYTHON_LIBRARIES}
)
-ADD_DEFINITIONS(-DPARAMETERSPLUGIN_EXPORTS)
+ADD_DEFINITIONS(-DPARAMETERSPLUGIN_EXPORTS -DHAVE_DEBUG_PYTHON)
ADD_LIBRARY(ParametersPlugin MODULE ${PROJECT_SOURCES} ${PROJECT_HEADERS} ${XML_RESOURCES})
TARGET_LINK_LIBRARIES(ParametersPlugin ${PROJECT_LIBRARIES})
// Author: sbh
#include "ParametersPlugin_Parameter.h"
+#include <ParametersPlugin_PyInterp.h>
+
#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_ResultParameter.h>
+#include <ModelAPI_AttributeDouble.h>
+
ParametersPlugin_Parameter::ParametersPlugin_Parameter()
{
+ myInterp = new ParametersPlugin_PyInterp();
+ myInterp->initialize();
+}
+
+ParametersPlugin_Parameter::~ParametersPlugin_Parameter()
+{
+ delete myInterp;
}
void ParametersPlugin_Parameter::initAttributes()
{
- data()->addAttribute(ParametersPlugin_Parameter::VARIABLE_ID(), ModelAPI_AttributeString::typeId());
- data()->addAttribute(ParametersPlugin_Parameter::EXPRESSION_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(ParametersPlugin_Parameter::VARIABLE_ID(),
+ ModelAPI_AttributeString::typeId());
+ data()->addAttribute(ParametersPlugin_Parameter::EXPRESSION_ID(),
+ ModelAPI_AttributeString::typeId());
}
void ParametersPlugin_Parameter::execute()
{
+ std::string anExpression = string(ParametersPlugin_Parameter::EXPRESSION_ID())->value();
+ if(anExpression.empty())
+ return;
+ ResultParameterPtr aParameterResult = document()->createParameter(data());
+ //AttributeDoublePtr anAttr = aParameterResult->data()->real(ModelAPI_ResultParameter::VALUE());
+
+ double aValue = evaluate(anExpression);
+ //anAttr->setValue(aValue);
+ setResult(aParameterResult);
+
+}
+
+double ParametersPlugin_Parameter::evaluate(std::string theExpression)
+{
+ std::list<std::string> anExprParams = myInterp->compile(theExpression);
+ // find expression's params in the model
+ // todo
+ // myInterp->extendLocalContext();
+ std::string outError;
+ return myInterp->evaluate(theExpression, outError);
+
}
#include "ParametersPlugin.h"
#include <ModelAPI_Feature.h>
+class ParametersPlugin_PyInterp;
+
class ParametersPlugin_Parameter : public ModelAPI_Feature
{
public:
+ virtual ~ParametersPlugin_Parameter();
+
/// Extrusion kind
inline static const std::string& ID()
{
/// Use plugin manager for features creation
ParametersPlugin_Parameter();
+
+ protected:
+ double evaluate(std::string);
+
+ private:
+ ParametersPlugin_PyInterp* myInterp;
};
#endif
--- /dev/null
+/*
+ * ParametersPlugin_PyInterp.cpp
+ *
+ * Created on: Apr 2, 2015
+ * Author: sbh
+ */
+
+#include <ParametersPlugin_PyInterp.h>
+
+#include <string>
+
+ParametersPlugin_PyInterp::ParametersPlugin_PyInterp()
+: PyInterp_Interp()
+{
+}
+
+ParametersPlugin_PyInterp::~ParametersPlugin_PyInterp()
+{
+}
+
+std::list<std::string> ParametersPlugin_PyInterp::compile(const std::string& theExpression)
+{
+ PyGILState_STATE aGilState = PyGILState_Ensure();
+ std::list<std::string> res = this->_compile(theExpression);
+ PyGILState_Release(aGilState);
+ return res;
+}
+
+void ParametersPlugin_PyInterp::extendLocalContext(const std::list<std::string>& theParameters)
+{
+ PyGILState_STATE aGilState = PyGILState_Ensure();
+ this->_extendLocalContext(theParameters);
+ PyGILState_Release(aGilState);
+}
+
+double ParametersPlugin_PyInterp::evaluate(const std::string& theExpression,
+ std::string& theError)
+{
+ PyGILState_STATE aGilState = PyGILState_Ensure();
+ double res = this->_evaluate(theExpression, theError);
+ PyGILState_Release(aGilState);
+ return res;
+}
+
+
+std::list<std::string> ParametersPlugin_PyInterp::_compile(const std::string& theExpression)
+{
+
+ std::list<std::string> aResult;
+ PyObject *aCodeopModule = PyImport_AddModule("codeop");
+ if(!aCodeopModule) { // Fatal error. No way to go on.
+ PyErr_Print();
+ return aResult;
+ }
+
+ PyObject *aCodePyObj =
+ PyObject_CallMethod(aCodeopModule, "compile_command", "(s)", theExpression.c_str());
+
+ if(!aCodePyObj || aCodePyObj == Py_None || !PyCode_Check(aCodePyObj)) {
+ Py_XDECREF(aCodePyObj);
+ return aResult;
+ }
+
+ PyCodeObject* aCodeObj = (PyCodeObject*) aCodePyObj;
+ // 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;
+
+ int params_size = PyTuple_Size(aCodeObj->co_names);
+ if (params_size > 0) {
+ for (int i = 0; i < params_size; i++) {
+ PyObject* aParamObj = PyTuple_GetItem(aCodeObj->co_names, i);
+ PyObject* aParamObjStr = PyObject_Str(aParamObj);
+ std::string aParamName(PyString_AsString(aParamObjStr));
+ aResult.push_back(aParamName);
+ Py_XDECREF(aParamObjStr);
+ }
+ }
+ Py_XDECREF(aCodeObj);
+ return aResult;
+}
+
+void ParametersPlugin_PyInterp::_extendLocalContext(const std::list<std::string>& theParameters)
+{
+ if (theParameters.empty())
+ return;
+}
+
+
+double ParametersPlugin_PyInterp::_evaluate(const std::string& theExpression, std::string& theError)
+{
+ PyCodeObject* anExprCode = (PyCodeObject *) Py_CompileString(theExpression.c_str(),
+ "<string>", Py_eval_input);
+ if(!anExprCode) {
+ theError = errorMessage();
+ Py_XDECREF(anExprCode);
+ return 0.;
+ }
+
+ PyObject* anEvalResult = PyEval_EvalCode(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(PyString_AsString(anEvalStrObj));
+ double result = std::stod(anEvalStr);
+
+ return result;
+}
+
+std::string ParametersPlugin_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(PyString_AsString(pstr));
+ Py_XDECREF(pstr);
+ Py_XDECREF(ptype);
+ Py_XDECREF(pvalue);
+ Py_XDECREF(ptraceback);
+ }
+ return aPyError;
+}
--- /dev/null
+/*
+ * ParametersPlugin_PyInterp.h
+ *
+ * Created on: Apr 2, 2015
+ * Author: sbh
+ */
+
+#ifndef PARAMETERSPLUGIN_PYINTERP_H_
+#define PARAMETERSPLUGIN_PYINTERP_H_
+
+#include <PyInterp_Interp.h>
+#include <ParametersPlugin.h>
+
+#include <list>
+#include <string>
+
+class PARAMETERSPLUGIN_EXPORT ParametersPlugin_PyInterp : public PyInterp_Interp
+{
+ public:
+ ParametersPlugin_PyInterp();
+ virtual ~ParametersPlugin_PyInterp();
+
+ std::list<std::string> compile(const std::string&);
+ void extendLocalContext(const std::list<std::string>&);
+ double evaluate(const std::string&, std::string&);
+
+ protected:
+ std::list<std::string> _compile(const std::string&);
+ void _extendLocalContext(const std::list<std::string>&);
+ double _evaluate(const std::string&, std::string&);
+ std::string errorMessage();
+};
+
+#endif /* PARAMETERSPLUGIN_PYINTERP_H_ */