]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
The ability to register python plugins added
authorSergey BELASH <belash.sergey@opencascade.com>
Thu, 6 Nov 2014 12:21:34 +0000 (15:21 +0300)
committerSergey BELASH <belash.sergey@opencascade.com>
Thu, 6 Nov 2014 12:21:34 +0000 (15:21 +0300)
16 files changed:
linux_env.sh
msvc10_env.bat
src/Config/CMakeLists.txt
src/Config/Config_Keywords.h
src/Config/Config_ModuleReader.cpp
src/Config/Config_ModuleReader.h
src/Config/plugins.xml
src/GeomAPI/CMakeLists.txt
src/GeomAlgoAPI/CMakeLists.txt
src/GeomDataAPI/CMakeLists.txt
src/Model/Model_Session.cpp
src/ModelAPI/CMakeLists.txt
src/ModelAPI/ModelAPI.i
src/ModelAPI/ModelAPI_Plugin.h
src/PythonFeaturesPlugin/PythonFeaturesPlugin.py
src/PythonFeaturesPlugin/PythonFeaturesPlugin_Box.py

index 7992a8794b3c47d58e37485238fd146fe3aa90c7..b58d16324ca82a3b78cf7a03151e1e651e710f94 100644 (file)
@@ -37,7 +37,7 @@ export PATH=${CASROOT}:${PATH}
 #------ NewGEOM ------
 export NEWGEOM_ROOT_DIR=${ROOT_DIR}/install
 export PATH=${NEWGEOM_ROOT_DIR}/bin:${NEWGEOM_ROOT_DIR}/plugins:${PATH}
-export PYTHONPATH=${NEWGEOM_ROOT_DIR}/swig:${NEW_GEOM_ROOT_DIR}/plugins:${PYTHONPATH}
+export PYTHONPATH=${NEWGEOM_ROOT_DIR}/swig:${NEWGEOM_ROOT_DIR}/plugins:${PYTHONPATH}
 export LD_LIBRARY_PATH=${NEWGEOM_ROOT_DIR}/bin:${NEWGEOM_ROOT_DIR}/swig:${NEWGEOM_ROOT_DIR}/plugins:${LD_LIBRARY_PATH}
 export NEW_GEOM_CONFIG_FILE=${NEWGEOM_ROOT_DIR}/plugins
 export NewGeomResources=${NEWGEOM_ROOT_DIR}/resources
index fd95eec285a538e75f5617ef4b89b038abfe5b91..f4964d4623d807349980704af58ea99db4aa8f58 100644 (file)
@@ -127,7 +127,7 @@ set PATH=%CMAKEDIR%\bin;%PATH%
 
 @SET NEW_GEOM_CONFIG_FILE=%ROOT_DIR%\install\plugins
 @SET PATH=%ROOT_DIR%\install\plugins;%ROOT_DIR%\install\bin;%PATH%
-@SET PYTHONPATH=%ROOT_DIR%\install\swig;%PYTHONPATH%
+@SET PYTHONPATH=%ROOT_DIR%\install\swig;%ROOT_DIR%\install\plugins;%PYTHONPATH%
 
 @REM -------------------------
 @REM PTHREAD
index 1be2129eda6bd0aa1a893354a57cdb5394800c6a..3ab03ef187af0a185f904d3009d35c13d4cb4501 100644 (file)
@@ -1,7 +1,8 @@
 INCLUDE(Common)
 INCLUDE(XMLProcessing)
 
-INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/src/Events) 
+INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/src/Events
+                     ${PYTHON_INCLUDE_DIRS}) 
 
 SET(PROJECT_HEADERS
   Config_def.h
@@ -40,6 +41,7 @@ SET(XML_RESOURCES
 SET(PROJECT_LIBRARIES
     Events
     ${LIBXML2_LIBRARIES}
+    ${PYTHON_LIBRARIES}
 )
 
 SOURCE_GROUP ("Resource Files" FILES ${XML_RESOURCES})
index 46338306b780427c9477f28978e747a0769b3621..cd16caf3f91742ced826d16b3ae6355c474a4f6c 100644 (file)
@@ -78,11 +78,14 @@ const static char* CONTAINER_PAGE_NAME = "title";
 /*
  * Hardcoded xml entities of plugins.xml
  */
+
+const static char* PLUGIN_FILE = "plugins.xml";
 const static char* NODE_PLUGIN = "plugin";
 const static char* NODE_PLUGINS = "plugins";
 
 const static char* PLUGINS_MODULE = "module";
 const static char* PLUGIN_CONFIG = "configuration";
 const static char* PLUGIN_LIBRARY = "library";
+const static char* PLUGIN_SCRIPT = "script";
 
 #endif /* CONFIG_KEYWORDS_H_ */
index f2fcda4b717278ae83d5787a0d497623b47bcb95..5fec456ad65d6b8a887af6500a85a2ead56ed5da 100644 (file)
@@ -14,6 +14,8 @@
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 
+#include <Python.h>
+
 //Necessary for cerr
 #include <iostream>
 
 #include <dlfcn.h>
 #endif
 
+std::map<std::string, Config_ModuleReader::PluginType> Config_ModuleReader::myPluginTypes;
+
 Config_ModuleReader::Config_ModuleReader(const char* theEventGenerated)
-    : Config_XMLReader("plugins.xml"),
+    : Config_XMLReader(PLUGIN_FILE),
       myEventGenerated(theEventGenerated)
 {
 }
@@ -56,7 +60,10 @@ void Config_ModuleReader::processNode(xmlNodePtr theNode)
   if (isNode(theNode, NODE_PLUGIN, NULL)) {
     std::string aPluginConf = getProperty(theNode, PLUGIN_CONFIG);
     std::string aPluginLibrary = getProperty(theNode, PLUGIN_LIBRARY);
-    std::list<std::string> aFeatures = importPlugin(aPluginLibrary, aPluginConf);
+    std::string aPluginScript = getProperty(theNode, PLUGIN_SCRIPT);
+    std::string aPluginName = addPlugin(aPluginLibrary, aPluginScript, aPluginConf);
+
+    std::list<std::string> aFeatures = importPlugin(aPluginName, aPluginConf);
     std::list<std::string>::iterator it = aFeatures.begin();
     for (; it != aFeatures.end(); it++) {
       myFeaturesInFiles[*it] = aPluginConf;
@@ -70,19 +77,74 @@ bool Config_ModuleReader::processChildren(xmlNodePtr theNode)
 }
 
 std::list<std::string> Config_ModuleReader::importPlugin(const std::string& thePluginLibrary,
-                                                         const std::string& thePluginFile)
+                                                         const std::string& thePluginXmlConf)
 {
-  if (thePluginFile.empty()) {  //probably a third party library
+  if (thePluginXmlConf.empty()) {  //probably a third party library
     loadLibrary(thePluginLibrary);
     return std::list<std::string>();
   }
 
-  Config_FeatureReader aReader = Config_FeatureReader(thePluginFile, thePluginLibrary,
+  Config_FeatureReader aReader = Config_FeatureReader(thePluginXmlConf,
+                                                      thePluginLibrary,
                                                       myEventGenerated);
   aReader.readAll();
   return aReader.features();
 }
 
+std::string Config_ModuleReader::addPlugin(const std::string& aPluginLibrary,
+                                           const std::string& aPluginScript,
+                                           const std::string& aPluginConf)
+{
+  PluginType aType = PluginType::Binary;
+  std::string aPluginName;
+  if (!aPluginLibrary.empty()) {
+    aPluginName = aPluginLibrary;
+    if (aPluginConf.empty()) {
+      aType = PluginType::Intrenal;
+    }
+  } else if (!aPluginScript.empty()) {
+    aPluginName = aPluginScript;
+    aType = PluginType::Python;
+  }
+  if(!aPluginName.empty()) {
+    myPluginTypes[aPluginName] = aType;
+
+  }
+  return aPluginName;
+}
+
+void Config_ModuleReader::loadPlugin(const std::string thePluginName)
+{
+  PluginType aType = PluginType::Binary;
+  if(myPluginTypes.find(thePluginName) != myPluginTypes.end()) {
+    aType = myPluginTypes.at(thePluginName);
+  }
+  switch (aType) {
+    case PluginType::Python:
+      loadScript(thePluginName);
+      break;
+    case PluginType::Binary:
+    case PluginType::Intrenal:
+    default:
+      loadLibrary(thePluginName);
+      break;
+  }
+}
+
+void Config_ModuleReader::loadScript(const std::string theFileName)
+{
+  std::string aPythonFile = theFileName + ".py";
+  PyGILState_STATE gstate;
+
+  /* aquire python thread */
+  gstate = PyGILState_Ensure();
+
+  PyObject* module = PyImport_ImportModule(aPythonFile.c_str());
+
+  /* release python thread */
+  PyGILState_Release(gstate);
+}
+
 void Config_ModuleReader::loadLibrary(const std::string theLibName)
 {
   std::string aFileName = library(theLibName);
@@ -91,16 +153,15 @@ void Config_ModuleReader::loadLibrary(const std::string theLibName)
 
 #ifdef WIN32
   HINSTANCE aModLib = ::LoadLibrary(aFileName.c_str());
-  if (!aModLib && theLibName != "DFBrowser") {  // don't shor error for internal debugging tool
-    std::string errorMsg = "Failed to load " + aFileName;
-    std::cerr << errorMsg << std::endl;
-    Events_Error::send(errorMsg);
-  }
 #else
   void* aModLib = dlopen( aFileName.c_str(), RTLD_LAZY | RTLD_GLOBAL );
-  if ( !aModLib && theLibName != "DFBrowser") {  // don't shor error for internal debugging tool
-    std::cerr << "Failed to load " << aFileName.c_str() << std::endl;
-  }
 #endif
+  if(!aModLib && theLibName != "DFBrowser") { // don't show error for internal debugging tool
+    std::string anErrorMsg = "Failed to load " + aFileName;
+    #ifndef WIN32
+    anErrorMsg += ": " + std::string(dlerror());
+    #endif
+    Events_Error::send(anErrorMsg);
+  }
 }
 
index 18962f3488b9dbc03f7c41173fa143052e43946b..137afbeaeaa67f03d1667ebd8e9762613e156226 100644 (file)
 
 class Config_ModuleReader : public Config_XMLReader
 {
+  enum PluginType {
+    Binary = 0,
+    Intrenal = 1,
+    Python = 2
+  };
 
  public:
-  CONFIG_EXPORT Config_ModuleReader(const char* theEventGenerated = 0);CONFIG_EXPORT virtual ~Config_ModuleReader();
+  CONFIG_EXPORT Config_ModuleReader(const char* theEventGenerated = 0);
+  CONFIG_EXPORT virtual ~Config_ModuleReader();
 
   CONFIG_EXPORT const std::map<std::string, std::string>& featuresInFiles() const;
 
   CONFIG_EXPORT std::string getModuleName();
 
+  CONFIG_EXPORT static void loadPlugin(const std::string thePluginName);
   /// loads the library with specific name, appends "lib*.dll" or "*.so" depending on the platform
   CONFIG_EXPORT static void loadLibrary(const std::string theLibName);
+  /// loads the python module with specified name
+  CONFIG_EXPORT static void loadScript(const std::string theFileName);
 
  protected:
   void processNode(xmlNodePtr aNode);
@@ -34,9 +43,13 @@ class Config_ModuleReader : public Config_XMLReader
 
   std::list<std::string> importPlugin(const std::string& thePluginLibrary,
                                       const std::string& thePluginFile);
+  std::string addPlugin(const std::string& aPluginLibrary,
+                        const std::string& aPluginScript,
+                        const std::string& aPluginConf);
 
  private:
   std::map<std::string, std::string> myFeaturesInFiles;
+  static std::map<std::string, PluginType> myPluginTypes;
   const char* myEventGenerated;
 
 };
index 9ae5ca51f6a9584d5797ac2e26dc4b8beb658033..474b0ba07def5ac985f424b14efbaefc4d0094ec 100644 (file)
@@ -3,9 +3,9 @@
   <plugin library="SketchPlugin" configuration="plugin-Sketch.xml"/>
   <plugin library="ConstructionPlugin" configuration="plugin-Construction.xml"/>
   <plugin library="FeaturesPlugin" configuration="plugin-Features.xml"/>
-  <plugin library="PythonFeaturesPlugin" configuration="plugin-PythonFeatures.xml"/>
   <plugin library="ExchangePlugin" configuration="plugin-Exchange.xml"/>
+  <plugin script="PythonFeaturesPlugin" configuration="plugin-PythonFeatures.xml"/>
   <plugin library="SketchSolver"/>
   <plugin library="GeomValidators"/>
-  <plugin library="DFBrowser"/>
+  <plugin library="DFBrowser" internal="true"/>
 </plugins>
index 2718fa98007c81bd5db0b61caf66488bbcedebf1..c49ab5a06b3f543b9d1a61412e4e9e000c9e88c2 100644 (file)
@@ -58,7 +58,7 @@ SET(PROJECT_LIBRARIES
 ADD_DEFINITIONS(-DGEOMAPI_EXPORTS ${CAS_DEFINITIONS})
 ADD_LIBRARY(GeomAPI SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS})
 
-SET(CMAKE_SWIG_FLAGS "")
+SET(CMAKE_SWIG_FLAGS "-Wall")
 
 SET_SOURCE_FILES_PROPERTIES(GeomAPI.i PROPERTIES CPLUSPLUS ON)
 SET_SOURCE_FILES_PROPERTIES(GeomAPI.i PROPERTIES SWIG_DEFINITIONS "-shadow")
index 5656a0ad8a5e0227eaa10d12050708099e3a7f12..ef36a838e3b4c70ff2ab0ab5ad9f4f7962132227 100644 (file)
@@ -41,7 +41,7 @@ SET(PROJECT_LIBRARIES
 ADD_DEFINITIONS(-DGEOMALGOAPI_EXPORTS ${CAS_DEFINITIONS})
 ADD_LIBRARY(GeomAlgoAPI SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS})
 
-SET(CMAKE_SWIG_FLAGS "")
+SET(CMAKE_SWIG_FLAGS "-Wall")
 
 SET_SOURCE_FILES_PROPERTIES(GeomAlgoAPI.i PROPERTIES CPLUSPLUS ON)
 SET_SOURCE_FILES_PROPERTIES(GeomAlgoAPI.i PROPERTIES SWIG_DEFINITIONS "-shadow")
index d956835d1a388204c223cbd41387214ea46e8623..b9e1488b7ffda88869b9855292b5276310b8fbe6 100644 (file)
@@ -10,7 +10,7 @@ SET(PROJECT_HEADERS
     GeomDataAPI_Point2D.h
 )
 
-SET(CMAKE_SWIG_FLAGS "")
+SET(CMAKE_SWIG_FLAGS "-Wall")
 
 SET_SOURCE_FILES_PROPERTIES(GeomDataAPI.i PROPERTIES CPLUSPLUS ON)
 SET_SOURCE_FILES_PROPERTIES(GeomDataAPI.i PROPERTIES SWIG_DEFINITIONS "-shadow")
index a42eb204696b7283251aae226a13b145bf6cc8e0..921017d11f25abde11e3b8a227261c17a7152a95 100644 (file)
@@ -21,9 +21,6 @@
 #include <TDF_RelocationTable.hxx>
 #include <TDF_ClosureTool.hxx>
 
-// TEST
-#include <Python.h>
-
 using namespace std;
 
 static Model_Session* myImpl = new Model_Session();
@@ -110,14 +107,7 @@ FeaturePtr Model_Session::createFeature(string theFeatureID)
     myCurrentPluginName = aPlugin.first;
     if (myPluginObjs.find(myCurrentPluginName) == myPluginObjs.end()) {
       // load plugin library if not yet done
-      //TODO: Get info from Config about python libraries
-      if (myCurrentPluginName.compare(string("PythonFeaturesPlugin")) == 0) {
-        Py_Initialize();
-        PyObject* module = PyImport_ImportModule(myCurrentPluginName.c_str());
-        assert(module != NULL);
-      } else {
-        Config_ModuleReader::loadLibrary(myCurrentPluginName);
-      }
+      Config_ModuleReader::loadPlugin(myCurrentPluginName);
     }
     if (myPluginObjs.find(myCurrentPluginName) != myPluginObjs.end()) {
       FeaturePtr aCreated = myPluginObjs[myCurrentPluginName]->createFeature(theFeatureID);
index 0bfa08a58c57ad2e1486feafaa3df577f0cb887a..8dff4fb3ff564001a1272210c1950f09a6028002 100644 (file)
@@ -59,7 +59,7 @@ INCLUDE_DIRECTORIES(
   ../GeomAlgoAPI
 )
 
-SET(CMAKE_SWIG_FLAGS "")
+SET(CMAKE_SWIG_FLAGS "-Wall")
 
 SET_SOURCE_FILES_PROPERTIES(ModelAPI.i PROPERTIES CPLUSPLUS ON)
 # "-includeall" is not needed: it starts to follow the standard inludes (like "string") without success
index e7ecbed9b54758c10395535b35147c378e4a73f3..711c77aacf038b46394428768ea01ca433590f0b 100644 (file)
 %include "std_string.i"
 %include "std_list.i"
 
+// directors
+%feature("director") ModelAPI_Plugin;
+// %feature("director") ModelAPI_Object;
+// %feature("director") ModelAPI_Feature;
+// %feature("director") ModelAPI_CompositeFeature;
+
 // boost pointers
 %include <boost_shared_ptr.i>
 // For ModelAPI_ResultConstruction.shape()
@@ -72,7 +78,6 @@
 %shared_ptr(ModelAPI_ResultConstruction)
 %shared_ptr(ModelAPI_ResultBody)
 %shared_ptr(ModelAPI_ResultPart)
-%feature("director") ModelAPI_Plugin;
 
 // all supported interfaces
 %include "GeomAPI_Interface.h"
@@ -80,6 +85,7 @@
 %include "ModelAPI_Document.h"
 %include "ModelAPI_Session.h"
 %include "ModelAPI_Object.h"
+// %nodefaultctor ModelAPI_Plugin;
 %include "ModelAPI_Plugin.h"
 %include "ModelAPI_Feature.h"
 %include "ModelAPI_CompositeFeature.h"
index 5222b4c7b5edcd23582cdffbd6933428784cb4a7..87406b422a8c8e6642c72dce37f8a394abf0acf2 100644 (file)
@@ -32,7 +32,6 @@ class MODELAPI_EXPORT ModelAPI_Plugin
   ModelAPI_Plugin()
   {
   }
-  ;
 };
 
 #endif
index e7a28080540a8284c36a9fbb433693512607cb86..dc4219d11d91cf038268998b30f87653127fa066 100644 (file)
@@ -1,9 +1,10 @@
-from ModelAPI import *
-import PythonFeaturesPlugin_Box
+import ModelAPI
+from PythonFeaturesPlugin_Box import PythonFeaturesPlugin_Box
 
-class PythonFeaturesPlugin(ModelAPI_Plugin):
+class PythonFeaturesPlugin(ModelAPI.ModelAPI_Plugin):
+  
   def __init__(self):
-    ModelAPI_Plugin.__init__(self)
+    ModelAPI.ModelAPI_Plugin.__init__(self)
     pass
 
   def createFeature(self, theFeatureID):
@@ -13,5 +14,6 @@ class PythonFeaturesPlugin(ModelAPI_Plugin):
       raise StandardError("No such feature %s"%theFeatureID)
 
 plugin = PythonFeaturesPlugin()
-ModelAPI_Session_get().registerPlugin(plugin)
-
+aSession = ModelAPI.ModelAPI_Session.get()
+print "Module loaded. Session", aSession
+aSession.registerPlugin(plugin)
index 800fbbeb8edcf16418e88a73e4b03ec714492eb0..e67278b2204b68547fdc441482813d312fe52b9b 100644 (file)
@@ -5,27 +5,31 @@ class PythonFeaturesPlugin_Box(ModelAPI_Feature):
   def __init__(self):
     pass
 
-  def ID(self):
+  @staticmethod
+  def ID():
     return "Box"
 
-  def WIDTH_ID(self):
+  @staticmethod
+  def WIDTH_ID():
     return "box_width"
   
-  def LENGTH_ID(self):
+  @staticmethod
+  def LENGTH_ID():
     return "box_length"
   
-  def HEIGHT_ID(self):
+  @staticmethod
+  def HEIGHT_ID():
     return "box_height"
 
   def initAttributes(self):
-    self.data().addAttribute(self.WIDTH_ID(), ModelAPI_AttributeDouble.type())
-    self.data().addAttribute(self.LENGTH_ID(), ModelAPI_AttributeDouble.type())
-    self.data().addAttribute(self.HEIGHT_ID(), ModelAPI_AttributeDouble.type())
+    self.data().addAttribute(PythonFeaturesPlugin_Box.WIDTH_ID(), ModelAPI_AttributeDouble.type())
+    self.data().addAttribute(PythonFeaturesPlugin_Box.LENGTH_ID(), ModelAPI_AttributeDouble.type())
+    self.data().addAttribute(PythonFeaturesPlugin_Box.HEIGHT_ID(), ModelAPI_AttributeDouble.type())
 
   def execute(self):
-    aWidth  = self.data().attribute(self.WIDTH_ID()).value()
-    aLength = self.data().attribute(self.LENGTH_ID()).value()
-    aHeight = self.data().attribute(self.HEIGHT_ID()).value()
+    aWidth  = self.attribute(PythonFeaturesPlugin_Box.WIDTH_ID()).value()
+    aLength = self.attribute(PythonFeaturesPlugin_Box.LENGTH_ID()).value()
+    aHeight = self.attribute(PythonFeaturesPlugin_Box.HEIGHT_ID()).value()
 
     aResult = document().createBody(data())
     #aResult.store(UserPackage.makeBox(aLength, aWidth, aHeight)