1 // Copyright (C) 2014-2021 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 /// \brief Create plane by 3 points. Return empty handle if failed.
74 static Handle(Geom_Plane) makePlane(const gp_Pnt& theP1, const gp_Pnt& theP2, const gp_Pnt& theP3);
76 static void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
77 const TopoDS_Shape& theBase,
78 const TopAbs_ShapeEnum theType,
79 BRepPrimAPI_MakeRevol* theRevolBuilder);
81 static void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
82 const TopoDS_Shape& theResult,
83 const TopAbs_ShapeEnum theType,
84 const TopoDS_Shape& theToFace,
85 const TopoDS_Shape& theFromFace);
87 static void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
88 const TopoDS_Shape& theResult,
89 const TopAbs_ShapeEnum theType,
90 const TopoDS_Shape& theRotatedBoundingFace,
91 const TopoDS_Shape& theModifiedBaseShape,
92 const bool theIsFromFaceSet);
94 //==================================================================================================
95 GeomAlgoAPI_Revolution::GeomAlgoAPI_Revolution(const GeomShapePtr theBaseShape,
96 const std::shared_ptr<GeomAPI_Ax1> theAxis,
97 const GeomShapePtr theToShape,
98 const double theToAngle,
99 const GeomShapePtr theFromShape,
100 const double theFromAngle)
102 build(theBaseShape, theAxis, theToShape, theToAngle, theFromShape, theFromAngle);
105 //==================================================================================================
106 void GeomAlgoAPI_Revolution::build(const GeomShapePtr& theBaseShape,
107 const std::shared_ptr<GeomAPI_Ax1>& theAxis,
108 const GeomShapePtr& theToShape,
109 const double theToAngle,
110 const GeomShapePtr& theFromShape,
111 const double theFromAngle)
113 if(!theBaseShape || !theAxis ||
114 (((!theFromShape && !theToShape) ||
115 (theFromShape && theToShape && theFromShape->isEqual(theToShape)))
116 && (theFromAngle == -theToAngle))) {
120 // Getting base shape.
121 const TopoDS_Shape& aBaseShape = theBaseShape->impl<TopoDS_Shape>();
122 TopAbs_ShapeEnum aShapeTypeToExp;
123 switch(aBaseShape.ShapeType()) {
125 aShapeTypeToExp = TopAbs_VERTEX;
129 aShapeTypeToExp = TopAbs_EDGE;
133 aShapeTypeToExp = TopAbs_FACE;
135 case TopAbs_COMPOUND:
136 aShapeTypeToExp = TopAbs_COMPOUND;
143 gp_Ax1 anAxis = theAxis->impl<gp_Ax1>();
145 // Getting base plane.
146 Handle(Geom_Plane) aBasePlane;
147 BRepBuilderAPI_FindPlane aFindPlane(aBaseShape);
148 if(aShapeTypeToExp == TopAbs_FACE && aFindPlane.Found() == Standard_True) {
149 aBasePlane = aFindPlane.Plane();
151 gp_Pnt aPnt1 = anAxis.Location();
153 TopExp_Explorer anExp(aBaseShape, TopAbs_VERTEX);
154 gp_Pnt aPnt2 = BRep_Tool::Pnt(TopoDS::Vertex(anExp.Current()));
155 gp_Pnt aPnt3 = aPnt1;
157 for (anExp.Next(); anExp.More() && aBasePlane.IsNull(); anExp.Next()) {
158 aPnt3 = BRep_Tool::Pnt(TopoDS::Vertex(anExp.Current()));
159 aBasePlane = makePlane(aPnt1, aPnt2, aPnt3);
162 if(aBasePlane.IsNull()) {
163 gp_Pnt aPossiblePoints[] = { aPnt1.Translated(anAxis.Direction()), centreOfMass(aBaseShape) };
164 for (auto it = std::begin(aPossiblePoints);
165 it != std::end(aPossiblePoints) && aBasePlane.IsNull(); ++it)
166 aBasePlane = makePlane(aPnt1, aPnt2, *it);
170 if(aShapeTypeToExp == TopAbs_FACE) {
171 if(aBasePlane->Axis().Angle(anAxis) < Precision::Confusion()) {
176 gp_Pnt aBaseCentre = GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape)->impl<gp_Pnt>();
178 TopoDS_Shape aResult;
179 if(!theFromShape && !theToShape) { // Case 1: When only angles was set.
180 // Rotating base face with the negative value of "from angle".
182 aBaseTrsf.SetRotation(anAxis, -theFromAngle / 180.0 * M_PI);
183 BRepBuilderAPI_Transform* aBaseTransform = new BRepBuilderAPI_Transform(aBaseShape,
186 if(!aBaseTransform) {
189 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
190 new GeomAlgoAPI_MakeShape(aBaseTransform)));
191 if(!aBaseTransform->IsDone()) {
194 TopoDS_Shape aRotatedBase = aBaseTransform->Shape();
196 // Making revolution to the angle equal to the sum of "from angle" and "to angle".
197 BRepPrimAPI_MakeRevol* aRevolBuilder = new BRepPrimAPI_MakeRevol(aRotatedBase,
199 (theFromAngle + theToAngle) / 180 * M_PI,
204 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
205 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
206 if(!aRevolBuilder->IsDone()) {
209 aResult = aRevolBuilder->Shape();
212 if(aShapeTypeToExp == TopAbs_COMPOUND) {
213 storeGenerationHistory(this, aRotatedBase, TopAbs_EDGE, aRevolBuilder);
214 storeGenerationHistory(this, aRotatedBase, TopAbs_FACE, aRevolBuilder);
216 storeGenerationHistory(this, aRotatedBase, aShapeTypeToExp, aRevolBuilder);
218 } else if(theFromShape && theToShape) { // Case 2: When both bounding planes were set.
219 // Making revolution to the 360 angle.
220 BRepPrimAPI_MakeRevol* aRevolBuilder =
221 new BRepPrimAPI_MakeRevol(aBaseShape, anAxis, 2 * M_PI, Standard_True);
225 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
226 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
227 if(!aRevolBuilder->IsDone()) {
230 aResult = aRevolBuilder->Shape();
232 // Getting bounding faces.
233 TopoDS_Face aFromFace = TopoDS::Face(theFromShape->impl<TopoDS_Shape>());
234 TopoDS_Face aToFace = TopoDS::Face(theToShape->impl<TopoDS_Shape>());
236 // Getting planes from bounding face.
237 GeomLib_IsPlanarSurface isFromPlanar(BRep_Tool::Surface(aFromFace));
238 GeomLib_IsPlanarSurface isToPlanar(BRep_Tool::Surface(aToFace));
239 if(!isFromPlanar.IsPlanar() || !isToPlanar.IsPlanar()) {
240 // non-planar shapes is not supported for revolution bounding
244 std::shared_ptr<GeomAPI_Face> aGeomFromFace(new GeomAPI_Face(theFromShape));
245 std::shared_ptr<GeomAPI_Face> aGeomToFace(new GeomAPI_Face(theToShape));
247 gp_Pln aFromPln = aGeomFromFace->getPlane()->impl<gp_Pln>();
248 gp_Pln aToPln = aGeomToFace->getPlane()->impl<gp_Pln>();
250 // Orienting bounding planes properly so that the center of mass of the base face stays
251 // on the result shape after cut.
252 aFromFace = makeFaceFromPlane(aFromPln, aBaseCentre);
253 aToFace = makeFaceFromPlane(aToPln, aBaseCentre);
255 // Making solids from bounding planes and putting them in compound.
256 TopoDS_Shape aFromSolid = makeSolidFromShape(aFromFace);
257 TopoDS_Shape aToSolid = makeSolidFromShape(aToFace);
259 // Rotating bounding planes to the specified angle.
262 double aFromRotAngle =
263 ((aFromPln.Axis().Direction() * aBasePlane->Axis().Direction()) > 0) ? -theFromAngle :
266 ((aToPln.Axis().Direction() * aBasePlane->Axis().Direction()) > 0) ? -theToAngle :
268 aFromTrsf.SetRotation(anAxis,aFromRotAngle / 180.0 * M_PI);
269 aToTrsf.SetRotation(anAxis, aToRotAngle / 180.0 * M_PI);
270 BRepBuilderAPI_Transform aFromTransform(aFromSolid, aFromTrsf, true);
271 BRepBuilderAPI_Transform aToTransform(aToSolid, aToTrsf, true);
272 TopoDS_Shape aRotatedFromFace = aFromTransform.Modified(aFromFace).First();
273 TopoDS_Shape aRotatedToFace = aToTransform.Modified(aToFace).First();
274 aFromSolid = aFromTransform.Shape();
275 aToSolid = aToTransform.Shape();
277 // Cutting revolution with from plane.
278 BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid);
279 aFromCutBuilder->Build();
280 if(!aFromCutBuilder->IsDone()) {
283 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
284 new GeomAlgoAPI_MakeShape(aFromCutBuilder)));
285 aResult = aFromCutBuilder->Shape();
286 if(aResult.ShapeType() == TopAbs_COMPOUND) {
287 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
290 // Cutting revolution with to plane.
291 BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid);
292 aToCutBuilder->Build();
293 if(!aToCutBuilder->IsDone()) {
296 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
297 new GeomAlgoAPI_MakeShape(aToCutBuilder)));
298 aResult = aToCutBuilder->Shape();
299 TopoDS_Iterator aCheckIt(aResult);
300 if(!aCheckIt.More()) {
303 if(aResult.ShapeType() == TopAbs_COMPOUND) {
304 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
306 if(aResult.ShapeType() == TopAbs_COMPOUND) {
307 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
308 aGeomShape->setImpl(new TopoDS_Shape(aResult));
309 ListOfShape aResults;
310 aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
311 GeomAPI_Shape::COMPSOLID,
313 aResult = aGeomShape->impl<TopoDS_Shape>();
316 // If after cut we got more than one solids then take closest
317 // to the center of mass of the base face.
318 aResult = findClosest(aResult, aBaseCentre);
321 if(aShapeTypeToExp == TopAbs_COMPOUND) {
322 storeGenerationHistory(this, aResult, TopAbs_EDGE, aRotatedToFace, aRotatedFromFace);
323 storeGenerationHistory(this, aResult, TopAbs_FACE, aRotatedToFace, aRotatedFromFace);
325 storeGenerationHistory(this, aResult, aShapeTypeToExp, aRotatedToFace, aRotatedFromFace);
327 } else { //Case 3: When only one bounding plane was set.
328 // Making revolution to the 360 angle.
329 BRepPrimAPI_MakeRevol* aRevolBuilder =
330 new BRepPrimAPI_MakeRevol(aBaseShape, anAxis, 2 * M_PI, Standard_True);
334 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
335 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
336 if(!aRevolBuilder->IsDone()) {
339 aResult = aRevolBuilder->Shape();
341 // Getting bounding face.
342 bool isFromFaceSet = false;
343 std::shared_ptr<GeomAPI_Face> aGeomBoundingFace;
345 aGeomBoundingFace.reset(new GeomAPI_Face(theFromShape));
346 isFromFaceSet = true;
347 } else if(theToShape) {
348 aGeomBoundingFace.reset(new GeomAPI_Face(theToShape));
350 TopoDS_Face aBoundingFace = TopoDS::Face(aGeomBoundingFace->impl<TopoDS_Shape>());
352 // Getting plane from bounding face.
353 GeomLib_IsPlanarSurface isBoundingPlanar(BRep_Tool::Surface(aBoundingFace));
354 if(!isBoundingPlanar.IsPlanar()) { // non-planar shapes is not supported for revolution bounding
358 gp_Pln aBoundingPln = aGeomBoundingFace->getPlane()->impl<gp_Pln>();
360 // Orienting bounding plane properly so that the center of mass of the base face stays
361 // on the result shape after cut.
362 aBoundingFace = makeFaceFromPlane(aBoundingPln, aBaseCentre);
364 // Making solid from bounding plane.
365 TopoDS_Shape aBoundingSolid = makeSolidFromShape(aBoundingFace);
367 // Rotating bounding plane to the specified angle.
368 double aBoundingRotAngle = isFromFaceSet ? theFromAngle : theToAngle;
369 if(aBoundingPln.Axis().IsParallel(aBasePlane->Axis(), Precision::Confusion())) {
370 if(isFromFaceSet) aBoundingRotAngle = -aBoundingRotAngle;
372 double aSign = (aBoundingPln.Axis().Direction() ^ aBasePlane->Axis().Direction()) *
374 if((aSign <= 0 && !isFromFaceSet) || (aSign > 0 && isFromFaceSet)) {
375 aBoundingRotAngle = -aBoundingRotAngle;
378 gp_Trsf aBoundingTrsf;
379 aBoundingTrsf.SetRotation(anAxis, aBoundingRotAngle / 180.0 * M_PI);
380 BRepBuilderAPI_Transform aBoundingTransform(aBoundingSolid, aBoundingTrsf, true);
381 TopoDS_Shape aRotatedBoundingFace = aBoundingTransform.Modified(aBoundingFace).First();
382 aBoundingSolid = aBoundingTransform.Shape();
384 // Cutting revolution with bounding plane.
385 BRepAlgoAPI_Cut* aBoundingCutBuilder = new BRepAlgoAPI_Cut(aResult, aBoundingSolid);
386 aBoundingCutBuilder->Build();
387 if(!aBoundingCutBuilder->IsDone()) {
390 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
391 new GeomAlgoAPI_MakeShape(aBoundingCutBuilder)));
392 aResult = aBoundingCutBuilder->Shape();
393 if(aResult.ShapeType() == TopAbs_COMPOUND) {
394 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
398 if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) {
399 const TopTools_ListOfShape& aBndShapes = aBoundingCutBuilder->Modified(aBoundingFace);
400 for(TopTools_ListIteratorOfListOfShape anIt(aBndShapes); anIt.More(); anIt.Next()) {
401 GeomShapePtr aShape(new GeomAPI_Shape());
402 aShape->setImpl(new TopoDS_Shape(anIt.Value()));
403 fixOrientation(aShape);
404 isFromFaceSet ? this->addFromShape(aShape) : this->addToShape(aShape);
408 // Try to cut with base face. If it can not be done then keep result of cut with bounding plane.
409 TopoDS_Shape aModifiedBaseShape;
410 if(aShapeTypeToExp != TopAbs_FACE) {
412 GeomShapePtr aSh(new GeomAPI_Shape());
413 aSh->setImpl(new TopoDS_Shape(aBaseShape));
414 std::shared_ptr<GeomAPI_Pnt> theCenter(new GeomAPI_Pnt(aBasePlane->Location().X(),
415 aBasePlane->Location().Y(),
416 aBasePlane->Location().Z()));
417 std::shared_ptr<GeomAPI_Dir> theNormal(new GeomAPI_Dir(aBasePlane->Axis().Direction().X(),
418 aBasePlane->Axis().Direction().Y(),
419 aBasePlane->Axis().Direction().Z()));
420 GeomShapePtr aPln = GeomAlgoAPI_FaceBuilder::planarFace(theCenter, theNormal);
421 aList.push_back(aSh);
422 std::list<std::shared_ptr<GeomAPI_Pnt> >
423 aBoundingPoints = GeomAlgoAPI_ShapeTools::getBoundingBox(aList);
424 aSh = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPln, aBoundingPoints);
425 aModifiedBaseShape = aSh->impl<TopoDS_Shape>();
427 aModifiedBaseShape = aBaseShape;
430 if(aModifiedBaseShape.ShapeType() == TopAbs_FACE) {
431 aModifiedBaseShape.Orientation(TopAbs_REVERSED);
434 aMirrorTrsf.SetMirror(aBasePlane->Position().Ax2());
435 BRepBuilderAPI_Transform aMirrorTransform(aModifiedBaseShape, aMirrorTrsf, true);
436 aModifiedBaseShape = aMirrorTransform.Shape();
440 // Making solid from base face.
441 TopoDS_Shape aBaseSolid = makeSolidFromShape(aModifiedBaseShape);
443 // Rotating base face to the specified angle.
445 double aBaseRotAngle = isFromFaceSet ? theToAngle : -theFromAngle;
446 aBaseTrsf.SetRotation(anAxis, aBaseRotAngle / 180.0 * M_PI);
447 BRepBuilderAPI_Transform aBaseTransform(aBaseSolid, aBaseTrsf, true);
448 aBaseSolid = aBaseTransform.Shape();
450 // Cutting revolution with base.
451 BRepAlgoAPI_Cut* aBaseCutBuilder = new BRepAlgoAPI_Cut(aResult, aBaseSolid);
452 aBaseCutBuilder->Build();
453 if(aBaseCutBuilder->IsDone()) {
454 TopoDS_Shape aCutResult = aBaseCutBuilder->Shape();
455 TopoDS_Iterator aCheckIt(aCutResult);
456 if(aCheckIt.More()) {
457 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
458 new GeomAlgoAPI_MakeShape(aBaseCutBuilder)));
459 aResult = aCutResult;
460 if(aResult.ShapeType() == TopAbs_COMPOUND) {
461 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
463 if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) {
464 const TopTools_ListOfShape& aBsShapes = aBaseCutBuilder->Modified(aBoundingFace);
465 for(TopTools_ListIteratorOfListOfShape anIt(aBsShapes); anIt.More(); anIt.Next()) {
466 GeomShapePtr aShape(new GeomAPI_Shape());
467 aShape->setImpl(new TopoDS_Shape(anIt.Value()));
468 fixOrientation(aShape);
469 isFromFaceSet ? this->addToShape(aShape) : this->addFromShape(aShape);
475 if(aResult.ShapeType() == TopAbs_COMPOUND) {
476 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
477 aGeomShape->setImpl(new TopoDS_Shape(aResult));
478 ListOfShape aResults;
479 aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
480 GeomAPI_Shape::COMPSOLID,
482 aResult = aGeomShape->impl<TopoDS_Shape>();
485 // If after cut we got more than one solids then take
486 // closest to the center of mass of the base face.
487 aResult = findClosest(aResult, aBaseCentre);
490 if(aShapeTypeToExp == TopAbs_COMPOUND) {
491 storeGenerationHistory(this, aResult, TopAbs_EDGE,
492 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
493 storeGenerationHistory(this, aResult, TopAbs_FACE,
494 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
496 storeGenerationHistory(this, aResult, aShapeTypeToExp,
497 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
502 if(aResult.IsNull()) {
505 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
506 GeomShapePtr aShape(new GeomAPI_Shape());
507 aShape->setImpl(new TopoDS_Shape(aResult));
508 this->setShape(aShape);
512 //==================================================================================================
513 TopoDS_Face makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint)
515 if(!thePlane.Contains(thePoint, Precision::Confusion())) {
516 gp_XYZ aVec = thePoint.XYZ() - thePlane.Location().XYZ();
517 double aSign = aVec * thePlane.Axis().Direction().XYZ();
518 if(aSign < 0) thePlane.SetAxis(thePlane.Axis().Reversed());
521 BRepBuilderAPI_MakeFace aMakeFace(thePlane);
522 TopoDS_Face aResultFace = TopoDS::Face(aMakeFace.Shape());
527 //==================================================================================================
528 TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape)
533 BRep_Builder aBoundingBuilder;
534 if(theShape.ShapeType() == TopAbs_SHELL) {
535 aShell = TopoDS::Shell(theShape);
537 aBoundingBuilder.MakeShell(aShell);
538 aBoundingBuilder.Add(aShell, theShape);
540 aBoundingBuilder.MakeSolid(aSolid);
541 aBoundingBuilder.Add(aSolid, aShell);
546 //================================================================================================
547 gp_Pnt centreOfMass(const TopoDS_Shape& theShape)
549 TopAbs_ShapeEnum aShType = theShape.ShapeType();
550 GProp_GProps aGProps;
552 if(aShType == TopAbs_EDGE || aShType == TopAbs_WIRE) {
553 BRepGProp::LinearProperties(theShape, aGProps);
554 } else if(aShType == TopAbs_FACE || aShType == TopAbs_SHELL) {
555 BRepGProp::SurfaceProperties(theShape, aGProps);
556 } else if(aShType == TopAbs_SOLID || aShType == TopAbs_COMPSOLID) {
557 BRepGProp::VolumeProperties(theShape, aGProps);
560 return aGProps.CentreOfMass();
563 //================================================================================================
564 TopoDS_Shape findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint)
566 TopoDS_Shape aResult = theShape;
568 if(theShape.ShapeType() == TopAbs_COMPOUND) {
569 double aMinDistance = Precision::Infinite();
572 for (TopoDS_Iterator anItr(theShape); anItr.More(); anItr.Next()) {
573 TopoDS_Shape aValue = anItr.Value();
574 aCentr = centreOfMass(aValue);
575 aCurDistance = aCentr.Distance(thePoint);
577 if(aCurDistance < aMinDistance) {
578 aMinDistance = aCurDistance;
587 //================================================================================================
588 Handle(Geom_Plane) makePlane(const gp_Pnt& theP1, const gp_Pnt& theP2, const gp_Pnt& theP3)
590 Handle(Geom_Plane) aPlane;
591 GC_MakePlane aMkPlane(theP1, theP2, theP3);
592 if (aMkPlane.IsDone())
593 aPlane = aMkPlane.Value();
597 //================================================================================================
598 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
599 const TopoDS_Shape& theBase,
600 const TopAbs_ShapeEnum theType,
601 BRepPrimAPI_MakeRevol* theRevolBuilder)
603 for(TopExp_Explorer anExp(theBase, theType); anExp.More(); anExp.Next()) {
604 const TopoDS_Shape& aShape = anExp.Current();
605 GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
606 aFromShape->setImpl(new TopoDS_Shape(theRevolBuilder->FirstShape(aShape)));
607 aToShape->setImpl(new TopoDS_Shape(theRevolBuilder->LastShape(aShape)));
608 theRevolutionAlgo->fixOrientation(aFromShape);
609 theRevolutionAlgo->fixOrientation(aToShape);
610 theRevolutionAlgo->addFromShape(aFromShape);
611 theRevolutionAlgo->addToShape(aToShape);
615 //================================================================================================
616 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
617 const TopoDS_Shape& theResult,
618 const TopAbs_ShapeEnum theType,
619 const TopoDS_Shape& theToFace,
620 const TopoDS_Shape& theFromFace)
622 for(TopExp_Explorer anExp(theResult, theType); anExp.More (); anExp.Next ()) {
623 const TopoDS_Shape& aShape = anExp.Current();
624 GeomShapePtr aGeomSh(new GeomAPI_Shape());
625 if(theType == TopAbs_VERTEX) {
626 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
627 IntTools_Context anIntTools;
628 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theToFace),
629 Precision::Confusion()) == Standard_True) {
630 aGeomSh->setImpl(new TopoDS_Shape(aShape));
631 theRevolutionAlgo->fixOrientation(aGeomSh);
632 theRevolutionAlgo->addToShape(aGeomSh);
634 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theFromFace),
635 Precision::Confusion()) == Standard_True) {
636 aGeomSh->setImpl(new TopoDS_Shape(aShape));
637 theRevolutionAlgo->fixOrientation(aGeomSh);
638 theRevolutionAlgo->addFromShape(aGeomSh);
640 } else if(theType == TopAbs_EDGE) {
641 TopoDS_Edge anEdge = TopoDS::Edge(aShape);
642 BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, TopoDS::Face(theToFace));
643 anEdgeCheck.Perform();
644 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
645 aGeomSh->setImpl(new TopoDS_Shape(aShape));
646 theRevolutionAlgo->fixOrientation(aGeomSh);
647 theRevolutionAlgo->addToShape(aGeomSh);
649 anEdgeCheck.Init(anEdge, TopoDS::Face(theFromFace));
650 anEdgeCheck.Perform();
651 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
652 aGeomSh->setImpl(new TopoDS_Shape(aShape));
653 theRevolutionAlgo->fixOrientation(aGeomSh);
654 theRevolutionAlgo->addFromShape(aGeomSh);
657 Handle(Geom_Surface) aFaceSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
658 Handle(Geom_Surface) aFromSurface = BRep_Tool::Surface(TopoDS::Face(theFromFace));
659 Handle(Geom_Surface) aToSurface = BRep_Tool::Surface(TopoDS::Face(theToFace));
660 if(aFaceSurface == aFromSurface) {
661 aGeomSh->setImpl(new TopoDS_Shape(aShape));
662 theRevolutionAlgo->fixOrientation(aGeomSh);
663 theRevolutionAlgo->addFromShape(aGeomSh);
665 if(aFaceSurface == aToSurface) {
666 aGeomSh->setImpl(new TopoDS_Shape(aShape));
667 theRevolutionAlgo->fixOrientation(aGeomSh);
668 theRevolutionAlgo->addToShape(aGeomSh);
674 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
675 const TopoDS_Shape& theResult,
676 const TopAbs_ShapeEnum theType,
677 const TopoDS_Shape& theRotatedBoundingFace,
678 const TopoDS_Shape& theModifiedBaseShape,
679 const bool theIsFromFaceSet)
681 for(TopExp_Explorer anExp(theResult, theType); anExp.More (); anExp.Next ()) {
682 const TopoDS_Shape& aShape = anExp.Current();
683 GeomShapePtr aGeomSh(new GeomAPI_Shape());
684 if(theType == TopAbs_VERTEX) {
685 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
686 IntTools_Context anIntTools;
687 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theRotatedBoundingFace),
688 Precision::Confusion()) == Standard_True) {
689 aGeomSh->setImpl(new TopoDS_Shape(aShape));
690 theRevolutionAlgo->fixOrientation(aGeomSh);
691 theIsFromFaceSet ? theRevolutionAlgo->addFromShape(aGeomSh) :
692 theRevolutionAlgo->addToShape(aGeomSh);
694 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theModifiedBaseShape),
695 Precision::Confusion()) == Standard_True) {
696 aGeomSh->setImpl(new TopoDS_Shape(aShape));
697 theRevolutionAlgo->fixOrientation(aGeomSh);
698 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
699 theRevolutionAlgo->addFromShape(aGeomSh);
701 } else if(theType == TopAbs_EDGE) {
702 TopoDS_Edge anEdge = TopoDS::Edge(aShape);
703 BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, TopoDS::Face(theRotatedBoundingFace));
704 anEdgeCheck.Perform();
705 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
706 aGeomSh->setImpl(new TopoDS_Shape(aShape));
707 theRevolutionAlgo->fixOrientation(aGeomSh);
708 theIsFromFaceSet ? theRevolutionAlgo->addFromShape(aGeomSh) :
709 theRevolutionAlgo->addToShape(aGeomSh);
711 anEdgeCheck.Init(anEdge, TopoDS::Face(theModifiedBaseShape));
712 anEdgeCheck.Perform();
713 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
714 aGeomSh->setImpl(new TopoDS_Shape(aShape));
715 theRevolutionAlgo->fixOrientation(aGeomSh);
716 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
717 theRevolutionAlgo->addFromShape(aGeomSh);
720 Handle(Geom_Surface) aFaceSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
721 Handle(Geom_Surface) aBoundingSurface =
722 BRep_Tool::Surface(TopoDS::Face(theRotatedBoundingFace));
723 Handle(Geom_Surface) aBaseSurface = BRep_Tool::Surface(TopoDS::Face(theModifiedBaseShape));
724 if(aFaceSurface == aBoundingSurface) {
725 aGeomSh->setImpl(new TopoDS_Shape(aShape));
726 theRevolutionAlgo->fixOrientation(aGeomSh);
727 theIsFromFaceSet ? theRevolutionAlgo->addFromShape(aGeomSh) :
728 theRevolutionAlgo->addToShape(aGeomSh);
730 if(aFaceSurface == aBaseSurface) {
731 aGeomSh->setImpl(new TopoDS_Shape(aShape));
732 theRevolutionAlgo->fixOrientation(aGeomSh);
733 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
734 theRevolutionAlgo->addFromShape(aGeomSh);