1 // Copyright (C) 2014-2019 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "GeomAlgoAPI_Revolution.h"
22 #include <GeomAPI_Face.h>
23 #include <GeomAPI_Pln.h>
24 #include <GeomAPI_ShapeExplorer.h>
25 #include <GeomAlgoAPI_DFLoader.h>
26 #include <GeomAlgoAPI_FaceBuilder.h>
27 #include <GeomAlgoAPI_MakeShapeList.h>
28 #include <GeomAlgoAPI_ShapeTools.h>
30 #include <BRep_Builder.hxx>
31 #include <BRep_Tool.hxx>
32 #include <BRepAlgoAPI_Cut.hxx>
33 #include <BRepBuilderAPI_FindPlane.hxx>
34 #include <BRepBuilderAPI_MakeFace.hxx>
35 #include <BRepBuilderAPI_Transform.hxx>
36 #include <BRepCheck_Analyzer.hxx>
37 #include <Geom_Curve.hxx>
38 #include <Geom2d_Curve.hxx>
39 #include <BRepLib_CheckCurveOnSurface.hxx>
40 #include <BRepPrimAPI_MakeRevol.hxx>
41 #include <BRepGProp.hxx>
42 #include <GC_MakePlane.hxx>
43 #include <Geom_Plane.hxx>
44 #include <GeomLib_IsPlanarSurface.hxx>
46 #include <GProp_GProps.hxx>
47 #include <IntTools_Context.hxx>
48 #include <TopExp_Explorer.hxx>
50 #include <TopoDS_Edge.hxx>
51 #include <TopTools_ListIteratorOfListOfShape.hxx>
53 /// \brief Constructs infinite face from thePlane, and with axis located on the same side
54 /// of the plane as thePoint. Modifies thePlane axis direction.
55 /// \param[in,out] thePlane plane to construct face.
56 /// \param[in] thePoint point to locate plane axis.
57 /// \return constructed face.
58 static TopoDS_Face makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint);
60 /// \return solid created from face or shell.
61 static TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape);
63 /// \brief return centre of mass for theShape.
64 /// \param[in] theShape shape.
65 static gp_Pnt centreOfMass(const TopoDS_Shape& theShape);
67 /// \brief Selects solid from theShape with closest center of mass to thePoint
68 /// \param[in] theShape compound with solids.
69 /// \param[in] thePoint point.
71 static TopoDS_Shape findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint);
73 static void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
74 const TopoDS_Shape& theBase,
75 const TopAbs_ShapeEnum theType,
76 BRepPrimAPI_MakeRevol* theRevolBuilder);
78 static void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
79 const TopoDS_Shape& theResult,
80 const TopAbs_ShapeEnum theType,
81 const TopoDS_Shape& theToFace,
82 const TopoDS_Shape& theFromFace);
84 static void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
85 const TopoDS_Shape& theResult,
86 const TopAbs_ShapeEnum theType,
87 const TopoDS_Shape& theRotatedBoundingFace,
88 const TopoDS_Shape& theModifiedBaseShape,
89 const bool theIsFromFaceSet);
91 //==================================================================================================
92 GeomAlgoAPI_Revolution::GeomAlgoAPI_Revolution(const GeomShapePtr theBaseShape,
93 const std::shared_ptr<GeomAPI_Ax1> theAxis,
94 const GeomShapePtr theToShape,
95 const double theToAngle,
96 const GeomShapePtr theFromShape,
97 const double theFromAngle)
99 build(theBaseShape, theAxis, theToShape, theToAngle, theFromShape, theFromAngle);
102 //==================================================================================================
103 void GeomAlgoAPI_Revolution::build(const GeomShapePtr& theBaseShape,
104 const std::shared_ptr<GeomAPI_Ax1>& theAxis,
105 const GeomShapePtr& theToShape,
106 const double theToAngle,
107 const GeomShapePtr& theFromShape,
108 const double theFromAngle)
110 if(!theBaseShape || !theAxis ||
111 (((!theFromShape && !theToShape) ||
112 (theFromShape && theToShape && theFromShape->isEqual(theToShape)))
113 && (theFromAngle == -theToAngle))) {
117 // Getting base shape.
118 const TopoDS_Shape& aBaseShape = theBaseShape->impl<TopoDS_Shape>();
119 TopAbs_ShapeEnum aShapeTypeToExp;
120 switch(aBaseShape.ShapeType()) {
122 aShapeTypeToExp = TopAbs_VERTEX;
126 aShapeTypeToExp = TopAbs_EDGE;
130 aShapeTypeToExp = TopAbs_FACE;
132 case TopAbs_COMPOUND:
133 aShapeTypeToExp = TopAbs_COMPOUND;
140 gp_Ax1 anAxis = theAxis->impl<gp_Ax1>();
142 // Getting base plane.
143 Handle(Geom_Plane) aBasePlane;
144 BRepBuilderAPI_FindPlane aFindPlane(aBaseShape);
145 if(aShapeTypeToExp == TopAbs_FACE && aFindPlane.Found() == Standard_True) {
146 aBasePlane = aFindPlane.Plane();
148 gp_Pnt aPnt1 = anAxis.Location();
149 gp_Pnt aPnt2 = aPnt1;
150 aPnt2.Translate(anAxis.Direction());
153 for(TopExp_Explorer anExp(aBaseShape, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
154 aPnt3 = BRep_Tool::Pnt(TopoDS::Vertex(anExp.Current()));
156 GC_MakePlane aMkPlane(aPnt1, aPnt2, aPnt3);
157 if(aMkPlane.IsDone() != Standard_True) {
161 aBasePlane = aMkPlane.Value();
165 if(aBasePlane.IsNull()) {
166 aPnt3 = centreOfMass(aBaseShape);
168 GC_MakePlane aMkPlane(aPnt1, aPnt2, aPnt3);
169 if(aMkPlane.IsDone() != Standard_True) {
173 aBasePlane = aMkPlane.Value();
177 if(aShapeTypeToExp == TopAbs_FACE) {
178 if(aBasePlane->Axis().Angle(anAxis) < Precision::Confusion()) {
183 gp_Pnt aBaseCentre = GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape)->impl<gp_Pnt>();
185 TopoDS_Shape aResult;
186 if(!theFromShape && !theToShape) { // Case 1: When only angles was set.
187 // Rotating base face with the negative value of "from angle".
189 aBaseTrsf.SetRotation(anAxis, -theFromAngle / 180.0 * M_PI);
190 BRepBuilderAPI_Transform* aBaseTransform = new BRepBuilderAPI_Transform(aBaseShape,
193 if(!aBaseTransform) {
196 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
197 new GeomAlgoAPI_MakeShape(aBaseTransform)));
198 if(!aBaseTransform->IsDone()) {
201 TopoDS_Shape aRotatedBase = aBaseTransform->Shape();
203 // Making revolution to the angle equal to the sum of "from angle" and "to angle".
204 BRepPrimAPI_MakeRevol* aRevolBuilder = new BRepPrimAPI_MakeRevol(aRotatedBase,
206 (theFromAngle + theToAngle) / 180 * M_PI,
211 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
212 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
213 if(!aRevolBuilder->IsDone()) {
216 aResult = aRevolBuilder->Shape();
219 if(aShapeTypeToExp == TopAbs_COMPOUND) {
220 storeGenerationHistory(this, aRotatedBase, TopAbs_EDGE, aRevolBuilder);
221 storeGenerationHistory(this, aRotatedBase, TopAbs_FACE, aRevolBuilder);
223 storeGenerationHistory(this, aRotatedBase, aShapeTypeToExp, aRevolBuilder);
225 } else if(theFromShape && theToShape) { // Case 2: When both bounding planes were set.
226 // Making revolution to the 360 angle.
227 BRepPrimAPI_MakeRevol* aRevolBuilder =
228 new BRepPrimAPI_MakeRevol(aBaseShape, anAxis, 2 * M_PI, Standard_True);
232 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
233 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
234 if(!aRevolBuilder->IsDone()) {
237 aResult = aRevolBuilder->Shape();
239 // Getting bounding faces.
240 TopoDS_Face aFromFace = TopoDS::Face(theFromShape->impl<TopoDS_Shape>());
241 TopoDS_Face aToFace = TopoDS::Face(theToShape->impl<TopoDS_Shape>());
243 // Getting planes from bounding face.
244 GeomLib_IsPlanarSurface isFromPlanar(BRep_Tool::Surface(aFromFace));
245 GeomLib_IsPlanarSurface isToPlanar(BRep_Tool::Surface(aToFace));
246 if(!isFromPlanar.IsPlanar() || !isToPlanar.IsPlanar()) {
247 // non-planar shapes is not supported for revolution bounding
251 std::shared_ptr<GeomAPI_Face> aGeomFromFace(new GeomAPI_Face(theFromShape));
252 std::shared_ptr<GeomAPI_Face> aGeomToFace(new GeomAPI_Face(theToShape));
254 gp_Pln aFromPln = aGeomFromFace->getPlane()->impl<gp_Pln>();
255 gp_Pln aToPln = aGeomToFace->getPlane()->impl<gp_Pln>();
257 // Orienting bounding planes properly so that the center of mass of the base face stays
258 // on the result shape after cut.
259 aFromFace = makeFaceFromPlane(aFromPln, aBaseCentre);
260 aToFace = makeFaceFromPlane(aToPln, aBaseCentre);
262 // Making solids from bounding planes and putting them in compound.
263 TopoDS_Shape aFromSolid = makeSolidFromShape(aFromFace);
264 TopoDS_Shape aToSolid = makeSolidFromShape(aToFace);
266 // Rotating bounding planes to the specified angle.
269 double aFromRotAngle =
270 ((aFromPln.Axis().Direction() * aBasePlane->Axis().Direction()) > 0) ? -theFromAngle :
273 ((aToPln.Axis().Direction() * aBasePlane->Axis().Direction()) > 0) ? -theToAngle :
275 aFromTrsf.SetRotation(anAxis,aFromRotAngle / 180.0 * M_PI);
276 aToTrsf.SetRotation(anAxis, aToRotAngle / 180.0 * M_PI);
277 BRepBuilderAPI_Transform aFromTransform(aFromSolid, aFromTrsf, true);
278 BRepBuilderAPI_Transform aToTransform(aToSolid, aToTrsf, true);
279 TopoDS_Shape aRotatedFromFace = aFromTransform.Modified(aFromFace).First();
280 TopoDS_Shape aRotatedToFace = aToTransform.Modified(aToFace).First();
281 aFromSolid = aFromTransform.Shape();
282 aToSolid = aToTransform.Shape();
284 // Cutting revolution with from plane.
285 BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid);
286 aFromCutBuilder->Build();
287 if(!aFromCutBuilder->IsDone()) {
290 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
291 new GeomAlgoAPI_MakeShape(aFromCutBuilder)));
292 aResult = aFromCutBuilder->Shape();
293 if(aResult.ShapeType() == TopAbs_COMPOUND) {
294 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
297 // Cutting revolution with to plane.
298 BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid);
299 aToCutBuilder->Build();
300 if(!aToCutBuilder->IsDone()) {
303 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
304 new GeomAlgoAPI_MakeShape(aToCutBuilder)));
305 aResult = aToCutBuilder->Shape();
306 TopoDS_Iterator aCheckIt(aResult);
307 if(!aCheckIt.More()) {
310 if(aResult.ShapeType() == TopAbs_COMPOUND) {
311 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
313 if(aResult.ShapeType() == TopAbs_COMPOUND) {
314 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
315 aGeomShape->setImpl(new TopoDS_Shape(aResult));
316 ListOfShape aResults;
317 aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
318 GeomAPI_Shape::COMPSOLID,
320 aResult = aGeomShape->impl<TopoDS_Shape>();
323 // If after cut we got more than one solids then take closest
324 // to the center of mass of the base face.
325 aResult = findClosest(aResult, aBaseCentre);
328 if(aShapeTypeToExp == TopAbs_COMPOUND) {
329 storeGenerationHistory(this, aResult, TopAbs_EDGE, aRotatedToFace, aRotatedFromFace);
330 storeGenerationHistory(this, aResult, TopAbs_FACE, aRotatedToFace, aRotatedFromFace);
332 storeGenerationHistory(this, aResult, aShapeTypeToExp, aRotatedToFace, aRotatedFromFace);
334 } else { //Case 3: When only one bounding plane was set.
335 // Making revolution to the 360 angle.
336 BRepPrimAPI_MakeRevol* aRevolBuilder =
337 new BRepPrimAPI_MakeRevol(aBaseShape, anAxis, 2 * M_PI, Standard_True);
341 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
342 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
343 if(!aRevolBuilder->IsDone()) {
346 aResult = aRevolBuilder->Shape();
348 // Getting bounding face.
349 bool isFromFaceSet = false;
350 std::shared_ptr<GeomAPI_Face> aGeomBoundingFace;
352 aGeomBoundingFace.reset(new GeomAPI_Face(theFromShape));
353 isFromFaceSet = true;
354 } else if(theToShape) {
355 aGeomBoundingFace.reset(new GeomAPI_Face(theToShape));
357 TopoDS_Face aBoundingFace = TopoDS::Face(aGeomBoundingFace->impl<TopoDS_Shape>());
359 // Getting plane from bounding face.
360 GeomLib_IsPlanarSurface isBoundingPlanar(BRep_Tool::Surface(aBoundingFace));
361 if(!isBoundingPlanar.IsPlanar()) { // non-planar shapes is not supported for revolution bounding
365 gp_Pln aBoundingPln = aGeomBoundingFace->getPlane()->impl<gp_Pln>();
367 // Orienting bounding plane properly so that the center of mass of the base face stays
368 // on the result shape after cut.
369 aBoundingFace = makeFaceFromPlane(aBoundingPln, aBaseCentre);
371 // Making solid from bounding plane.
372 TopoDS_Shape aBoundingSolid = makeSolidFromShape(aBoundingFace);
374 // Rotating bounding plane to the specified angle.
375 double aBoundingRotAngle = isFromFaceSet ? theFromAngle : theToAngle;
376 if(aBoundingPln.Axis().IsParallel(aBasePlane->Axis(), Precision::Confusion())) {
377 if(isFromFaceSet) aBoundingRotAngle = -aBoundingRotAngle;
379 double aSign = (aBoundingPln.Axis().Direction() ^ aBasePlane->Axis().Direction()) *
381 if((aSign <= 0 && !isFromFaceSet) || (aSign > 0 && isFromFaceSet)) {
382 aBoundingRotAngle = -aBoundingRotAngle;
385 gp_Trsf aBoundingTrsf;
386 aBoundingTrsf.SetRotation(anAxis, aBoundingRotAngle / 180.0 * M_PI);
387 BRepBuilderAPI_Transform aBoundingTransform(aBoundingSolid, aBoundingTrsf, true);
388 TopoDS_Shape aRotatedBoundingFace = aBoundingTransform.Modified(aBoundingFace).First();
389 aBoundingSolid = aBoundingTransform.Shape();
391 // Cutting revolution with bounding plane.
392 BRepAlgoAPI_Cut* aBoundingCutBuilder = new BRepAlgoAPI_Cut(aResult, aBoundingSolid);
393 aBoundingCutBuilder->Build();
394 if(!aBoundingCutBuilder->IsDone()) {
397 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
398 new GeomAlgoAPI_MakeShape(aBoundingCutBuilder)));
399 aResult = aBoundingCutBuilder->Shape();
400 if(aResult.ShapeType() == TopAbs_COMPOUND) {
401 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
405 if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) {
406 const TopTools_ListOfShape& aBndShapes = aBoundingCutBuilder->Modified(aBoundingFace);
407 for(TopTools_ListIteratorOfListOfShape anIt(aBndShapes); anIt.More(); anIt.Next()) {
408 GeomShapePtr aShape(new GeomAPI_Shape());
409 aShape->setImpl(new TopoDS_Shape(anIt.Value()));
410 fixOrientation(aShape);
411 isFromFaceSet ? this->addFromShape(aShape) : this->addToShape(aShape);
415 // Try to cut with base face. If it can not be done then keep result of cut with bounding plane.
416 TopoDS_Shape aModifiedBaseShape;
417 if(aShapeTypeToExp != TopAbs_FACE) {
419 GeomShapePtr aSh(new GeomAPI_Shape());
420 aSh->setImpl(new TopoDS_Shape(aBaseShape));
421 std::shared_ptr<GeomAPI_Pnt> theCenter(new GeomAPI_Pnt(aBasePlane->Location().X(),
422 aBasePlane->Location().Y(),
423 aBasePlane->Location().Z()));
424 std::shared_ptr<GeomAPI_Dir> theNormal(new GeomAPI_Dir(aBasePlane->Axis().Direction().X(),
425 aBasePlane->Axis().Direction().Y(),
426 aBasePlane->Axis().Direction().Z()));
427 GeomShapePtr aPln = GeomAlgoAPI_FaceBuilder::planarFace(theCenter, theNormal);
428 aList.push_back(aSh);
429 std::list<std::shared_ptr<GeomAPI_Pnt> >
430 aBoundingPoints = GeomAlgoAPI_ShapeTools::getBoundingBox(aList);
431 aSh = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPln, aBoundingPoints);
432 aModifiedBaseShape = aSh->impl<TopoDS_Shape>();
434 aModifiedBaseShape = aBaseShape;
437 if(aModifiedBaseShape.ShapeType() == TopAbs_FACE) {
438 aModifiedBaseShape.Orientation(TopAbs_REVERSED);
441 aMirrorTrsf.SetMirror(aBasePlane->Position().Ax2());
442 BRepBuilderAPI_Transform aMirrorTransform(aModifiedBaseShape, aMirrorTrsf, true);
443 aModifiedBaseShape = aMirrorTransform.Shape();
447 // Making solid from base face.
448 TopoDS_Shape aBaseSolid = makeSolidFromShape(aModifiedBaseShape);
450 // Rotating base face to the specified angle.
452 double aBaseRotAngle = isFromFaceSet ? theToAngle : -theFromAngle;
453 aBaseTrsf.SetRotation(anAxis, aBaseRotAngle / 180.0 * M_PI);
454 BRepBuilderAPI_Transform aBaseTransform(aBaseSolid, aBaseTrsf, true);
455 aBaseSolid = aBaseTransform.Shape();
457 // Cutting revolution with base.
458 BRepAlgoAPI_Cut* aBaseCutBuilder = new BRepAlgoAPI_Cut(aResult, aBaseSolid);
459 aBaseCutBuilder->Build();
460 if(aBaseCutBuilder->IsDone()) {
461 TopoDS_Shape aCutResult = aBaseCutBuilder->Shape();
462 TopoDS_Iterator aCheckIt(aCutResult);
463 if(aCheckIt.More()) {
464 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
465 new GeomAlgoAPI_MakeShape(aBaseCutBuilder)));
466 aResult = aCutResult;
467 if(aResult.ShapeType() == TopAbs_COMPOUND) {
468 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
470 if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) {
471 const TopTools_ListOfShape& aBsShapes = aBaseCutBuilder->Modified(aBoundingFace);
472 for(TopTools_ListIteratorOfListOfShape anIt(aBsShapes); anIt.More(); anIt.Next()) {
473 GeomShapePtr aShape(new GeomAPI_Shape());
474 aShape->setImpl(new TopoDS_Shape(anIt.Value()));
475 fixOrientation(aShape);
476 isFromFaceSet ? this->addToShape(aShape) : this->addFromShape(aShape);
482 if(aResult.ShapeType() == TopAbs_COMPOUND) {
483 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
484 aGeomShape->setImpl(new TopoDS_Shape(aResult));
485 ListOfShape aResults;
486 aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
487 GeomAPI_Shape::COMPSOLID,
489 aResult = aGeomShape->impl<TopoDS_Shape>();
492 // If after cut we got more than one solids then take
493 // closest to the center of mass of the base face.
494 aResult = findClosest(aResult, aBaseCentre);
497 if(aShapeTypeToExp == TopAbs_COMPOUND) {
498 storeGenerationHistory(this, aResult, TopAbs_EDGE,
499 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
500 storeGenerationHistory(this, aResult, TopAbs_FACE,
501 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
503 storeGenerationHistory(this, aResult, aShapeTypeToExp,
504 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
509 if(aResult.IsNull()) {
512 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
513 GeomShapePtr aShape(new GeomAPI_Shape());
514 aShape->setImpl(new TopoDS_Shape(aResult));
515 this->setShape(aShape);
519 //==================================================================================================
520 TopoDS_Face makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint)
522 if(!thePlane.Contains(thePoint, Precision::Confusion())) {
523 gp_XYZ aVec = thePoint.XYZ() - thePlane.Location().XYZ();
524 double aSign = aVec * thePlane.Axis().Direction().XYZ();
525 if(aSign < 0) thePlane.SetAxis(thePlane.Axis().Reversed());
528 BRepBuilderAPI_MakeFace aMakeFace(thePlane);
529 TopoDS_Face aResultFace = TopoDS::Face(aMakeFace.Shape());
534 //==================================================================================================
535 TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape)
540 BRep_Builder aBoundingBuilder;
541 if(theShape.ShapeType() == TopAbs_SHELL) {
542 aShell = TopoDS::Shell(theShape);
544 aBoundingBuilder.MakeShell(aShell);
545 aBoundingBuilder.Add(aShell, theShape);
547 aBoundingBuilder.MakeSolid(aSolid);
548 aBoundingBuilder.Add(aSolid, aShell);
553 //================================================================================================
554 gp_Pnt centreOfMass(const TopoDS_Shape& theShape)
556 TopAbs_ShapeEnum aShType = theShape.ShapeType();
557 GProp_GProps aGProps;
559 if(aShType == TopAbs_EDGE || aShType == TopAbs_WIRE) {
560 BRepGProp::LinearProperties(theShape, aGProps);
561 } else if(aShType == TopAbs_FACE || aShType == TopAbs_SHELL) {
562 BRepGProp::SurfaceProperties(theShape, aGProps);
563 } else if(aShType == TopAbs_SOLID || aShType == TopAbs_COMPSOLID) {
564 BRepGProp::VolumeProperties(theShape, aGProps);
567 return aGProps.CentreOfMass();
570 //================================================================================================
571 TopoDS_Shape findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint)
573 TopoDS_Shape aResult = theShape;
575 if(theShape.ShapeType() == TopAbs_COMPOUND) {
576 double aMinDistance = Precision::Infinite();
579 for (TopoDS_Iterator anItr(theShape); anItr.More(); anItr.Next()) {
580 TopoDS_Shape aValue = anItr.Value();
581 aCentr = centreOfMass(aValue);
582 aCurDistance = aCentr.Distance(thePoint);
584 if(aCurDistance < aMinDistance) {
585 aMinDistance = aCurDistance;
594 //================================================================================================
595 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
596 const TopoDS_Shape& theBase,
597 const TopAbs_ShapeEnum theType,
598 BRepPrimAPI_MakeRevol* theRevolBuilder)
600 for(TopExp_Explorer anExp(theBase, theType); anExp.More(); anExp.Next()) {
601 const TopoDS_Shape& aShape = anExp.Current();
602 GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
603 aFromShape->setImpl(new TopoDS_Shape(theRevolBuilder->FirstShape(aShape)));
604 aToShape->setImpl(new TopoDS_Shape(theRevolBuilder->LastShape(aShape)));
605 theRevolutionAlgo->fixOrientation(aFromShape);
606 theRevolutionAlgo->fixOrientation(aToShape);
607 theRevolutionAlgo->addFromShape(aFromShape);
608 theRevolutionAlgo->addToShape(aToShape);
612 //================================================================================================
613 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
614 const TopoDS_Shape& theResult,
615 const TopAbs_ShapeEnum theType,
616 const TopoDS_Shape& theToFace,
617 const TopoDS_Shape& theFromFace)
619 for(TopExp_Explorer anExp(theResult, theType); anExp.More (); anExp.Next ()) {
620 const TopoDS_Shape& aShape = anExp.Current();
621 GeomShapePtr aGeomSh(new GeomAPI_Shape());
622 if(theType == TopAbs_VERTEX) {
623 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
624 IntTools_Context anIntTools;
625 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theToFace),
626 Precision::Confusion()) == Standard_True) {
627 aGeomSh->setImpl(new TopoDS_Shape(aShape));
628 theRevolutionAlgo->fixOrientation(aGeomSh);
629 theRevolutionAlgo->addToShape(aGeomSh);
631 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theFromFace),
632 Precision::Confusion()) == Standard_True) {
633 aGeomSh->setImpl(new TopoDS_Shape(aShape));
634 theRevolutionAlgo->fixOrientation(aGeomSh);
635 theRevolutionAlgo->addFromShape(aGeomSh);
637 } else if(theType == TopAbs_EDGE) {
638 TopoDS_Edge anEdge = TopoDS::Edge(aShape);
639 BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, TopoDS::Face(theToFace));
640 anEdgeCheck.Perform();
641 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
642 aGeomSh->setImpl(new TopoDS_Shape(aShape));
643 theRevolutionAlgo->fixOrientation(aGeomSh);
644 theRevolutionAlgo->addToShape(aGeomSh);
646 anEdgeCheck.Init(anEdge, TopoDS::Face(theFromFace));
647 anEdgeCheck.Perform();
648 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
649 aGeomSh->setImpl(new TopoDS_Shape(aShape));
650 theRevolutionAlgo->fixOrientation(aGeomSh);
651 theRevolutionAlgo->addFromShape(aGeomSh);
654 Handle(Geom_Surface) aFaceSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
655 Handle(Geom_Surface) aFromSurface = BRep_Tool::Surface(TopoDS::Face(theFromFace));
656 Handle(Geom_Surface) aToSurface = BRep_Tool::Surface(TopoDS::Face(theToFace));
657 if(aFaceSurface == aFromSurface) {
658 aGeomSh->setImpl(new TopoDS_Shape(aShape));
659 theRevolutionAlgo->fixOrientation(aGeomSh);
660 theRevolutionAlgo->addFromShape(aGeomSh);
662 if(aFaceSurface == aToSurface) {
663 aGeomSh->setImpl(new TopoDS_Shape(aShape));
664 theRevolutionAlgo->fixOrientation(aGeomSh);
665 theRevolutionAlgo->addToShape(aGeomSh);
671 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
672 const TopoDS_Shape& theResult,
673 const TopAbs_ShapeEnum theType,
674 const TopoDS_Shape& theRotatedBoundingFace,
675 const TopoDS_Shape& theModifiedBaseShape,
676 const bool theIsFromFaceSet)
678 for(TopExp_Explorer anExp(theResult, theType); anExp.More (); anExp.Next ()) {
679 const TopoDS_Shape& aShape = anExp.Current();
680 GeomShapePtr aGeomSh(new GeomAPI_Shape());
681 if(theType == TopAbs_VERTEX) {
682 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
683 IntTools_Context anIntTools;
684 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theRotatedBoundingFace),
685 Precision::Confusion()) == Standard_True) {
686 aGeomSh->setImpl(new TopoDS_Shape(aShape));
687 theRevolutionAlgo->fixOrientation(aGeomSh);
688 theIsFromFaceSet ? theRevolutionAlgo->addFromShape(aGeomSh) :
689 theRevolutionAlgo->addToShape(aGeomSh);
691 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theModifiedBaseShape),
692 Precision::Confusion()) == Standard_True) {
693 aGeomSh->setImpl(new TopoDS_Shape(aShape));
694 theRevolutionAlgo->fixOrientation(aGeomSh);
695 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
696 theRevolutionAlgo->addFromShape(aGeomSh);
698 } else if(theType == TopAbs_EDGE) {
699 TopoDS_Edge anEdge = TopoDS::Edge(aShape);
700 BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, TopoDS::Face(theRotatedBoundingFace));
701 anEdgeCheck.Perform();
702 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
703 aGeomSh->setImpl(new TopoDS_Shape(aShape));
704 theRevolutionAlgo->fixOrientation(aGeomSh);
705 theIsFromFaceSet ? theRevolutionAlgo->addFromShape(aGeomSh) :
706 theRevolutionAlgo->addToShape(aGeomSh);
708 anEdgeCheck.Init(anEdge, TopoDS::Face(theModifiedBaseShape));
709 anEdgeCheck.Perform();
710 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
711 aGeomSh->setImpl(new TopoDS_Shape(aShape));
712 theRevolutionAlgo->fixOrientation(aGeomSh);
713 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
714 theRevolutionAlgo->addFromShape(aGeomSh);
717 Handle(Geom_Surface) aFaceSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
718 Handle(Geom_Surface) aBoundingSurface =
719 BRep_Tool::Surface(TopoDS::Face(theRotatedBoundingFace));
720 Handle(Geom_Surface) aBaseSurface = BRep_Tool::Surface(TopoDS::Face(theModifiedBaseShape));
721 if(aFaceSurface == aBoundingSurface) {
722 aGeomSh->setImpl(new TopoDS_Shape(aShape));
723 theRevolutionAlgo->fixOrientation(aGeomSh);
724 theIsFromFaceSet ? theRevolutionAlgo->addFromShape(aGeomSh) :
725 theRevolutionAlgo->addToShape(aGeomSh);
727 if(aFaceSurface == aBaseSurface) {
728 aGeomSh->setImpl(new TopoDS_Shape(aShape));
729 theRevolutionAlgo->fixOrientation(aGeomSh);
730 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
731 theRevolutionAlgo->addFromShape(aGeomSh);