//==================================================================================================
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);
}
}
}
//==================================================================================================
-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();
}
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));
}
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
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
/// Set tools list
OPERAAPI_EXPORT
- void setToolsList(const std::list<ModelHighAPI_Selection>& theToolsList);
+ void setToolObject(const ModelHighAPI_Selection& theTool);
/// Dump wrapped feature
OPERAAPI_EXPORT
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_
#include <ModelAPI_Feature.h>
+#include <iostream>
+
//=================================================================================================
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);
}
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();
</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>
#=========================================================================
# Initialization of the test
#=========================================================================
+from GeomAPI import GeomAPI_Shape
from salome.shaper import model
model.begin()
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
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>
#. 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
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
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()