1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: GeomAlgoAPI_Revolution.cpp
4 // Created: 12 May 2015
5 // Author: Dmitry Bobylev
7 #include "GeomAlgoAPI_Revolution.h"
9 #include <GeomAPI_Face.h>
10 #include <GeomAPI_Pln.h>
11 #include <GeomAPI_ShapeExplorer.h>
12 #include <GeomAlgoAPI_DFLoader.h>
13 #include <GeomAlgoAPI_FaceBuilder.h>
14 #include <GeomAlgoAPI_MakeShapeList.h>
15 #include <GeomAlgoAPI_ShapeTools.h>
17 #include <BRep_Builder.hxx>
18 #include <BRep_Tool.hxx>
19 #include <BRepAlgoAPI_Cut.hxx>
20 #include <BRepBuilderAPI_FindPlane.hxx>
21 #include <BRepBuilderAPI_MakeFace.hxx>
22 #include <BRepBuilderAPI_Transform.hxx>
23 #include <BRepCheck_Analyzer.hxx>
24 #include <Geom_Curve.hxx>
25 #include <Geom2d_Curve.hxx>
26 #include <BRepLib_CheckCurveOnSurface.hxx>
27 #include <BRepPrimAPI_MakeRevol.hxx>
28 #include <BRepGProp.hxx>
29 #include <GC_MakePlane.hxx>
30 #include <Geom_Plane.hxx>
31 #include <GeomLib_IsPlanarSurface.hxx>
33 #include <GProp_GProps.hxx>
34 #include <IntTools_Context.hxx>
35 #include <TopExp_Explorer.hxx>
37 #include <TopoDS_Edge.hxx>
38 #include <TopTools_ListIteratorOfListOfShape.hxx>
40 /// \brief Constructs infinite face from thePlane, and with axis located on the same side
41 /// of the plane as thePoint. Modifies thePlane axis direction.
42 /// \param[in,out] thePlane plane to construct face.
43 /// \param[in] thePoint point to locate plane axis.
44 /// \return constructed face.
45 static TopoDS_Face makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint);
47 /// \return solid created from face or shell.
48 static TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape);
50 /// \brief return centre of mass for theShape.
51 /// \param[in] theShape shape.
52 static gp_Pnt centreOfMass(const TopoDS_Shape& theShape);
54 /// \brief Selects solid from theShape with closest center of mass to thePoint
55 /// \param[in] theShape compound with solids.
56 /// \param[in] thePoint point.
58 static TopoDS_Shape findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint);
60 static void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
61 const TopoDS_Shape& theBase,
62 const TopAbs_ShapeEnum theType,
63 BRepPrimAPI_MakeRevol* theRevolBuilder);
65 static void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
66 const TopoDS_Shape& theResult,
67 const TopAbs_ShapeEnum theType,
68 const TopoDS_Shape& theToFace,
69 const TopoDS_Shape& theFromFace);
71 static void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
72 const TopoDS_Shape& theResult,
73 const TopAbs_ShapeEnum theType,
74 const TopoDS_Shape& theRotatedBoundingFace,
75 const TopoDS_Shape& theModifiedBaseShape,
76 const bool theIsFromFaceSet);
78 //==================================================================================================
79 GeomAlgoAPI_Revolution::GeomAlgoAPI_Revolution(const GeomShapePtr theBaseShape,
80 const std::shared_ptr<GeomAPI_Ax1> theAxis,
81 const double theToAngle,
82 const double theFromAngle)
84 build(theBaseShape, theAxis, GeomShapePtr(), theToAngle, GeomShapePtr(), theFromAngle);
87 //==================================================================================================
88 GeomAlgoAPI_Revolution::GeomAlgoAPI_Revolution(const GeomShapePtr theBaseShape,
89 const std::shared_ptr<GeomAPI_Ax1> theAxis,
90 const GeomShapePtr theToShape,
91 const double theToAngle,
92 const GeomShapePtr theFromShape,
93 const double theFromAngle)
95 build(theBaseShape, theAxis, theToShape, theToAngle, theFromShape, theFromAngle);
98 //==================================================================================================
99 void GeomAlgoAPI_Revolution::build(const GeomShapePtr& theBaseShape,
100 const std::shared_ptr<GeomAPI_Ax1>& theAxis,
101 const GeomShapePtr& theToShape,
102 const double theToAngle,
103 const GeomShapePtr& theFromShape,
104 const double theFromAngle)
106 if(!theBaseShape || !theAxis ||
107 (((!theFromShape && !theToShape) ||
108 (theFromShape && theToShape && theFromShape->isEqual(theToShape)))
109 && (theFromAngle == -theToAngle))) {
113 // Getting base shape.
114 const TopoDS_Shape& aBaseShape = theBaseShape->impl<TopoDS_Shape>();
115 TopAbs_ShapeEnum aShapeTypeToExp;
116 switch(aBaseShape.ShapeType()) {
118 aShapeTypeToExp = TopAbs_VERTEX;
122 aShapeTypeToExp = TopAbs_EDGE;
126 aShapeTypeToExp = TopAbs_FACE;
128 case TopAbs_COMPOUND:
129 aShapeTypeToExp = TopAbs_COMPOUND;
136 gp_Ax1 anAxis = theAxis->impl<gp_Ax1>();
138 // Getting base plane.
139 Handle(Geom_Plane) aBasePlane;
140 BRepBuilderAPI_FindPlane aFindPlane(aBaseShape);
141 if(aShapeTypeToExp == TopAbs_FACE && aFindPlane.Found() == Standard_True) {
142 aBasePlane = aFindPlane.Plane();
144 gp_Pnt aPnt1 = anAxis.Location();
145 gp_Pnt aPnt2 = aPnt1;
146 aPnt2.Translate(anAxis.Direction());
149 for(TopExp_Explorer anExp(aBaseShape, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
150 aPnt3 = BRep_Tool::Pnt(TopoDS::Vertex(anExp.Current()));
152 GC_MakePlane aMkPlane(aPnt1, aPnt2, aPnt3);
153 if(aMkPlane.IsDone() != Standard_True) {
157 aBasePlane = aMkPlane.Value();
161 if(aBasePlane.IsNull()) {
162 aPnt3 = centreOfMass(aBaseShape);
164 GC_MakePlane aMkPlane(aPnt1, aPnt2, aPnt3);
165 if(aMkPlane.IsDone() != Standard_True) {
169 aBasePlane = aMkPlane.Value();
173 if(aShapeTypeToExp == TopAbs_FACE) {
174 if(aBasePlane->Axis().Angle(anAxis) < Precision::Confusion()) {
179 gp_Pnt aBaseCentre = GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape)->impl<gp_Pnt>();
181 TopoDS_Shape aResult;
182 if(!theFromShape && !theToShape) { // Case 1: When only angles was set.
183 // Rotating base face with the negative value of "from angle".
185 aBaseTrsf.SetRotation(anAxis, -theFromAngle / 180.0 * M_PI);
186 BRepBuilderAPI_Transform* aBaseTransform = new BRepBuilderAPI_Transform(aBaseShape,
189 if(!aBaseTransform) {
192 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
193 new GeomAlgoAPI_MakeShape(aBaseTransform)));
194 if(!aBaseTransform->IsDone()) {
197 TopoDS_Shape aRotatedBase = aBaseTransform->Shape();
199 // Making revolution to the angle equal to the sum of "from angle" and "to angle".
200 BRepPrimAPI_MakeRevol* aRevolBuilder = new BRepPrimAPI_MakeRevol(aRotatedBase,
202 (theFromAngle + theToAngle) / 180 * M_PI,
207 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
208 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
209 if(!aRevolBuilder->IsDone()) {
212 aResult = aRevolBuilder->Shape();
215 if(aShapeTypeToExp == TopAbs_COMPOUND) {
216 storeGenerationHistory(this, aRotatedBase, TopAbs_EDGE, aRevolBuilder);
217 storeGenerationHistory(this, aRotatedBase, TopAbs_FACE, aRevolBuilder);
219 storeGenerationHistory(this, aRotatedBase, aShapeTypeToExp, aRevolBuilder);
221 } else if(theFromShape && theToShape) { // Case 2: When both bounding planes were set.
222 // Making revolution to the 360 angle.
223 BRepPrimAPI_MakeRevol* aRevolBuilder =
224 new BRepPrimAPI_MakeRevol(aBaseShape, anAxis, 2 * M_PI, Standard_True);
228 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
229 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
230 if(!aRevolBuilder->IsDone()) {
233 aResult = aRevolBuilder->Shape();
235 // Getting bounding faces.
236 TopoDS_Face aFromFace = TopoDS::Face(theFromShape->impl<TopoDS_Shape>());
237 TopoDS_Face aToFace = TopoDS::Face(theToShape->impl<TopoDS_Shape>());
239 // Getting planes from bounding face.
240 GeomLib_IsPlanarSurface isFromPlanar(BRep_Tool::Surface(aFromFace));
241 GeomLib_IsPlanarSurface isToPlanar(BRep_Tool::Surface(aToFace));
242 if(!isFromPlanar.IsPlanar() || !isToPlanar.IsPlanar()) {
243 // non-planar shapes is not supported for revolution bounding
247 std::shared_ptr<GeomAPI_Face> aGeomFromFace(new GeomAPI_Face(theFromShape));
248 std::shared_ptr<GeomAPI_Face> aGeomToFace(new GeomAPI_Face(theToShape));
250 gp_Pln aFromPln = aGeomFromFace->getPlane()->impl<gp_Pln>();
251 gp_Pln aToPln = aGeomToFace->getPlane()->impl<gp_Pln>();
253 // Orienting bounding planes properly so that the center of mass of the base face stays
254 // on the result shape after cut.
255 aFromFace = makeFaceFromPlane(aFromPln, aBaseCentre);
256 aToFace = makeFaceFromPlane(aToPln, aBaseCentre);
258 // Making solids from bounding planes and putting them in compound.
259 TopoDS_Shape aFromSolid = makeSolidFromShape(aFromFace);
260 TopoDS_Shape aToSolid = makeSolidFromShape(aToFace);
262 // Rotating bounding planes to the specified angle.
265 double aFromRotAngle =
266 ((aFromPln.Axis().Direction() * aBasePlane->Axis().Direction()) > 0) ? -theFromAngle :
269 ((aToPln.Axis().Direction() * aBasePlane->Axis().Direction()) > 0) ? -theToAngle :
271 aFromTrsf.SetRotation(anAxis,aFromRotAngle / 180.0 * M_PI);
272 aToTrsf.SetRotation(anAxis, aToRotAngle / 180.0 * M_PI);
273 BRepBuilderAPI_Transform aFromTransform(aFromSolid, aFromTrsf, true);
274 BRepBuilderAPI_Transform aToTransform(aToSolid, aToTrsf, true);
275 TopoDS_Shape aRotatedFromFace = aFromTransform.Modified(aFromFace).First();
276 TopoDS_Shape aRotatedToFace = aToTransform.Modified(aToFace).First();
277 aFromSolid = aFromTransform.Shape();
278 aToSolid = aToTransform.Shape();
280 // Cutting revolution with from plane.
281 BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid);
282 aFromCutBuilder->Build();
283 if(!aFromCutBuilder->IsDone()) {
286 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
287 new GeomAlgoAPI_MakeShape(aFromCutBuilder)));
288 aResult = aFromCutBuilder->Shape();
289 if(aResult.ShapeType() == TopAbs_COMPOUND) {
290 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
293 // Cutting revolution with to plane.
294 BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid);
295 aToCutBuilder->Build();
296 if(!aToCutBuilder->IsDone()) {
299 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
300 new GeomAlgoAPI_MakeShape(aToCutBuilder)));
301 aResult = aToCutBuilder->Shape();
302 TopoDS_Iterator aCheckIt(aResult);
303 if(!aCheckIt.More()) {
306 if(aResult.ShapeType() == TopAbs_COMPOUND) {
307 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
309 if(aResult.ShapeType() == TopAbs_COMPOUND) {
310 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
311 aGeomShape->setImpl(new TopoDS_Shape(aResult));
312 ListOfShape aCompSolids, aFreeSolids;
313 aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
314 GeomAPI_Shape::COMPSOLID,
317 aResult = aGeomShape->impl<TopoDS_Shape>();
320 // If after cut we got more than one solids then take closest
321 // to the center of mass of the base face.
322 aResult = findClosest(aResult, aBaseCentre);
325 if(aShapeTypeToExp == TopAbs_COMPOUND) {
326 storeGenerationHistory(this, aResult, TopAbs_EDGE, aRotatedToFace, aRotatedFromFace);
327 storeGenerationHistory(this, aResult, TopAbs_FACE, aRotatedToFace, aRotatedFromFace);
329 storeGenerationHistory(this, aResult, aShapeTypeToExp, aRotatedToFace, aRotatedFromFace);
331 } else { //Case 3: When only one bounding plane was set.
332 // Making revolution to the 360 angle.
333 BRepPrimAPI_MakeRevol* aRevolBuilder =
334 new BRepPrimAPI_MakeRevol(aBaseShape, anAxis, 2 * M_PI, Standard_True);
338 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
339 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
340 if(!aRevolBuilder->IsDone()) {
343 aResult = aRevolBuilder->Shape();
345 // Getting bounding face.
346 bool isFromFaceSet = false;
347 std::shared_ptr<GeomAPI_Face> aGeomBoundingFace;
349 aGeomBoundingFace.reset(new GeomAPI_Face(theFromShape));
350 isFromFaceSet = true;
351 } else if(theToShape) {
352 aGeomBoundingFace.reset(new GeomAPI_Face(theToShape));
354 TopoDS_Face aBoundingFace = TopoDS::Face(aGeomBoundingFace->impl<TopoDS_Shape>());
356 // Getting plane from bounding face.
357 GeomLib_IsPlanarSurface isBoundingPlanar(BRep_Tool::Surface(aBoundingFace));
358 if(!isBoundingPlanar.IsPlanar()) { // non-planar shapes is not supported for revolution bounding
362 gp_Pln aBoundingPln = aGeomBoundingFace->getPlane()->impl<gp_Pln>();
364 // Orienting bounding plane properly so that the center of mass of the base face stays
365 // on the result shape after cut.
366 aBoundingFace = makeFaceFromPlane(aBoundingPln, aBaseCentre);
368 // Making solid from bounding plane.
369 TopoDS_Shape aBoundingSolid = makeSolidFromShape(aBoundingFace);
371 // Rotating bounding plane to the specified angle.
372 double aBoundingRotAngle = isFromFaceSet ? theFromAngle : theToAngle;
373 if(aBoundingPln.Axis().IsParallel(aBasePlane->Axis(), Precision::Confusion())) {
374 if(isFromFaceSet) aBoundingRotAngle = -aBoundingRotAngle;
376 double aSign = (aBoundingPln.Axis().Direction() ^ aBasePlane->Axis().Direction()) *
378 if((aSign <= 0 && !isFromFaceSet) || (aSign > 0 && isFromFaceSet)) {
379 aBoundingRotAngle = -aBoundingRotAngle;
382 gp_Trsf aBoundingTrsf;
383 aBoundingTrsf.SetRotation(anAxis, aBoundingRotAngle / 180.0 * M_PI);
384 BRepBuilderAPI_Transform aBoundingTransform(aBoundingSolid, aBoundingTrsf, true);
385 TopoDS_Shape aRotatedBoundingFace = aBoundingTransform.Modified(aBoundingFace).First();
386 aBoundingSolid = aBoundingTransform.Shape();
388 // Cutting revolution with bounding plane.
389 BRepAlgoAPI_Cut* aBoundingCutBuilder = new BRepAlgoAPI_Cut(aResult, aBoundingSolid);
390 aBoundingCutBuilder->Build();
391 if(!aBoundingCutBuilder->IsDone()) {
394 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
395 new GeomAlgoAPI_MakeShape(aBoundingCutBuilder)));
396 aResult = aBoundingCutBuilder->Shape();
397 if(aResult.ShapeType() == TopAbs_COMPOUND) {
398 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
402 if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) {
403 const TopTools_ListOfShape& aBndShapes = aBoundingCutBuilder->Modified(aBoundingFace);
404 for(TopTools_ListIteratorOfListOfShape anIt(aBndShapes); anIt.More(); anIt.Next()) {
405 GeomShapePtr aShape(new GeomAPI_Shape());
406 aShape->setImpl(new TopoDS_Shape(anIt.Value()));
407 isFromFaceSet ? this->addFromShape(aShape) : this->addToShape(aShape);
411 // Try to cut with base face. If it can not be done then keep result of cut with bounding plane.
412 TopoDS_Shape aModifiedBaseShape;
413 if(aShapeTypeToExp != TopAbs_FACE) {
415 GeomShapePtr aSh(new GeomAPI_Shape());
416 aSh->setImpl(new TopoDS_Shape(aBaseShape));
417 std::shared_ptr<GeomAPI_Pnt> theCenter(new GeomAPI_Pnt(aBasePlane->Location().X(),
418 aBasePlane->Location().Y(),
419 aBasePlane->Location().Z()));
420 std::shared_ptr<GeomAPI_Dir> theNormal(new GeomAPI_Dir(aBasePlane->Axis().Direction().X(),
421 aBasePlane->Axis().Direction().Y(),
422 aBasePlane->Axis().Direction().Z()));
423 GeomShapePtr aPln = GeomAlgoAPI_FaceBuilder::planarFace(theCenter, theNormal);
424 aList.push_back(aSh);
425 std::list<std::shared_ptr<GeomAPI_Pnt> >
426 aBoundingPoints = GeomAlgoAPI_ShapeTools::getBoundingBox(aList);
427 aSh = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPln, aBoundingPoints);
428 aModifiedBaseShape = aSh->impl<TopoDS_Shape>();
430 aModifiedBaseShape = aBaseShape;
433 if(aModifiedBaseShape.ShapeType() == TopAbs_FACE) {
434 aModifiedBaseShape.Orientation(TopAbs_REVERSED);
437 aMirrorTrsf.SetMirror(aBasePlane->Position().Ax2());
438 BRepBuilderAPI_Transform aMirrorTransform(aModifiedBaseShape, aMirrorTrsf, true);
439 aModifiedBaseShape = aMirrorTransform.Shape();
443 // Making solid from base face.
444 TopoDS_Shape aBaseSolid = makeSolidFromShape(aModifiedBaseShape);
446 // Rotating base face to the specified angle.
448 double aBaseRotAngle = isFromFaceSet ? theToAngle : -theFromAngle;
449 aBaseTrsf.SetRotation(anAxis, aBaseRotAngle / 180.0 * M_PI);
450 BRepBuilderAPI_Transform aBaseTransform(aBaseSolid, aBaseTrsf, true);
451 aBaseSolid = aBaseTransform.Shape();
453 // Cutting revolution with base.
454 BRepAlgoAPI_Cut* aBaseCutBuilder = new BRepAlgoAPI_Cut(aResult, aBaseSolid);
455 aBaseCutBuilder->Build();
456 if(aBaseCutBuilder->IsDone()) {
457 TopoDS_Shape aCutResult = aBaseCutBuilder->Shape();
458 TopoDS_Iterator aCheckIt(aCutResult);
459 if(aCheckIt.More()) {
460 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
461 new GeomAlgoAPI_MakeShape(aBaseCutBuilder)));
462 aResult = aCutResult;
463 if(aResult.ShapeType() == TopAbs_COMPOUND) {
464 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
466 if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) {
467 const TopTools_ListOfShape& aBsShapes = aBaseCutBuilder->Modified(aBoundingFace);
468 for(TopTools_ListIteratorOfListOfShape anIt(aBsShapes); anIt.More(); anIt.Next()) {
469 GeomShapePtr aShape(new GeomAPI_Shape());
470 aShape->setImpl(new TopoDS_Shape(anIt.Value()));
471 isFromFaceSet ? this->addToShape(aShape) : this->addFromShape(aShape);
477 if(aResult.ShapeType() == TopAbs_COMPOUND) {
478 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
479 aGeomShape->setImpl(new TopoDS_Shape(aResult));
480 ListOfShape aCompSolids, aFreeSolids;
481 aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
482 GeomAPI_Shape::COMPSOLID,
485 aResult = aGeomShape->impl<TopoDS_Shape>();
488 // If after cut we got more than one solids then take
489 // closest to the center of mass of the base face.
490 aResult = findClosest(aResult, aBaseCentre);
493 if(aShapeTypeToExp == TopAbs_COMPOUND) {
494 storeGenerationHistory(this, aResult, TopAbs_EDGE,
495 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
496 storeGenerationHistory(this, aResult, TopAbs_FACE,
497 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
499 storeGenerationHistory(this, aResult, aShapeTypeToExp,
500 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
505 if(aResult.IsNull()) {
508 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
509 GeomShapePtr aShape(new GeomAPI_Shape());
510 aShape->setImpl(new TopoDS_Shape(aResult));
511 this->setShape(aShape);
515 //==================================================================================================
516 TopoDS_Face makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint)
518 if(!thePlane.Contains(thePoint, Precision::Confusion())) {
519 gp_XYZ aVec = thePoint.XYZ() - thePlane.Location().XYZ();
520 double aSign = aVec * thePlane.Axis().Direction().XYZ();
521 if(aSign < 0) thePlane.SetAxis(thePlane.Axis().Reversed());
524 BRepBuilderAPI_MakeFace aMakeFace(thePlane);
525 TopoDS_Face aResultFace = TopoDS::Face(aMakeFace.Shape());
530 //==================================================================================================
531 TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape)
536 BRep_Builder aBoundingBuilder;
537 if(theShape.ShapeType() == TopAbs_SHELL) {
538 aShell = TopoDS::Shell(theShape);
540 aBoundingBuilder.MakeShell(aShell);
541 aBoundingBuilder.Add(aShell, theShape);
543 aBoundingBuilder.MakeSolid(aSolid);
544 aBoundingBuilder.Add(aSolid, aShell);
549 //================================================================================================
550 gp_Pnt centreOfMass(const TopoDS_Shape& theShape)
552 TopAbs_ShapeEnum aShType = theShape.ShapeType();
553 GProp_GProps aGProps;
555 if(aShType == TopAbs_EDGE || aShType == TopAbs_WIRE) {
556 BRepGProp::LinearProperties(theShape, aGProps);
557 } else if(aShType == TopAbs_FACE || aShType == TopAbs_SHELL) {
558 BRepGProp::SurfaceProperties(theShape, aGProps);
559 } else if(aShType == TopAbs_SOLID || aShType == TopAbs_COMPSOLID) {
560 BRepGProp::VolumeProperties(theShape, aGProps);
563 return aGProps.CentreOfMass();
566 //================================================================================================
567 TopoDS_Shape findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint)
569 TopoDS_Shape aResult = theShape;
571 if(theShape.ShapeType() == TopAbs_COMPOUND) {
572 double aMinDistance = Precision::Infinite();
575 for (TopoDS_Iterator anItr(theShape); anItr.More(); anItr.Next()) {
576 TopoDS_Shape aValue = anItr.Value();
577 aCentr = centreOfMass(aValue);
578 aCurDistance = aCentr.Distance(thePoint);
580 if(aCurDistance < aMinDistance) {
581 aMinDistance = aCurDistance;
590 //================================================================================================
591 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
592 const TopoDS_Shape& theBase,
593 const TopAbs_ShapeEnum theType,
594 BRepPrimAPI_MakeRevol* theRevolBuilder)
596 for(TopExp_Explorer anExp(theBase, theType); anExp.More(); anExp.Next()) {
597 const TopoDS_Shape& aShape = anExp.Current();
598 GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
599 aFromShape->setImpl(new TopoDS_Shape(theRevolBuilder->FirstShape(aShape)));
600 aToShape->setImpl(new TopoDS_Shape(theRevolBuilder->LastShape(aShape)));
601 theRevolutionAlgo->addFromShape(aFromShape);
602 theRevolutionAlgo->addToShape(aToShape);
606 //================================================================================================
607 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
608 const TopoDS_Shape& theResult,
609 const TopAbs_ShapeEnum theType,
610 const TopoDS_Shape& theToFace,
611 const TopoDS_Shape& theFromFace)
613 for(TopExp_Explorer anExp(theResult, theType); anExp.More (); anExp.Next ()) {
614 const TopoDS_Shape& aShape = anExp.Current();
615 GeomShapePtr aGeomSh(new GeomAPI_Shape());
616 if(theType == TopAbs_VERTEX) {
617 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
618 IntTools_Context anIntTools;
619 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theToFace),
620 Precision::Confusion()) == Standard_True) {
621 aGeomSh->setImpl(new TopoDS_Shape(aShape));
622 theRevolutionAlgo->addToShape(aGeomSh);
624 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theFromFace),
625 Precision::Confusion()) == Standard_True) {
626 aGeomSh->setImpl(new TopoDS_Shape(aShape));
627 theRevolutionAlgo->addFromShape(aGeomSh);
629 } else if(theType == TopAbs_EDGE) {
630 TopoDS_Edge anEdge = TopoDS::Edge(aShape);
631 BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, TopoDS::Face(theToFace));
632 anEdgeCheck.Perform();
633 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
634 aGeomSh->setImpl(new TopoDS_Shape(aShape));
635 theRevolutionAlgo->addToShape(aGeomSh);
637 anEdgeCheck.Init(anEdge, TopoDS::Face(theFromFace));
638 anEdgeCheck.Perform();
639 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
640 aGeomSh->setImpl(new TopoDS_Shape(aShape));
641 theRevolutionAlgo->addFromShape(aGeomSh);
644 Handle(Geom_Surface) aFaceSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
645 Handle(Geom_Surface) aFromSurface = BRep_Tool::Surface(TopoDS::Face(theFromFace));
646 Handle(Geom_Surface) aToSurface = BRep_Tool::Surface(TopoDS::Face(theToFace));
647 if(aFaceSurface == aFromSurface) {
648 aGeomSh->setImpl(new TopoDS_Shape(aShape));
649 theRevolutionAlgo->addFromShape(aGeomSh);
651 if(aFaceSurface == aToSurface) {
652 aGeomSh->setImpl(new TopoDS_Shape(aShape));
653 theRevolutionAlgo->addToShape(aGeomSh);
659 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
660 const TopoDS_Shape& theResult,
661 const TopAbs_ShapeEnum theType,
662 const TopoDS_Shape& theRotatedBoundingFace,
663 const TopoDS_Shape& theModifiedBaseShape,
664 const bool theIsFromFaceSet)
666 for(TopExp_Explorer anExp(theResult, theType); anExp.More (); anExp.Next ()) {
667 const TopoDS_Shape& aShape = anExp.Current();
668 GeomShapePtr aGeomSh(new GeomAPI_Shape());
669 if(theType == TopAbs_VERTEX) {
670 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
671 IntTools_Context anIntTools;
672 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theRotatedBoundingFace),
673 Precision::Confusion()) == Standard_True) {
674 aGeomSh->setImpl(new TopoDS_Shape(aShape));
675 theIsFromFaceSet ? theRevolutionAlgo->addFromShape(aGeomSh) :
676 theRevolutionAlgo->addToShape(aGeomSh);
678 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theModifiedBaseShape),
679 Precision::Confusion()) == Standard_True) {
680 aGeomSh->setImpl(new TopoDS_Shape(aShape));
681 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
682 theRevolutionAlgo->addFromShape(aGeomSh);
684 } else if(theType == TopAbs_EDGE) {
685 TopoDS_Edge anEdge = TopoDS::Edge(aShape);
686 BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, TopoDS::Face(theRotatedBoundingFace));
687 anEdgeCheck.Perform();
688 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
689 aGeomSh->setImpl(new TopoDS_Shape(aShape));
690 theIsFromFaceSet ? theRevolutionAlgo->addFromShape(aGeomSh) :
691 theRevolutionAlgo->addToShape(aGeomSh);
693 anEdgeCheck.Init(anEdge, TopoDS::Face(theModifiedBaseShape));
694 anEdgeCheck.Perform();
695 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
696 aGeomSh->setImpl(new TopoDS_Shape(aShape));
697 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
698 theRevolutionAlgo->addFromShape(aGeomSh);
701 Handle(Geom_Surface) aFaceSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
702 Handle(Geom_Surface) aBoundingSurface =
703 BRep_Tool::Surface(TopoDS::Face(theRotatedBoundingFace));
704 Handle(Geom_Surface) aBaseSurface = BRep_Tool::Surface(TopoDS::Face(theModifiedBaseShape));
705 if(aFaceSurface == aBoundingSurface) {
706 aGeomSh->setImpl(new TopoDS_Shape(aShape));
707 theIsFromFaceSet ? theRevolutionAlgo->addFromShape(aGeomSh) :
708 theRevolutionAlgo->addToShape(aGeomSh);
710 if(aFaceSurface == aBaseSurface) {
711 aGeomSh->setImpl(new TopoDS_Shape(aShape));
712 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
713 theRevolutionAlgo->addFromShape(aGeomSh);