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 email : webmaster.salome@opencascade.com<mailto: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 double theToAngle,
95 const double theFromAngle)
97 build(theBaseShape, theAxis, GeomShapePtr(), theToAngle, GeomShapePtr(), theFromAngle);
100 //==================================================================================================
101 GeomAlgoAPI_Revolution::GeomAlgoAPI_Revolution(const GeomShapePtr theBaseShape,
102 const std::shared_ptr<GeomAPI_Ax1> theAxis,
103 const GeomShapePtr theToShape,
104 const double theToAngle,
105 const GeomShapePtr theFromShape,
106 const double theFromAngle)
108 build(theBaseShape, theAxis, theToShape, theToAngle, theFromShape, theFromAngle);
111 //==================================================================================================
112 void GeomAlgoAPI_Revolution::build(const GeomShapePtr& theBaseShape,
113 const std::shared_ptr<GeomAPI_Ax1>& theAxis,
114 const GeomShapePtr& theToShape,
115 const double theToAngle,
116 const GeomShapePtr& theFromShape,
117 const double theFromAngle)
119 if(!theBaseShape || !theAxis ||
120 (((!theFromShape && !theToShape) ||
121 (theFromShape && theToShape && theFromShape->isEqual(theToShape)))
122 && (theFromAngle == -theToAngle))) {
126 // Getting base shape.
127 const TopoDS_Shape& aBaseShape = theBaseShape->impl<TopoDS_Shape>();
128 TopAbs_ShapeEnum aShapeTypeToExp;
129 switch(aBaseShape.ShapeType()) {
131 aShapeTypeToExp = TopAbs_VERTEX;
135 aShapeTypeToExp = TopAbs_EDGE;
139 aShapeTypeToExp = TopAbs_FACE;
141 case TopAbs_COMPOUND:
142 aShapeTypeToExp = TopAbs_COMPOUND;
149 gp_Ax1 anAxis = theAxis->impl<gp_Ax1>();
151 // Getting base plane.
152 Handle(Geom_Plane) aBasePlane;
153 BRepBuilderAPI_FindPlane aFindPlane(aBaseShape);
154 if(aShapeTypeToExp == TopAbs_FACE && aFindPlane.Found() == Standard_True) {
155 aBasePlane = aFindPlane.Plane();
157 gp_Pnt aPnt1 = anAxis.Location();
158 gp_Pnt aPnt2 = aPnt1;
159 aPnt2.Translate(anAxis.Direction());
162 for(TopExp_Explorer anExp(aBaseShape, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
163 aPnt3 = BRep_Tool::Pnt(TopoDS::Vertex(anExp.Current()));
165 GC_MakePlane aMkPlane(aPnt1, aPnt2, aPnt3);
166 if(aMkPlane.IsDone() != Standard_True) {
170 aBasePlane = aMkPlane.Value();
174 if(aBasePlane.IsNull()) {
175 aPnt3 = centreOfMass(aBaseShape);
177 GC_MakePlane aMkPlane(aPnt1, aPnt2, aPnt3);
178 if(aMkPlane.IsDone() != Standard_True) {
182 aBasePlane = aMkPlane.Value();
186 if(aShapeTypeToExp == TopAbs_FACE) {
187 if(aBasePlane->Axis().Angle(anAxis) < Precision::Confusion()) {
192 gp_Pnt aBaseCentre = GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape)->impl<gp_Pnt>();
194 TopoDS_Shape aResult;
195 if(!theFromShape && !theToShape) { // Case 1: When only angles was set.
196 // Rotating base face with the negative value of "from angle".
198 aBaseTrsf.SetRotation(anAxis, -theFromAngle / 180.0 * M_PI);
199 BRepBuilderAPI_Transform* aBaseTransform = new BRepBuilderAPI_Transform(aBaseShape,
202 if(!aBaseTransform) {
205 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
206 new GeomAlgoAPI_MakeShape(aBaseTransform)));
207 if(!aBaseTransform->IsDone()) {
210 TopoDS_Shape aRotatedBase = aBaseTransform->Shape();
212 // Making revolution to the angle equal to the sum of "from angle" and "to angle".
213 BRepPrimAPI_MakeRevol* aRevolBuilder = new BRepPrimAPI_MakeRevol(aRotatedBase,
215 (theFromAngle + theToAngle) / 180 * M_PI,
220 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
221 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
222 if(!aRevolBuilder->IsDone()) {
225 aResult = aRevolBuilder->Shape();
228 if(aShapeTypeToExp == TopAbs_COMPOUND) {
229 storeGenerationHistory(this, aRotatedBase, TopAbs_EDGE, aRevolBuilder);
230 storeGenerationHistory(this, aRotatedBase, TopAbs_FACE, aRevolBuilder);
232 storeGenerationHistory(this, aRotatedBase, aShapeTypeToExp, aRevolBuilder);
234 } else if(theFromShape && theToShape) { // Case 2: When both bounding planes were set.
235 // Making revolution to the 360 angle.
236 BRepPrimAPI_MakeRevol* aRevolBuilder =
237 new BRepPrimAPI_MakeRevol(aBaseShape, anAxis, 2 * M_PI, Standard_True);
241 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
242 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
243 if(!aRevolBuilder->IsDone()) {
246 aResult = aRevolBuilder->Shape();
248 // Getting bounding faces.
249 TopoDS_Face aFromFace = TopoDS::Face(theFromShape->impl<TopoDS_Shape>());
250 TopoDS_Face aToFace = TopoDS::Face(theToShape->impl<TopoDS_Shape>());
252 // Getting planes from bounding face.
253 GeomLib_IsPlanarSurface isFromPlanar(BRep_Tool::Surface(aFromFace));
254 GeomLib_IsPlanarSurface isToPlanar(BRep_Tool::Surface(aToFace));
255 if(!isFromPlanar.IsPlanar() || !isToPlanar.IsPlanar()) {
256 // non-planar shapes is not supported for revolution bounding
260 std::shared_ptr<GeomAPI_Face> aGeomFromFace(new GeomAPI_Face(theFromShape));
261 std::shared_ptr<GeomAPI_Face> aGeomToFace(new GeomAPI_Face(theToShape));
263 gp_Pln aFromPln = aGeomFromFace->getPlane()->impl<gp_Pln>();
264 gp_Pln aToPln = aGeomToFace->getPlane()->impl<gp_Pln>();
266 // Orienting bounding planes properly so that the center of mass of the base face stays
267 // on the result shape after cut.
268 aFromFace = makeFaceFromPlane(aFromPln, aBaseCentre);
269 aToFace = makeFaceFromPlane(aToPln, aBaseCentre);
271 // Making solids from bounding planes and putting them in compound.
272 TopoDS_Shape aFromSolid = makeSolidFromShape(aFromFace);
273 TopoDS_Shape aToSolid = makeSolidFromShape(aToFace);
275 // Rotating bounding planes to the specified angle.
278 double aFromRotAngle =
279 ((aFromPln.Axis().Direction() * aBasePlane->Axis().Direction()) > 0) ? -theFromAngle :
282 ((aToPln.Axis().Direction() * aBasePlane->Axis().Direction()) > 0) ? -theToAngle :
284 aFromTrsf.SetRotation(anAxis,aFromRotAngle / 180.0 * M_PI);
285 aToTrsf.SetRotation(anAxis, aToRotAngle / 180.0 * M_PI);
286 BRepBuilderAPI_Transform aFromTransform(aFromSolid, aFromTrsf, true);
287 BRepBuilderAPI_Transform aToTransform(aToSolid, aToTrsf, true);
288 TopoDS_Shape aRotatedFromFace = aFromTransform.Modified(aFromFace).First();
289 TopoDS_Shape aRotatedToFace = aToTransform.Modified(aToFace).First();
290 aFromSolid = aFromTransform.Shape();
291 aToSolid = aToTransform.Shape();
293 // Cutting revolution with from plane.
294 BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid);
295 aFromCutBuilder->Build();
296 if(!aFromCutBuilder->IsDone()) {
299 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
300 new GeomAlgoAPI_MakeShape(aFromCutBuilder)));
301 aResult = aFromCutBuilder->Shape();
302 if(aResult.ShapeType() == TopAbs_COMPOUND) {
303 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
306 // Cutting revolution with to plane.
307 BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid);
308 aToCutBuilder->Build();
309 if(!aToCutBuilder->IsDone()) {
312 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
313 new GeomAlgoAPI_MakeShape(aToCutBuilder)));
314 aResult = aToCutBuilder->Shape();
315 TopoDS_Iterator aCheckIt(aResult);
316 if(!aCheckIt.More()) {
319 if(aResult.ShapeType() == TopAbs_COMPOUND) {
320 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
322 if(aResult.ShapeType() == TopAbs_COMPOUND) {
323 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
324 aGeomShape->setImpl(new TopoDS_Shape(aResult));
325 ListOfShape aCompSolids, aFreeSolids;
326 aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
327 GeomAPI_Shape::COMPSOLID,
330 aResult = aGeomShape->impl<TopoDS_Shape>();
333 // If after cut we got more than one solids then take closest
334 // to the center of mass of the base face.
335 aResult = findClosest(aResult, aBaseCentre);
338 if(aShapeTypeToExp == TopAbs_COMPOUND) {
339 storeGenerationHistory(this, aResult, TopAbs_EDGE, aRotatedToFace, aRotatedFromFace);
340 storeGenerationHistory(this, aResult, TopAbs_FACE, aRotatedToFace, aRotatedFromFace);
342 storeGenerationHistory(this, aResult, aShapeTypeToExp, aRotatedToFace, aRotatedFromFace);
344 } else { //Case 3: When only one bounding plane was set.
345 // Making revolution to the 360 angle.
346 BRepPrimAPI_MakeRevol* aRevolBuilder =
347 new BRepPrimAPI_MakeRevol(aBaseShape, anAxis, 2 * M_PI, Standard_True);
351 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
352 new GeomAlgoAPI_MakeShape(aRevolBuilder)));
353 if(!aRevolBuilder->IsDone()) {
356 aResult = aRevolBuilder->Shape();
358 // Getting bounding face.
359 bool isFromFaceSet = false;
360 std::shared_ptr<GeomAPI_Face> aGeomBoundingFace;
362 aGeomBoundingFace.reset(new GeomAPI_Face(theFromShape));
363 isFromFaceSet = true;
364 } else if(theToShape) {
365 aGeomBoundingFace.reset(new GeomAPI_Face(theToShape));
367 TopoDS_Face aBoundingFace = TopoDS::Face(aGeomBoundingFace->impl<TopoDS_Shape>());
369 // Getting plane from bounding face.
370 GeomLib_IsPlanarSurface isBoundingPlanar(BRep_Tool::Surface(aBoundingFace));
371 if(!isBoundingPlanar.IsPlanar()) { // non-planar shapes is not supported for revolution bounding
375 gp_Pln aBoundingPln = aGeomBoundingFace->getPlane()->impl<gp_Pln>();
377 // Orienting bounding plane properly so that the center of mass of the base face stays
378 // on the result shape after cut.
379 aBoundingFace = makeFaceFromPlane(aBoundingPln, aBaseCentre);
381 // Making solid from bounding plane.
382 TopoDS_Shape aBoundingSolid = makeSolidFromShape(aBoundingFace);
384 // Rotating bounding plane to the specified angle.
385 double aBoundingRotAngle = isFromFaceSet ? theFromAngle : theToAngle;
386 if(aBoundingPln.Axis().IsParallel(aBasePlane->Axis(), Precision::Confusion())) {
387 if(isFromFaceSet) aBoundingRotAngle = -aBoundingRotAngle;
389 double aSign = (aBoundingPln.Axis().Direction() ^ aBasePlane->Axis().Direction()) *
391 if((aSign <= 0 && !isFromFaceSet) || (aSign > 0 && isFromFaceSet)) {
392 aBoundingRotAngle = -aBoundingRotAngle;
395 gp_Trsf aBoundingTrsf;
396 aBoundingTrsf.SetRotation(anAxis, aBoundingRotAngle / 180.0 * M_PI);
397 BRepBuilderAPI_Transform aBoundingTransform(aBoundingSolid, aBoundingTrsf, true);
398 TopoDS_Shape aRotatedBoundingFace = aBoundingTransform.Modified(aBoundingFace).First();
399 aBoundingSolid = aBoundingTransform.Shape();
401 // Cutting revolution with bounding plane.
402 BRepAlgoAPI_Cut* aBoundingCutBuilder = new BRepAlgoAPI_Cut(aResult, aBoundingSolid);
403 aBoundingCutBuilder->Build();
404 if(!aBoundingCutBuilder->IsDone()) {
407 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
408 new GeomAlgoAPI_MakeShape(aBoundingCutBuilder)));
409 aResult = aBoundingCutBuilder->Shape();
410 if(aResult.ShapeType() == TopAbs_COMPOUND) {
411 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
415 if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) {
416 const TopTools_ListOfShape& aBndShapes = aBoundingCutBuilder->Modified(aBoundingFace);
417 for(TopTools_ListIteratorOfListOfShape anIt(aBndShapes); anIt.More(); anIt.Next()) {
418 GeomShapePtr aShape(new GeomAPI_Shape());
419 aShape->setImpl(new TopoDS_Shape(anIt.Value()));
420 isFromFaceSet ? this->addFromShape(aShape) : this->addToShape(aShape);
424 // Try to cut with base face. If it can not be done then keep result of cut with bounding plane.
425 TopoDS_Shape aModifiedBaseShape;
426 if(aShapeTypeToExp != TopAbs_FACE) {
428 GeomShapePtr aSh(new GeomAPI_Shape());
429 aSh->setImpl(new TopoDS_Shape(aBaseShape));
430 std::shared_ptr<GeomAPI_Pnt> theCenter(new GeomAPI_Pnt(aBasePlane->Location().X(),
431 aBasePlane->Location().Y(),
432 aBasePlane->Location().Z()));
433 std::shared_ptr<GeomAPI_Dir> theNormal(new GeomAPI_Dir(aBasePlane->Axis().Direction().X(),
434 aBasePlane->Axis().Direction().Y(),
435 aBasePlane->Axis().Direction().Z()));
436 GeomShapePtr aPln = GeomAlgoAPI_FaceBuilder::planarFace(theCenter, theNormal);
437 aList.push_back(aSh);
438 std::list<std::shared_ptr<GeomAPI_Pnt> >
439 aBoundingPoints = GeomAlgoAPI_ShapeTools::getBoundingBox(aList);
440 aSh = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPln, aBoundingPoints);
441 aModifiedBaseShape = aSh->impl<TopoDS_Shape>();
443 aModifiedBaseShape = aBaseShape;
446 if(aModifiedBaseShape.ShapeType() == TopAbs_FACE) {
447 aModifiedBaseShape.Orientation(TopAbs_REVERSED);
450 aMirrorTrsf.SetMirror(aBasePlane->Position().Ax2());
451 BRepBuilderAPI_Transform aMirrorTransform(aModifiedBaseShape, aMirrorTrsf, true);
452 aModifiedBaseShape = aMirrorTransform.Shape();
456 // Making solid from base face.
457 TopoDS_Shape aBaseSolid = makeSolidFromShape(aModifiedBaseShape);
459 // Rotating base face to the specified angle.
461 double aBaseRotAngle = isFromFaceSet ? theToAngle : -theFromAngle;
462 aBaseTrsf.SetRotation(anAxis, aBaseRotAngle / 180.0 * M_PI);
463 BRepBuilderAPI_Transform aBaseTransform(aBaseSolid, aBaseTrsf, true);
464 aBaseSolid = aBaseTransform.Shape();
466 // Cutting revolution with base.
467 BRepAlgoAPI_Cut* aBaseCutBuilder = new BRepAlgoAPI_Cut(aResult, aBaseSolid);
468 aBaseCutBuilder->Build();
469 if(aBaseCutBuilder->IsDone()) {
470 TopoDS_Shape aCutResult = aBaseCutBuilder->Shape();
471 TopoDS_Iterator aCheckIt(aCutResult);
472 if(aCheckIt.More()) {
473 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(
474 new GeomAlgoAPI_MakeShape(aBaseCutBuilder)));
475 aResult = aCutResult;
476 if(aResult.ShapeType() == TopAbs_COMPOUND) {
477 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
479 if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) {
480 const TopTools_ListOfShape& aBsShapes = aBaseCutBuilder->Modified(aBoundingFace);
481 for(TopTools_ListIteratorOfListOfShape anIt(aBsShapes); anIt.More(); anIt.Next()) {
482 GeomShapePtr aShape(new GeomAPI_Shape());
483 aShape->setImpl(new TopoDS_Shape(anIt.Value()));
484 isFromFaceSet ? this->addToShape(aShape) : this->addFromShape(aShape);
490 if(aResult.ShapeType() == TopAbs_COMPOUND) {
491 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
492 aGeomShape->setImpl(new TopoDS_Shape(aResult));
493 ListOfShape aCompSolids, aFreeSolids;
494 aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
495 GeomAPI_Shape::COMPSOLID,
498 aResult = aGeomShape->impl<TopoDS_Shape>();
501 // If after cut we got more than one solids then take
502 // closest to the center of mass of the base face.
503 aResult = findClosest(aResult, aBaseCentre);
506 if(aShapeTypeToExp == TopAbs_COMPOUND) {
507 storeGenerationHistory(this, aResult, TopAbs_EDGE,
508 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
509 storeGenerationHistory(this, aResult, TopAbs_FACE,
510 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
512 storeGenerationHistory(this, aResult, aShapeTypeToExp,
513 aRotatedBoundingFace, aModifiedBaseShape, isFromFaceSet);
518 if(aResult.IsNull()) {
521 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
522 GeomShapePtr aShape(new GeomAPI_Shape());
523 aShape->setImpl(new TopoDS_Shape(aResult));
524 this->setShape(aShape);
528 //==================================================================================================
529 TopoDS_Face makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint)
531 if(!thePlane.Contains(thePoint, Precision::Confusion())) {
532 gp_XYZ aVec = thePoint.XYZ() - thePlane.Location().XYZ();
533 double aSign = aVec * thePlane.Axis().Direction().XYZ();
534 if(aSign < 0) thePlane.SetAxis(thePlane.Axis().Reversed());
537 BRepBuilderAPI_MakeFace aMakeFace(thePlane);
538 TopoDS_Face aResultFace = TopoDS::Face(aMakeFace.Shape());
543 //==================================================================================================
544 TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape)
549 BRep_Builder aBoundingBuilder;
550 if(theShape.ShapeType() == TopAbs_SHELL) {
551 aShell = TopoDS::Shell(theShape);
553 aBoundingBuilder.MakeShell(aShell);
554 aBoundingBuilder.Add(aShell, theShape);
556 aBoundingBuilder.MakeSolid(aSolid);
557 aBoundingBuilder.Add(aSolid, aShell);
562 //================================================================================================
563 gp_Pnt centreOfMass(const TopoDS_Shape& theShape)
565 TopAbs_ShapeEnum aShType = theShape.ShapeType();
566 GProp_GProps aGProps;
568 if(aShType == TopAbs_EDGE || aShType == TopAbs_WIRE) {
569 BRepGProp::LinearProperties(theShape, aGProps);
570 } else if(aShType == TopAbs_FACE || aShType == TopAbs_SHELL) {
571 BRepGProp::SurfaceProperties(theShape, aGProps);
572 } else if(aShType == TopAbs_SOLID || aShType == TopAbs_COMPSOLID) {
573 BRepGProp::VolumeProperties(theShape, aGProps);
576 return aGProps.CentreOfMass();
579 //================================================================================================
580 TopoDS_Shape findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint)
582 TopoDS_Shape aResult = theShape;
584 if(theShape.ShapeType() == TopAbs_COMPOUND) {
585 double aMinDistance = Precision::Infinite();
588 for (TopoDS_Iterator anItr(theShape); anItr.More(); anItr.Next()) {
589 TopoDS_Shape aValue = anItr.Value();
590 aCentr = centreOfMass(aValue);
591 aCurDistance = aCentr.Distance(thePoint);
593 if(aCurDistance < aMinDistance) {
594 aMinDistance = aCurDistance;
603 //================================================================================================
604 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
605 const TopoDS_Shape& theBase,
606 const TopAbs_ShapeEnum theType,
607 BRepPrimAPI_MakeRevol* theRevolBuilder)
609 for(TopExp_Explorer anExp(theBase, theType); anExp.More(); anExp.Next()) {
610 const TopoDS_Shape& aShape = anExp.Current();
611 GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
612 aFromShape->setImpl(new TopoDS_Shape(theRevolBuilder->FirstShape(aShape)));
613 aToShape->setImpl(new TopoDS_Shape(theRevolBuilder->LastShape(aShape)));
614 theRevolutionAlgo->addFromShape(aFromShape);
615 theRevolutionAlgo->addToShape(aToShape);
619 //================================================================================================
620 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
621 const TopoDS_Shape& theResult,
622 const TopAbs_ShapeEnum theType,
623 const TopoDS_Shape& theToFace,
624 const TopoDS_Shape& theFromFace)
626 for(TopExp_Explorer anExp(theResult, theType); anExp.More (); anExp.Next ()) {
627 const TopoDS_Shape& aShape = anExp.Current();
628 GeomShapePtr aGeomSh(new GeomAPI_Shape());
629 if(theType == TopAbs_VERTEX) {
630 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
631 IntTools_Context anIntTools;
632 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theToFace),
633 Precision::Confusion()) == Standard_True) {
634 aGeomSh->setImpl(new TopoDS_Shape(aShape));
635 theRevolutionAlgo->addToShape(aGeomSh);
637 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theFromFace),
638 Precision::Confusion()) == Standard_True) {
639 aGeomSh->setImpl(new TopoDS_Shape(aShape));
640 theRevolutionAlgo->addFromShape(aGeomSh);
642 } else if(theType == TopAbs_EDGE) {
643 TopoDS_Edge anEdge = TopoDS::Edge(aShape);
644 BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, TopoDS::Face(theToFace));
645 anEdgeCheck.Perform();
646 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
647 aGeomSh->setImpl(new TopoDS_Shape(aShape));
648 theRevolutionAlgo->addToShape(aGeomSh);
650 anEdgeCheck.Init(anEdge, TopoDS::Face(theFromFace));
651 anEdgeCheck.Perform();
652 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
653 aGeomSh->setImpl(new TopoDS_Shape(aShape));
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->addFromShape(aGeomSh);
664 if(aFaceSurface == aToSurface) {
665 aGeomSh->setImpl(new TopoDS_Shape(aShape));
666 theRevolutionAlgo->addToShape(aGeomSh);
672 void storeGenerationHistory(GeomAlgoAPI_Revolution* theRevolutionAlgo,
673 const TopoDS_Shape& theResult,
674 const TopAbs_ShapeEnum theType,
675 const TopoDS_Shape& theRotatedBoundingFace,
676 const TopoDS_Shape& theModifiedBaseShape,
677 const bool theIsFromFaceSet)
679 for(TopExp_Explorer anExp(theResult, theType); anExp.More (); anExp.Next ()) {
680 const TopoDS_Shape& aShape = anExp.Current();
681 GeomShapePtr aGeomSh(new GeomAPI_Shape());
682 if(theType == TopAbs_VERTEX) {
683 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
684 IntTools_Context anIntTools;
685 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(theRotatedBoundingFace),
686 Precision::Confusion()) == Standard_True) {
687 aGeomSh->setImpl(new TopoDS_Shape(aShape));
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 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
695 theRevolutionAlgo->addFromShape(aGeomSh);
697 } else if(theType == TopAbs_EDGE) {
698 TopoDS_Edge anEdge = TopoDS::Edge(aShape);
699 BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, TopoDS::Face(theRotatedBoundingFace));
700 anEdgeCheck.Perform();
701 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
702 aGeomSh->setImpl(new TopoDS_Shape(aShape));
703 theIsFromFaceSet ? theRevolutionAlgo->addFromShape(aGeomSh) :
704 theRevolutionAlgo->addToShape(aGeomSh);
706 anEdgeCheck.Init(anEdge, TopoDS::Face(theModifiedBaseShape));
707 anEdgeCheck.Perform();
708 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
709 aGeomSh->setImpl(new TopoDS_Shape(aShape));
710 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
711 theRevolutionAlgo->addFromShape(aGeomSh);
714 Handle(Geom_Surface) aFaceSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
715 Handle(Geom_Surface) aBoundingSurface =
716 BRep_Tool::Surface(TopoDS::Face(theRotatedBoundingFace));
717 Handle(Geom_Surface) aBaseSurface = BRep_Tool::Surface(TopoDS::Face(theModifiedBaseShape));
718 if(aFaceSurface == aBoundingSurface) {
719 aGeomSh->setImpl(new TopoDS_Shape(aShape));
720 theIsFromFaceSet ? theRevolutionAlgo->addFromShape(aGeomSh) :
721 theRevolutionAlgo->addToShape(aGeomSh);
723 if(aFaceSurface == aBaseSurface) {
724 aGeomSh->setImpl(new TopoDS_Shape(aShape));
725 theIsFromFaceSet ? theRevolutionAlgo->addToShape(aGeomSh) :
726 theRevolutionAlgo->addFromShape(aGeomSh);