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_ShapeExplorer.h>
11 #include <GeomAlgoAPI_DFLoader.h>
12 #include <GeomAlgoAPI_MakeShapeList.h>
13 #include <GeomAlgoAPI_ShapeTools.h>
15 #include <BRep_Builder.hxx>
16 #include <BRep_Tool.hxx>
17 #include <BRepAlgoAPI_Cut.hxx>
18 #include <BRepBuilderAPI_FindPlane.hxx>
19 #include <BRepBuilderAPI_MakeFace.hxx>
20 #include <BRepBuilderAPI_Transform.hxx>
21 #include <BRepCheck_Analyzer.hxx>
22 #include <Geom_Curve.hxx>
23 #include <Geom2d_Curve.hxx>
24 #include <BRepLib_CheckCurveOnSurface.hxx>
25 #include <BRepPrimAPI_MakeRevol.hxx>
26 #include <BRepGProp.hxx>
27 #include <GC_MakePlane.hxx>
28 #include <Geom_Plane.hxx>
29 #include <GeomLib_IsPlanarSurface.hxx>
31 #include <GProp_GProps.hxx>
32 #include <IntTools_Context.hxx>
33 #include <TopExp_Explorer.hxx>
35 #include <TopoDS_Edge.hxx>
36 #include <TopTools_ListIteratorOfListOfShape.hxx>
38 /// \brief Constructs infinite face from thePlane, and with axis located on the same side
39 /// of the plane as thePoint. Modifies thePlane axis direction.
40 /// \param[in,out] thePlane plane to construct face.
41 /// \param[in] thePoint point to locate plane axis.
42 /// \return constructed face.
43 static TopoDS_Face makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint);
45 /// \return solid created from face or shell.
46 static TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape);
48 /// \brief return centre of mass for theShape.
49 /// \param[in] theShape shape.
50 static gp_Pnt centreOfMass(const TopoDS_Shape& theShape);
52 /// \brief Selects solid from theShape with closest center of mass to thePoint
53 /// \param[in] theShape compound with solids.
54 /// \param[in] thePoint point.
56 static TopoDS_Shape findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint);
58 //=================================================================================================
59 GeomAlgoAPI_Revolution::GeomAlgoAPI_Revolution(const GeomShapePtr theBaseShape,
60 const std::shared_ptr<GeomAPI_Ax1> theAxis,
61 const double theToAngle,
62 const double theFromAngle)
64 build(theBaseShape, theAxis, GeomShapePtr(), theToAngle, GeomShapePtr(), theFromAngle);
67 //=================================================================================================
68 GeomAlgoAPI_Revolution::GeomAlgoAPI_Revolution(const GeomShapePtr theBaseShape,
69 const std::shared_ptr<GeomAPI_Ax1> theAxis,
70 const GeomShapePtr theToShape,
71 const double theToAngle,
72 const GeomShapePtr theFromShape,
73 const double theFromAngle)
75 build(theBaseShape, theAxis, theToShape, theToAngle, theFromShape, theFromAngle);
78 //=================================================================================================
79 void GeomAlgoAPI_Revolution::build(const GeomShapePtr& theBaseShape,
80 const std::shared_ptr<GeomAPI_Ax1>& theAxis,
81 const GeomShapePtr& theToShape,
82 const double theToAngle,
83 const GeomShapePtr& theFromShape,
84 const double theFromAngle)
86 if(!theBaseShape || !theAxis ||
87 (((!theFromShape && !theToShape) || (theFromShape && theToShape && theFromShape->isEqual(theToShape)))
88 && (theFromAngle == -theToAngle))) {
92 // Getting base shape.
93 const TopoDS_Shape& aBaseShape = theBaseShape->impl<TopoDS_Shape>();
94 TopAbs_ShapeEnum aShapeTypeToExp;
95 switch(aBaseShape.ShapeType()) {
97 aShapeTypeToExp = TopAbs_VERTEX;
101 aShapeTypeToExp = TopAbs_EDGE;
105 aShapeTypeToExp = TopAbs_FACE;
112 gp_Ax1 anAxis = theAxis->impl<gp_Ax1>();
114 // Getting base plane.
115 Handle(Geom_Plane) aBasePlane;
116 BRepBuilderAPI_FindPlane aFindPlane(aBaseShape);
117 if(aShapeTypeToExp == TopAbs_FACE && aFindPlane.Found() == Standard_True) {
118 aBasePlane = aFindPlane.Plane();
120 gp_Pnt aPnt1 = anAxis.Location();
121 gp_Pnt aPnt2 = aPnt1;
122 aPnt2.Translate(anAxis.Direction());
125 for(TopExp_Explorer anExp(aBaseShape, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
126 aPnt3 = BRep_Tool::Pnt(TopoDS::Vertex(anExp.Current()));
128 GC_MakePlane aMkPlane(aPnt1, aPnt2, aPnt3);
129 if(aMkPlane.IsDone() != Standard_True) {
133 aBasePlane = aMkPlane.Value();
137 if(aBasePlane.IsNull()) {
138 aPnt3 = centreOfMass(aBaseShape);
140 GC_MakePlane aMkPlane(aPnt1, aPnt2, aPnt3);
141 if(aMkPlane.IsDone() != Standard_True) {
145 aBasePlane = aMkPlane.Value();
149 if(aShapeTypeToExp == TopAbs_FACE) {
150 if(aBasePlane->Axis().Angle(anAxis) < Precision::Confusion()) {
155 gp_Pnt aBaseCentre = GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape)->impl<gp_Pnt>();
157 TopoDS_Shape aResult;
158 if(!theFromShape && !theToShape) { // Case 1: When only angles was set.
159 // Rotating base face with the negative value of "from angle".
161 aBaseTrsf.SetRotation(anAxis, -theFromAngle / 180.0 * M_PI);
162 BRepBuilderAPI_Transform* aBaseTransform = new BRepBuilderAPI_Transform(aBaseShape,
165 if(!aBaseTransform) {
168 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aBaseTransform)));
169 if(!aBaseTransform->IsDone()) {
172 TopoDS_Shape aRotatedBase = aBaseTransform->Shape();
174 // Making revolution to the angle equal to the sum of "from angle" and "to angle".
175 BRepPrimAPI_MakeRevol* aRevolBuilder = new BRepPrimAPI_MakeRevol(aRotatedBase,
177 (theFromAngle + theToAngle) / 180 * M_PI,
182 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aRevolBuilder)));
183 if(!aRevolBuilder->IsDone()) {
186 aResult = aRevolBuilder->Shape();
189 for(TopExp_Explorer anExp(aRotatedBase, aShapeTypeToExp); anExp.More(); anExp.Next()) {
190 const TopoDS_Shape& aShape = anExp.Current();
191 GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape);
192 aFromShape->setImpl(new TopoDS_Shape(aRevolBuilder->FirstShape(aShape)));
193 aToShape->setImpl(new TopoDS_Shape(aRevolBuilder->LastShape(aShape)));
194 this->addFromShape(aFromShape);
195 this->addToShape(aToShape);
197 } else if(theFromShape && theToShape) { // Case 2: When both bounding planes were set.
198 // Making revolution to the 360 angle.
199 BRepPrimAPI_MakeRevol* aRevolBuilder = new BRepPrimAPI_MakeRevol(aBaseShape, anAxis, 2 * M_PI, Standard_True);
203 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aRevolBuilder)));
204 if(!aRevolBuilder->IsDone()) {
207 aResult = aRevolBuilder->Shape();
209 // Getting bounding faces.
210 TopoDS_Face aFromFace = TopoDS::Face(theFromShape->impl<TopoDS_Shape>());
211 TopoDS_Face aToFace = TopoDS::Face(theToShape->impl<TopoDS_Shape>());
213 // Getting planes from bounding face.
214 GeomLib_IsPlanarSurface isFromPlanar(BRep_Tool::Surface(aFromFace));
215 GeomLib_IsPlanarSurface isToPlanar(BRep_Tool::Surface(aToFace));
216 if(!isFromPlanar.IsPlanar() || !isToPlanar.IsPlanar()) {// non-planar shapes is not supported for revolution bounding
219 gp_Pln aFromPln = isFromPlanar.Plan();
220 gp_Pln aToPln = isToPlanar.Plan();
222 // Orienting bounding planes properly so that the center of mass of the base face stays
223 // on the result shape after cut.
224 aFromFace = makeFaceFromPlane(aFromPln, aBaseCentre);
225 aToFace = makeFaceFromPlane(aToPln, aBaseCentre);
227 // Making solids from bounding planes and putting them in compound.
228 TopoDS_Shape aFromSolid = makeSolidFromShape(aFromFace);
229 TopoDS_Shape aToSolid = makeSolidFromShape(aToFace);
231 // Rotating bounding planes to the specified angle.
234 double aFromRotAngle = ((aFromPln.Axis().Direction() * aBasePlane->Axis().Direction()) > 0) ? -theFromAngle : theFromAngle;
235 double aToRotAngle = ((aToPln.Axis().Direction() * aBasePlane->Axis().Direction()) > 0) ? -theToAngle : theToAngle;
236 aFromTrsf.SetRotation(anAxis,aFromRotAngle / 180.0 * M_PI);
237 aToTrsf.SetRotation(anAxis, aToRotAngle / 180.0 * M_PI);
238 BRepBuilderAPI_Transform aFromTransform(aFromSolid, aFromTrsf, true);
239 BRepBuilderAPI_Transform aToTransform(aToSolid, aToTrsf, true);
240 TopoDS_Shape aRotatedFromFace = aFromTransform.Modified(aFromFace).First();
241 TopoDS_Shape aRotatedToFace = aToTransform.Modified(aToFace).First();
242 aFromSolid = aFromTransform.Shape();
243 aToSolid = aToTransform.Shape();
245 // Cutting revolution with from plane.
246 BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid);
247 aFromCutBuilder->Build();
248 if(!aFromCutBuilder->IsDone()) {
251 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aFromCutBuilder)));
252 aResult = aFromCutBuilder->Shape();
253 if(aResult.ShapeType() == TopAbs_COMPOUND) {
254 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
257 // Cutting revolution with to plane.
258 BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid);
259 aToCutBuilder->Build();
260 if(!aToCutBuilder->IsDone()) {
263 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aToCutBuilder)));
264 aResult = aToCutBuilder->Shape();
265 TopoDS_Iterator aCheckIt(aResult);
266 if(!aCheckIt.More()) {
269 if(aResult.ShapeType() == TopAbs_COMPOUND) {
270 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
272 if(aResult.ShapeType() == TopAbs_COMPOUND) {
273 GeomShapePtr aCompound(new GeomAPI_Shape);
274 aCompound->setImpl(new TopoDS_Shape(aResult));
275 ListOfShape aCompSolids, aFreeSolids;
276 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids);
277 if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) {
278 aResult = aCompSolids.front()->impl<TopoDS_Shape>();
279 } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) {
280 TopoDS_Compound aResultComp;
281 TopoDS_Builder aBuilder;
282 aBuilder.MakeCompound(aResultComp);
283 for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) {
284 aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
286 for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) {
287 aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
289 aResult = aResultComp;
293 // If after cut we got more than one solids then take closest to the center of mass of the base face.
294 aResult = findClosest(aResult, aBaseCentre);
297 for(TopExp_Explorer anExp(aResult, aShapeTypeToExp); anExp.More (); anExp.Next ()) {
298 const TopoDS_Shape& aShape = anExp.Current();
299 if(aShapeTypeToExp == TopAbs_VERTEX) {
300 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
301 IntTools_Context anIntTools;
302 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(aRotatedToFace), Precision::Confusion()) == Standard_True) {
303 GeomShapePtr aGeomSh(new GeomAPI_Shape());
304 aGeomSh->setImpl(new TopoDS_Shape(aShape));
305 this->addToShape(aGeomSh);
307 if(anIntTools.IsValidPointForFace(aPnt, TopoDS::Face(aRotatedFromFace), Precision::Confusion()) == Standard_True) {
308 GeomShapePtr aGeomSh(new GeomAPI_Shape());
309 aGeomSh->setImpl(new TopoDS_Shape(aShape));
310 this->addFromShape(aGeomSh);
312 } else if(aShapeTypeToExp == TopAbs_EDGE) {
313 TopoDS_Edge anEdge = TopoDS::Edge(aShape);
314 BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, TopoDS::Face(aRotatedToFace));
315 anEdgeCheck.Perform();
316 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
317 GeomShapePtr aGeomSh(new GeomAPI_Shape());
318 aGeomSh->setImpl(new TopoDS_Shape(aShape));
319 this->addToShape(aGeomSh);
321 anEdgeCheck.Init(anEdge, TopoDS::Face(aRotatedFromFace));
322 anEdgeCheck.Perform();
323 if(anEdgeCheck.MaxDistance() < Precision::Confusion()) {
324 GeomShapePtr aGeomSh(new GeomAPI_Shape());
325 aGeomSh->setImpl(new TopoDS_Shape(aShape));
326 this->addFromShape(aGeomSh);
329 Handle(Geom_Surface) aFaceSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
330 Handle(Geom_Surface) aFromSurface = BRep_Tool::Surface(TopoDS::Face(aRotatedFromFace));
331 Handle(Geom_Surface) aToSurface = BRep_Tool::Surface(TopoDS::Face(aRotatedToFace));
332 if(aFaceSurface == aFromSurface) {
333 GeomShapePtr aFSHape(new GeomAPI_Shape);
334 aFSHape->setImpl(new TopoDS_Shape(aShape));
335 this->addFromShape(aFSHape);
337 if(aFaceSurface == aToSurface) {
338 GeomShapePtr aTSHape(new GeomAPI_Shape);
339 aTSHape->setImpl(new TopoDS_Shape(aShape));
340 this->addToShape(aTSHape);
344 } else { //Case 3: When only one bounding plane was set.
345 // Making revolution to the 360 angle.
346 BRepPrimAPI_MakeRevol* aRevolBuilder = new BRepPrimAPI_MakeRevol(aBaseShape, anAxis, 2 * M_PI, Standard_True);
350 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aRevolBuilder)));
351 if(!aRevolBuilder->IsDone()) {
354 aResult = aRevolBuilder->Shape();
356 // Getting bounding face.
357 TopoDS_Face aBoundingFace;
358 bool isFromFaceSet = false;
360 aBoundingFace = TopoDS::Face(theFromShape->impl<TopoDS_Shape>());
361 isFromFaceSet = true;
362 } else if(theToShape) {
363 aBoundingFace = TopoDS::Face(theToShape->impl<TopoDS_Shape>());
366 // Getting plane from bounding face.
367 GeomLib_IsPlanarSurface isBoundingPlanar(BRep_Tool::Surface(aBoundingFace));
368 if(!isBoundingPlanar.IsPlanar()) { // non-planar shapes is not supported for revolution bounding
371 gp_Pln aBoundingPln = isBoundingPlanar.Plan();
373 // Orienting bounding plane properly so that the center of mass of the base face stays
374 // on the result shape after cut.
375 aBoundingFace = makeFaceFromPlane(aBoundingPln, aBaseCentre);
377 // Making solid from bounding plane.
378 TopoDS_Shape aBoundingSolid = makeSolidFromShape(aBoundingFace);
380 // Rotating bounding plane to the specified angle.
381 double aBoundingRotAngle = isFromFaceSet ? theFromAngle : theToAngle;
382 if(aBoundingPln.Axis().IsParallel(aBasePlane->Axis(), Precision::Confusion())) {
383 if(isFromFaceSet) aBoundingRotAngle = -aBoundingRotAngle;
385 double aSign = (aBoundingPln.Axis().Direction() ^ aBasePlane->Axis().Direction()) *
387 if((aSign <= 0 && !isFromFaceSet) || (aSign > 0 && isFromFaceSet)) {
388 aBoundingRotAngle = -aBoundingRotAngle;
391 gp_Trsf aBoundingTrsf;
392 aBoundingTrsf.SetRotation(anAxis, aBoundingRotAngle / 180.0 * M_PI);
393 BRepBuilderAPI_Transform aBoundingTransform(aBoundingSolid, aBoundingTrsf, true);
394 TopoDS_Shape aRotatedBoundingFace = aBoundingTransform.Modified(aBoundingFace).First();
395 aBoundingSolid = aBoundingTransform.Shape();
397 // Cutting revolution with bounding plane.
398 BRepAlgoAPI_Cut* aBoundingCutBuilder = new BRepAlgoAPI_Cut(aResult, aBoundingSolid);
399 aBoundingCutBuilder->Build();
400 if(!aBoundingCutBuilder->IsDone()) {
403 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aBoundingCutBuilder)));
404 aResult = aBoundingCutBuilder->Shape();
407 const TopTools_ListOfShape& aBndShapes = aBoundingCutBuilder->Modified(aBoundingFace);
408 for(TopTools_ListIteratorOfListOfShape anIt(aBndShapes); anIt.More(); anIt.Next()) {
409 GeomShapePtr aShape(new GeomAPI_Shape());
410 aShape->setImpl(new TopoDS_Shape(anIt.Value()));
411 isFromFaceSet ? this->addFromShape(aShape) : this->addToShape(aShape);
414 // Try to cut with base face. If it can not be done then keep result of cut with bounding plane.
415 TopoDS_Shape aModifiedBaseShape = aBaseShape;
417 if(aModifiedBaseShape.ShapeType() == TopAbs_FACE) {
418 aModifiedBaseShape.Orientation(TopAbs_REVERSED);
421 aMirrorTrsf.SetMirror(aBasePlane->Position().Ax2());
422 BRepBuilderAPI_Transform aMirrorTransform(aModifiedBaseShape, aMirrorTrsf, true);
423 aModifiedBaseShape = aMirrorTransform.Shape();
427 // Making solid from base face.
428 TopoDS_Shape aBaseSolid = makeSolidFromShape(aModifiedBaseShape);
430 // Rotating base face to the specified angle.
432 double aBaseRotAngle = isFromFaceSet ? theToAngle : -theFromAngle;
433 aBaseTrsf.SetRotation(anAxis, aBaseRotAngle / 180.0 * M_PI);
434 BRepBuilderAPI_Transform aBaseTransform(aBaseSolid, aBaseTrsf, true);
435 aBaseSolid = aBaseTransform.Shape();
437 // Cutting revolution with base.
438 BRepAlgoAPI_Cut* aBaseCutBuilder = new BRepAlgoAPI_Cut(aResult, aBaseSolid);
439 aBaseCutBuilder->Build();
440 if(aBaseCutBuilder->IsDone()) {
441 TopoDS_Shape aCutResult = aBaseCutBuilder->Shape();
442 TopExp_Explorer anExp(aCutResult, TopAbs_SOLID);
444 this->appendAlgo(std::shared_ptr<GeomAlgoAPI_MakeShape>(new GeomAlgoAPI_MakeShape(aBaseCutBuilder)));
445 aResult = aCutResult;
449 const TopTools_ListOfShape& aBsShapes = aBaseCutBuilder->Modified(aBoundingFace);
450 for(TopTools_ListIteratorOfListOfShape anIt(aBsShapes); anIt.More(); anIt.Next()) {
451 GeomShapePtr aShape(new GeomAPI_Shape());
452 aShape->setImpl(new TopoDS_Shape(anIt.Value()));
453 isFromFaceSet ? this->addToShape(aShape) : this->addFromShape(aShape);
456 TopExp_Explorer anExp(aResult, TopAbs_SOLID);
460 if(aResult.ShapeType() == TopAbs_COMPOUND) {
461 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
463 if(aResult.ShapeType() == TopAbs_COMPOUND) {
464 GeomShapePtr aCompound(new GeomAPI_Shape);
465 aCompound->setImpl(new TopoDS_Shape(aResult));
466 ListOfShape aCompSolids, aFreeSolids;
467 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids);
468 if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) {
469 aResult = aCompSolids.front()->impl<TopoDS_Shape>();
470 } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) {
471 TopoDS_Compound aResultComp;
472 TopoDS_Builder aBuilder;
473 aBuilder.MakeCompound(aResultComp);
474 for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) {
475 aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
477 for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) {
478 aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
480 aResult = aResultComp;
484 // If after cut we got more than one solids then take closest to the center of mass of the base face.
485 aResult = findClosest(aResult, aBaseCentre);
488 for(TopExp_Explorer anExp(aResult, TopAbs_FACE); anExp.More (); anExp.Next ()) {
489 const TopoDS_Shape& aFaceOnResult = anExp.Current();
490 Handle(Geom_Surface) aFaceSurface = BRep_Tool::Surface(TopoDS::Face(aFaceOnResult));
491 Handle(Geom_Surface) aBoundingSurface = BRep_Tool::Surface(TopoDS::Face(aRotatedBoundingFace));
492 if(aFaceSurface == aBoundingSurface) {
493 GeomShapePtr aShape(new GeomAPI_Shape());
494 aShape->setImpl(new TopoDS_Shape(aFaceOnResult));
495 isFromFaceSet ? this->addFromShape(aShape) : this->addToShape(aShape);
501 if(aResult.IsNull()) {
504 GeomShapePtr aShape(new GeomAPI_Shape());
505 aShape->setImpl(new TopoDS_Shape(aResult));
506 this->setShape(aShape);
510 //=================================================================================================
511 TopoDS_Face makeFaceFromPlane(gp_Pln& thePlane, const gp_Pnt& thePoint)
513 if(!thePlane.Contains(thePoint, Precision::Confusion())) {
514 gp_XYZ aVec = thePoint.XYZ() - thePlane.Location().XYZ();
515 double aSign = aVec * thePlane.Axis().Direction().XYZ();
516 if(aSign < 0) thePlane.SetAxis(thePlane.Axis().Reversed());
519 BRepBuilderAPI_MakeFace aMakeFace(thePlane);
520 TopoDS_Face aResultFace = TopoDS::Face(aMakeFace.Shape());
525 //=================================================================================================
526 TopoDS_Solid makeSolidFromShape(const TopoDS_Shape& theShape)
531 BRep_Builder aBoundingBuilder;
532 if(theShape.ShapeType() == TopAbs_SHELL) {
533 aShell = TopoDS::Shell(theShape);
535 aBoundingBuilder.MakeShell(aShell);
536 aBoundingBuilder.Add(aShell, theShape);
538 aBoundingBuilder.MakeSolid(aSolid);
539 aBoundingBuilder.Add(aSolid, aShell);
544 //=================================================================================================
545 gp_Pnt centreOfMass(const TopoDS_Shape& theShape)
547 TopAbs_ShapeEnum aShType = theShape.ShapeType();
548 GProp_GProps aGProps;
550 if(aShType == TopAbs_EDGE || aShType == TopAbs_WIRE) {
551 BRepGProp::LinearProperties(theShape, aGProps);
552 } else if(aShType == TopAbs_FACE || aShType == TopAbs_SHELL) {
553 BRepGProp::SurfaceProperties(theShape, aGProps);
554 } else if(aShType == TopAbs_SOLID || aShType == TopAbs_COMPSOLID) {
555 BRepGProp::VolumeProperties(theShape, aGProps);
558 return aGProps.CentreOfMass();
561 //=================================================================================================
562 TopoDS_Shape findClosest(const TopoDS_Shape& theShape, const gp_Pnt& thePoint)
564 TopoDS_Shape aResult = theShape;
566 if(theShape.ShapeType() == TopAbs_COMPOUND) {
567 double aMinDistance = Precision::Infinite();
570 for (TopoDS_Iterator anItr(theShape); anItr.More(); anItr.Next()) {
571 TopoDS_Shape aValue = anItr.Value();
572 aCentr = centreOfMass(aValue);
573 aCurDistance = aCentr.Distance(thePoint);
575 if(aCurDistance < aMinDistance) {
576 aMinDistance = aCurDistance;