]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
first implementation of AddNode for OPERA, case 1 and 2 cgt/opera_970 nrn/Opera/AddNode
authorNicolas RECHATIN <nicolas.rechatin@cea.fr>
Thu, 5 Aug 2021 10:26:08 +0000 (12:26 +0200)
committerNicolas Rechatin <nicolas.rechatin@cea.fr>
Fri, 4 Feb 2022 09:10:36 +0000 (10:10 +0100)
27 files changed:
src/OperaAPI/CMakeLists.txt
src/OperaAPI/OperaAPI.i
src/OperaAPI/OperaAPI_AddNode.cpp [new file with mode: 0644]
src/OperaAPI/OperaAPI_AddNode.h [new file with mode: 0644]
src/OperaAPI/OperaAPI_swig.h
src/OperaPlugin/CMakeLists.txt
src/OperaPlugin/OperaPlugin_AddNode.cpp [new file with mode: 0644]
src/OperaPlugin/OperaPlugin_AddNode.h [new file with mode: 0644]
src/OperaPlugin/OperaPlugin_Plugin.cpp
src/OperaPlugin/OperaPlugin_Tools.cpp [new file with mode: 0644]
src/OperaPlugin/OperaPlugin_Tools.h [new file with mode: 0644]
src/OperaPlugin/OperaPlugin_Volume.cpp
src/OperaPlugin/OperaPlugin_msg_fr.ts
src/OperaPlugin/Test/TestAddNode.py [new file with mode: 0644]
src/OperaPlugin/addnode_widget.xml [new file with mode: 0644]
src/OperaPlugin/doc/OperaPlugin.rst
src/OperaPlugin/doc/TUI_addnode.rst [new file with mode: 0644]
src/OperaPlugin/doc/addnodeFeature.rst [new file with mode: 0644]
src/OperaPlugin/doc/examples/addnode.py [new file with mode: 0644]
src/OperaPlugin/doc/images/AddNode.png [new file with mode: 0644]
src/OperaPlugin/doc/images/AddNode1.png [new file with mode: 0644]
src/OperaPlugin/doc/images/AddNode_button.png [new file with mode: 0644]
src/OperaPlugin/doc/volumeFeature.rst
src/OperaPlugin/icons/AddNode.png [new file with mode: 0644]
src/OperaPlugin/plugin-Opera.xml
src/OperaPlugin/tests.set
src/PythonAPI/model/opera/__init__.py

