Salome HOME
updated copyright message
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_ExtrusionFuse.cpp
1 // Copyright (C) 2014-2023  CEA, EDF
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "FeaturesPlugin_ExtrusionFuse.h"
21
22 #include <ModelAPI_AttributeString.h>
23 #include <ModelAPI_AttributeSelectionList.h>
24
25 #include <GeomAlgoAPI_Boolean.h>
26 #include <GeomAlgoAPI_Prism.h>
27 #include <GeomAlgoAPI_ThroughAll.h>
28 #include <GeomAlgoAPI_CompoundBuilder.h>
29
30 //=================================================================================================
31 FeaturesPlugin_ExtrusionFuse::FeaturesPlugin_ExtrusionFuse()
32 {
33   myFeature = this;
34   myOperationType = BOOL_FUSE;
35 }
36
37 //=================================================================================================
38 void FeaturesPlugin_ExtrusionFuse::execute()
39 {
40   if (string(CREATION_METHOD())->value() != CREATION_METHOD_THROUGH_ALL())
41     executeCompositeBoolean();
42   else {
43     executeFuseThroughAll();
44   }
45 }
46
47 //=================================================================================================
48 void FeaturesPlugin_ExtrusionFuse::executeFuseThroughAll()
49 {
50   // Getting objects.
51   ListOfShape anObjects;
52   AttributeSelectionListPtr anObjectsSelList = myFeature->selectionList(OBJECTS_ID());
53   for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
54     AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
55     GeomShapePtr anObject = anObjectAttr->value();
56     if (!anObject.get()) {
57       myFeature->setError("Error: Could not get object.");
58       return;
59     }
60     anObjects.push_back(anObject);
61   }
62
63   // Make generation.
64   ListOfShape aGenBaseShapes;
65   ListOfMakeShape aGenMakeShapes;
66   if (!makeGeneration(aGenBaseShapes, aGenMakeShapes)) {
67     return;
68   }
69
70   // Getting tools.
71   ListOfShape aNewTools;
72   ListOfMakeShape aToolsMakeShapes;
73   for (ListOfMakeShape::const_iterator
74          anIt = aGenMakeShapes.cbegin(); anIt != aGenMakeShapes.cend(); ++anIt) {
75     GeomMakeShapePtr anAlgo = (*anIt);
76     std::shared_ptr<GeomAlgoAPI_Prism> aPrismAlgo =
77         std::dynamic_pointer_cast<GeomAlgoAPI_Prism>(anAlgo);
78
79     // Cut the prism by all objects and throw away end pieces
80     std::shared_ptr<GeomAlgoAPI_ThroughAll> aToolAlgo (
81         new GeomAlgoAPI_ThroughAll(aPrismAlgo, anObjects));
82
83     // Checking that the algorithm worked properly
84     if (!aToolAlgo->isDone() || aToolAlgo->shape()->isNull() || !aToolAlgo->isValid()) {
85       myFeature->setError("Error: ThroughAll algorithm failed.");
86     } else {
87       GeomShapePtr aCuttedTool = aToolAlgo->shape();
88       aNewTools.push_back(aCuttedTool);
89       aToolsMakeShapes.push_back(aToolAlgo);
90     }
91   }
92
93   // Perform FeaturesPlugin_CompositeBoolean::makeBoolean() with new (cutted) tools
94   ListOfShape aBooleanObjects;
95   ListOfMakeShape aBooleanMakeShapes;
96   if (!makeBoolean(aNewTools, aBooleanObjects, aBooleanMakeShapes)) {
97     return;
98   }
99
100   if (myOperationType == BOOL_FUSE) {
101     aNewTools.splice(aNewTools.begin(), aBooleanObjects);
102     aBooleanObjects.splice(aBooleanObjects.begin(), aNewTools, aNewTools.begin());
103   }
104
105   // 4. Store result (like in FeaturesPlugin_CompositeBoolean::executeCompositeBoolean())
106   int aResultIndex = 0;
107   std::vector<ResultBaseAlgo> aResultBaseAlgoList;
108   ListOfShape aResultShapesList;
109   ListOfShape::const_iterator aBoolObjIt = aBooleanObjects.cbegin();
110   ListOfMakeShape::const_iterator aBoolMSIt = aBooleanMakeShapes.cbegin();
111   for(; aBoolObjIt != aBooleanObjects.cend() && aBoolMSIt != aBooleanMakeShapes.cend();
112       ++aBoolObjIt, ++aBoolMSIt) {
113
114     ResultBodyPtr aResultBody = myFeature->document()->createBody(myFeature->data(), aResultIndex);
115
116     if((*aBoolObjIt)->isEqual((*aBoolMSIt)->shape())) {
117       aResultBody->store((*aBoolMSIt)->shape(), false);
118     }
119     else
120     {
121       aResultBody->storeModified(*aBoolObjIt, (*aBoolMSIt)->shape());
122
123       // Store generation history.
124       ListOfShape::const_iterator aGenBaseIt = aGenBaseShapes.cbegin();
125       ListOfMakeShape::const_iterator aGenMSIt = aGenMakeShapes.cbegin();
126       for(; aGenBaseIt != aGenBaseShapes.cend() && aGenMSIt != aGenMakeShapes.cend();
127           ++aGenBaseIt, ++aGenMSIt) {
128
129         // ???
130         ListOfMakeShape::const_iterator aToolsMSIt = aToolsMakeShapes.cbegin();
131         for(; aToolsMSIt != aToolsMakeShapes.cend(); ++aToolsMSIt) {
132           std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMSList(new GeomAlgoAPI_MakeShapeList());
133
134           // prism generation
135           aMSList->appendAlgo(*aGenMSIt);
136
137           // tool modification (cut by objects)
138           aMSList->appendAlgo(*aToolsMSIt);
139
140           // bool fuse
141           aMSList->appendAlgo(*aBoolMSIt);
142           storeGenerationHistory(aResultBody, *aGenBaseIt, aMSList);
143         }
144       }
145
146       storeModificationHistory(aResultBody, *aBoolObjIt, aNewTools, *aBoolMSIt);
147
148       ResultBaseAlgo aRBA;
149       aRBA.resultBody = aResultBody;
150       aRBA.baseShape = *aBoolObjIt;
151       aRBA.makeShape = *aBoolMSIt;
152       aResultBaseAlgoList.push_back(aRBA);
153       aResultShapesList.push_back((*aBoolMSIt)->shape());
154     }
155
156     myFeature->setResult(aResultBody, aResultIndex++);
157   }
158
159   // Store deleted shapes after all results has been proceeded. This is to avoid issue when in one
160   // result shape has been deleted, but in another it was modified or stayed.
161   GeomShapePtr aResultShapesCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList);
162   storeDeletedShapes(aResultBaseAlgoList, aNewTools, aResultShapesCompound);
163
164   myFeature->removeResults(aResultIndex);
165 }