]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Feature AddNode v1.0
authorNicolas Rechatin <nicolas.rechatin@cea.fr>
Wed, 13 Oct 2021 10:12:22 +0000 (12:12 +0200)
committerNicolas Rechatin <nicolas.rechatin@cea.fr>
Wed, 13 Oct 2021 10:12:22 +0000 (12:12 +0200)
src/OperaAPI/OperaAPI_AddNode.cpp
src/OperaAPI/OperaAPI_AddNode.h
src/OperaPlugin/OperaPlugin_AddNode.cpp
src/OperaPlugin/OperaPlugin_AddNode.h
src/OperaPlugin/OperaPlugin_msg_fr.ts
src/OperaPlugin/Test/TestAddNode.py
src/OperaPlugin/addnode_widget.xml
src/OperaPlugin/doc/addnodeFeature.rst
src/OperaPlugin/doc/examples/addnode.py

index 29785805462b6a1c6622dac82276b4d866ef5a3d..74d578de993394f45fb600ed943c966069a6749a 100644 (file)
@@ -32,12 +32,12 @@ OperaAPI_AddNode::OperaAPI_AddNode(const std::shared_ptr<ModelAPI_Feature>& theF
 //==================================================================================================
 OperaAPI_AddNode::OperaAPI_AddNode(const std::shared_ptr<ModelAPI_Feature>& theFeature,
                                    const ModelHighAPI_Selection& theMainObject,
-                                   const std::list<ModelHighAPI_Selection>& theToolsList)
-                                                                  : ModelHighAPI_Interface(theFeature)
+                                   const ModelHighAPI_Selection& theTool)
+                                                                      : ModelHighAPI_Interface(theFeature)
 {
   if(initialize()) {
     fillAttribute(theMainObject, mainObject());
-    setToolsList(theToolsList);
+    setToolObject(theTool);
   }
 }
 
@@ -54,9 +54,9 @@ void OperaAPI_AddNode::setMainObject(const ModelHighAPI_Selection& theMainObject
 }
 
 //==================================================================================================
-void OperaAPI_AddNode::setToolsList(const std::list<ModelHighAPI_Selection>& theToolsList)
+void OperaAPI_AddNode::setToolObject(const ModelHighAPI_Selection& theTool)
 {
-  fillAttribute(theToolsList, toolsList());
+  fillAttribute(theTool, toolObject());
   execute();
 }
 
@@ -69,16 +69,16 @@ void OperaAPI_AddNode::dump(ModelHighAPI_Dumper& theDumper) const
   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;
+  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 std::list<ModelHighAPI_Selection>& theToolsList)
+                      const ModelHighAPI_Selection& theTool)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(OperaAPI_AddNode::ID());
-  return AddNodePtr(new OperaAPI_AddNode(aFeature, theMainObject, theToolsList));
+  return AddNodePtr(new OperaAPI_AddNode(aFeature, theMainObject, theTool));
 }
index 2886216276645482cfb76b87c6130423dd7dd2b4..0fa0bce94e97f6700a614ddfe3adcc15de7970ee 100644 (file)
@@ -42,7 +42,7 @@ public:
   OPERAAPI_EXPORT
   explicit OperaAPI_AddNode(const std::shared_ptr<ModelAPI_Feature>& theFeature,
                             const ModelHighAPI_Selection& theMainObject,
-                            const std::list<ModelHighAPI_Selection>& theToolsList);
+                            const ModelHighAPI_Selection& theTool);
 
   /// Destructor.
   OPERAAPI_EXPORT
@@ -51,8 +51,8 @@ public:
   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*/)
+              toolObject, OperaPlugin_AddNode::TOOL_OBJECT_ID(),
+              ModelAPI_AttributeSelection, /** Tool Object*/)
 
   /// Set main object
   OPERAAPI_EXPORT
@@ -60,7 +60,7 @@ public:
 
   /// Set tools list
   OPERAAPI_EXPORT
-  void setToolsList(const std::list<ModelHighAPI_Selection>& theToolsList);
+  void setToolObject(const ModelHighAPI_Selection& theTool);
 
   /// Dump wrapped feature
   OPERAAPI_EXPORT