index a9da8f18117f4f4f129143e05046e23d8e1e6e2f..192634bd9499106eef3ad810b5c6aea2937bbecc 100644 (file)
@@ -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
index 6bbadc5250aa4705b23c4d48bbf4b3e05705ee48..57223e944fcc8eb69f6f70f38eeaf8a427fe3df1 100644 (file)
@@ -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 (file)
index 0000000..74d578d
--- /dev/null
@@ -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 <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 ModelHighAPI_Selection& theTool)
+                                                                      : ModelHighAPI_Interface(theFeature)
+{
+  if(initialize()) {
+    fillAttribute(theMainObject, mainObject());
+    setToolObject(theTool);
+  }
+}
+
+//==================================================================================================
+OperaAPI_AddNode::~OperaAPI_AddNode()
+{
+}
+
+//==================================================================================================
+void OperaAPI_AddNode::setMainObject(const ModelHighAPI_Selection& theMainObject)
+{
+  fillAttribute(theMainObject, mainObject());
+  execute();
+}
+
+//==================================================================================================
+void OperaAPI_AddNode::setToolObject(const ModelHighAPI_Selection& theTool)
+{
+  fillAttribute(theTool, toolObject());
+  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 << ", ";
+
+  AttributeSelectionPtr anAttrTool =
+    aBase->selection(OperaPlugin_AddNode::TOOL_OBJECT_ID());
+  theDumper << anAttrTool << ")" << std::endl;
+}
+
+//==================================================================================================
+AddNodePtr addAddNode(const std::shared_ptr<ModelAPI_Document>& thePart,
+                      const ModelHighAPI_Selection& theMainObject,
+                      const ModelHighAPI_Selection& theTool)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(OperaAPI_AddNode::ID());
+  return AddNodePtr(new OperaAPI_AddNode(aFeature, theMainObject, theTool));
+}
diff --git a/src/OperaAPI/OperaAPI_AddNode.h b/src/OperaAPI/OperaAPI_AddNode.h
new file mode 100644 (file)
index 0000000..0fa0bce
--- /dev/null
@@ -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 <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 ModelHighAPI_Selection& theTool);
+
+  /// Destructor.
+  OPERAAPI_EXPORT
+  virtual ~OperaAPI_AddNode();
+
+  INTERFACE_2(OperaPlugin_AddNode::ID(),
+              mainObject, OperaPlugin_AddNode::MAIN_OBJECT_ID(),
+              ModelAPI_AttributeSelection, /** Main Object */,
+              toolObject, OperaPlugin_AddNode::TOOL_OBJECT_ID(),
+              ModelAPI_AttributeSelection, /** Tool Object*/)
+
+  /// Set main object
+  OPERAAPI_EXPORT
+  void setMainObject(const ModelHighAPI_Selection& theMainObject);
+
+  /// Set tools list
+  OPERAAPI_EXPORT
+  void setToolObject(const ModelHighAPI_Selection& theTool);
+
+  /// 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 ModelHighAPI_Selection& theTool);
+
+#endif // OPERAAPI_ADDNODE_H_
index eaa088dc9cccce96e2e13d36f6c4d08b026b89fc..661e51618f795b5a7a8fa05390875eeefab5acf4 100644 (file)
@@ -24,5 +24,6 @@
 
   #include "OperaAPI.h"
   #include "OperaAPI_Volume.h"
+  #include "OperaAPI_AddNode.h"
 
 #endif // OPERAAPI_SWIG_H_
index a1f7fd6002df40552a1e1df478d468f9b99bc432..92f3460c8caad5b64941d9c24c843f64fbf1cba1 100644 (file)
 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 (file)
