SET(PROJECT_HEADERS
OperaAPI.h
OperaAPI_Volume.h
+ OperaAPI_AddNode.h
)
SET(PROJECT_SOURCES
OperaAPI_Volume.cpp
+ OperaAPI_AddNode.cpp
)
SET(PROJECT_LIBRARIES
// shared pointers
%shared_ptr(OperaAPI_Volume)
+%shared_ptr(OperaAPI_AddNode)
// all supported interfaces
%include "OperaAPI_Volume.h"
+%include "OperaAPI_AddNode.h"
--- /dev/null
+// 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 <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+//==================================================================================================
+OperaAPI_AddNode::OperaAPI_AddNode(const std::shared_ptr<ModelAPI_Feature>& theFeature)
+: ModelHighAPI_Interface(theFeature)
+{
+ initialize();
+}
+
+
+//==================================================================================================
+OperaAPI_AddNode::OperaAPI_AddNode(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const ModelHighAPI_Selection& theMainObject,
+ const std::list<ModelHighAPI_Selection>& 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<ModelHighAPI_Selection>& 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<ModelAPI_Document>& thePart,
+ const ModelHighAPI_Selection& theMainObject,
+ const std::list<ModelHighAPI_Selection>& theToolsList)
+{
+ std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(OperaAPI_AddNode::ID());
+ return AddNodePtr(new OperaAPI_AddNode(aFeature, theMainObject, theToolsList));
+}
--- /dev/null
+// 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 <OperaPlugin_AddNode.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+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<ModelAPI_Feature>& theFeature);
+
+ /// Constructor with values.
+ OPERAAPI_EXPORT
+ explicit OperaAPI_AddNode(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+ const ModelHighAPI_Selection& theMainObject,
+ const std::list<ModelHighAPI_Selection>& 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<ModelHighAPI_Selection>& theToolsList);
+
+ /// Dump wrapped feature
+ OPERAAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+/// Pointer AddNode feature
+typedef std::shared_ptr<OperaAPI_AddNode> AddNodePtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create Volume feature.
+OPERAAPI_EXPORT
+AddNodePtr addAddNode(const std::shared_ptr<ModelAPI_Document>& thePart,
+ const ModelHighAPI_Selection& theMainObject,
+ const std::list<ModelHighAPI_Selection>& theToolsList);
+
+#endif // OPERAAPI_ADDNODE_H_
#include "OperaAPI.h"
#include "OperaAPI_Volume.h"
+ #include "OperaAPI_AddNode.h"
#endif // OPERAAPI_SWIG_H_
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
--- /dev/null
+// 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 <ModelAPI_Feature.h>
+
+//=================================================================================================
+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<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
+ std::shared_ptr<GeomAlgoAPI_MakeShape> 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<GeomAlgoAPI_MakeShapeList> 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);
+}
--- /dev/null
+// 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 <OperaPlugin.h>
+#include <OperaPlugin_Tools.h>
+
+#include "GeomAPI_ShapeHierarchy.h"
+#include "GeomAPI_ShapeIterator.h"
+
+#include <GeomAlgoAPI_Boolean.h>
+#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_ShapeBuilder.h>
+#include "GeomAlgoAPI_Tools.h"
+
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_Tools.h>
+
+/**\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<GeomAlgoAPI_MakeShapeList> 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
#include <OperaPlugin_Plugin.h>
#include <OperaPlugin_Volume.h>
+#include <OperaPlugin_AddNode.h>
#include <ModelAPI_Session.h>
-#include <string>
-
// the only created instance of this plugin
static OperaPlugin_Plugin* MY_PRIMITIVES_INSTANCE = new OperaPlugin_Plugin();
{
if (theFeatureID == OperaPlugin_Volume::ID()) {
return FeaturePtr(new OperaPlugin_Volume);
+ } else if (theFeatureID == OperaPlugin_AddNode::ID()) {
+ return FeaturePtr(new OperaPlugin_AddNode);
} else {
return FeaturePtr();
}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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 <GeomAPI_Face.h>
+#include <GeomAPI_Shape.h>
+
+#include <GeomAlgoAPI_MakeShape.h>
+#include <GeomAlgoAPI_MakeShapeCustom.h>
+#include <GeomAlgoAPI_MakeShapeList.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_ResultBody.h>
+
+GeomShapePtr shapeOfSelection(AttributeSelectionPtr theSel);
+
+#endif
{
}
-//=================================================================================================
-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()
{
</context>
<context>
- <name>Volume:medium</name>
+ <name>AddNode</name>
+ <message>
+ <source>AddNode</source>
+ <translation>AddNode</translation>
+ </message>
+ <message>
+ <source>Perform OPERA Add Node</source>
+ <translation>Faire un AddNode OPERA</translation>
+ </message>
+ </context>
+
+ <context>
+ <name>AddNode:medium</name>
<message>
<source>Medium</source>
<translation>Milieu</translation>
</message>
</context>
+
+
+
+
+ <context>
+ <name>AddNode:main_object</name>
+ <message>
+ <source>Main object</source>
+ <translation>Objet Principal</translation>
+ </message>
+ <message>
+ <source>Select a main object</source>
+ <translation>Veuillez séléctioner un objet principal</translation>
+ </message>
+ </context>
+
+ <context>
+ <name>Volume:tools_list</name>
+ <message>
+ <source>Tools objects</source>
+ <translation>Outils</translation>
+ </message>
+ <message>
+ <source>Select solid objects as tools</source>
+ <translation>Sélectionnez les outils</translation>
+ </message>
+ </context>
+
+ <context>
+ <name>Volume:main_object</name>
+ <message>
+ <source>Attribute "%1" is not initialized.</source>
+ <translation>Sélectionnez un object principal.</translation>
+ </message>
+ </context>
+ <context>
+ <name>Volume:tools_list</name>
+ <message>
+ <source>Attribute "%2" is not initialized.</source>
+ <translation>Sélectionnez les outils.</translation>
+ </message>
+ </context>
+
</TS>
--- /dev/null
+# 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
+#=========================================================================
--- /dev/null
+<source>
+ <shape_selector id="main_object"
+ label="Main object"
+ tooltip="Select a main object"
+ shape_types="solids">
+ <validator id="GeomValidators_ShapeType" parameters="solid"/>
+ </shape_selector>
+ <multi_selector id="tools_list"
+ label="Tools objects"
+ tooltip="Select solid objects as tools"
+ shape_types="solids"
+ concealment="true">
+ <validator id="PartSet_DifferentObjects"/>
+ <validator id="GeomValidators_ShapeType" parameters="solid"/>
+ </multi_selector>
+</source>
:maxdepth: 1
volumeFeature.rst
+ addnodeFeature.rst
--- /dev/null
+
+ .. _tui_create_addnode:
+
+Create Add Node
+=============
+
+.. literalinclude:: examples/addnode.py
+ :linenos:
+ :language: python
+
+:download:`Download this script <examples/addnode.py>`
--- /dev/null
+.. |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.
--- /dev/null
+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()
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.
.. figure:: images/Volume1.png
:align: center
- Volume created
+ Volume created
**See Also** a sample TUI Script of :ref:`tui_create_volume` operation.
helpfile="volumeFeature.html">
<source path="volume_widget.xml"/>
</feature>
+ <feature id="AddNode"
+ title="AddNode"
+ tooltip="Perform OPERA Add Node"
+ icon="icons/Opera/AddNode.png"
+ auto_preview="true"
+ helpfile="addnodeFeature.html">
+ <source path="addnode_widget.xml"/>
+ </feature>
</group>
</workbench>
</plugin>
SET(TEST_NAMES
TestVolume.py
+ TestAddNode.py
)
"""
from OperaAPI import addVolume
+from OperaAPI import addAddNode