Salome HOME
Merge branch 'Dev_1.5.0' of salome:modules/shaper into Dev_1.5.0
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Revolution.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        GeomAlgoAPI_Revolution.cpp
4 // Created:     12 May 2015
5 // Author:      Dmitry Bobylev
6
7 #include <GeomAlgoAPI_Revolution.h>
8
9 #include <GeomAPI_Face.h>
10 #include <GeomAPI_ShapeExplorer.h>
11 #include <GeomAlgoAPI_DFLoader.h>
12 #include <GeomAlgoAPI_MakeShapeList.h>
13 #include <GeomAlgoAPI_ShapeTools.h>
14
15 #include <BRep_Builder.hxx>
16 #include <BRep_Tool.hxx>
17 #include <BRepAlgoAPI_Cut.hxx>
18 #include <BRepBuilderAPI_MakeFace.hxx>
19 #include <BRepBuilderAPI_Transform.hxx>
20 #include <BRepCheck_Analyzer.hxx>
21 #include <BRepPrimAPI_MakeRevol.hxx>
22 #include <BRepGProp.hxx>
23 #include <Geom_Plane.hxx>
24 #include <GeomLib_IsPlanarSurface.hxx>
25 #include <gp_Pln.hxx>
26 #include <GProp_GProps.hxx>
27 #include <TopExp_Explorer.hxx>
28 #include <TopoDS.hxx>
29 #include <TopTools_ListIteratorOfListOfShape.hxx>
30
31 //=================================================================================================
32 GeomAlgoAPI_Revolution::GeomAlgoAPI_Revolution(std::shared_ptr<GeomAPI_Shape> theBaseShape,
33                                                std::shared_ptr<GeomAPI_Ax1>   theAxis,
34                                                double                         theToAngle,
35                                                double                         theFromAngle)
36 : myDone(false)
37 {
38   build(theBaseShape, theAxis, std::shared_ptr<GeomAPI_Shape>(), theToAngle, std::shared_ptr<GeomAPI_Shape>(), theFromAngle);
39 }
40
41 //=================================================================================================
42 GeomAlgoAPI_Revolution::GeomAlgoAPI_Revolution(std::shared_ptr<GeomAPI_Shape> theBaseShape,
43                                                std::shared_ptr<GeomAPI_Ax1>   theAxis,
44                                                std::shared_ptr<GeomAPI_Shape> theToShape,
45                                                double                         theToAngle,
46                                                std::shared_ptr<GeomAPI_Shape> theFromShape,
47                                                double                         theFromAngle)
48 : myDone(false)
49 {
50   build(theBaseShape, theAxis, theToShape, theToAngle, theFromShape, theFromAngle);
51 }
52
53 //=================================================================================================
54 TopoDS_Face GeomAlgoAPI_Revolution::makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint)
55 {
56   if(!thePlane.Contains(thePoint, Precision::Confusion())) {
57     gp_XYZ aVec = thePoint.XYZ() - thePlane.Location().XYZ();
58     double aSign = aVec * thePlane.Axis().Direction().XYZ();
59     if(aSign < 0) thePlane.SetAxis(thePlane.Axis().Reversed());
60   }
61
62   BRepBuilderAPI_MakeFace aMakeFace(thePlane);
63   TopoDS_Face aResultFace = TopoDS::Face(aMakeFace.Shape());
64
65   return aResultFace;
66 }
67
68 //=================================================================================================
69 TopoDS_Solid GeomAlgoAPI_Revolution::makeSolidFromShape(const TopoDS_Shape& theShape)
70 {
71   TopoDS_Shell aShell;
72   TopoDS_Solid aSolid;
73
74   BRep_Builder aBoundingBuilder;
75   if(theShape.ShapeType() == TopAbs_SHELL) {
76     aShell = TopoDS::Shell(theShape);
77   } else {
78     aBoundingBuilder.MakeShell(aShell);
79     aBoundingBuilder.Add(aShell, theShape);
80   }
81   aBoundingBuilder.MakeSolid(aSolid);
82   aBoundingBuilder.Add(aSolid, aShell);
83
84   return aSolid;
85 }
86
87 //=================================================================================================
88 TopoDS_Shape GeomAlgoAPI_Revolution::findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint)
89 {
90   TopoDS_Shape aResult = theShape;
91
92   if(theShape.ShapeType() == TopAbs_COMPOUND) {
93     double aMinDistance = Precision::Infinite();
94     double aCurDistance;
95     GProp_GProps aGProps;
96     gp_Pnt aCentr;
97
98     for (TopoDS_Iterator anItr(theShape); anItr.More(); anItr.Next()) {
99       TopoDS_Shape aValue = anItr.Value();
100       BRepGProp::VolumeProperties(aValue, aGProps);
101       aCentr = aGProps.CentreOfMass();
102       aCurDistance = aCentr.Distance(thePoint);
103
104       if(aCurDistance < aMinDistance) {
105         aMinDistance = aCurDistance;
106         aResult = aValue;
107       }
108     }
109   }
110
111   return aResult;
112 }
113
114 //=================================================================================================
115 void GeomAlgoAPI_Revolution::build(const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
116                                    const std::shared_ptr<GeomAPI_Ax1>&   theAxis,
117                                    const std::shared_ptr<GeomAPI_Shape>& theToShape,
118                                    double                                theToAngle,
119                                    const std::shared_ptr<GeomAPI_Shape>& theFromShape,
120                                    double                                theFromAngle)
121 {
122   if(!theBaseShape || !theAxis ||
123     (((!theFromShape && !theToShape) || (theFromShape && theToShape && theFromShape->isEqual(theToShape)))
124     && (theFromAngle == -theToAngle))) {
125     return;
126   }
127
128   // Geting base plane.
129   const TopoDS_Shape& aBaseShape = theBaseShape->impl<TopoDS_Shape>();
130   TopoDS_Face aBaseFace;
131   if(theBaseShape->shapeType() == GeomAPI_Shape::FACE) {
132     aBaseFace = TopoDS::Face(theBaseShape->impl<TopoDS_Shape>());
133   } else if(theBaseShape->shapeType() == GeomAPI_Shape::SHELL) {
134     GeomAPI_ShapeExplorer anExp(theBaseShape, GeomAPI_Shape::FACE);
135     if(anExp.more()) {
136       std::shared_ptr<GeomAPI_Shape> aFaceOnShell = anExp.current();
137       aBaseFace = TopoDS::Face(aFaceOnShell->impl<TopoDS_Shape>());
138     }
139   }
140   if(aBaseFace.IsNull()) {
141     return;
142   }
143   GeomLib_IsPlanarSurface isBasePlanar(BRep_Tool::Surface(aBaseFace));
144   gp_Pln aBasePln = isBasePlanar.Plan();
145   Geom_Plane aBasePlane(aBasePln);
146   gp_Ax1 anAxis = theAxis->impl<gp_Ax1>();
147   if(aBasePlane.Axis().Angle(anAxis) < Precision::Confusion()) {
148     return;
149   }
150
151   gp_Pnt aBaseCentre = GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape)->impl<gp_Pnt>();
152
153   TopoDS_Shape aResult;
154   ListOfMakeShape aListOfMakeShape;
155   if(!theFromShape && !theToShape) { // Case 1: When only angles was set.
156     // Rotating base face with the negative value of "from angle".
157     gp_Trsf aBaseTrsf;
158     aBaseTrsf.SetRotation(anAxis, -theFromAngle / 180.0 * M_PI);
159     BRepBuilderAPI_Transform* aBaseTransform = new BRepBuilderAPI_Transform(aBaseShape,
160                                                                             aBaseTrsf,
161                                                                             true);
162     if(!aBaseTransform) {
163       return;
164     }
165     aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aBaseTransform)));
166     if(!aBaseTransform->IsDone()) {
167       return;
168     }
169     TopoDS_Shape aRotatedBase = aBaseTransform->Shape();
170
171     // Making revolution to the angle equal to the sum of "from angle" and "to angle".
172     BRepPrimAPI_MakeRevol* aRevolBuilder = new BRepPrimAPI_MakeRevol(aRotatedBase,
173                                                                       anAxis,
174                                                                       (theFromAngle + theToAngle) / 180 * M_PI,
175                                                                       Standard_True);
176     if(!aRevolBuilder) {
177       return;
178     }
179     aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aRevolBuilder)));
180     if(!aRevolBuilder->IsDone()) {
181       return;
182     }
183     aResult = aRevolBuilder->Shape();
184
185     // Setting naming.
186     for(TopExp_Explorer anExp(aRotatedBase, TopAbs_FACE); anExp.More(); anExp.Next()) {
187       const TopoDS_Shape& aFace = anExp.Current();
188       std::shared_ptr<GeomAPI_Shape> aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
189       aFromShape->setImpl(new TopoDS_Shape(aRevolBuilder->FirstShape(aFace)));
190       aToShape->setImpl(new TopoDS_Shape(aRevolBuilder->LastShape(aFace)));
191       myFromFaces.push_back(aFromShape);
192       myToFaces.push_back(aToShape);
193     }
194   } else if(theFromShape && theToShape) { // Case 2: When both bounding planes were set.
195     // Making revolution to the 360 angle.
196     BRepPrimAPI_MakeRevol* aRevolBuilder = new BRepPrimAPI_MakeRevol(aBaseShape, anAxis, 2 * M_PI, Standard_True);
197     if(!aRevolBuilder) {
198       return;
199     }
200     aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aRevolBuilder)));
201     if(!aRevolBuilder->IsDone()) {
202       return;
203     }
204     aResult = aRevolBuilder->Shape();
205
206     // Getting bounding faces.
207     TopoDS_Face aFromFace = TopoDS::Face(theFromShape->impl<TopoDS_Shape>());
208     TopoDS_Face aToFace   = TopoDS::Face(theToShape->impl<TopoDS_Shape>());
209
210     // Getting planes from bounding face.
211     GeomLib_IsPlanarSurface isFromPlanar(BRep_Tool::Surface(aFromFace));
212     GeomLib_IsPlanarSurface isToPlanar(BRep_Tool::Surface(aToFace));
213     if(!isFromPlanar.IsPlanar() || !isToPlanar.IsPlanar()) {// non-planar shapes is not supported for revolution bounding
214       return;
215     }
216     gp_Pln aFromPln = isFromPlanar.Plan();
217     gp_Pln aToPln   = isToPlanar.Plan();
218
219     // Orienting bounding planes properly so that the center of mass of the base face stays
220     // on the result shape after cut.
221     aFromFace = makeFaceFromPlane(aFromPln, aBaseCentre);
222     aToFace   = makeFaceFromPlane(aToPln, aBaseCentre);
223
224     // Making solids from bounding planes and putting them in compound.
225     TopoDS_Shape aFromSolid = makeSolidFromShape(aFromFace);
226     TopoDS_Shape aToSolid   = makeSolidFromShape(aToFace);
227
228     // Rotating bounding planes to the specified angle.
229     gp_Trsf aFromTrsf;
230     gp_Trsf aToTrsf;
231     double aFromRotAngle = ((aFromPln.Axis().Direction() * aBasePln.Axis().Direction()) > 0) ? -theFromAngle : theFromAngle;
232     double aToRotAngle = ((aToPln.Axis().Direction() * aBasePln.Axis().Direction()) > 0) ? -theToAngle : theToAngle;
233     aFromTrsf.SetRotation(anAxis,aFromRotAngle / 180.0 * M_PI);
234     aToTrsf.SetRotation(anAxis, aToRotAngle / 180.0 * M_PI);
235     BRepBuilderAPI_Transform aFromTransform(aFromSolid, aFromTrsf, true);
236     BRepBuilderAPI_Transform aToTransform(aToSolid, aToTrsf, true);
237     TopoDS_Shape aRotatedFromFace = aFromTransform.Modified(aFromFace).First();
238     TopoDS_Shape aRotatedToFace = aToTransform.Modified(aToFace).First();
239     aFromSolid = aFromTransform.Shape();
240     aToSolid = aToTransform.Shape();
241
242     // Cutting revolution with from plane.
243     BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid);
244     aFromCutBuilder->Build();
245     if(!aFromCutBuilder->IsDone()) {
246       return;
247     }
248     aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aFromCutBuilder)));
249     aResult = aFromCutBuilder->Shape();
250
251     // Cutting revolution with to plane.
252     BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid);
253     aToCutBuilder->Build();
254     if(!aToCutBuilder->IsDone()) {
255       return;
256     }
257     aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aToCutBuilder)));
258     aResult = aToCutBuilder->Shape();
259
260     TopExp_Explorer anExp(aResult, TopAbs_SOLID);
261     if(!anExp.More()) {
262       return;
263     }
264     if(aResult.ShapeType() == TopAbs_COMPOUND) {
265       aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
266     }
267     if(aResult.ShapeType() == TopAbs_COMPOUND) {
268       std::shared_ptr<GeomAPI_Shape> aCompound(new GeomAPI_Shape);
269       aCompound->setImpl(new TopoDS_Shape(aResult));
270       ListOfShape aCompSolids, aFreeSolids;
271       GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids);
272       if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) {
273         aResult = aCompSolids.front()->impl<TopoDS_Shape>();
274       } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) {
275         TopoDS_Compound aResultComp;
276         TopoDS_Builder aBuilder;
277         aBuilder.MakeCompound(aResultComp);
278         for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) {
279           aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
280         }
281         for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) {
282           aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
283         }
284         aResult = aResultComp;
285       }
286     }
287
288     // If after cut we got more than one solids then take closest to the center of mass of the base face.
289     aResult = findClosest(aResult, aBaseCentre);
290
291     // Setting naming.
292     for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More (); anExp.Next ()) {
293       const TopoDS_Shape& aFaceOnResult = anExp.Current();
294       Handle(Geom_Surface) aFaceSurface = BRep_Tool::Surface(TopoDS::Face(aFaceOnResult));
295       Handle(Geom_Surface) aFromSurface = BRep_Tool::Surface(TopoDS::Face(aRotatedFromFace));
296       Handle(Geom_Surface) aToSurface = BRep_Tool::Surface(TopoDS::Face(aRotatedToFace));
297       if(aFaceSurface == aFromSurface) {
298         std::shared_ptr<GeomAPI_Shape> aFSHape(new GeomAPI_Shape);
299         aFSHape->setImpl(new TopoDS_Shape(aFaceOnResult));
300         myFromFaces.push_back(aFSHape);
301       }
302       if(aFaceSurface == aToSurface) {
303         std::shared_ptr<GeomAPI_Shape> aTSHape(new GeomAPI_Shape);
304         aTSHape->setImpl(new TopoDS_Shape(aFaceOnResult));
305         myToFaces.push_back(aTSHape);
306       }
307     }
308   } else { //Case 3: When only one bounding plane was set.
309     // Making revolution to the 360 angle.
310     BRepPrimAPI_MakeRevol* aRevolBuilder = new BRepPrimAPI_MakeRevol(aBaseShape, anAxis, 2 * M_PI, Standard_True);
311     if(!aRevolBuilder) {
312       return;
313     }
314     aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aRevolBuilder)));
315     if(!aRevolBuilder->IsDone()) {
316       return;
317     }
318     aResult = aRevolBuilder->Shape();
319
320     // Getting bounding face.
321     TopoDS_Face aBoundingFace;
322     bool isFromFaceSet = false;
323     if(theFromShape) {
324       aBoundingFace = TopoDS::Face(theFromShape->impl<TopoDS_Shape>());
325       isFromFaceSet = true;
326     } else if(theToShape) {
327       aBoundingFace = TopoDS::Face(theToShape->impl<TopoDS_Shape>());
328     }
329
330     // Getting plane from bounding face.
331     GeomLib_IsPlanarSurface isBoundingPlanar(BRep_Tool::Surface(aBoundingFace));
332     if(!isBoundingPlanar.IsPlanar()) { // non-planar shapes is not supported for revolution bounding
333       return;
334     }
335     gp_Pln aBoundingPln = isBoundingPlanar.Plan();
336
337     // Orienting bounding plane properly so that the center of mass of the base face stays
338     // on the result shape after cut.
339     aBoundingFace = makeFaceFromPlane(aBoundingPln, aBaseCentre);
340
341     // Making solid from bounding plane.
342     TopoDS_Shape aBoundingSolid = makeSolidFromShape(aBoundingFace);
343
344     // Rotating bounding plane to the specified angle.
345     double aBoundingRotAngle = isFromFaceSet ? theFromAngle : theToAngle;
346     if(aBoundingPln.Axis().IsParallel(aBasePln.Axis(), Precision::Confusion())) {
347       if(isFromFaceSet) aBoundingRotAngle = -aBoundingRotAngle;
348     } else {
349       double aSign = (aBoundingPln.Axis().Direction() ^ aBasePln.Axis().Direction()) *
350                      anAxis.Direction();
351       if((aSign <= 0 && !isFromFaceSet) || (aSign > 0 && isFromFaceSet)) {
352         aBoundingRotAngle = -aBoundingRotAngle;
353       }
354     }
355     gp_Trsf aBoundingTrsf;
356     aBoundingTrsf.SetRotation(anAxis, aBoundingRotAngle / 180.0 * M_PI);
357     BRepBuilderAPI_Transform aBoundingTransform(aBoundingSolid, aBoundingTrsf, true);
358     TopoDS_Shape aRotatedBoundingFace = aBoundingTransform.Modified(aBoundingFace).First();
359     aBoundingSolid = aBoundingTransform.Shape();
360
361     // Cutting revolution with bounding plane.
362     BRepAlgoAPI_Cut* aBoundingCutBuilder = new BRepAlgoAPI_Cut(aResult, aBoundingSolid);
363     aBoundingCutBuilder->Build();
364     if(!aBoundingCutBuilder->IsDone()) {
365       return;
366     }
367     aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aBoundingCutBuilder)));
368     aResult = aBoundingCutBuilder->Shape();
369
370     // Setting naming.
371     const TopTools_ListOfShape& aBndShapes = aBoundingCutBuilder->Modified(aBoundingFace);
372     for(TopTools_ListIteratorOfListOfShape anIt(aBndShapes); anIt.More(); anIt.Next()) {
373       std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
374       aShape->setImpl(new TopoDS_Shape(anIt.Value()));
375       isFromFaceSet ? myFromFaces.push_back(aShape) : myToFaces.push_back(aShape);
376     }
377
378     // Try to cut with base face. If it can not be done then keep result of cut with bounding plane.
379     TopoDS_Shape aModifiedBaseShape = aBaseShape;
380     if(isFromFaceSet) {
381       if(aModifiedBaseShape.ShapeType() == TopAbs_FACE) {
382         aModifiedBaseShape.Orientation(TopAbs_REVERSED);
383       } else {
384         gp_Trsf aMirrorTrsf;
385         aMirrorTrsf.SetMirror(aBasePlane.Position().Ax2());
386         BRepBuilderAPI_Transform aMirrorTransform(aModifiedBaseShape, aMirrorTrsf, true);
387         aModifiedBaseShape = aMirrorTransform.Shape();
388       }
389     }
390
391     // Making solid from base face.
392     TopoDS_Shape aBaseSolid = makeSolidFromShape(aModifiedBaseShape);
393
394     // Rotating base face to the specified angle.
395     gp_Trsf aBaseTrsf;
396     double aBaseRotAngle = isFromFaceSet ? theToAngle : -theFromAngle;
397     aBaseTrsf.SetRotation(anAxis, aBaseRotAngle / 180.0 * M_PI);
398     BRepBuilderAPI_Transform aBaseTransform(aBaseSolid, aBaseTrsf, true);
399     aBaseSolid = aBaseTransform.Shape();
400
401     // Cutting revolution with base.
402     BRepAlgoAPI_Cut* aBaseCutBuilder = new BRepAlgoAPI_Cut(aResult, aBaseSolid);
403     aBaseCutBuilder->Build();
404     if(aBaseCutBuilder->IsDone()) {
405       TopoDS_Shape aCutResult = aBaseCutBuilder->Shape();
406       TopExp_Explorer anExp(aCutResult, TopAbs_SOLID);
407       if(anExp.More()) {
408         aListOfMakeShape.push_back(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aBaseCutBuilder)));
409         aResult = aCutResult;
410       }
411     }
412
413     const TopTools_ListOfShape& aBsShapes = aBaseCutBuilder->Modified(aBoundingFace);
414     for(TopTools_ListIteratorOfListOfShape anIt(aBsShapes); anIt.More(); anIt.Next()) {
415       std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
416       aShape->setImpl(new TopoDS_Shape(anIt.Value()));
417       isFromFaceSet ? myToFaces.push_back(aShape) : myFromFaces.push_back(aShape);
418     }
419
420     TopExp_Explorer anExp(aResult, TopAbs_SOLID);
421     if(!anExp.More()) {
422       return;
423     }
424     if(aResult.ShapeType() == TopAbs_COMPOUND) {
425       aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
426     }
427     if(aResult.ShapeType() == TopAbs_COMPOUND) {
428       std::shared_ptr<GeomAPI_Shape> aCompound(new GeomAPI_Shape);
429       aCompound->setImpl(new TopoDS_Shape(aResult));
430       ListOfShape aCompSolids, aFreeSolids;
431       GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids);
432       if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) {
433         aResult = aCompSolids.front()->impl<TopoDS_Shape>();
434       } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) {
435         TopoDS_Compound aResultComp;
436         TopoDS_Builder aBuilder;
437         aBuilder.MakeCompound(aResultComp);
438         for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) {
439           aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
440         }
441         for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) {
442           aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
443         }
444         aResult = aResultComp;
445       }
446     }
447
448     // If after cut we got more than one solids then take closest to the center of mass of the base face.
449     aResult = findClosest(aResult, aBaseCentre);
450
451     // Setting naming.
452     for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More (); anExp.Next ()) {
453       const TopoDS_Shape& aFaceOnResult = anExp.Current();
454       Handle(Geom_Surface) aFaceSurface = BRep_Tool::Surface(TopoDS::Face(aFaceOnResult));
455       Handle(Geom_Surface) aBoundingSurface = BRep_Tool::Surface(TopoDS::Face(aRotatedBoundingFace));
456       if(aFaceSurface == aBoundingSurface) {
457         std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
458         aShape->setImpl(new TopoDS_Shape(aFaceOnResult));
459         isFromFaceSet ? myFromFaces.push_back(aShape) : myToFaces.push_back(aShape);
460       }
461     }
462   }
463
464   // Setting result.
465   if(aResult.IsNull()) {
466     return;
467   }
468   myShape.reset(new GeomAPI_Shape);
469   myShape->setImpl(new TopoDS_Shape(aResult));
470
471   // Filling data map to keep correct orientation of sub-shapes.
472   myMap.reset(new GeomAPI_DataMapOfShapeShape);
473   for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
474     std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape);
475     aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
476     myMap->bind(aCurrentShape, aCurrentShape);
477   }
478
479   // Setting list of make shape.
480   myMkShape.reset(new GeomAlgoAPI_MakeShapeList(aListOfMakeShape));
481
482   myDone = true;
483 }
484
485 //=================================================================================================
486 const bool GeomAlgoAPI_Revolution::isDone() const
487 {
488   return myDone;
489 }
490
491 //=================================================================================================
492 const bool GeomAlgoAPI_Revolution::isValid() const
493 {
494   BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
495   return (aChecker.IsValid() == Standard_True);
496 }
497
498 //=================================================================================================
499 const bool GeomAlgoAPI_Revolution::hasVolume() const
500 {
501   bool hasVolume(false);
502   if(isValid()) {
503     const TopoDS_Shape& aRShape = myShape->impl<TopoDS_Shape>();
504     GProp_GProps aGProp;
505     BRepGProp::VolumeProperties(aRShape, aGProp);
506     if(aGProp.Mass() > Precision::Confusion())
507       hasVolume = true;
508   }
509   return hasVolume;
510 }
511
512 //=================================================================================================
513 const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Revolution::shape () const
514 {
515   return myShape;
516 }
517
518 //=================================================================================================
519 const ListOfShape& GeomAlgoAPI_Revolution::fromFaces() const
520 {
521   return myFromFaces;
522 }
523
524 //=================================================================================================
525 const ListOfShape& GeomAlgoAPI_Revolution::toFaces() const
526 {
527   return myToFaces;
528 }
529
530 //=================================================================================================
531 std::shared_ptr<GeomAPI_DataMapOfShapeShape> GeomAlgoAPI_Revolution::mapOfShapes() const
532 {
533   return myMap;
534 }
535
536 //=================================================================================================
537 std::shared_ptr<GeomAlgoAPI_MakeShape> GeomAlgoAPI_Revolution::makeShape() const
538 {
539   return myMkShape;
540 }