index 0000000..7054d83
--- /dev/null
@@ -0,0 +1,132 @@
+// 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(TOOL_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+}
+
+
+//=================================================================================================
+void OperaPlugin_AddNode::handleNaming(const GeomMakeShapePtr& theBoolAlgo,
+                                       const GeomShapePtr theTool,
+                                       const ListOfShape& theToolsList)
+{
+  //Get result shape
+  int anIndexToRemove = 0;
+  GeomShapePtr theResShape = theBoolAlgo->shape();
+
+  std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
+  aMakeShapeList->appendAlgo(theBoolAlgo);
+
+  // Result list
+  ListOfShape aResList;
+  if (!theToolsList.empty())
+    for (auto it = theToolsList.begin(); it != theToolsList.end(); it++)
+      aResList.push_back(*it);
+  aResList.push_front(theResShape);
+  aResList.push_back(theTool);
+
+  //Build result compund
+  GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aResList);
+  if (aCompound) {
+    ResultBodyPtr aResultBody = document()->createBody(data(), anIndexToRemove++);
+    aResultBody->storeModified(aResList, aCompound, theBoolAlgo);
+    aResultBody->loadModifiedShapes(aMakeShapeList, aCompound, GeomAPI_Shape::VERTEX);
+    aResultBody->loadModifiedShapes(aMakeShapeList, aCompound, GeomAPI_Shape::EDGE);
+    aResultBody->loadModifiedShapes(aMakeShapeList, aCompound, GeomAPI_Shape::FACE);
+    setResult(aResultBody);
+  }
+}
+
+
+//=================================================================================================
+void OperaPlugin_AddNode::performAlgo(const GeomShapePtr& theObject,
+                                      GeomShapePtr theTool,
+                                      const ListOfShape& theToolsList)
+{
+  //Intersecting tool case
+  if (theObject->intersect(theTool)){
+    std::shared_ptr<GeomAlgoAPI_MakeShape> aCommonAlgo;
+    aCommonAlgo.reset(new GeomAlgoAPI_Boolean(theObject,
+                                              theTool,
+                                              GeomAlgoAPI_Tools::BOOL_COMMON));
+    theTool = aCommonAlgo->shape();
+  }
+
+  //Perform algorithm
+  std::shared_ptr<GeomAlgoAPI_MakeShape> aBoolAlgo;
+  aBoolAlgo.reset(new GeomAlgoAPI_Boolean(theObject,
+                                          theTool,
+                                          GeomAlgoAPI_Tools::BOOL_CUT));
+  //Check for error
+  std::string anError;
+  if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError))
+    return setError(anError);
+
+  //Naming
+  handleNaming(aBoolAlgo, theTool, theToolsList);
+}
+
+//=================================================================================================
+void OperaPlugin_AddNode::execute()
+{
+  ListOfShape aToolList;
+
+  //Get Selection and Shapes
+  AttributeSelectionPtr aMainObjectAttr = selection(MAIN_OBJECT_ID());
+  AttributeSelectionPtr aToolsAttrList = selection(TOOL_OBJECT_ID());
+
+  // Get Shapes from selection
+  GeomShapePtr aMainObjectShape = shapeOfSelection(aMainObjectAttr);
+  GeomShapePtr aToolShape = shapeOfSelection(aToolsAttrList);
+
+  // Get older tools and main shape
+  if (aMainObjectShape->shapeType() == GeomAPI_Shape::COMPOUND){
+    ListOfShape aMainObjectSubShapes = aMainObjectShape->subShapes(GeomAPI_Shape::SOLID);
+    for (auto it = aMainObjectSubShapes.begin(); it != aMainObjectSubShapes.end(); it++) {
+      if (it == aMainObjectSubShapes.begin())
+        aMainObjectShape = *it;
+      else
+        aToolList.push_back(*it);
+    }
+  }
+
+  // Get Case
+  if (!aMainObjectShape->isIntersect(aToolShape))
+    return setError("Error: All tools must intersect the main object");
+  if(aMainObjectShape == nullptr )
+    return setError("Error: cannot perform an AddNode with no main object.");
+  if(aToolShape == nullptr)
+    return setError("Error: cannot perform an AddNode with no tool object.");
+
+  //Perform Algorithm
+  performAlgo(aMainObjectShape, aToolShape, aToolList);
+}
diff --git a/src/OperaPlugin/OperaPlugin_AddNode.h b/src/OperaPlugin/OperaPlugin_AddNode.h
new file mode 100644 (file)
index 0000000..f10b429
--- /dev/null
@@ -0,0 +1,97 @@
+// 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 tool object.
+    inline static const std::string& TOOL_OBJECT_ID()
+    {
+      static const std::string MY_TOOL_OBJECT_ID("tool_object");
+      return MY_TOOL_OBJECT_ID;
+    }
+
+    /// Perform boolean alogrithm according to AddNode cases
+    void performAlgo(const GeomShapePtr& theObject,
+                     GeomShapePtr theTool,
+                     const ListOfShape& theToolsList);
+
+    /// Creates naming for AddNode results
+    void OperaPlugin_AddNode::handleNaming(const GeomMakeShapePtr& theBoolAlgo,
+                                           const GeomShapePtr theTool,
+                                           const ListOfShape& theToolsList);
+
+    /// 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
index 894925751c8bcf529ff952bc4bfb5bcde0ddcd9b..7ffeab434d59ee01e116639eaa5f4dbb1eb268db 100644 (file)
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
+#include <OperaPlugin_AddNode.h>
 #include <OperaPlugin_Plugin.h>
 #include <OperaPlugin_Volume.h>
 
 #include <ModelAPI_Session.h>
 
-#include <string>
-
 // 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 (file)
