From 5081522522ff18e59ed3cb00a5057e7bf65edbb3 Mon Sep 17 00:00:00 2001 From: Nicolas RECHATIN Date: Tue, 27 Jul 2021 16:06:09 +0200 Subject: [PATCH] Add new Feature Volume for OPERA --- CMakeLists.txt | 2 + src/CTestTestfileInstall.cmake | 1 + src/Config/plugins.xml.in | 1 + src/OperaAPI/CMakeLists.txt | 88 ++++++++++++++ src/OperaAPI/OperaAPI.h | 37 ++++++ src/OperaAPI/OperaAPI.i | 44 +++++++ src/OperaAPI/OperaAPI_Volume.cpp | 84 +++++++++++++ src/OperaAPI/OperaAPI_Volume.h | 80 +++++++++++++ src/OperaAPI/OperaAPI_swig.h | 28 +++++ src/OperaPlugin/CMakeLists.txt | 87 ++++++++++++++ src/OperaPlugin/CTestTestfileInstall.cmake | 29 +++++ src/OperaPlugin/OperaPlugin.h | 37 ++++++ src/OperaPlugin/OperaPlugin_Plugin.cpp | 43 +++++++ src/OperaPlugin/OperaPlugin_Plugin.h | 43 +++++++ src/OperaPlugin/OperaPlugin_Volume.cpp | 117 +++++++++++++++++++ src/OperaPlugin/OperaPlugin_Volume.h | 74 ++++++++++++ src/OperaPlugin/OperaPlugin_msg_fr.ts | 57 +++++++++ src/OperaPlugin/Test/TestVolume.py | 82 +++++++++++++ src/OperaPlugin/doc/OperaPlugin.rst | 13 +++ src/OperaPlugin/doc/TUI_volume.rst | 11 ++ src/OperaPlugin/doc/examples/volume.py | 12 ++ src/OperaPlugin/doc/images/Volume.png | Bin 0 -> 5741 bytes src/OperaPlugin/doc/images/Volume1.png | Bin 0 -> 4249 bytes src/OperaPlugin/doc/images/Volume_button.png | Bin 0 -> 13208 bytes src/OperaPlugin/doc/volumeFeature.rst | 43 +++++++ src/OperaPlugin/icons/Volume.png | Bin 0 -> 7075 bytes src/OperaPlugin/plugin-Opera.xml | 14 +++ src/OperaPlugin/tests.set | 22 ++++ src/OperaPlugin/volume_widget.xml | 13 +++ src/PythonAPI/Test/TestFeatures.py | 3 + src/PythonAPI/model/__init__.py | 1 + src/PythonAPI/model/opera/__init__.py | 22 ++++ src/SHAPERGUI/resources/LightApp.xml.in | 3 + 33 files changed, 1091 insertions(+) create mode 100644 src/OperaAPI/CMakeLists.txt create mode 100644 src/OperaAPI/OperaAPI.h create mode 100644 src/OperaAPI/OperaAPI.i create mode 100644 src/OperaAPI/OperaAPI_Volume.cpp create mode 100644 src/OperaAPI/OperaAPI_Volume.h create mode 100644 src/OperaAPI/OperaAPI_swig.h create mode 100644 src/OperaPlugin/CMakeLists.txt create mode 100644 src/OperaPlugin/CTestTestfileInstall.cmake create mode 100644 src/OperaPlugin/OperaPlugin.h create mode 100644 src/OperaPlugin/OperaPlugin_Plugin.cpp create mode 100644 src/OperaPlugin/OperaPlugin_Plugin.h create mode 100644 src/OperaPlugin/OperaPlugin_Volume.cpp create mode 100644 src/OperaPlugin/OperaPlugin_Volume.h create mode 100644 src/OperaPlugin/OperaPlugin_msg_fr.ts create mode 100755 src/OperaPlugin/Test/TestVolume.py create mode 100644 src/OperaPlugin/doc/OperaPlugin.rst create mode 100644 src/OperaPlugin/doc/TUI_volume.rst create mode 100644 src/OperaPlugin/doc/examples/volume.py create mode 100644 src/OperaPlugin/doc/images/Volume.png create mode 100644 src/OperaPlugin/doc/images/Volume1.png create mode 100644 src/OperaPlugin/doc/images/Volume_button.png create mode 100644 src/OperaPlugin/doc/volumeFeature.rst create mode 100644 src/OperaPlugin/icons/Volume.png create mode 100644 src/OperaPlugin/plugin-Opera.xml create mode 100644 src/OperaPlugin/tests.set create mode 100644 src/OperaPlugin/volume_widget.xml create mode 100644 src/PythonAPI/model/opera/__init__.py diff --git a/CMakeLists.txt b/CMakeLists.txt index c566338c3..0e36ac329 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -168,6 +168,7 @@ ADD_SUBDIRECTORY (src/PartSetPlugin) ADD_SUBDIRECTORY (src/ConstructionPlugin) ADD_SUBDIRECTORY (src/BuildPlugin) ADD_SUBDIRECTORY (src/PrimitivesPlugin) +ADD_SUBDIRECTORY (src/OperaPlugin) ADD_SUBDIRECTORY (src/GDMLPlugin) ADD_SUBDIRECTORY (src/FeaturesPlugin) ADD_SUBDIRECTORY (src/CollectionPlugin) @@ -196,6 +197,7 @@ ADD_SUBDIRECTORY (src/CollectionAPI) ADD_SUBDIRECTORY (src/ParametersAPI) ADD_SUBDIRECTORY (src/PartSetAPI) ADD_SUBDIRECTORY (src/PrimitivesAPI) +ADD_SUBDIRECTORY (src/OperaAPI) ADD_SUBDIRECTORY (src/SketchAPI) ADD_SUBDIRECTORY (src/GDMLAPI) ADD_SUBDIRECTORY (src/ConnectorAPI) diff --git a/src/CTestTestfileInstall.cmake b/src/CTestTestfileInstall.cmake index b52f407b3..daabb1b56 100644 --- a/src/CTestTestfileInstall.cmake +++ b/src/CTestTestfileInstall.cmake @@ -47,4 +47,5 @@ SUBDIRS(ConnectorAPI ModelGeomAlgo Locale test_API + OperaPlugin ) diff --git a/src/Config/plugins.xml.in b/src/Config/plugins.xml.in index 7c23b377e..a9e6b148f 100644 --- a/src/Config/plugins.xml.in +++ b/src/Config/plugins.xml.in @@ -6,6 +6,7 @@ + diff --git a/src/OperaAPI/CMakeLists.txt b/src/OperaAPI/CMakeLists.txt new file mode 100644 index 000000000..a9da8f181 --- /dev/null +++ b/src/OperaAPI/CMakeLists.txt @@ -0,0 +1,88 @@ +# Copyright (C) 2014-2021 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(Common) + +SET(PROJECT_HEADERS + OperaAPI.h + OperaAPI_Volume.h +) + +SET(PROJECT_SOURCES + OperaAPI_Volume.cpp +) + +SET(PROJECT_LIBRARIES + ModelAPI + ModelHighAPI +) + +INCLUDE_DIRECTORIES( + ${PROJECT_SOURCE_DIR}/src/Events + ${PROJECT_SOURCE_DIR}/src/ModelAPI + ${PROJECT_SOURCE_DIR}/src/ModelHighAPI +) + +# Plugin headers dependency +INCLUDE_DIRECTORIES( + ${PROJECT_SOURCE_DIR}/src/GeomAPI + ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI + ${PROJECT_SOURCE_DIR}/src/GeomDataAPI + ${PROJECT_SOURCE_DIR}/src/OperaPlugin +) + +ADD_DEFINITIONS(-DOperaAPI_EXPORTS ${OpenCASCADE_DEFINITIONS}) +ADD_LIBRARY(OperaAPI SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS}) +TARGET_LINK_LIBRARIES(OperaAPI ${PROJECT_LIBRARIES}) + +# SWIG wrapper + +INCLUDE(PythonAPI) + +SET_SOURCE_FILES_PROPERTIES(OperaAPI.i PROPERTIES CPLUSPLUS ON) +SET_SOURCE_FILES_PROPERTIES(OperaAPI.i PROPERTIES SWIG_DEFINITIONS "-shadow") + +SET(SWIG_LINK_LIBRARIES + OperaAPI + ModelHighAPI + ModelAPI + ${PYTHON_LIBRARIES} +) +SET(CMAKE_SWIG_FLAGS -threads -w325,321,302,362,322,383,403) + +SET(SWIG_MODULE_OperaAPI_EXTRA_DEPS ${SWIG_MODULE_OperaAPI_EXTRA_DEPS} + ${PROJECT_SOURCE_DIR}/src/ModelHighAPI/ModelHighAPI.i + doxyhelp.i + ${PROJECT_HEADERS} +) + +IF(${CMAKE_VERSION} VERSION_GREATER "3.8.0") + SWIG_ADD_LIBRARY(OperaAPI LANGUAGE python SOURCES OperaAPI.i ${PROJECT_HEADERS}) +ELSE() + SWIG_ADD_MODULE(OperaAPI python OperaAPI.i ${PROJECT_HEADERS}) +ENDIF() +SWIG_LINK_LIBRARIES(OperaAPI ${SWIG_LINK_LIBRARIES}) + +IF(WIN32) + SET_TARGET_PROPERTIES(_OperaAPI PROPERTIES DEBUG_OUTPUT_NAME _OperaAPI_d) +ENDIF(WIN32) + +INSTALL(TARGETS _OperaAPI DESTINATION ${SHAPER_INSTALL_SWIG}) +INSTALL(TARGETS OperaAPI DESTINATION ${SHAPER_INSTALL_BIN}) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/OperaAPI.py DESTINATION ${SHAPER_INSTALL_SWIG}) diff --git a/src/OperaAPI/OperaAPI.h b/src/OperaAPI/OperaAPI.h new file mode 100644 index 000000000..8a1808b1e --- /dev/null +++ b/src/OperaAPI/OperaAPI.h @@ -0,0 +1,37 @@ +// Copyright (C) 2014-2021 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 OPERAAPI_H +#define OPERAAPI_H + +#if defined OPERAAPI_EXPORTS +#if defined WIN32 +#define OPERAAPI_EXPORT __declspec( dllexport ) +#else +#define OPERAAPI_EXPORT +#endif +#else +#if defined WIN32 +#define OPERAAPI_EXPORT __declspec( dllimport ) +#else +#define OPERAAPI_EXPORT +#endif +#endif + +#endif //OPERAAPI_H diff --git a/src/OperaAPI/OperaAPI.i b/src/OperaAPI/OperaAPI.i new file mode 100644 index 000000000..6bbadc525 --- /dev/null +++ b/src/OperaAPI/OperaAPI.i @@ -0,0 +1,44 @@ +// Copyright (C) 2014-2021 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 +// + +/* OperaAPI.i */ + +%module OperaAPI + +%{ + #include "OperaAPI_swig.h" +%} + +%include "doxyhelp.i" + +// import other modules +%import "ModelHighAPI.i" + +// to avoid error on this +#define OPERAAPI_EXPORT + +// standard definitions +%include "typemaps.i" +%include "std_shared_ptr.i" + +// shared pointers +%shared_ptr(OperaAPI_Volume) + +// all supported interfaces +%include "OperaAPI_Volume.h" diff --git a/src/OperaAPI/OperaAPI_Volume.cpp b/src/OperaAPI/OperaAPI_Volume.cpp new file mode 100644 index 000000000..cf7dd40c9 --- /dev/null +++ b/src/OperaAPI/OperaAPI_Volume.cpp @@ -0,0 +1,84 @@ +// Copyright (C) 2014-2021 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 "OperaAPI_Volume.h" + +#include +#include + +//================================================================================================== +OperaAPI_Volume::OperaAPI_Volume(const std::shared_ptr& theFeature) +: ModelHighAPI_Interface(theFeature) +{ + initialize(); +} + + +//================================================================================================== +OperaAPI_Volume::OperaAPI_Volume(const std::shared_ptr& theFeature, + const std::string& theMedium, + const std::list& theObjectsList) +: ModelHighAPI_Interface(theFeature) +{ + if(initialize()) { + fillAttribute(theMedium, medium()); + setObjectsList(theObjectsList); + } +} + +//================================================================================================== +OperaAPI_Volume::~OperaAPI_Volume() +{ +} + +//================================================================================================== +void OperaAPI_Volume::setMedium(const std::string& theMedium) +{ + fillAttribute(theMedium, medium()); + execute(); +} + +//================================================================================================== +void OperaAPI_Volume::setObjectsList(const std::list& theObjectsList) +{ + fillAttribute(theObjectsList, objectsList()); + execute(); +} + +//================================================================================================== +void OperaAPI_Volume::dump(ModelHighAPI_Dumper& theDumper) const +{ + FeaturePtr aBase = feature(); + const std::string& aDocName = theDumper.name(aBase->document()); + + AttributeStringPtr anAttrMedium = aBase->string(OperaPlugin_Volume::MEDIUM_ID()); + theDumper << aBase << " = model.addVolume(" << aDocName << ", " << anAttrMedium << ", "; + + AttributeSelectionListPtr anAttrList = + aBase->selectionList(OperaPlugin_Volume::OBJECTS_LIST_ID()); + theDumper << anAttrList << ")" << std::endl; +} + +//================================================================================================== +VolumePtr addVolume(const std::shared_ptr& thePart, + const std::string& theMedium, + const std::list& theObjectsList) +{ + std::shared_ptr aFeature = thePart->addFeature(OperaAPI_Volume::ID()); + return VolumePtr(new OperaAPI_Volume(aFeature, theMedium, theObjectsList)); +} diff --git a/src/OperaAPI/OperaAPI_Volume.h b/src/OperaAPI/OperaAPI_Volume.h new file mode 100644 index 000000000..78aca0374 --- /dev/null +++ b/src/OperaAPI/OperaAPI_Volume.h @@ -0,0 +1,80 @@ +// Copyright (C) 2014-2021 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 OPERAAPI_VOLUME_H_ +#define OPERAAPI_VOLUME_H_ + +#include "OperaAPI.h" +#include + +#include +#include + +class ModelHighAPI_Selection; + +/// \class OperaAPI_Volume +/// \ingroup CPPHighAPI +/// \brief Interface for Volume feature. +class OperaAPI_Volume: public ModelHighAPI_Interface +{ +public: + /// Constructor without values. + OPERAAPI_EXPORT + explicit OperaAPI_Volume(const std::shared_ptr& theFeature); + + /// Constructor with values. + OPERAAPI_EXPORT + explicit OperaAPI_Volume(const std::shared_ptr& theFeature, + const std::string& theMedium, + const std::list& theObjectList); + + /// Destructor. + OPERAAPI_EXPORT + virtual ~OperaAPI_Volume(); + + INTERFACE_2(OperaPlugin_Volume::ID(), + medium, OperaPlugin_Volume::MEDIUM_ID(), + ModelAPI_AttributeString, /** Medium */, + objectsList, OperaPlugin_Volume::OBJECTS_LIST_ID(), + ModelAPI_AttributeSelectionList, /** Objects list*/) + + /// Set medium + OPERAAPI_EXPORT + void setMedium(const std::string& theMedium); + + /// Set main objects list. + OPERAAPI_EXPORT + void setObjectsList(const std::list& theObjectsList); + + /// Dump wrapped feature + OPERAAPI_EXPORT + virtual void dump(ModelHighAPI_Dumper& theDumper) const; +}; + +/// Pointer Volume feature +typedef std::shared_ptr VolumePtr; + +/// \ingroup CPPHighAPI +/// \brief Create Volume feature. +OPERAAPI_EXPORT +VolumePtr addVolume(const std::shared_ptr& thePart, + const std::string& theMedium, + const std::list& theObjectsList); + +#endif // OPERAAPI_VOLUME_H_ diff --git a/src/OperaAPI/OperaAPI_swig.h b/src/OperaAPI/OperaAPI_swig.h new file mode 100644 index 000000000..eaa088dc9 --- /dev/null +++ b/src/OperaAPI/OperaAPI_swig.h @@ -0,0 +1,28 @@ +// Copyright (C) 2014-2021 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 OPERAAPI_SWIG_H_ +#define OPERAAPI_SWIG_H_ + + #include + + #include "OperaAPI.h" + #include "OperaAPI_Volume.h" + +#endif // OPERAAPI_SWIG_H_ diff --git a/src/OperaPlugin/CMakeLists.txt b/src/OperaPlugin/CMakeLists.txt new file mode 100644 index 000000000..a1f7fd600 --- /dev/null +++ b/src/OperaPlugin/CMakeLists.txt @@ -0,0 +1,87 @@ +# Copyright (C) 2014-2021 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 +# + +SET(PROJECT_HEADERS + OperaPlugin.h + OperaPlugin_Plugin.h + OperaPlugin_Volume.h +) + +SET(PROJECT_SOURCES + OperaPlugin_Plugin.cpp + OperaPlugin_Volume.cpp + +) + +SET(XML_RESOURCES + plugin-Opera.xml + volume_widget.xml +) + +SET(TEXT_RESOURCES + OperaPlugin_msg_fr.ts +) + +SOURCE_GROUP ("XML Files" FILES ${XML_RESOURCES}) +SOURCE_GROUP ("Resource Files" FILES ${TEXT_RESOURCES}) + +INCLUDE_DIRECTORIES( + ../ModelAPI + ../GeomAPI + ../GeomAlgoAPI + ../Events +) + +SET(PROJECT_LIBRARIES + Events + ModelAPI + GeomAPI + GeomAlgoAPI +) + +ADD_DEFINITIONS(-DOPERAPLUGIN_EXPORTS) +ADD_LIBRARY(OperaPlugin MODULE ${PROJECT_SOURCES} ${PROJECT_HEADERS} ${XML_RESOURCES} ${TEXT_RESOURCES}) +TARGET_LINK_LIBRARIES(OperaPlugin ${PROJECT_LIBRARIES}) + +INSTALL(TARGETS OperaPlugin DESTINATION ${SHAPER_INSTALL_PLUGIN_FILES}) +INSTALL(FILES ${XML_RESOURCES} ${TEXT_RESOURCES} DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}) +INSTALL(DIRECTORY icons/ DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}/icons/Opera) + +include(tests.set) + +ADD_UNIT_TESTS(${TEST_NAMES}) + +if(${HAVE_SALOME}) + enable_testing() + set(TEST_INSTALL_DIRECTORY "${SALOME_SHAPER_INSTALL_TESTS}/OperaPlugin") + + install(FILES CTestTestfileInstall.cmake + DESTINATION ${TEST_INSTALL_DIRECTORY} + RENAME CTestTestfile.cmake) + install(FILES tests.set DESTINATION ${TEST_INSTALL_DIRECTORY}) + + set(TMP_TESTS_NAMES) + foreach(tfile ${TEST_NAMES}) + list(APPEND TMP_TESTS_NAMES "Test/${tfile}") + endforeach(tfile ${TEST_NAMES}) + + install(FILES ${TMP_TESTS_NAMES} DESTINATION ${TEST_INSTALL_DIRECTORY}) +endif(${HAVE_SALOME}) + + diff --git a/src/OperaPlugin/CTestTestfileInstall.cmake b/src/OperaPlugin/CTestTestfileInstall.cmake new file mode 100644 index 000000000..42056d5fe --- /dev/null +++ b/src/OperaPlugin/CTestTestfileInstall.cmake @@ -0,0 +1,29 @@ +# Copyright (C) 2021 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(tests.set) + +#SET(SALOME_TEST_DRIVER "$ENV{KERNEL_ROOT_DIR}/bin/salome/appliskel/salome_test_driver.py") +#SET(TIMEOUT 300) + +foreach(tfile ${TEST_NAMES}) + set(TEST_NAME ${COMPONENT_NAME}_${tfile}) + add_test(${TEST_NAME} python ${tfile}) + set_tests_properties(${TEST_NAME} PROPERTIES LABELS "${SALOME_TEST_LABEL_ADV}") +endforeach() diff --git a/src/OperaPlugin/OperaPlugin.h b/src/OperaPlugin/OperaPlugin.h new file mode 100644 index 000000000..85a17bfac --- /dev/null +++ b/src/OperaPlugin/OperaPlugin.h @@ -0,0 +1,37 @@ +// Copyright (C) 2014-2021 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 OPERAPLUGIN_H +#define OPERAPLUGIN_H + +#if defined OPERAPLUGIN_EXPORTS +#if defined WIN32 +#define OPERAPLUGIN_EXPORT __declspec( dllexport ) +#else +#define OPERAPLUGIN_EXPORT +#endif +#else +#if defined WIN32 +#define OPERAPLUGIN_EXPORT __declspec( dllimport ) +#else +#define OPERAPLUGIN_EXPORT +#endif +#endif + +#endif diff --git a/src/OperaPlugin/OperaPlugin_Plugin.cpp b/src/OperaPlugin/OperaPlugin_Plugin.cpp new file mode 100644 index 000000000..894925751 --- /dev/null +++ b/src/OperaPlugin/OperaPlugin_Plugin.cpp @@ -0,0 +1,43 @@ +// Copyright (C) 2014-2021 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 + +// the only created instance of this plugin +static OperaPlugin_Plugin* MY_PRIMITIVES_INSTANCE = new OperaPlugin_Plugin(); + +OperaPlugin_Plugin::OperaPlugin_Plugin() +{ + // register this plugin + ModelAPI_Session::get()->registerPlugin(this); +} + +FeaturePtr OperaPlugin_Plugin::createFeature(std::string theFeatureID) +{ + if (theFeatureID == OperaPlugin_Volume::ID()) { + return FeaturePtr(new OperaPlugin_Volume); + } else { + return FeaturePtr(); + } +} diff --git a/src/OperaPlugin/OperaPlugin_Plugin.h b/src/OperaPlugin/OperaPlugin_Plugin.h new file mode 100644 index 000000000..a68e29f25 --- /dev/null +++ b/src/OperaPlugin/OperaPlugin_Plugin.h @@ -0,0 +1,43 @@ +// Copyright (C) 2014-2021 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 OperaPlugin_Plugin_H_ +#define OperaPlugin_Plugin_H_ + +#include "OperaPlugin.h" +#include +#include + +/**\class OperaPlugin_Plugin + * \ingroup Plugins + * \brief The main class managing Opera Features as plugins. + */ +class OPERAPLUGIN_EXPORT OperaPlugin_Plugin : public ModelAPI_Plugin +{ + public: + /// Creates the feature object of this plugin by the feature string ID + virtual FeaturePtr createFeature(std::string theFeatureID); + + public: + /// Default constructor + OperaPlugin_Plugin(); + +}; + +#endif diff --git a/src/OperaPlugin/OperaPlugin_Volume.cpp b/src/OperaPlugin/OperaPlugin_Volume.cpp new file mode 100644 index 000000000..57393a226 --- /dev/null +++ b/src/OperaPlugin/OperaPlugin_Volume.cpp @@ -0,0 +1,117 @@ +// Copyright (C) 2014-2021 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 +#include +#include + +#include +#include + +//================================================================================================= +OperaPlugin_Volume::OperaPlugin_Volume() // Nothing to do during instantiation +{ +} + +//================================================================================================= +static GeomShapePtr shapeOfSelection(AttributeSelectionPtr theSel) { + GeomShapePtr aResult; + FeaturePtr aSelFeature = theSel->contextFeature(); + if (aSelFeature.get()) { + if (aSelFeature->results().empty()) // if selected feature has no results, make nothing + return aResult; + if (aSelFeature->results().size() == 1) { // for one sub-result don't make compound + aResult = aSelFeature->firstResult()->shape(); + } + } + if (!aResult.get()) + aResult = theSel->value(); + if (!aResult.get()) { + if (theSel->context().get()) + aResult = theSel->context()->shape(); + } + return aResult; +} + +//================================================================================================= +void OperaPlugin_Volume::initAttributes() +{ + // Get Medium + data()->addAttribute(MEDIUM_ID(), ModelAPI_AttributeString::typeId()); + + // Get Objects + data()->addAttribute(OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); +} + +//================================================================================================= +void OperaPlugin_Volume::execute() +{ + std::string aCopiesMedium = string(MEDIUM_ID())->value(); + if (aCopiesMedium.empty()) + { + setError("Error: Medium cannot be empty."); + return; + } + + int aResultIndex = 0; + + AttributeSelectionListPtr aList = selectionList(OBJECTS_LIST_ID()); + std::wstring aBaseName; + for (int aSelIndex = 0; aSelIndex < aList->size(); aSelIndex++) { + AttributeSelectionPtr aSel = aList->value(aSelIndex); + GeomShapePtr aResult; + FeaturePtr aSelFeature = aSel->contextFeature(); + if (aSelFeature.get()) { + if (aSelFeature->results().empty()) // if selected feature has no results, make nothing + continue; + if (aSelFeature->results().size() == 1) { // for one sub-result don't make compound + aResult = aSelFeature->firstResult()->shape(); + } + } + if (!aResult.get()) + aResult = aSel->value(); + if (!aResult.get()) { + if (aSel->context().get()) + aResult = aSel->context()->shape(); + } + + // Handle naming : Volume_ + std::wstring aName; + std::set anExistingNames; + std::wstring aBaseName = aSel->context() ? aSel->context()->data()->name() : + aSel->contextFeature()->firstResult()->data()->name(); + do { + std::wostringstream aNameStr; + aNameStr << "Volume_" << aBaseName; + aName = aNameStr.str(); + } while (anExistingNames.count(aName)); + anExistingNames.insert(aName); + + ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex); + aResultBody->data()->setName(aName); + aResultBody->store(aResult); + setResult(aResultBody, aResultIndex++); + } + // Remove the rest results if there were produced in the previous pass. + removeResults(aResultIndex); +} diff --git a/src/OperaPlugin/OperaPlugin_Volume.h b/src/OperaPlugin/OperaPlugin_Volume.h new file mode 100644 index 000000000..be8b73824 --- /dev/null +++ b/src/OperaPlugin/OperaPlugin_Volume.h @@ -0,0 +1,74 @@ +// Copyright (C) 2014-2021 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 OperaPlugin_Volume_H_ +#define OperaPlugin_Volume_H_ + +#include +#include + +class GeomAPI_Shape; +class ModelAPI_ResultBody; + +/**\class OperaPlugin_Volume + * \ingroup Plugins + * \brief Feature for creation of a Volume using solids. + * + * Volume creates Volume object - This volume takes selected solids shape + * and transform the result to a volume with a medium for OPERA. + */ +class OperaPlugin_Volume : public ModelAPI_Feature +{ + public: + /// Volume kind + inline static const std::string& ID() + { + static const std::string MY_VOLUME_ID("Volume"); + return MY_VOLUME_ID; + } + inline static const std::string& MEDIUM_ID() + { + static const std::string MY_MEDIUM_ID("medium"); + return MY_MEDIUM_ID; + } + /// attribute name of selected entities list + inline static const std::string& OBJECTS_LIST_ID() + { + static const std::string MY_OBJECTS_LIST_ID("objects_list"); + return MY_OBJECTS_LIST_ID; + } + + // Creates a new part document if needed + OPERAPLUGIN_EXPORT virtual void execute(); + + /// Request for initialization of data model of the feature: adding all attributes + OPERAPLUGIN_EXPORT virtual void initAttributes(); + + /// Returns the kind of a feature + OPERAPLUGIN_EXPORT virtual const std::string& getKind() + { + static std::string MY_KIND = OperaPlugin_Volume::ID(); + return MY_KIND; + } + + /// Use plugin manager for features creation + OperaPlugin_Volume(); +}; + +#endif diff --git a/src/OperaPlugin/OperaPlugin_msg_fr.ts b/src/OperaPlugin/OperaPlugin_msg_fr.ts new file mode 100644 index 000000000..aca1a8815 --- /dev/null +++ b/src/OperaPlugin/OperaPlugin_msg_fr.ts @@ -0,0 +1,57 @@ + + + + + + workshop + + Volume + Volume + + + + + Volume + + Volume + Volume + + + Create a volume + Créer un volume + + + + + Volume:medium + + Medium + Milieu + + + Please input the volumes medium + Veuillez indiquer le milieu des volumes + + + + + Volume:objects_list + + Objects + Objets + + + Select solid objects + Sélectionnez les solides + + + + + Volume:objects_list + + Attribute "%1" is not initialized. + Sélectionnez les solides. + + + + diff --git a/src/OperaPlugin/Test/TestVolume.py b/src/OperaPlugin/Test/TestVolume.py new file mode 100755 index 000000000..66538baca --- /dev/null +++ b/src/OperaPlugin/Test/TestVolume.py @@ -0,0 +1,82 @@ +# Copyright (C) 2014-2021 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 +# + +""" + TestVolume.py + Test case of OperaPlugin_Volume +""" +#========================================================================= +# Initialization of the test +#========================================================================= +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() + +### Create two box (one for error case) +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Box_2 = model.addBox(Part_1_doc, 10, 10, 10) + +### Create a cylinder +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10) + +### Create a sphere +Sphere_1 = model.addSphere(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), 10) + +### Create a volume from the box +Volume_1 = model.addVolume(Part_1_doc, "Air", [model.selection("SOLID", "Box_1_1")]) + +### Create a volume from the cylinder and the sphere +Volume_2 = model.addVolume(Part_1_doc, "Air", [model.selection("SOLID", "Cylinder_1_1"), model.selection("SOLID", "Sphere_1_1")]) +Volume_2.setMedium("Eau") + +#Checks +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Volume_1, 1) +model.testNbSubResults(Volume_1, [0]) +model.testNbSubShapes(Volume_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Volume_1, GeomAPI_Shape.FACE, [6]) +model.testHaveNamingFaces(Volume_1, model, Part_1_doc) + +model.testNbResults(Volume_2, 2) +model.testNbSubResults(Volume_2, [0, 0]) +model.testNbSubShapes(Volume_2, GeomAPI_Shape.SOLID, [1, 1]) +model.testNbSubShapes(Volume_2, GeomAPI_Shape.FACE, [3, 1]) + +### Create a volume with no medium +Volume_3 = model.addVolume(Part_1_doc, "", [model.selection("SOLID", "Box_2_1")]) +model.testNbResults(Volume_3, 0) +assert(Volume_3.feature().error() == "Error: Medium cannot be empty.") + +### Create a volume with no shapes +Volume_4 = model.addVolume(Part_1_doc, "Error", []) +model.testNbResults(Volume_4, 0) +assert(Volume_4.feature().error() == "Attribute \"objects_list\" is not initialized.") + +### Create a volume with bad shapes +Volume_5 = model.addVolume(Part_1_doc, "Bad Shape", [model.selection("VERTEX", "PartSet/Origin")]) +model.testNbResults(Volume_5, 0) +assert(Volume_5.feature().error() == "It does not contain element with acceptable shape type. The type should be one of the next: solid") + +#========================================================================= +# End of test +#========================================================================= diff --git a/src/OperaPlugin/doc/OperaPlugin.rst b/src/OperaPlugin/doc/OperaPlugin.rst new file mode 100644 index 000000000..f61f280bd --- /dev/null +++ b/src/OperaPlugin/doc/OperaPlugin.rst @@ -0,0 +1,13 @@ + +.. _operaPlugin: + +Opera plug-in +================== + +The Opera plug-in provides a set of common operations to ROOT geometry. It implements the following features: + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + volumeFeature.rst diff --git a/src/OperaPlugin/doc/TUI_volume.rst b/src/OperaPlugin/doc/TUI_volume.rst new file mode 100644 index 000000000..3f3ecbd0f --- /dev/null +++ b/src/OperaPlugin/doc/TUI_volume.rst @@ -0,0 +1,11 @@ + + .. _tui_create_volume: + +Create Volume +============= + +.. literalinclude:: examples/volume.py + :linenos: + :language: python + +:download:`Download this script ` diff --git a/src/OperaPlugin/doc/examples/volume.py b/src/OperaPlugin/doc/examples/volume.py new file mode 100644 index 000000000..a21ef5396 --- /dev/null +++ b/src/OperaPlugin/doc/examples/volume.py @@ -0,0 +1,12 @@ +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() + +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Volume_1 = model.addVolume(Part_1_doc, "Air", [model.selection("SOLID", "Box_1_1")]) + +model.do() +model.end() diff --git a/src/OperaPlugin/doc/images/Volume.png b/src/OperaPlugin/doc/images/Volume.png new file mode 100644 index 0000000000000000000000000000000000000000..281fc7197b8001c47de93c0de6f4e649e61000f7 GIT binary patch literal 5741 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 literal 0 HcmV?d00001 diff --git a/src/OperaPlugin/doc/images/Volume1.png b/src/OperaPlugin/doc/images/Volume1.png new file mode 100644 index 0000000000000000000000000000000000000000..4e8a1d2a8fdcf09faba5686b4aded630ca433e1e GIT binary patch literal 4249 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 literal 0 HcmV?d00001 diff --git a/src/OperaPlugin/doc/volumeFeature.rst b/src/OperaPlugin/doc/volumeFeature.rst new file mode 100644 index 000000000..8ea5c8548 --- /dev/null +++ b/src/OperaPlugin/doc/volumeFeature.rst @@ -0,0 +1,43 @@ +.. |Volume_button.icon| image:: images/Volume_button.png + +Volume +------ + +Volume feature creates a basic object used in bulding the ROOT geometrical hierarchy. + +To create a Volume in the active part: + +#. select in the Main Menu *Opera - > Volume* item or +#. click |Volume_button.icon| **Volume** button in the toolbar: + +Volume is created by a value and a list of solids + +.. figure:: images/Volume.png + :align: center + +Input fields: + +- **Medium** defines the name of the medium; +- **Objects** defines the list of solid objects + +**TUI Command**: + +.. py:function:: + model.addVolume(Part_doc, medium, model.selection[("SOLID", ...), ...]) + + :param part: The current part object. + :param string: A medium name. + :param list: A list of solids. + :return: Result object. + +Result +"""""" + +One solid for each selected solid in the volume list with according medium + +.. figure:: images/Volume1.png + :align: center + + Volume created + +**See Also** a sample TUI Script of :ref:`tui_create_volume` operation. diff --git a/src/OperaPlugin/icons/Volume.png b/src/OperaPlugin/icons/Volume.png new file mode 100644 index 0000000000000000000000000000000000000000..32da1330a92c844a3782694a1a442ed43fd3bfa7 GIT binary patch literal 7075 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 literal 0 HcmV?d00001 diff --git a/src/OperaPlugin/plugin-Opera.xml b/src/OperaPlugin/plugin-Opera.xml new file mode 100644 index 000000000..f16bf394b --- /dev/null +++ b/src/OperaPlugin/plugin-Opera.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/src/OperaPlugin/tests.set b/src/OperaPlugin/tests.set new file mode 100644 index 000000000..019d00b2f --- /dev/null +++ b/src/OperaPlugin/tests.set @@ -0,0 +1,22 @@ +# Copyright (C) 2021 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 +# + +SET(TEST_NAMES + TestVolume.py +) diff --git a/src/OperaPlugin/volume_widget.xml b/src/OperaPlugin/volume_widget.xml new file mode 100644 index 000000000..a0cbd22b7 --- /dev/null +++ b/src/OperaPlugin/volume_widget.xml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/src/PythonAPI/Test/TestFeatures.py b/src/PythonAPI/Test/TestFeatures.py index 0431d5e45..ae3041ab7 100644 --- a/src/PythonAPI/Test/TestFeatures.py +++ b/src/PythonAPI/Test/TestFeatures.py @@ -104,6 +104,9 @@ class FeaturesTestCase(FeaturesFixture): import PrimitivesAPI PrimitivesAPI.PrimitivesAPI_Box(self.part.addFeature("Box")) + import OperaAPI + OperaAPI.OperaAPI_Volume(self.part.addFeature("Volume")) + import ParametersAPI ParametersAPI.ParametersAPI_Parameter(self.part.addFeature("Parameter")) diff --git a/src/PythonAPI/model/__init__.py b/src/PythonAPI/model/__init__.py index 6e2d15b70..eb043c97f 100644 --- a/src/PythonAPI/model/__init__.py +++ b/src/PythonAPI/model/__init__.py @@ -42,5 +42,6 @@ from .collection import * from .parameter import * from .partset import * from .primitives import * +from .opera import * from .gdml import * from .tests import * diff --git a/src/PythonAPI/model/opera/__init__.py b/src/PythonAPI/model/opera/__init__.py new file mode 100644 index 000000000..a13965476 --- /dev/null +++ b/src/PythonAPI/model/opera/__init__.py @@ -0,0 +1,22 @@ +# Copyright (C) 2016-2021 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 +# +"""Package for Opera plugin for SHAPER Opera. +""" + +from OperaAPI import addVolume diff --git a/src/SHAPERGUI/resources/LightApp.xml.in b/src/SHAPERGUI/resources/LightApp.xml.in index 33908724f..6d303a073 100644 --- a/src/SHAPERGUI/resources/LightApp.xml.in +++ b/src/SHAPERGUI/resources/LightApp.xml.in @@ -22,6 +22,9 @@ +
+ +
-- 2.39.2