@@ -75,6 +75,6 @@ typedef std::shared_ptr<OperaAPI_AddNode> AddNodePtr;
 OPERAAPI_EXPORT
 AddNodePtr addAddNode(const std::shared_ptr<ModelAPI_Document>& thePart,
                       const ModelHighAPI_Selection& theMainObject,
-                      const std::list<ModelHighAPI_Selection>& theToolsList);
+                      const ModelHighAPI_Selection& theTool);
 
 #endif // OPERAAPI_ADDNODE_H_
index 3908316c618b73f8e8b6910e957b55413e0a1e17..f7b74175f59fe4bc6d6f7f96b301d360383a6193 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <ModelAPI_Feature.h>
 
+#include <iostream>
+
 //=================================================================================================
 OperaPlugin_AddNode::OperaPlugin_AddNode() // Nothing to do during instantiation
 {
@@ -30,105 +32,103 @@ 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());
+  data()->addAttribute(TOOL_OBJECT_ID(), ModelAPI_AttributeSelection::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::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 GeomAlgoAPI_Tools::BOPType theBooleanType,
-                                      const GeomShapePtr& theObject,
-                                      const ListOfShape& theTools,
-                                      const ListOfShape& thePlanes,
-                                      int& theResultIndex)
+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
-  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));
+  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(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);
-  }
+  handleNaming(aBoolAlgo, theTool, theToolsList);
 }
 
 //=================================================================================================
 void OperaPlugin_AddNode::execute()
 {
-  int aResultIndex = 0;
-  ListOfShape aPlanes, aToolList;
+  ListOfShape aToolList;
 
   //Get Selection and Shapes
   AttributeSelectionPtr aMainObjectAttr = selection(MAIN_OBJECT_ID());
-  AttributeSelectionListPtr aToolsAttrList = selectionList(TOOLS_LIST_ID());
+  AttributeSelectionPtr aToolsAttrList = selection(TOOL_OBJECT_ID());
 
-  // Get Shapes from selection and test intersection with Main Object
+  // Get Shapes from selection
   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);
+  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);
+    }
   }
 
-  // Check tools intersections
-  if (toolsIntersect(aToolList))
-    return setError("Error: Tools must not intersect each others");
-
-  //Check for error then clean part results
+  // 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(aToolList.empty())
-    return setError("Error: Tools list cannot be empty.");
+  if(aToolShape == nullptr)
+    return setError("Error: cannot perform an AddNode with no tool object.");
 
   //Perform Algorithm
-  performAlgo(GeomAlgoAPI_Tools::BOOL_CUT,
-              shapeOfSelection(aMainObjectAttr), aToolList, aPlanes,
-              aResultIndex);
+  performAlgo(aMainObjectShape, aToolShape, aToolList);
 }
index 0a41de4ad8116b66fb63c2bb910f9dd38f3ea4d3..f10b429fb227be8b9f50fe230ba2bb1b70599e3b 100644 (file)
@@ -60,25 +60,22 @@ class OperaPlugin_AddNode : public ModelAPI_Feature
       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()
+    /// Attribute name of tool object.
+    inline static const std::string& TOOL_OBJECT_ID()
     {
-      static const std::string MY_TOOLS_LIST_ID("tools_list");
-      return MY_TOOLS_LIST_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 GeomAlgoAPI_Tools::BOPType theBooleanType,
-                     const GeomShapePtr& theObject,
-                     const ListOfShape& theTools,
-                     const ListOfShape& thePlanes,
-                     int& theResultIndex);
+    void performAlgo(const GeomShapePtr& theObject,
+                     GeomShapePtr theTool,
+                     const ListOfShape& theToolsList);
 
     /// Creates naming for AddNode results
-    void OperaPlugin_AddNode::handleNaming(GeomShapePtr theResShape,
-                                           GeomMakeShapePtr theBoolAlgo,
-                                          std::shared_ptr<GeomAlgoAPI_MakeShapeList> theMakeShapeList,
-                                          const ListOfShape& theTools);
+    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();
index 88085affe8a44ca6339976bcec5f32f615db98c0..fed606565e8d71c9e578c2a881e895072151fb20 100644 (file)
     </message>
   </context>
 