index 0000000..8ca4594
--- /dev/null
@@ -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 (file)
index 0000000..ba8b76e
--- /dev/null
@@ -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 <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
index 57393a226d90bb89e5c6ee69e4e4c34988ee4e9d..5a2b69613e67294162c8eec26836020b1b7f7a13 100644 (file)
@@ -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()
 {
index aca1a88156482398b807c9d6ba0d1129a502a869..fed606565e8d71c9e578c2a881e895072151fb20 100644 (file)
   </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:tool_object</name>
+    <message>
+      <source>Tool object</source>
+      <translation>Outil</translation>
+    </message>
+    <message>
+      <source>Select a tool object</source>
+      <translation>Veuillez séléctioner un outil</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:tool_object</name>
+    <message>
+      <source>Attribute "%2" is not initialized.</source>
+      <translation>Sélectionnez un outil.</translation>
+    </message>
+  </context>
+
 </TS>
diff --git a/src/OperaPlugin/Test/TestAddNode.py b/src/OperaPlugin/Test/TestAddNode.py
new file mode 100644 (file)
index 0000000..40a53f7
--- /dev/null
@@ -0,0 +1,76 @@
+# 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 GeomAPI import GeomAPI_Shape
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+### Create Box
+Box_1 = model.addBox(Part_1_doc, 0, 0, 0, 20, 20, 20)
+Box_2 = model.addBox(Part_1_doc, 10, 0, -10, 5, 5, 5)
+Box_3 = model.addBox(Part_1_doc, 0, 0, 20, 10, 10, 10)
+Box_4 = model.addBox(Part_1_doc, 0, 0, 0, 2, 2, 2)
+Box_5 = model.addBox(Part_1_doc, -3, -3, -3, 3, 3, 3)
+Box_6 = model.addBox(Part_1_doc, -10, 13, -10, 7, 7, 7)
+Box_7 = model.addBox(Part_1_doc, 35, 35, 35, 10, 10, 10) #ERROR : Box is outside main Object
+Box_8 = model.addBox(Part_1_doc, 0, 0, 0, 10, 10, 10)    #ERROR : For test with no Main Object
+Box_9 = model.addBox(Part_1_doc, 0, 0, 0, 10, 10, 10)    #ERROR : For test with no Main Object
+
+### Create addNodes
+AddNode_1 = model.addAddNode(Part_1_doc, model.selection("SOLID", "Box_1_1"), model.selection("SOLID", "Box_2_1"))
+AddNode_2 = model.addAddNode(Part_1_doc, model.selection("SOLID", "AddNode_1_1"), model.selection("SOLID", "Box_3_1"))
+AddNode_3 = model.addAddNode(Part_1_doc, model.selection("SOLID", "AddNode_2_1"), model.selection("SOLID", "Box_4_1"))
+AddNode_4 = model.addAddNode(Part_1_doc, model.selection("SOLID", "AddNode_3_1"), model.selection("SOLID", "Box_5_1"))
+AddNode_5 = model.addAddNode(Part_1_doc, model.selection("SOLID", "AddNode_4_1"), model.selection("SOLID", "Box_6_1"))
+
+# # #Checks
+model.testNbResults(AddNode_5, 1)
+model.testNbSubResults(AddNode_5, [6])
+model.testNbSubShapes(AddNode_5, GeomAPI_Shape.SOLID, [6])
+model.testHaveNamingFaces(AddNode_5, model, Part_1_doc)
+
+# ### Create a AddNode with tools outside the main object
+AddNode_6 = model.addAddNode(Part_1_doc, model.selection("SOLID", "AddNode_5_1"), model.selection("SOLID", "Box_7_1"))
+model.testNbResults(AddNode_6, 0)
+assert(AddNode_6.feature().error() == "Error: All tools must intersect the main object")
+
+### Create a AddNode with no main object
+AddNode_7 = model.addAddNode(Part_1_doc, model.selection("SOLID", "None"), model.selection("SOLID", "Box_8_1"))
+model.testNbResults(AddNode_7, 0)
+assert(AddNode_7.feature().error() == "Attribute \"main_object\" is not initialized.")
+
+### Create a AddNode with no tools
+AddNode_8 = model.addAddNode(Part_1_doc, model.selection("SOLID", "Box_9_1"), model.selection("SOLID", "None"))
+model.testNbResults(AddNode_8, 0)
+assert(AddNode_8.feature().error() == "Attribute \"tool_object\" is not initialized.")
+
+#=========================================================================
+# End of test
+#=========================================================================
diff --git a/src/OperaPlugin/addnode_widget.xml b/src/OperaPlugin/addnode_widget.xml
new file mode 100644 (file)
index 0000000..12bb3d6
--- /dev/null
@@ -0,0 +1,16 @@
+<source>
+  <shape_selector id="main_object"
+                  label="Main object"
+                  tooltip="Select a main object"
+                  shape_types="solids"
+                  concealment="true">
+    <validator id="GeomValidators_ShapeType" parameters="solid"/>
+  </shape_selector>
+  <shape_selector id="tool_object"
+                  label="Tool object"
+                  tooltip="Select a tool object"
+                  shape_types="solids"
+                  concealment="true">
+    <validator id="GeomValidators_ShapeType" parameters="solid"/>
+  </shape_selector>
+</source>
index f61f280bdf90485c39c5db0d10508ad37dfdd01c..0e61c3302c1b8ede681c76602ec779ce41f9ecc1 100644 (file)
@@ -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 (file)
index 0000000..fdd30ce
--- /dev/null
@@ -0,0 +1,11 @@
+
+  .. _tui_create_addnode:
+
+Create Add Node
+=============
+
+.. literalinclude:: examples/addnode.py
+    :linenos:
+    :language: python
+
+:download:`Download this script <examples/addnode.py>`
diff --git a/src/OperaPlugin/doc/addnodeFeature.rst b/src/OperaPlugin/doc/addnodeFeature.rst
new file mode 100644 (file)
index 0000000..667f775
--- /dev/null
@@ -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 tool object
+
+.. figure:: images/AddNode.png
+   :align: center
+
+Input fields:
+
+- **MainOject** defines the solid main object;
+- **Tool** defines the tool object
+
+**TUI Command**:
+
+.. py:function::
+    model.addAddNode(Part_doc, model.selection("SOLID", main_object_name), model.selection("SOLID", main_object_name))
+
+    :param part: The current part object.
+    :param object: A main object solid.
+    :param object: A tool object solid.
+    :return: Result compound.
+
+Result
+""""""
+
+One compound with the boolean operation result and the tools objects used on the geometry below it. Depends 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 (file)
index 0000000..a330ab6
--- /dev/null
@@ -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 (file)
index 0000000..64a1755
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 (file)
index 0000000..3df2991
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 (file)
index 0000000..9265aff
Binary files /dev/null and b/src/OperaPlugin/doc/images/AddNode_button.png differ
index 8ea5c85480358c963e881804d5a4095075afd11c..25e9ead045200d90998a2767f07c3d95582cdb09 100644 (file)
@@ -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 (file)
index 0000000..457dc0f
Binary files /dev/null and b/src/OperaPlugin/icons/AddNode.png differ
index f16bf394b0218e0cfd07a44f8b4324de15645942..90fc01f3395236044abaa3093c200a26927a7aa6 100644 (file)
@@ -9,6 +9,14 @@
                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>
index 019d00b2f6438c69a3cd75923337998c026767b3..cd7e55f0d4a96a132f6273f1ae378efe802a9fb7 100644 (file)
@@ -19,4 +19,5 @@
 
 SET(TEST_NAMES
               TestVolume.py
+              TestAddNode.py
 )
index a13965476a47e75489087eb2fa529c0a336b4e2a..a1aa77d1da15c7fc661a5fb8d3e3acea7359577a 100644 (file)
@@ -20,3 +20,4 @@
 """
 
 from OperaAPI import addVolume
+from OperaAPI import addAddNode