1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: FeaturesPlugin_Union.cpp
4 // Created: 17 June 2016
5 // Author: Dmitry Bobylev
7 #include "FeaturesPlugin_Union.h"
9 #include <GeomAlgoAPI_Boolean.h>
10 #include <GeomAlgoAPI_MakeShapeList.h>
11 #include <GeomAlgoAPI_PaveFiller.h>
13 #include <GeomAPI_ShapeExplorer.h>
15 #include <ModelAPI_AttributeSelectionList.h>
16 #include <ModelAPI_ResultCompSolid.h>
17 #include <ModelAPI_Tools.h>
19 //=================================================================================================
20 FeaturesPlugin_Union::FeaturesPlugin_Union()
24 //=================================================================================================
25 void FeaturesPlugin_Union::initAttributes()
27 data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
30 //=================================================================================================
31 void FeaturesPlugin_Union::execute()
33 ListOfShape anObjects;
34 std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape> aCompSolidsObjects;
37 AttributeSelectionListPtr anObjectsSelList =
38 selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
39 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
40 AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
41 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
45 ResultPtr aContext = anObjectAttr->context();
46 ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext);
47 if(aResCompSolidPtr.get()) {
48 std::shared_ptr<GeomAPI_Shape> aContextShape = aResCompSolidPtr->shape();
49 std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
50 anIt = aCompSolidsObjects.begin();
51 for(; anIt != aCompSolidsObjects.end(); anIt++) {
52 if(anIt->first->isEqual(aContextShape)) {
53 aCompSolidsObjects[anIt->first].push_back(anObject);
57 if(anIt == aCompSolidsObjects.end()) {
58 aCompSolidsObjects[aContextShape].push_back(anObject);
61 anObjects.push_back(anObject);
65 // Collecting solids from compsolids which will not be modified in
66 // boolean operation and will be added to result.
67 ListOfShape aShapesToAdd;
68 for(std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
69 anIt = aCompSolidsObjects.begin();
70 anIt != aCompSolidsObjects.end(); anIt++) {
71 std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
72 ListOfShape& aUsedInOperationSolids = anIt->second;
73 anObjects.insert(anObjects.end(), aUsedInOperationSolids.begin(), aUsedInOperationSolids.end());
75 // Collect solids from compsolid which will not be modified in boolean operation.
76 for(GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
77 std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
78 ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
79 for(; anIt != aUsedInOperationSolids.end(); anIt++) {
80 if(aSolidInCompSolid->isEqual(*anIt)) {
84 if(anIt == aUsedInOperationSolids.end()) {
85 aShapesToAdd.push_back(aSolidInCompSolid);
90 if(anObjects.size() < 2) {
91 setError("Error: Not enough objects for operation. Should be at least 2.");
97 aTools.splice(aTools.begin(), anObjects, anObjects.begin());
98 std::shared_ptr<GeomAlgoAPI_Boolean> aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects,
100 GeomAlgoAPI_Boolean::BOOL_FUSE));
102 // Checking that the algorithm worked properly.
103 GeomAlgoAPI_MakeShapeList aMakeShapeList;
104 GeomAPI_DataMapOfShapeShape aMapOfShapes;
105 if(!aFuseAlgo->isDone()) {
106 setError("Error: Boolean algorithm failed.");
109 if(aFuseAlgo->shape()->isNull()) {
110 setError("Error: Resulting shape is Null.");
113 if(!aFuseAlgo->isValid()) {
114 setError("Error: Resulting shape is not valid.");
118 GeomShapePtr aShape = aFuseAlgo->shape();
119 aMakeShapeList.appendAlgo(aFuseAlgo);
120 aMapOfShapes.merge(aFuseAlgo->mapOfSubShapes());
122 // Store original shapes for naming.
123 anObjects.splice(anObjects.begin(), aTools);
124 anObjects.insert(anObjects.end(), aShapesToAdd.begin(), aShapesToAdd.end());
126 // Combine result with not used solids from compsolid.
127 if(aShapesToAdd.size() > 0) {
128 aShapesToAdd.push_back(aShape);
129 std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(
130 new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
131 if(!aFillerAlgo->isDone()) {
132 setError("Error: PaveFiller algorithm failed.");
135 if(aFillerAlgo->shape()->isNull()) {
136 setError("Error: Resulting shape is Null.");
139 if(!aFillerAlgo->isValid()) {
140 setError("Error: Resulting shape is not valid.");
144 aShape = aFillerAlgo->shape();
145 aMakeShapeList.appendAlgo(aFillerAlgo);
146 aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
149 // Store result and naming.
150 const int aModifyTag = 1;
151 const int aDeletedTag = 2;
152 /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
153 const int aSubsolidsTag = 3;
154 const std::string aModName = "Modified";
156 std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
157 aResultBody->storeModified(anObjects.front(), aShape, aSubsolidsTag);
159 for(ListOfShape::const_iterator anIter = anObjects.begin(); anIter != anObjects.end(); ++anIter) {
160 aResultBody->loadAndOrientModifiedShapes(&aMakeShapeList, *anIter, GeomAPI_Shape::FACE,
161 aModifyTag, aModName, aMapOfShapes);
162 aResultBody->loadDeletedShapes(&aMakeShapeList, *anIter, GeomAPI_Shape::FACE, aDeletedTag);
165 setResult(aResultBody);