-
-
-
-
   <context>
     <name>AddNode:main_object</name>
     <message>
   </context>
 
   <context>
-    <name>Volume:tools_list</name>
+    <name>Volume:tool_object</name>
     <message>
-      <source>Tools objects</source>
-      <translation>Outils</translation>
+      <source>Tool object</source>
+      <translation>Outil</translation>
     </message>
     <message>
-      <source>Select solid objects as tools</source>
-      <translation>Sélectionnez les outils</translation>
+      <source>Select a tool object</source>
+      <translation>Veuillez séléctioner un outil</translation>
     </message>
   </context>
 
     </message>
   </context>
   <context>
-    <name>Volume:tools_list</name>
+    <name>Volume:tool_object</name>
     <message>
       <source>Attribute "%2" is not initialized.</source>
-      <translation>Sélectionnez les outils.</translation>
+      <translation>Sélectionnez un outil.</translation>
     </message>
   </context>
 
index ca0573892d9acf7b9f61cd5683d657f9521b5c30..40a53f74604ef4c29d9c352ac5d0338bc2f5f8d8 100644 (file)
@@ -24,6 +24,7 @@
 #=========================================================================
 # Initialization of the test
 #=========================================================================
+from GeomAPI import GeomAPI_Shape
 from salome.shaper import model
 
 model.begin()
@@ -31,70 +32,44 @@ partSet = model.moduleDocument()
 Part_1 = model.addPart(partSet)
 Part_1_doc = Part_1.document()
 
-### Create two box (one inside the other)
+### Create Box
 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")])
+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: Tools must not intersect each others")
+assert(AddNode_6.feature().error() == "Error: All tools must intersect the main object")
 
-### 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")])
+### 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() == "Error: Tools must not intersect each others")
+assert(AddNode_7.feature().error() == "Attribute \"main_object\" is not initialized.")
 
-
-# TODO : Test with out of bounds tools
-# TODO : Test with intersected tools
+### 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
index 89e424d769e564f97001daaeb2203fd71019361c..12bb3d60dbe9fba3b0bac6e8252969c155abebcc 100644 (file)
@@ -6,12 +6,11 @@
                   concealment="true">
     <validator id="GeomValidators_ShapeType" parameters="solid"/>
   </shape_selector>
-  <multi_selector id="tools_list"
-                  label="Tools objects"
-                  tooltip="Select solid objects as tools"
+  <shape_selector id="tool_object"
+                  label="Tool object"
+                  tooltip="Select a tool object"
                   shape_types="solids"
                   concealment="true">
-    <validator id="PartSet_DifferentObjects"/>
     <validator id="GeomValidators_ShapeType" parameters="solid"/>
-  </multi_selector>
+  </shape_selector>
 </source>
index 1b28e4e042be66d4d6ebcd13b89f466faf9fc786..667f775f4e4a5a06fbaa4727525e9907b1861f34 100644 (file)
@@ -10,7 +10,7 @@ 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
+AddNode is created by a solid as main object and a tool object
 
 .. figure:: images/AddNode.png
    :align: center
@@ -18,22 +18,22 @@ AddNode is created by a solid as main object and a list of solids as tools
 Input fields:
 
 - **MainOject** defines the solid main object;
-- **Tools** defines the list of solid tools
+- **Tool** defines the tool object
 
 **TUI Command**:
 
 .. py:function::
-    model.addAddNode(Part_doc, model.selection("SOLID", main_object_name), model.selection[("SOLID", ...), ...])
+    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 list: A list of tools solids.
+    :param object: A tool object solid.
     :return: Result compound.
 
 Result
 """"""
 
-One compound with the boolean operation result and the tools objects below it, depending on geometry cases
+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
index 8e8aea51ca710adb099b80777de151686d30e1a9..a330ab65b0a9fcab431155d9108b2d997a4381da 100644 (file)
@@ -8,7 +8,7 @@ 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")])
+AddNode_1 = model.addAddNode(Part_1_doc, model.selection("SOLID", "Box_1_1"), model.selection("SOLID", "Box_2_1"))
 
 model.do()
 model.end()