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 = selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
38 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
39 AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
40 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
44 ResultPtr aContext = anObjectAttr->context();
45 ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext);
46 if(aResCompSolidPtr.get()) {
47 std::shared_ptr<GeomAPI_Shape> aContextShape = aResCompSolidPtr->shape();
48 std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
49 for(; anIt != aCompSolidsObjects.end(); anIt++) {
50 if(anIt->first->isEqual(aContextShape)) {
51 aCompSolidsObjects[anIt->first].push_back(anObject);
55 if(anIt == aCompSolidsObjects.end()) {
56 aCompSolidsObjects[aContextShape].push_back(anObject);
59 anObjects.push_back(anObject);
63 // Collecting solids from compsolids which will not be modified in boolean operation and will be added to result.
64 ListOfShape aShapesToAdd;
65 for(std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
66 anIt != aCompSolidsObjects.end(); anIt++) {
67 std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
68 ListOfShape& aUsedInOperationSolids = anIt->second;
69 anObjects.insert(anObjects.end(), aUsedInOperationSolids.begin(), aUsedInOperationSolids.end());
71 // Collect solids from compsolid which will not be modified in boolean operation.
72 for(GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
73 std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
74 ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
75 for(; anIt != aUsedInOperationSolids.end(); anIt++) {
76 if(aSolidInCompSolid->isEqual(*anIt)) {
80 if(anIt == aUsedInOperationSolids.end()) {
81 aShapesToAdd.push_back(aSolidInCompSolid);
86 if(anObjects.size() < 2) {
87 setError("Error: Not enough objects for operation. Should be at least 2.");
93 aTools.splice(aTools.begin(), anObjects, anObjects.begin());
94 std::shared_ptr<GeomAlgoAPI_Boolean> aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects,
96 GeomAlgoAPI_Boolean::BOOL_FUSE));
98 // Checking that the algorithm worked properly.
99 GeomAlgoAPI_MakeShapeList aMakeShapeList;
100 GeomAPI_DataMapOfShapeShape aMapOfShapes;
101 if(!aFuseAlgo->isDone()) {
102 setError("Error: Boolean algorithm failed.");
105 if(aFuseAlgo->shape()->isNull()) {
106 setError("Error: Resulting shape is Null.");
109 if(!aFuseAlgo->isValid()) {
110 setError("Error: Resulting shape is not valid.");
114 GeomShapePtr aShape = aFuseAlgo->shape();
115 aMakeShapeList.appendAlgo(aFuseAlgo);
116 aMapOfShapes.merge(aFuseAlgo->mapOfSubShapes());
118 // Store original shapes for naming.
119 anObjects.splice(anObjects.begin(), aTools);
120 anObjects.insert(anObjects.end(), aShapesToAdd.begin(), aShapesToAdd.end());
122 // Combine result with not used solids from compsolid.
123 if(aShapesToAdd.size() > 0) {
124 aShapesToAdd.push_back(aShape);
125 std::shared_ptr<GeomAlgoAPI_PaveFiller> aFillerAlgo(new GeomAlgoAPI_PaveFiller(aShapesToAdd, true));
126 if(!aFillerAlgo->isDone()) {
127 setError("Error: PaveFiller algorithm failed.");
130 if(aFillerAlgo->shape()->isNull()) {
131 setError("Error: Resulting shape is Null.");
134 if(!aFillerAlgo->isValid()) {
135 setError("Error: Resulting shape is not valid.");
139 aShape = aFillerAlgo->shape();
140 aMakeShapeList.appendAlgo(aFillerAlgo);
141 aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes());
144 // Store result and naming.
145 const int aModifyTag = 1;
146 const int aDeletedTag = 2;
147 const int aSubsolidsTag = 3; /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
148 const std::string aModName = "Modified";
150 std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
151 aResultBody->storeModified(anObjects.front(), aShape, aSubsolidsTag);
153 for(ListOfShape::const_iterator anIter = anObjects.begin(); anIter != anObjects.end(); ++anIter) {
154 aResultBody->loadAndOrientModifiedShapes(&aMakeShapeList, *anIter, GeomAPI_Shape::FACE,
155 aModifyTag, aModName, aMapOfShapes);
156 aResultBody->loadDeletedShapes(&aMakeShapeList, *anIter, GeomAPI_Shape::FACE, aDeletedTag);
159 setResult(aResultBody);