Salome HOME
Get rid of compilation warnings. Part I.
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_CompositeSketch.cpp
1 // Copyright (C) 2014-2020  CEA/DEN, EDF R&D
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_CompositeSketch.h>
21 #include <FeaturesPlugin_Tools.h>
22
23 #include <ModelAPI_AttributeSelectionList.h>
24 #include <ModelAPI_AttributeReference.h>
25 #include <ModelAPI_BodyBuilder.h>
26 #include <ModelAPI_ResultConstruction.h>
27 #include <ModelAPI_Session.h>
28 #include <ModelAPI_Validator.h>
29
30 #include <GeomAlgoAPI_Revolution.h>
31
32 #include <GeomAPI_ShapeExplorer.h>
33
34
35 static void storeSubShape(const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
36                           ResultBodyPtr theResultBody,
37                           const GeomShapePtr theShape,
38                           const GeomAPI_Shape::ShapeType theType,
39                           const std::string& theName);
40
41 //=================================================================================================
42 void FeaturesPlugin_CompositeSketch::initCompositeSketchAttribtues(const int theInitFlags)
43 {
44   // Initialize sketch launcher.
45   if(theInitFlags & InitSketchLauncher) {
46     data()->addAttribute(SKETCH_ID(), ModelAPI_AttributeReference::typeId());
47     ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SKETCH_ID());
48   }
49
50   // Initialize selection list.
51   if(theInitFlags & InitBaseObjectsList) {
52     data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
53   }
54 }
55
56 //=================================================================================================
57 std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_CompositeSketch::addFeature(std::string theID)
58 {
59   FeaturePtr aNew = document()->addFeature(theID, false);
60   if(aNew) {
61     data()->reference(SKETCH_ID())->setValue(aNew);
62   }
63
64   // Set as current also after it becomes sub to set correctly enabled for other sketch subs.
65   document()->setCurrentFeature(aNew, false);
66   return aNew;
67 }
68
69 //=================================================================================================
70 int FeaturesPlugin_CompositeSketch::numberOfSubs(bool forTree) const
71 {
72   ObjectPtr aObj = data()->reference(SKETCH_ID())->value();
73   return aObj.get() ? 1 : 0;
74 }
75
76 //=================================================================================================
77 std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_CompositeSketch::subFeature(const int theIndex,
78                                                                              bool forTree)
79 {
80   FeaturePtr aSubFeature;
81   if(theIndex == 0) {
82     aSubFeature =
83         std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_ID())->value());
84   }
85   return aSubFeature;
86 }
87
88 //=================================================================================================
89 int FeaturesPlugin_CompositeSketch::subFeatureId(const int theIndex) const
90 {
91   if(theIndex == 0) {
92     FeaturePtr aFeature =
93       std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_ID())->value());
94     if(aFeature.get()) {
95       return aFeature->data()->featureId();
96     }
97   }
98
99   return -1;
100 }
101
102 //=================================================================================================
103 bool FeaturesPlugin_CompositeSketch::isSub(ObjectPtr theObject) const
104 {
105   bool isSubFeature = false;
106   // Check is this feature of result
107   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
108   if (aFeature.get()) {
109     ObjectPtr aSub = data()->reference(SKETCH_ID())->value();
110     isSubFeature = aSub == theObject;
111   }
112   return isSubFeature;
113 }
114
115 //=================================================================================================
116 void FeaturesPlugin_CompositeSketch::removeFeature(std::shared_ptr<ModelAPI_Feature> theFeature)
117 {
118   AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID());
119   if(aBaseObjectsSelectionList.get() && aBaseObjectsSelectionList->size() > 0) {
120     aBaseObjectsSelectionList->clear();
121   }
122
123   reference(SKETCH_ID())->setValue(ObjectPtr());
124 }
125
126 //=================================================================================================
127 void FeaturesPlugin_CompositeSketch::getBaseShapes(ListOfShape& theBaseShapesList,
128                                                    const bool theIsMakeShells)
129 {
130   AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID());
131   std::string anError;
132   bool isOk = FeaturesPlugin_Tools::getShape(
133       aBaseObjectsSelectionList, theIsMakeShells, theBaseShapesList, anError);
134   if (!isOk)
135     setError(anError);
136 }
137
138 //=================================================================================================
139 void FeaturesPlugin_CompositeSketch::storeResult(const GeomShapePtr theBaseShape,
140                                         const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
141                                         const int theIndex)
142 {
143   // Create result body.
144   ResultBodyPtr aResultBody = document()->createBody(data(), theIndex);
145
146   // Store generated shape.
147   aResultBody->storeGenerated(theBaseShape, theMakeShape->shape());
148
149   // Store generated edges/faces.
150   storeGenerationHistory(aResultBody, theBaseShape, theMakeShape);
151
152   setResult(aResultBody, theIndex);
153 }
154
155 //=================================================================================================
156 void FeaturesPlugin_CompositeSketch::storeGenerationHistory(ResultBodyPtr theResultBody,
157                                         const GeomShapePtr theBaseShape,
158                                         const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)
159 {
160   GeomAPI_Shape::ShapeType aBaseShapeType = theBaseShape->shapeType();
161   GeomAPI_Shape::ShapeType aShapeTypeToExplode = GeomAPI_Shape::SHAPE;
162
163   switch(aBaseShapeType) {
164     case GeomAPI_Shape::EDGE: {
165             aShapeTypeToExplode = GeomAPI_Shape::VERTEX;
166       break;
167     }
168     case GeomAPI_Shape::WIRE: {
169       aShapeTypeToExplode = GeomAPI_Shape::COMPOUND;
170       break;
171     }
172     case GeomAPI_Shape::FACE:
173     case GeomAPI_Shape::SHELL: {
174       aShapeTypeToExplode = GeomAPI_Shape::EDGE;
175       break;
176     }
177     case GeomAPI_Shape::COMPOUND: {
178       aShapeTypeToExplode = GeomAPI_Shape::COMPOUND;
179     }
180     default: // [to avoid compilation warnings]
181       break;
182   }
183
184   if(aShapeTypeToExplode == GeomAPI_Shape::VERTEX ||
185       aShapeTypeToExplode == GeomAPI_Shape::COMPOUND) {
186     theResultBody->loadGeneratedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::VERTEX);
187   }
188   if(aShapeTypeToExplode == GeomAPI_Shape::EDGE ||
189       aShapeTypeToExplode == GeomAPI_Shape::COMPOUND) {
190     theResultBody->loadGeneratedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::EDGE);
191   }
192   std::list<std::shared_ptr<GeomAlgoAPI_MakeSweep> > aSweeps; // all sweeps collected
193   std::shared_ptr<GeomAlgoAPI_MakeSweep> aMakeSweep =
194     std::dynamic_pointer_cast<GeomAlgoAPI_MakeSweep>(theMakeShape);
195   if(aMakeSweep.get()) {
196     aSweeps.push_back(aMakeSweep);
197   } else {
198     std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeList =
199       std::dynamic_pointer_cast<GeomAlgoAPI_MakeShapeList>(theMakeShape);
200     if (aMakeList.get()) {
201       ListOfMakeShape::const_iterator anIter = aMakeList->list().cbegin();
202       for(; anIter != aMakeList->list().cend(); anIter++) {
203         std::shared_ptr<GeomAlgoAPI_MakeSweep> aSweep =
204           std::dynamic_pointer_cast<GeomAlgoAPI_MakeSweep>(*anIter);
205         if (aSweep.get())
206           aSweeps.push_back(aSweep);
207       }
208     }
209   }
210   std::list<std::shared_ptr<GeomAlgoAPI_MakeSweep> >::iterator aSweep = aSweeps.begin();
211   for(; aSweep != aSweeps.end(); aSweep++) {
212     // Store from shapes.
213     storeShapes(theMakeShape, theResultBody, aBaseShapeType, (*aSweep)->fromShapes(), "From_");
214
215     // Store to shapes.
216     storeShapes(theMakeShape, theResultBody, aBaseShapeType, (*aSweep)->toShapes(), "To_");
217   }
218 }
219
220 //=================================================================================================
221 void FeaturesPlugin_CompositeSketch::storeShapes(
222   const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
223   ResultBodyPtr theResultBody,
224   const GeomAPI_Shape::ShapeType theBaseShapeType,
225   const ListOfShape& theShapes,
226   const std::string theName)
227 {
228   GeomAPI_Shape::ShapeType aShapeTypeToExplore = GeomAPI_Shape::FACE;
229   std::string aShapeTypeStr = "Face";
230   switch(theBaseShapeType) {
231     case GeomAPI_Shape::VERTEX: {
232       aShapeTypeToExplore = GeomAPI_Shape::VERTEX;
233       aShapeTypeStr = "Vertex";
234       break;
235     }
236     case GeomAPI_Shape::EDGE:
237     case GeomAPI_Shape::WIRE: {
238       aShapeTypeToExplore = GeomAPI_Shape::EDGE;
239       aShapeTypeStr = "Edge";
240       break;
241     }
242     case GeomAPI_Shape::FACE:
243     case GeomAPI_Shape::SHELL: {
244       aShapeTypeToExplore = GeomAPI_Shape::FACE;
245       aShapeTypeStr = "Face";
246       break;
247     }
248     case GeomAPI_Shape::COMPOUND: {
249       aShapeTypeToExplore = GeomAPI_Shape::COMPOUND;
250       break;
251     }
252     default: // [to avoid compilation warnings]
253       break;
254   }
255
256   // Store shapes.
257   for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) {
258     GeomShapePtr aShape = *anIt;
259
260     if(aShapeTypeToExplore == GeomAPI_Shape::COMPOUND) {
261       std::string aName = theName + (aShape->shapeType() == GeomAPI_Shape::EDGE ? "Edge" : "Face");
262       storeSubShape(theMakeShape, theResultBody, aShape, aShape->shapeType(), aName);
263     } else {
264       std::string aName = theName + aShapeTypeStr;
265       storeSubShape(theMakeShape, theResultBody, aShape, aShapeTypeToExplore, aName);
266       if (theBaseShapeType == GeomAPI_Shape::WIRE) { // issue 2289: special names also for vertices
267         aName = theName + "Vertex";
268         storeSubShape(theMakeShape, theResultBody, aShape, GeomAPI_Shape::VERTEX, aName);
269       }
270     }
271   }
272 }
273
274 void storeSubShape(
275   const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
276   ResultBodyPtr theResultBody,
277   const GeomShapePtr theShape,
278   const GeomAPI_Shape::ShapeType theType,
279   const std::string& theName)
280 {
281   for(GeomAPI_ShapeExplorer anExp(theShape, theType); anExp.more(); anExp.next()) {
282     GeomShapePtr aSubShape = anExp.current();
283     if (!theResultBody->generated(aSubShape, theName)) {
284       int aNbSubs = theResultBody->numberOfSubs();
285       if (aNbSubs > 0) {
286         // check the modified shape is in the result body, don't store it if not
287         ListOfShape aNewShapes;
288         theMakeShape->modified(aSubShape, aNewShapes);
289         for (int i = 0; i < aNbSubs; ++i) {
290           ResultBodyPtr aSubRes = theResultBody->subResult(i);
291           GeomShapePtr aShape = aSubRes->shape();
292           ListOfShape::iterator aNewIt = aNewShapes.begin();
293           for (; aNewIt != aNewShapes.end(); ++aNewIt)
294             if (aShape->isSubShape(*aNewIt, false))
295               break;
296           if (aNewIt != aNewShapes.end()) {
297             // store from/to shapes as primitives and then store modification of them by the boolean
298             aSubRes->generated(aSubShape, theName, false);
299             aSubRes->loadModifiedShapes(theMakeShape, aSubShape, theType);
300           }
301         }
302       }
303       else {
304         // store from/to shapes as primitives and then store modification of them by the boolean
305         theResultBody->generated(aSubShape, theName, false);
306         theResultBody->loadModifiedShapes(theMakeShape, aSubShape, theType);
307       }
308     }
309   }
310 }