1 // Copyright (C) 2014-2017 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
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "GeomAlgoAPI_Revolution.h"
23 #include <GeomAPI_Face.h>
24 #include <GeomAPI_Pln.h>
25 #include <GeomAPI_ShapeExplorer.h>
26 #include <GeomAlgoAPI_DFLoader.h>
27 #include <GeomAlgoAPI_FaceBuilder.h>
28 #include <GeomAlgoAPI_MakeShapeList.h>
29 #include <GeomAlgoAPI_ShapeTools.h>
31 #include <BRep_Builder.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRepAlgoAPI_Cut.hxx>
34 #include <BRepBuilderAPI_FindPlane.hxx>
35 #include <BRepBuilderAPI_MakeFace.hxx>
36 #include <BRepBuilderAPI_Transform.hxx>
37 #include <BRepCheck_Analyzer.hxx>
38 #include <Geom_Curve.hxx>
39 #include <Geom2d_Curve.hxx>
40 #include <BRepLib_CheckCurveOnSurface.hxx>
41 #include <BRepPrimAPI_MakeRevol.hxx>
42 #include <BRepGProp.hxx>
43 #include <GC_MakePlane.hxx>
44 #include <Geom_Plane.hxx>
45 #include <GeomLib_IsPlanarSurface.hxx>
47 #include <GProp_GProps.hxx>
48 #include <IntTools_Context.hxx>
49 #include <TopExp_Explorer.hxx>
51 #include <TopoDS_Edge.hxx>
52 #include <TopTools_ListIteratorOfListOfShape.hxx>
54 /// \brief Constructs infinite face from thePlane, and with axis located on the same side
55 /// of the plane as thePoint. Modifies thePlane axis direction.
56 /// \param[in,out] thePlane plane to construct face.
57 /// \param[in] thePoint point to locate plane axis.
58 /// \return constructed face.
59 static TopoDS_Face makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint);
61 /// \return solid created from face or shell.
62 static TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape);
64 /// \brief return centre of mass for theShape.
65 /// \param[in] theShape shape.
66 static gp_Pnt centreOfMass(const TopoDS_Shape& theShape);
68 /// \brief Selects solid from theShape with closest center of mass to thePoint
69 /// \param[in] theShape compound with solids.
70 /// \param[in] thePoint point.
72 static TopoDS_Shape findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint);
74 static void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
75 const TopoDS_Shape& theBase,
76 const TopAbs_ShapeEnum theType,
77 BRepPrimAPI_MakeRevol* theRevolBuilder);
79 static void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
80 const TopoDS_Shape& theResult,
81 const TopAbs_ShapeEnum theType,
82 const TopoDS_Shape& theToFace,
83 const TopoDS_Shape& theFromFace);
85 static void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
86 const TopoDS_Shape& theResult,
87 const TopAbs_ShapeEnum theType,
88 const TopoDS_Shape& theRotatedBoundingFace,
89 const TopoDS_Shape& theModifiedBaseShape,
90 const bool theIsFromFaceSet);
92 //==================================================================================================
93 GeomAlgoAPI_Revolution::GeomAlgoAPI_Revolution(const GeomShapePtr theBaseShape,
94 const std::shared_ptr<GeomAPI_Ax1> theAxis,
95 const double theToAngle,
96 const double theFromAngle)
98 build(theBaseShape, theAxis, GeomShapePtr(), theToAngle, GeomShapePtr(), theFromAngle);
101 //==================================================================================================
102 GeomAlgoAPI_Revolution::GeomAlgoAPI_Revolution(const GeomShapePtr theBaseShape,
103 const std::shared_ptr<GeomAPI_Ax1> theAxis,
104 const GeomShapePtr theToShape,
105 const double theToAngle,
106 const GeomShapePtr theFromShape,
107 const double theFromAngle)
109 build(theBaseShape, theAxis, theToShape, theToAngle, theFromShape, theFromAngle);
112 //==================================================================================================
113 void GeomAlgoAPI_Revolution::build(const GeomShapePtr& theBaseShape,
114 const std::shared_ptr<GeomAPI_Ax1>& theAxis,
115 const GeomShapePtr& theToShape,
116 const double theToAngle,
117 const GeomShapePtr& theFromShape,
118 const double theFromAngle)
120 if(!theBaseShape || !theAxis ||
121 (((!theFromShape && !theToShape) ||
122 (theFromShape && theToShape && theFromShape->isEqual(theToShape)))
123 && (theFromAngle == -theToAngle))) {
127 // Getting base shape.
128 const TopoDS_Shape& aBaseShape = theBaseShape->impl<TopoDS_Shape>();
129 TopAbs_ShapeEnum aShapeTypeToExp;
130 switch(aBaseShape.ShapeType()) {
132 aShapeTypeToExp = TopAbs_VERTEX;
136 aShapeTypeToExp = TopAbs_EDGE;
140 aShapeTypeToExp = TopAbs_FACE;
142 case TopAbs_COMPOUND:
143 aShapeTypeToExp = TopAbs_COMPOUND;
150 gp_Ax1 anAxis = theAxis->impl<gp_Ax1>();
152 // Getting base plane.
153 Handle(Geom_Plane) aBasePlane;
154 BRepBuilderAPI_FindPlane aFindPlane(aBaseShape);
155 if(aShapeTypeToExp == TopAbs_FACE && aFindPlane.Found() == Standard_True) {
156 aBasePlane = aFindPlane.Plane();
158 gp_Pnt aPnt1 = anAxis.Location();
159 gp_Pnt aPnt2 = aPnt1;
160 aPnt2.Translate(anAxis.Direction());
163 for(TopExp_Explorer anExp(aBaseShape, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
164 aPnt3 = BRep_Tool::Pnt(TopoDS::Vertex(anExp.Current()));
166 GC_MakePlane aMkPlane(aPnt1, aPnt2, aPnt3);
167 if(aMkPlane.IsDone() != Standard_True) {
171 aBasePlane = aMkPlane.Value();
175 if(aBasePlane.IsNull()) {
176 aPnt3 = centreOfMass(aBaseShape);
178 GC_MakePlane aMkPlane(aPnt1, aPnt2, aPnt3);
179 if(aMkPlane.IsDone() != Standard_True) {
183 aBasePlane = aMkPlane.Value();
187 if(aShapeTypeToExp == TopAbs_FACE) {
188 if(aBasePlane->Axis().Angle(anAxis) < Precision::Confusion()) {
193 gp_Pnt aBaseCentre = GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape)->impl<gp_Pnt>();
195 TopoDS_Shape aResult;
196 if(!theFromShape && !theToShape) { // Case 1: When only angles was set.
197 // Rotating base face with the negative value of "from angle".
199 aBaseTrsf.SetRotation(anAxis, -theFromAngle / 180.0 * M_PI);
200 BRepBuilderAPI_Transform* aBaseTransform = new BRepBuilderAPI_Transform(aBaseShape,
203 if(!aBaseTransform) {
206 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
207 new GeomAlgoAPI_MakeShape(aBaseTransform)));
208 if(!aBaseTransform->IsDone()) {
211 TopoDS_Shape aRotatedBase = aBaseTransform->Shape();
213 // Making revolution to the angle equal to the sum of "from angle" and "to angle".
214 BRepPrimAPI_MakeRevol* aRevolBuilder = new BRepPrimAPI_MakeRevol(aRotatedBase,
216 (theFromAngle + theToAngle) / 180 * M_PI,
221 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
222 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
223 if(!aRevolBuilder->IsDone()) {
226 aResult = aRevolBuilder->Shape();
229 if(aShapeTypeToExp == TopAbs_COMPOUND) {
230 storeGenerationHistory(this, aRotatedBase, TopAbs_EDGE, aRevolBuilder);
231 storeGenerationHistory(this, aRotatedBase, TopAbs_FACE, aRevolBuilder);
233 storeGenerationHistory(this, aRotatedBase, aShapeTypeToExp, aRevolBuilder);
235 } else if(theFromShape && theToShape) { // Case 2: When both bounding planes were set.
236 // Making revolution to the 360 angle.
237 BRepPrimAPI_MakeRevol* aRevolBuilder =
238 new BRepPrimAPI_MakeRevol(aBaseShape, anAxis, 2 * M_PI, Standard_True);
242 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
243 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
244 if(!aRevolBuilder->IsDone()) {
247 aResult = aRevolBuilder->Shape();
249 // Getting bounding faces.
250 TopoDS_Face aFromFace = TopoDS::Face(theFromShape->impl<TopoDS_Shape>());
251 TopoDS_Face aToFace = TopoDS::Face(theToShape->impl<TopoDS_Shape>());
253 // Getting planes from bounding face.
254 GeomLib_IsPlanarSurface isFromPlanar(BRep_Tool::Surface(aFromFace));
255 GeomLib_IsPlanarSurface isToPlanar(BRep_Tool::Surface(aToFace));
256 if(!isFromPlanar.IsPlanar() || !isToPlanar.IsPlanar()) {
257 // non-planar shapes is not supported for revolution bounding
261 std::shared_ptr<GeomAPI_Face> aGeomFromFace(new GeomAPI_Face(theFromShape));
262 std::shared_ptr<GeomAPI_Face> aGeomToFace(new GeomAPI_Face(theToShape));
264 gp_Pln aFromPln = aGeomFromFace->getPlane()->impl<gp_Pln>();
265 gp_Pln aToPln = aGeomToFace->getPlane()->impl<gp_Pln>();
267 // Orienting bounding planes properly so that the center of mass of the base face stays
268 // on the result shape after cut.
269 aFromFace = makeFaceFromPlane(aFromPln, aBaseCentre);
270 aToFace = makeFaceFromPlane(aToPln, aBaseCentre);
272 // Making solids from bounding planes and putting them in compound.
273 TopoDS_Shape aFromSolid = makeSolidFromShape(aFromFace);
274 TopoDS_Shape aToSolid = makeSolidFromShape(aToFace);
276 // Rotating bounding planes to the specified angle.
279 double aFromRotAngle =
280 ((aFromPln.Axis().Direction() * aBasePlane->Axis().Direction()) > 0) ? -theFromAngle :
283 ((aToPln.Axis().Direction() * aBasePlane->Axis().Direction()) > 0) ? -theToAngle :
285 aFromTrsf.SetRotation(anAxis,aFromRotAngle / 180.0 * M_PI);
286 aToTrsf.SetRotation(anAxis, aToRotAngle / 180.0 * M_PI);
287 BRepBuilderAPI_Transform aFromTransform(aFromSolid, aFromTrsf, true);
288 BRepBuilderAPI_Transform aToTransform(aToSolid, aToTrsf, true);
289 TopoDS_Shape aRotatedFromFace = aFromTransform.Modified(aFromFace).First();
290 TopoDS_Shape aRotatedToFace = aToTransform.Modified(aToFace).First();
291 aFromSolid = aFromTransform.Shape();
292 aToSolid = aToTransform.Shape();
294 // Cutting revolution with from plane.
295 BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid);
296 aFromCutBuilder->Build();
297 if(!aFromCutBuilder->IsDone()) {
300 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
301 new GeomAlgoAPI_MakeShape(aFromCutBuilder)));
302 aResult = aFromCutBuilder->Shape();
303 if(aResult.ShapeType() == TopAbs_COMPOUND) {
304 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
307 // Cutting revolution with to plane.
308 BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid);
309 aToCutBuilder->Build();
310 if(!aToCutBuilder->IsDone()) {
313 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
314 new GeomAlgoAPI_MakeShape(aToCutBuilder)));
315 aResult = aToCutBuilder->Shape();
316 TopoDS_Iterator aCheckIt(aResult);
317 if(!aCheckIt.More()) {
320 if(aResult.ShapeType() == TopAbs_COMPOUND) {
321 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
323 if(aResult.ShapeType() == TopAbs_COMPOUND) {
324 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
325 aGeomShape->setImpl(new TopoDS_Shape(aResult));
326 ListOfShape aCompSolids, aFreeSolids;
327 aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
328 GeomAPI_Shape::COMPSOLID,
331 aResult = aGeomShape->impl<TopoDS_Shape>();
334 // If after cut we got more than one solids then take closest
335 // to the center of mass of the base face.
336 aResult = findClosest(aResult, aBaseCentre);
339 if(aShapeTypeToExp == TopAbs_COMPOUND) {
340 storeGenerationHistory(this, aResult, TopAbs_EDGE, aRotatedToFace, aRotatedFromFace);
341 storeGenerationHistory(this, aResult, TopAbs_FACE, aRotatedToFace, aRotatedFromFace);
343 storeGenerationHistory(this, aResult, aShapeTypeToExp, aRotatedToFace, aRotatedFromFace);
345 } else { //Case 3: When only one bounding plane was set.
346 // Making revolution to the 360 angle.
347 BRepPrimAPI_MakeRevol* aRevolBuilder =
348 new BRepPrimAPI_MakeRevol(aBaseShape, anAxis, 2 * M_PI, Standard_True);
352 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
353 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
354 if(!aRevolBuilder->IsDone()) {
357 aResult = aRevolBuilder->Shape();
359 // Getting bounding face.
360 bool isFromFaceSet = false;
361 std::shared_ptr<GeomAPI_Face> aGeomBoundingFace;
363 aGeomBoundingFace.reset(new GeomAPI_Face(theFromShape));
364 isFromFaceSet = true;
365 } else if(theToShape) {
366 aGeomBoundingFace.reset(new GeomAPI_Face(theToShape));
368 TopoDS_Face aBoundingFace = TopoDS::Face(aGeomBoundingFace->impl<TopoDS_Shape>());
370 // Getting plane from bounding face.
371 GeomLib_IsPlanarSurface isBoundingPlanar(BRep_Tool::Surface(aBoundingFace));
372 if(!isBoundingPlanar.IsPlanar()) { // non-planar shapes is not supported for revolution bounding
376 gp_Pln aBoundingPln = aGeomBoundingFace->getPlane()->impl<gp_Pln>();
378 // Orienting bounding plane properly so that the center of mass of the base face stays
379 // on the result shape after cut.
380 aBoundingFace = makeFaceFromPlane(aBoundingPln, aBaseCentre);
382 // Making solid from bounding plane.
383 TopoDS_Shape aBoundingSolid = makeSolidFromShape(aBoundingFace);
385 // Rotating bounding plane to the specified angle.
386 double aBoundingRotAngle = isFromFaceSet ? theFromAngle : theToAngle;
387 if(aBoundingPln.Axis().IsParallel(aBasePlane->Axis(), Precision::Confusion())) {
388 if(isFromFaceSet) aBoundingRotAngle = -aBoundingRotAngle;
390 double aSign = (aBoundingPln.Axis().Direction() ^ aBasePlane->Axis().Direction()) *
392 if((aSign <= 0 && !isFromFaceSet) || (aSign > 0 && isFromFaceSet)) {
393 aBoundingRotAngle = -aBoundingRotAngle;
396 gp_Trsf aBoundingTrsf;
397 aBoundingTrsf.SetRotation(anAxis, aBoundingRotAngle / 180.0 * M_PI);
398 BRepBuilderAPI_Transform aBoundingTransform(aBoundingSolid, aBoundingTrsf, true);
399 TopoDS_Shape aRotatedBoundingFace = aBoundingTransform.Modified(aBoundingFace).First();
400 aBoundingSolid = aBoundingTransform.Shape();
402 // Cutting revolution with bounding plane.
403 BRepAlgoAPI_Cut* aBoundingCutBuilder = new BRepAlgoAPI_Cut(aResult, aBoundingSolid);
404 aBoundingCutBuilder->Build();
405 if(!aBoundingCutBuilder->IsDone()) {
408 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
409 new GeomAlgoAPI_MakeShape(aBoundingCutBuilder)));
410 aResult = aBoundingCutBuilder->Shape();
411 if(aResult.ShapeType() == TopAbs_COMPOUND) {
412 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
416 if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) {
417 const TopTools_ListOfShape& aBndShapes = aBoundingCutBuilder->Modified(aBoundingFace);
418 for(TopTools_ListIteratorOfListOfShape anIt(aBndShapes); anIt.More(); anIt.Next()) {
419 GeomShapePtr aShape(new GeomAPI_Shape());
420 aShape->setImpl(new TopoDS_Shape(anIt.Value()));
421 fixOrientation(aShape);
422 isFromFaceSet ? this->addFromShape(aShape) : this->addToShape(aShape);
426 // Try to cut with base face. If it can not be done then keep result of cut with bounding plane.
427 TopoDS_Shape aModifiedBaseShape;
428 if(aShapeTypeToExp != TopAbs_FACE) {
430 GeomShapePtr aSh(new GeomAPI_Shape());
431 aSh->setImpl(new TopoDS_Shape(aBaseShape));
432 std::shared_ptr<GeomAPI_Pnt> theCenter(new GeomAPI_Pnt(aBasePlane->Location().X(),
433 aBasePlane->Location().Y(),
434 aBasePlane->Location().Z()));
435 std::shared_ptr<GeomAPI_Dir> theNormal(new GeomAPI_Dir(aBasePlane->Axis().Direction().X(),
436 aBasePlane->Axis().Direction().Y(),
437 aBasePlane->Axis().Direction().Z()));
438 GeomShapePtr aPln = GeomAlgoAPI_FaceBuilder::planarFace(theCenter, theNormal);
439 aList.push_back(aSh);
440 std::list<std::shared_ptr<GeomAPI_Pnt> >
441 aBoundingPoints = GeomAlgoAPI_ShapeTools::getBoundingBox(aList);
442 aSh = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPln, aBoundingPoints);
443 aModifiedBaseShape = aSh->impl<TopoDS_Shape>();
445 aModifiedBaseShape = aBaseShape;
448 if(aModifiedBaseShape.ShapeType() == TopAbs_FACE) {
449 aModifiedBaseShape.Orientation(TopAbs_REVERSED);
452 aMirrorTrsf.SetMirror(aBasePlane->Position().Ax2());
453 BRepBuilderAPI_Transform aMirrorTransform(aModifiedBaseShape, aMirrorTrsf, true);
454 aModifiedBaseShape = aMirrorTransform.Shape();
458 // Making solid from base face.
459 TopoDS_Shape aBaseSolid = makeSolidFromShape(aModifiedBaseShape);
461 // Rotating base face to the specified angle.
463 double aBaseRotAngle = isFromFaceSet ? theToAngle : -theFromAngle;
464 aBaseTrsf.SetRotation(anAxis, aBaseRotAngle / 180.0 * M_PI);
465 BRepBuilderAPI_Transform aBaseTransform(aBaseSolid, aBaseTrsf, true);
466 aBaseSolid = aBaseTransform.Shape();
468 // Cutting revolution with base.
469 BRepAlgoAPI_Cut* aBaseCutBuilder = new BRepAlgoAPI_Cut(aResult, aBaseSolid);
470 aBaseCutBuilder->Build();
471 if(aBaseCutBuilder->IsDone()) {
472 TopoDS_Shape aCutResult = aBaseCutBuilder->Shape();
473 TopoDS_Iterator aCheckIt(aCutResult);
474 if(aCheckIt.More()) {
475 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
476 new GeomAlgoAPI_MakeShape(aBaseCutBuilder)));
477 aResult = aCutResult;
478 if(aResult.ShapeType() == TopAbs_COMPOUND) {
479 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
481 if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) {
482 const TopTools_ListOfShape& aBsShapes = aBaseCutBuilder->Modified(aBoundingFace);
483 for(TopTools_ListIteratorOfListOfShape anIt(aBsShapes); anIt.More(); anIt.Next()) {
484 GeomShapePtr aShape(new GeomAPI_Shape());
485 aShape->setImpl(new TopoDS_Shape(anIt.Value()));
486 fixOrientation(aShape);
487 isFromFaceSet ? this->addToShape(aShape) : this->addFromShape(aShape);
493 if(aResult.ShapeType() == TopAbs_COMPOUND) {
494 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
495 aGeomShape->setImpl(new TopoDS_Shape(aResult));
496 ListOfShape aCompSolids, aFreeSolids;
497 aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
498 GeomAPI_Shape::COMPSOLID,
501 aResult = aGeomShape->impl<TopoDS_Shape>();
504 // If after cut we got more than one solids then take
505 // closest to the center of mass of the base face.
506 aResult = findClosest(aResult, aBaseCentre);
509 if(aShapeTypeToExp == TopAbs_COMPOUND) {
510 storeGenerationHistory(this, aResult, TopAbs_EDGE,
511 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
512 storeGenerationHistory(this, aResult, TopAbs_FACE,
513 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
515 storeGenerationHistory(this, aResult, aShapeTypeToExp,
516 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
521 if(aResult.IsNull()) {
524 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
525 GeomShapePtr aShape(new GeomAPI_Shape());
526 aShape->setImpl(new TopoDS_Shape(aResult));
527 this->setShape(aShape);
531 //==================================================================================================
532 TopoDS_Face makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint)
534 if(!thePlane.Contains(thePoint, Precision::Confusion())) {
535 gp_XYZ aVec = thePoint.XYZ() - thePlane.Location().XYZ();
536 double aSign = aVec * thePlane.Axis().Direction().XYZ();
537 if(aSign < 0) thePlane.SetAxis(thePlane.Axis().Reversed());
540 BRepBuilderAPI_MakeFace aMakeFace(thePlane);
541 TopoDS_Face aResultFace = TopoDS::Face(aMakeFace.Shape());
546 //==================================================================================================
547 TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape)
552 BRep_Builder aBoundingBuilder;
553 if(theShape.ShapeType() == TopAbs_SHELL) {
554 aShell = TopoDS::Shell(theShape);
556 aBoundingBuilder.MakeShell(aShell);
557 aBoundingBuilder.Add(aShell, theShape);
559 aBoundingBuilder.MakeSolid(aSolid);
560 aBoundingBuilder.Add(aSolid, aShell);
565 //================================================================================================
566 gp_Pnt centreOfMass(const TopoDS_Shape& theShape)
568 TopAbs_ShapeEnum aShType = theShape.ShapeType();
569 GProp_GProps aGProps;
571 if(aShType == TopAbs_EDGE || aShType == TopAbs_WIRE) {
572 BRepGProp::LinearProperties(theShape, aGProps);
573 } else if(aShType == TopAbs_FACE || aShType == TopAbs_SHELL) {
574 BRepGProp::SurfaceProperties(theShape, aGProps);
575 } else if(aShType == TopAbs_SOLID || aShType == TopAbs_COMPSOLID) {
576 BRepGProp::VolumeProperties(theShape, aGProps);
579 return aGProps.CentreOfMass();
582 //================================================================================================
583 TopoDS_Shape findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint)
585 TopoDS_Shape aResult = theShape;
587 if(theShape.ShapeType() == TopAbs_COMPOUND) {
588 double aMinDistance = Precision::Infinite();
591 for (TopoDS_Iterator anItr(theShape); anItr.More(); anItr.Next()) {
592 TopoDS_Shape aValue = anItr.Value();
593 aCentr = centreOfMass(aValue);
594 aCurDistance = aCentr.Distance(thePoint);
596 if(aCurDistance < aMinDistance) {
597 aMinDistance = aCurDistance;
606 //================================================================================================
607 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
608 const TopoDS_Shape& theBase,
609 const TopAbs_ShapeEnum theType,
610 BRepPrimAPI_MakeRevol* theRevolBuilder)
612 for(TopExp_Explorer anExp(theBase, theType); anExp.More(); anExp.Next()) {
613 const TopoDS_Shape& aShape = anExp.Current();
614 GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
615 aFromShape->setImpl(new TopoDS_Shape(theRevolBuilder->FirstShape(aShape)));
616 aToShape->setImpl(new TopoDS_Shape(theRevolBuilder->LastShape(aShape)));
617 theRevolutionAlgo->fixOrientation(aFromShape);
618 theRevolutionAlgo->fixOrientation(aToShape);
619 theRevolutionAlgo->addFromShape(aFromShape);
620 theRevolutionAlgo->addToShape(aToShape);
624 //================================================================================================
625 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
626 const TopoDS_Shape& theResult,
627 const TopAbs_ShapeEnum theType,
628 const TopoDS_Shape& theToFace,
629 const TopoDS_Shape& theFromFace)
631 for(TopExp_Explorer anExp(theResult, theType); anExp.More (); anExp.Next ()) {
632 const TopoDS_Shape& aShape = anExp.Current();
633 GeomShapePtr aGeomSh(new GeomAPI_Shape());
634 if(theType == TopAbs_VERTEX) {
635 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
636 IntTools_Context anIntTools;
637 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theToFace),
638 Precision::Confusion()) == Standard_True) {
639 aGeomSh->setImpl(new TopoDS_Shape(aShape));
640 theRevolutionAlgo->fixOrientation(aGeomSh);
641 theRevolutionAlgo->addToShape(aGeomSh);
643 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theFromFace),
644 Precision::Confusion()) == Standard_True) {
645 aGeomSh->setImpl(new TopoDS_Shape(aShape));
646 theRevolutionAlgo->fixOrientation(aGeomSh);
647 theRevolutionAlgo->addFromShape(aGeomSh);
649 } else if(theType == TopAbs_EDGE) {
650 TopoDS_Edge anEdge = TopoDS::Edge(aShape);
651 BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, TopoDS::Face(theToFace));
652 anEdgeCheck.Perform();
653 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
654 aGeomSh->setImpl(new TopoDS_Shape(aShape));
655 theRevolutionAlgo->fixOrientation(aGeomSh);
656 theRevolutionAlgo->addToShape(aGeomSh);
658 anEdgeCheck.Init(anEdge, TopoDS::Face(theFromFace));
659 anEdgeCheck.Perform();
660 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
661 aGeomSh->setImpl(new TopoDS_Shape(aShape));
662 theRevolutionAlgo->fixOrientation(aGeomSh);
663 theRevolutionAlgo->addFromShape(aGeomSh);
666 Handle(Geom_Surface) aFaceSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
667 Handle(Geom_Surface) aFromSurface = BRep_Tool::Surface(TopoDS::Face(theFromFace));
668 Handle(Geom_Surface) aToSurface = BRep_Tool::Surface(TopoDS::Face(theToFace));
669 if(aFaceSurface == aFromSurface) {
670 aGeomSh->setImpl(new TopoDS_Shape(aShape));
671 theRevolutionAlgo->fixOrientation(aGeomSh);
672 theRevolutionAlgo->addFromShape(aGeomSh);
674 if(aFaceSurface == aToSurface) {
675 aGeomSh->setImpl(new TopoDS_Shape(aShape));
676 theRevolutionAlgo->fixOrientation(aGeomSh);
677 theRevolutionAlgo->addToShape(aGeomSh);
683 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
684 const TopoDS_Shape& theResult,
685 const TopAbs_ShapeEnum theType,
686 const TopoDS_Shape& theRotatedBoundingFace,
687 const TopoDS_Shape& theModifiedBaseShape,
688 const bool theIsFromFaceSet)
690 for(TopExp_Explorer anExp(theResult, theType); anExp.More (); anExp.Next ()) {
691 const TopoDS_Shape& aShape = anExp.Current();
692 GeomShapePtr aGeomSh(new GeomAPI_Shape());
693 if(theType == TopAbs_VERTEX) {
694 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
695 IntTools_Context anIntTools;
696 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theRotatedBoundingFace),
697 Precision::Confusion()) == Standard_True) {
698 aGeomSh->setImpl(new TopoDS_Shape(aShape));
699 theRevolutionAlgo->fixOrientation(aGeomSh);
700 theIsFromFaceSet ? theRevolutionAlgo->addFromShape(aGeomSh) :
701 theRevolutionAlgo->addToShape(aGeomSh);
703 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theModifiedBaseShape),
704 Precision::Confusion()) == Standard_True) {
705 aGeomSh->setImpl(new TopoDS_Shape(aShape));
706 theRevolutionAlgo->fixOrientation(aGeomSh);
707 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
708 theRevolutionAlgo->addFromShape(aGeomSh);
710 } else if(theType == TopAbs_EDGE) {
711 TopoDS_Edge anEdge = TopoDS::Edge(aShape);
712 BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, TopoDS::Face(theRotatedBoundingFace));
713 anEdgeCheck.Perform();
714 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
715 aGeomSh->setImpl(new TopoDS_Shape(aShape));
716 theRevolutionAlgo->fixOrientation(aGeomSh);
717 theIsFromFaceSet ? theRevolutionAlgo->addFromShape(aGeomSh) :
718 theRevolutionAlgo->addToShape(aGeomSh);
720 anEdgeCheck.Init(anEdge, TopoDS::Face(theModifiedBaseShape));
721 anEdgeCheck.Perform();
722 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
723 aGeomSh->setImpl(new TopoDS_Shape(aShape));
724 theRevolutionAlgo->fixOrientation(aGeomSh);
725 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
726 theRevolutionAlgo->addFromShape(aGeomSh);
729 Handle(Geom_Surface) aFaceSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
730 Handle(Geom_Surface) aBoundingSurface =
731 BRep_Tool::Surface(TopoDS::Face(theRotatedBoundingFace));
732 Handle(Geom_Surface) aBaseSurface = BRep_Tool::Surface(TopoDS::Face(theModifiedBaseShape));
733 if(aFaceSurface == aBoundingSurface) {
734 aGeomSh->setImpl(new TopoDS_Shape(aShape));
735 theRevolutionAlgo->fixOrientation(aGeomSh);
736 theIsFromFaceSet ? theRevolutionAlgo->addFromShape(aGeomSh) :
737 theRevolutionAlgo->addToShape(aGeomSh);
739 if(aFaceSurface == aBaseSurface) {
740 aGeomSh->setImpl(new TopoDS_Shape(aShape));
741 theRevolutionAlgo->fixOrientation(aGeomSh);
742 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
743 theRevolutionAlgo->addFromShape(aGeomSh);