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