From: Nicolas RECHATIN Date: Thu, 5 Aug 2021 10:26:08 +0000 (+0200) Subject: Add new feature AddNode for OPERA X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=e3f32c9bf323edcb7086ff9613fa32aeb1180644;p=modules%2Fshaper.git Add new feature AddNode for OPERA --- diff --git a/src/OperaAPI/CMakeLists.txt b/src/OperaAPI/CMakeLists.txt index a9da8f181..192634bd9 100644 --- a/src/OperaAPI/CMakeLists.txt +++ b/src/OperaAPI/CMakeLists.txt @@ -22,10 +22,12 @@ INCLUDE(Common) SET(PROJECT_HEADERS OperaAPI.h OperaAPI_Volume.h + OperaAPI_AddNode.h ) SET(PROJECT_SOURCES OperaAPI_Volume.cpp + OperaAPI_AddNode.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/OperaAPI/OperaAPI.i b/src/OperaAPI/OperaAPI.i index 6bbadc525..57223e944 100644 --- a/src/OperaAPI/OperaAPI.i +++ b/src/OperaAPI/OperaAPI.i @@ -39,6 +39,8 @@ // shared pointers %shared_ptr(OperaAPI_Volume) +%shared_ptr(OperaAPI_AddNode) // all supported interfaces %include "OperaAPI_Volume.h" +%include "OperaAPI_AddNode.h" diff --git a/src/OperaAPI/OperaAPI_AddNode.cpp b/src/OperaAPI/OperaAPI_AddNode.cpp new file mode 100644 index 000000000..297858054 --- /dev/null +++ b/src/OperaAPI/OperaAPI_AddNode.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_AddNode.h" + +#include +#include + +//================================================================================================== +OperaAPI_AddNode::OperaAPI_AddNode(const std::shared_ptr& theFeature) +: ModelHighAPI_Interface(theFeature) +{ + initialize(); +} + + +//================================================================================================== +OperaAPI_AddNode::OperaAPI_AddNode(const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theMainObject, + const std::list& theToolsList) + : ModelHighAPI_Interface(theFeature) +{ + if(initialize()) { + fillAttribute(theMainObject, mainObject()); + setToolsList(theToolsList); + } +} + +//================================================================================================== +OperaAPI_AddNode::~OperaAPI_AddNode() +{ +} + +//================================================================================================== +void OperaAPI_AddNode::setMainObject(const ModelHighAPI_Selection& theMainObject) +{ + fillAttribute(theMainObject, mainObject()); + execute(); +} + +//================================================================================================== +void OperaAPI_AddNode::setToolsList(const std::list& theToolsList) +{ + fillAttribute(theToolsList, toolsList()); + execute(); +} + +//================================================================================================== +void OperaAPI_AddNode::dump(ModelHighAPI_Dumper& theDumper) const +{ + FeaturePtr aBase = feature(); + const std::string& aDocName = theDumper.name(aBase->document()); + + AttributeSelectionPtr anAttrObject = aBase->selection(OperaPlugin_AddNode::MAIN_OBJECT_ID()); + theDumper << aBase << " = model.addAddNode(" << aDocName << ", " << anAttrObject << ", "; + + AttributeSelectionListPtr anAttrList = + aBase->selectionList(OperaPlugin_AddNode::TOOLS_LIST_ID()); + theDumper << anAttrList << ")" << std::endl; +} + +//================================================================================================== +AddNodePtr addAddNode(const std::shared_ptr& thePart, + const ModelHighAPI_Selection& theMainObject, + const std::list& theToolsList) +{ + std::shared_ptr aFeature = thePart->addFeature(OperaAPI_AddNode::ID()); + return AddNodePtr(new OperaAPI_AddNode(aFeature, theMainObject, theToolsList)); +} diff --git a/src/OperaAPI/OperaAPI_AddNode.h b/src/OperaAPI/OperaAPI_AddNode.h new file mode 100644 index 000000000..288621627 --- /dev/null +++ b/src/OperaAPI/OperaAPI_AddNode.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_ADDNODE_H_ +#define OPERAAPI_ADDNODE_H_ + +#include "OperaAPI.h" +#include + +#include +#include + +class ModelHighAPI_Selection; + +/// \class OperaAPI_AddNode +/// \ingroup CPPHighAPI +/// \brief Interface for AddNode feature. +class OperaAPI_AddNode: public ModelHighAPI_Interface +{ +public: + /// Constructor without values. + OPERAAPI_EXPORT + explicit OperaAPI_AddNode(const std::shared_ptr& theFeature); + + /// Constructor with values. + OPERAAPI_EXPORT + explicit OperaAPI_AddNode(const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theMainObject, + const std::list& theToolsList); + + /// Destructor. + OPERAAPI_EXPORT + virtual ~OperaAPI_AddNode(); + + INTERFACE_2(OperaPlugin_AddNode::ID(), + mainObject, OperaPlugin_AddNode::MAIN_OBJECT_ID(), + ModelAPI_AttributeSelection, /** Main Object */, + toolsList, OperaPlugin_AddNode::TOOLS_LIST_ID(), + ModelAPI_AttributeSelectionList, /** Tools list*/) + + /// Set main object + OPERAAPI_EXPORT + void setMainObject(const ModelHighAPI_Selection& theMainObject); + + /// Set tools list + OPERAAPI_EXPORT + void setToolsList(const std::list& theToolsList); + + /// Dump wrapped feature + OPERAAPI_EXPORT + virtual void dump(ModelHighAPI_Dumper& theDumper) const; +}; + +/// Pointer AddNode feature +typedef std::shared_ptr AddNodePtr; + +/// \ingroup CPPHighAPI +/// \brief Create Volume feature. +OPERAAPI_EXPORT +AddNodePtr addAddNode(const std::shared_ptr& thePart, + const ModelHighAPI_Selection& theMainObject, + const std::list& theToolsList); + +#endif // OPERAAPI_ADDNODE_H_ diff --git a/src/OperaAPI/OperaAPI_swig.h b/src/OperaAPI/OperaAPI_swig.h index eaa088dc9..661e51618 100644 --- a/src/OperaAPI/OperaAPI_swig.h +++ b/src/OperaAPI/OperaAPI_swig.h @@ -24,5 +24,6 @@ #include "OperaAPI.h" #include "OperaAPI_Volume.h" + #include "OperaAPI_AddNode.h" #endif // OPERAAPI_SWIG_H_ diff --git a/src/OperaPlugin/CMakeLists.txt b/src/OperaPlugin/CMakeLists.txt index a1f7fd600..92f3460c8 100644 --- a/src/OperaPlugin/CMakeLists.txt +++ b/src/OperaPlugin/CMakeLists.txt @@ -20,18 +20,22 @@ SET(PROJECT_HEADERS OperaPlugin.h OperaPlugin_Plugin.h + OperaPlugin_Tools.h OperaPlugin_Volume.h + OperaPlugin_AddNode.h ) SET(PROJECT_SOURCES OperaPlugin_Plugin.cpp + OperaPlugin_Tools.cpp OperaPlugin_Volume.cpp - + OperaPlugin_AddNode.cpp ) SET(XML_RESOURCES plugin-Opera.xml volume_widget.xml + addnode_widget.xml ) SET(TEXT_RESOURCES diff --git a/src/OperaPlugin/OperaPlugin_AddNode.cpp b/src/OperaPlugin/OperaPlugin_AddNode.cpp new file mode 100644 index 000000000..9c67576d2 --- /dev/null +++ b/src/OperaPlugin/OperaPlugin_AddNode.cpp @@ -0,0 +1,135 @@ +// 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 "OperaPlugin_AddNode.h" + +#include + +//================================================================================================= +OperaPlugin_AddNode::OperaPlugin_AddNode() // Nothing to do during instantiation +{ +} + +//================================================================================================= +void OperaPlugin_AddNode::initAttributes() +{ + data()->addAttribute(MAIN_OBJECT_ID(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(TOOLS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); +} + +//================================================================================================= +bool toolsIntersect(ListOfShape& theToolsList){ + + for(auto it = theToolsList.begin(); it != theToolsList.end(); it++) + for(auto jt = theToolsList.begin(); jt != theToolsList.end(); jt++) + { + GeomShapePtr first = *it; + GeomShapePtr second = *jt; + if (!(first == second)) + if (first->isIntersect(second)) + return true; + } + return false; +} + +//================================================================================================= +void OperaPlugin_AddNode::performAlgo(const GeomAlgoAPI_Tools::BOPType theBooleanType, + const GeomShapePtr& theObject, + const ListOfShape& theTools, + const ListOfShape& thePlanes, + int& theResultIndex) +{ + //Perform algorithm + ListOfShape aListWithObject; + aListWithObject.push_back(theObject); + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); + std::shared_ptr aBoolAlgo; + GeomShapePtr aResShape; + aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aListWithObject, + theTools, + theBooleanType)); + //Check for error + std::string anError; + if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) + return setError(anError); + + //Naming + handleNaming(aResShape, aBoolAlgo, aMakeShapeList, theTools); +} + +//================================================================================================= +void OperaPlugin_AddNode::handleNaming(GeomShapePtr theResShape, + GeomMakeShapePtr theBoolAlgo, + std::shared_ptr theMakeShapeList, + const ListOfShape& theTools) +{ + //Get result shape + int anIndexToRemove = 0; + theResShape = theBoolAlgo->shape(); + theMakeShapeList->appendAlgo(theBoolAlgo); + ListOfShape aTestList = theTools; + aTestList.push_front(theResShape); + + //Build result compund + GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aTestList); + if (aCompound) { + ResultBodyPtr aResultBody = document()->createBody(data(), anIndexToRemove++); + aResultBody->storeModified(aTestList, aCompound, theBoolAlgo); + aResultBody->loadModifiedShapes(theMakeShapeList, aCompound, GeomAPI_Shape::VERTEX); + aResultBody->loadModifiedShapes(theMakeShapeList, aCompound, GeomAPI_Shape::EDGE); + aResultBody->loadModifiedShapes(theMakeShapeList, aCompound, GeomAPI_Shape::FACE); + setResult(aResultBody); + } +} + +//================================================================================================= +void OperaPlugin_AddNode::execute() +{ + int aResultIndex = 0; + ListOfShape aPlanes, aToolList; + + //Get Selection and Shapes + AttributeSelectionPtr aMainObjectAttr = selection(MAIN_OBJECT_ID()); + AttributeSelectionListPtr aToolsAttrList = selectionList(TOOLS_LIST_ID()); + + // Get Shapes from selection and test intersection with Main Object + GeomShapePtr aMainObjectShape = shapeOfSelection(aMainObjectAttr); + for (int anObjectsIndex = 0; anObjectsIndex < aToolsAttrList->size(); anObjectsIndex++){ + GeomShapePtr currentToolShape = shapeOfSelection(aToolsAttrList->value(anObjectsIndex)); + if (!aMainObjectShape->isIntersect(currentToolShape) || aMainObjectShape->intersect(currentToolShape)) + return setError("Error: All tools must be fully inside the main object"); + aToolList.push_back(currentToolShape); + } + + // Check tools intersections + if (toolsIntersect(aToolList)) + return setError("Error: Tools must not intersect each others"); + + //Check for error then clean part results + if(aMainObjectShape == nullptr ) + return setError("Error: cannot perform an AddNode with no main object."); + if(aToolList.empty()) + return setError("Error: Tools list cannot be empty."); + aMainObjectAttr->context()->setDisabled(aMainObjectAttr->context(), true); // To avoid activation of the Part result + + //Perform Algorithm + performAlgo(GeomAlgoAPI_Tools::BOOL_CUT, + shapeOfSelection(aMainObjectAttr), aToolList, aPlanes, + aResultIndex); +} diff --git a/src/OperaPlugin/OperaPlugin_AddNode.h b/src/OperaPlugin/OperaPlugin_AddNode.h new file mode 100644 index 000000000..0a41de4ad --- /dev/null +++ b/src/OperaPlugin/OperaPlugin_AddNode.h @@ -0,0 +1,100 @@ +// 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_AddNode_H_ +#define OperaPlugin_AddNode_H_ + +#include +#include + +#include "GeomAPI_ShapeHierarchy.h" +#include "GeomAPI_ShapeIterator.h" + +#include +#include +#include +#include "GeomAlgoAPI_Tools.h" + +#include +#include +#include +#include +#include +#include + +/**\class OperaPlugin_AddNode + * \ingroup Plugins + * \brief Feature for creation of a Node using solids. + * + * Node creates Node object - This Node takes selected solids shape + * and transform the result to a Node with a medium for OPERA. + */ +class OperaPlugin_AddNode : public ModelAPI_Feature +{ + public: + /// Node kind + inline static const std::string& ID() + { + static const std::string MY_NODE_ID("AddNode"); + return MY_NODE_ID; + } + /// Attribute name of main object. + inline static const std::string& MAIN_OBJECT_ID() + { + static const std::string MY_MAIN_OBJECT_ID("main_object"); + return MY_MAIN_OBJECT_ID; + } + /// Attribute name of selected tools list + inline static const std::string& TOOLS_LIST_ID() + { + static const std::string MY_TOOLS_LIST_ID("tools_list"); + return MY_TOOLS_LIST_ID; + } + + /// Perform boolean alogrithm according to AddNode cases + void performAlgo(const GeomAlgoAPI_Tools::BOPType theBooleanType, + const GeomShapePtr& theObject, + const ListOfShape& theTools, + const ListOfShape& thePlanes, + int& theResultIndex); + + /// Creates naming for AddNode results + void OperaPlugin_AddNode::handleNaming(GeomShapePtr theResShape, + GeomMakeShapePtr theBoolAlgo, + std::shared_ptr theMakeShapeList, + const ListOfShape& theTools); + + /// 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_AddNode::ID(); + return MY_KIND; + } + + /// Use plugin manager for features creation + OperaPlugin_AddNode(); +}; + +#endif diff --git a/src/OperaPlugin/OperaPlugin_Plugin.cpp b/src/OperaPlugin/OperaPlugin_Plugin.cpp index 894925751..34e927644 100644 --- a/src/OperaPlugin/OperaPlugin_Plugin.cpp +++ b/src/OperaPlugin/OperaPlugin_Plugin.cpp @@ -19,11 +19,10 @@ #include #include +#include #include -#include - // the only created instance of this plugin static OperaPlugin_Plugin* MY_PRIMITIVES_INSTANCE = new OperaPlugin_Plugin(); @@ -37,6 +36,8 @@ FeaturePtr OperaPlugin_Plugin::createFeature(std::string theFeatureID) { if (theFeatureID == OperaPlugin_Volume::ID()) { return FeaturePtr(new OperaPlugin_Volume); + } else if (theFeatureID == OperaPlugin_AddNode::ID()) { + return FeaturePtr(new OperaPlugin_AddNode); } else { return FeaturePtr(); } diff --git a/src/OperaPlugin/OperaPlugin_Tools.cpp b/src/OperaPlugin/OperaPlugin_Tools.cpp new file mode 100644 index 000000000..8ca459431 --- /dev/null +++ b/src/OperaPlugin/OperaPlugin_Tools.cpp @@ -0,0 +1,46 @@ +// 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 "OperaPlugin_Tools.h" + +//================================================================================================= +GeomShapePtr shapeOfSelection(AttributeSelectionPtr theSel) +{ + GeomShapePtr aResult; + FeaturePtr aSelFeature = theSel->contextFeature(); + + //Get result from selection + 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(); + } + } + + //Get shape from result + if (!aResult.get()) + aResult = theSel->value(); + if (!aResult.get()) { + if (theSel->context().get()) + aResult = theSel->context()->shape(); + } + + return aResult; +} diff --git a/src/OperaPlugin/OperaPlugin_Tools.h b/src/OperaPlugin/OperaPlugin_Tools.h new file mode 100644 index 000000000..ba8b76e13 --- /dev/null +++ b/src/OperaPlugin/OperaPlugin_Tools.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_Tools_H_ +#define OperaPlugin_Tools_H_ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +GeomShapePtr shapeOfSelection(AttributeSelectionPtr theSel); + +#endif diff --git a/src/OperaPlugin/OperaPlugin_Volume.cpp b/src/OperaPlugin/OperaPlugin_Volume.cpp index 57393a226..5a2b69613 100644 --- a/src/OperaPlugin/OperaPlugin_Volume.cpp +++ b/src/OperaPlugin/OperaPlugin_Volume.cpp @@ -33,26 +33,6 @@ 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() { diff --git a/src/OperaPlugin/OperaPlugin_msg_fr.ts b/src/OperaPlugin/OperaPlugin_msg_fr.ts index aca1a8815..88085affe 100644 --- a/src/OperaPlugin/OperaPlugin_msg_fr.ts +++ b/src/OperaPlugin/OperaPlugin_msg_fr.ts @@ -23,7 +23,19 @@ - Volume:medium + AddNode + + AddNode + AddNode + + + Perform OPERA Add Node + Faire un AddNode OPERA + + + + + AddNode:medium Medium Milieu @@ -54,4 +66,47 @@ + + + + + + AddNode:main_object + + Main object + Objet Principal + + + Select a main object + Veuillez séléctioner un objet principal + + + + + Volume:tools_list + + Tools objects + Outils + + + Select solid objects as tools + Sélectionnez les outils + + + + + Volume:main_object + + Attribute "%1" is not initialized. + Sélectionnez un object principal. + + + + Volume:tools_list + + Attribute "%2" is not initialized. + Sélectionnez les outils. + + + diff --git a/src/OperaPlugin/Test/TestAddNode.py b/src/OperaPlugin/Test/TestAddNode.py new file mode 100644 index 000000000..ca0573892 --- /dev/null +++ b/src/OperaPlugin/Test/TestAddNode.py @@ -0,0 +1,101 @@ +# 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 +# + +""" + TestAddNode.py + Test case of OperaPlugin_AddNode +""" +#========================================================================= +# 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 inside the other) +Box_1 = model.addBox(Part_1_doc, 0, 0, 0, 20, 20, 20) +Box_2 = model.addBox(Part_1_doc, 0, 0, 0, 10, 10, 10) + +### Create more boxes for error tests +Box_3= model.addBox(Part_1_doc, 0, 0, 0, 10, 10, 10) +Box_4 = model.addBox(Part_1_doc, 0, 0, 0, 20, 20, 20) +Box_5 = model.addBox(Part_1_doc, 0, 0, 0, 20, 20, 20) +Box_6 = model.addBox(Part_1_doc, 50, 50, 50, 10, 10, 10) +Box_7 = model.addBox(Part_1_doc, 0, 0, 0, 20, 20, 20) +Box_8 = model.addBox(Part_1_doc, 20, 0, 0, 10, 10, 10) +Box_9 = model.addBox(Part_1_doc, 0, 0, 0, 20, 20, 20) +Box_10 = model.addBox(Part_1_doc, 0, 0, 0, 10, 10, 10) +Box_11 = model.addBox(Part_1_doc, 5, 5, 5, 10, 10, 10) +Box_12 = model.addBox(Part_1_doc, 0, 0, 0, 20, 20, 20) +Box_13 = model.addBox(Part_1_doc, 0, 0, 0, 10, 10, 10) +Box_14 = model.addBox(Part_1_doc, 0, 0, 0, 5, 5, 5) + + +### Create a volume from the cylinder and the sphere +AddNode_1 = model.addAddNode(Part_1_doc, model.selection("SOLID", "Box_1_1"), [model.selection("SOLID", "Box_2_1")]) + +#Checks +from GeomAPI import GeomAPI_Shape + +model.testNbResults(AddNode_1, 1) +model.testNbSubResults(AddNode_1, [2]) +model.testNbSubShapes(AddNode_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(AddNode_1, GeomAPI_Shape.FACE, [18]) +model.testHaveNamingFaces(AddNode_1, model, Part_1_doc) + +### Create a AddNode with no main object +AddNode_2 = model.addAddNode(Part_1_doc, model.selection("SOLID", "None"), [model.selection("SOLID", "Box_3_1")]) +model.testNbResults(AddNode_2, 0) +assert(AddNode_2.feature().error() == "Attribute \"main_object\" is not initialized.") + +### Create a AddNode with no tools +AddNode_3 = model.addAddNode(Part_1_doc, model.selection("SOLID", "Box_4_1"), []) +model.testNbResults(AddNode_3, 0) +assert(AddNode_3.feature().error() == "Attribute \"tools_list\" is not initialized.") + +### Create a AddNode with tools outside the main object +AddNode_4 = model.addAddNode(Part_1_doc, model.selection("SOLID", "Box_5_1"), [model.selection("SOLID", "Box_6_1")]) +model.testNbResults(AddNode_4, 0) +assert(AddNode_4.feature().error() == "Error: All tools must be fully inside the main object") + +### Create a AddNode with tools intersecting the main object +AddNode_5 = model.addAddNode(Part_1_doc, model.selection("SOLID", "Box_7_1"), [model.selection("SOLID", "Box_8_1")]) +model.testNbResults(AddNode_5, 0) +assert(AddNode_5.feature().error() == "Error: All tools must be fully inside the main object") + +### Create a AddNode with intersecting tools +AddNode_6 = model.addAddNode(Part_1_doc, model.selection("SOLID", "Box_9_1"), [model.selection("SOLID", "Box_10_1"), model.selection("SOLID", "Box_11_1")]) +model.testNbResults(AddNode_6, 0) +assert(AddNode_6.feature().error() == "Error: Tools must not intersect each others") + +### Create a AddNode with a tool inside another +AddNode_7 = model.addAddNode(Part_1_doc, model.selection("SOLID", "Box_12_1"), [model.selection("SOLID", "Box_13_1"), model.selection("SOLID", "Box_14_1")]) +model.testNbResults(AddNode_7, 0) +assert(AddNode_7.feature().error() == "Error: Tools must not intersect each others") + + +# TODO : Test with out of bounds tools +# TODO : Test with intersected tools + +#========================================================================= +# End of test +#========================================================================= diff --git a/src/OperaPlugin/addnode_widget.xml b/src/OperaPlugin/addnode_widget.xml new file mode 100644 index 000000000..adf237d15 --- /dev/null +++ b/src/OperaPlugin/addnode_widget.xml @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/src/OperaPlugin/doc/OperaPlugin.rst b/src/OperaPlugin/doc/OperaPlugin.rst index f61f280bd..0e61c3302 100644 --- a/src/OperaPlugin/doc/OperaPlugin.rst +++ b/src/OperaPlugin/doc/OperaPlugin.rst @@ -11,3 +11,4 @@ The Opera plug-in provides a set of common operations to ROOT geometry. It imple :maxdepth: 1 volumeFeature.rst + addnodeFeature.rst diff --git a/src/OperaPlugin/doc/TUI_addnode.rst b/src/OperaPlugin/doc/TUI_addnode.rst new file mode 100644 index 000000000..fdd30ced3 --- /dev/null +++ b/src/OperaPlugin/doc/TUI_addnode.rst @@ -0,0 +1,11 @@ + + .. _tui_create_addnode: + +Create Add Node +============= + +.. literalinclude:: examples/addnode.py + :linenos: + :language: python + +:download:`Download this script ` diff --git a/src/OperaPlugin/doc/addnodeFeature.rst b/src/OperaPlugin/doc/addnodeFeature.rst new file mode 100644 index 000000000..1b28e4e04 --- /dev/null +++ b/src/OperaPlugin/doc/addnodeFeature.rst @@ -0,0 +1,43 @@ +.. |AddNode_button.icon| image:: images/AddNode_button.png + +AddNode +------ + +AddNode feature perform an AddNode operation used in bulding the ROOT geometrical hierarchy. + +To create a AddNode in the active part: + +#. select in the Main Menu *Opera - > AddNode* item or +#. click |AddNode_button.icon| **AddNode** button in the toolbar: + +AddNode is created by a solid as main object and a list of solids as tools + +.. figure:: images/AddNode.png + :align: center + +Input fields: + +- **MainOject** defines the solid main object; +- **Tools** defines the list of solid tools + +**TUI Command**: + +.. py:function:: + model.addAddNode(Part_doc, model.selection("SOLID", main_object_name), model.selection[("SOLID", ...), ...]) + + :param part: The current part object. + :param object: A main object solid. + :param list: A list of tools solids. + :return: Result compound. + +Result +"""""" + +One compound with the boolean operation result and the tools objects below it, depending on geometry cases + +.. figure:: images/AddNode1.png + :align: center + + AddNode created + +**See Also** a sample TUI Script of :ref:`tui_create_addnode` operation. diff --git a/src/OperaPlugin/doc/examples/addnode.py b/src/OperaPlugin/doc/examples/addnode.py new file mode 100644 index 000000000..8e8aea51c --- /dev/null +++ b/src/OperaPlugin/doc/examples/addnode.py @@ -0,0 +1,14 @@ +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, 0, 0, 0, 20, 20, 20) +Box_2 = model.addBox(Part_1_doc, 0, 0, 0, 10, 10, 10) + +AddNode_1 = model.addAddNode(Part_1_doc, model.selection("SOLID", "Box_1_1"), [model.selection("SOLID", "Box_2_1")]) + +model.do() +model.end() diff --git a/src/OperaPlugin/doc/images/AddNode.png b/src/OperaPlugin/doc/images/AddNode.png new file mode 100644 index 000000000..64a175548 Binary files /dev/null and b/src/OperaPlugin/doc/images/AddNode.png differ diff --git a/src/OperaPlugin/doc/images/AddNode1.png b/src/OperaPlugin/doc/images/AddNode1.png new file mode 100644 index 000000000..3df2991b3 Binary files /dev/null and b/src/OperaPlugin/doc/images/AddNode1.png differ diff --git a/src/OperaPlugin/doc/images/AddNode_button.png b/src/OperaPlugin/doc/images/AddNode_button.png new file mode 100644 index 000000000..9265afff1 Binary files /dev/null and b/src/OperaPlugin/doc/images/AddNode_button.png differ diff --git a/src/OperaPlugin/doc/volumeFeature.rst b/src/OperaPlugin/doc/volumeFeature.rst index 8ea5c8548..25e9ead04 100644 --- a/src/OperaPlugin/doc/volumeFeature.rst +++ b/src/OperaPlugin/doc/volumeFeature.rst @@ -17,12 +17,12 @@ Volume is created by a value and a list of solids Input fields: -- **Medium** defines the name of the medium; +- **Medium** defines the name of the medium; - **Objects** defines the list of solid objects **TUI Command**: -.. py:function:: +.. py:function:: model.addVolume(Part_doc, medium, model.selection[("SOLID", ...), ...]) :param part: The current part object. @@ -38,6 +38,6 @@ One solid for each selected solid in the volume list with according medium .. figure:: images/Volume1.png :align: center - Volume created + Volume created **See Also** a sample TUI Script of :ref:`tui_create_volume` operation. diff --git a/src/OperaPlugin/icons/AddNode.png b/src/OperaPlugin/icons/AddNode.png new file mode 100644 index 000000000..457dc0f4e Binary files /dev/null and b/src/OperaPlugin/icons/AddNode.png differ diff --git a/src/OperaPlugin/plugin-Opera.xml b/src/OperaPlugin/plugin-Opera.xml index f16bf394b..90fc01f33 100644 --- a/src/OperaPlugin/plugin-Opera.xml +++ b/src/OperaPlugin/plugin-Opera.xml @@ -9,6 +9,14 @@ helpfile="volumeFeature.html"> + + + diff --git a/src/OperaPlugin/tests.set b/src/OperaPlugin/tests.set index 019d00b2f..cd7e55f0d 100644 --- a/src/OperaPlugin/tests.set +++ b/src/OperaPlugin/tests.set @@ -19,4 +19,5 @@ SET(TEST_NAMES TestVolume.py + TestAddNode.py ) diff --git a/src/PythonAPI/model/opera/__init__.py b/src/PythonAPI/model/opera/__init__.py index a13965476..a1aa77d1d 100644 --- a/src/PythonAPI/model/opera/__init__.py +++ b/src/PythonAPI/model/opera/__init__.py @@ -20,3 +20,4 @@ """ from OperaAPI import addVolume +from OperaAPI import addAddNode