From 146168192b230171e6365a32b0272ad781f62a87 Mon Sep 17 00:00:00 2001 From: dbv Date: Fri, 20 Nov 2015 16:46:24 +0300 Subject: [PATCH] Partition namig fix --- .../FeaturesPlugin_Partition.cpp | 3 +- src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp | 52 +--------- src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp | 99 ++++++++++++++++++- src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h | 24 ++++- 4 files changed, 119 insertions(+), 59 deletions(-) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp b/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp index 44ab7cc84..5929e1e9f 100755 --- a/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp @@ -76,6 +76,7 @@ void FeaturesPlugin_Partition::execute() } GeomAlgoAPI_MakeShapeList aMakeShapeList; + std::list > aBoundingPoints = GeomAlgoAPI_ShapeTools::getBoundingBox(anObjects, 1.0); // Getting tools. AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Partition::TOOL_LIST_ID()); @@ -86,7 +87,7 @@ void FeaturesPlugin_Partition::execute() // it could be a construction plane ResultPtr aContext = aToolAttr->context(); if(aContext.get()) { - aTool = GeomAlgoAPI_ShapeTools::faceToInfinitePlane(aContext->shape()); + aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aContext->shape(), aBoundingPoints); std::shared_ptr aMkShCustom(new GeomAlgoAPI_MakeShapeCustom); aMkShCustom->addModified(aContext->shape(), aTool); aMakeShapeList.append(aMkShCustom); diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp index c9baa888e..d450efe86 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp @@ -61,65 +61,15 @@ void GeomAlgoAPI_Partition::build(const ListOfShape& theObjects, GEOMAlgo_Splitter* anOperation = new GEOMAlgo_Splitter; myMkShape.reset(new GeomAlgoAPI_MakeShape(anOperation, GeomAlgoAPI_MakeShape::BOPAlgoBuilder)); - // Bounding box of all objects. - Bnd_Box aBndBox; - // Getting objects. for (ListOfShape::const_iterator anObjectsIt = theObjects.begin(); anObjectsIt != theObjects.end(); anObjectsIt++) { const TopoDS_Shape& aShape = (*anObjectsIt)->impl(); - BRepBndLib::Add(aShape, aBndBox); anOperation->AddArgument(aShape); } - // We enlarge bounding box just to be sure that plane will be large enough to cut all objects. - aBndBox.Enlarge(1.0); - Standard_Real aXArr[2] = {aBndBox.CornerMin().X(), aBndBox.CornerMax().X()}; - Standard_Real aYArr[2] = {aBndBox.CornerMin().Y(), aBndBox.CornerMax().Y()}; - Standard_Real aZArr[2] = {aBndBox.CornerMin().Z(), aBndBox.CornerMax().Z()}; - gp_Pnt aPoints[8]; - int aNum = 0; - for(int i = 0; i < 2; i++) { - for(int j = 0; j < 2; j++) { - for(int k = 0; k < 2; k++) { - aPoints[aNum] = gp_Pnt(aXArr[i], aYArr[j], aZArr[k]); - aNum++; - } - } - } - // Getting tools. for (ListOfShape::const_iterator aToolsIt = theTools.begin(); aToolsIt != theTools.end(); aToolsIt++) { - TopoDS_Shape aShape = (*aToolsIt)->impl(); - if(aShape.ShapeType() == TopAbs_FACE) { - TopoDS_Face aFace = TopoDS::Face(aShape); - Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); - if (!aSurf.IsNull()) { - GeomLib_IsPlanarSurface isPlanar(aSurf); - if(isPlanar.IsPlanar()) { - Standard_Real UMin, UMax, VMin, VMax; - BRepTools::UVBounds(aFace, UMin, UMax, VMin, VMax); - if(UMin == -Precision::Infinite() && UMax == Precision::Infinite() && - VMin == -Precision::Infinite() && VMax == Precision::Infinite()) { - const gp_Pln& aFacePln = isPlanar.Plan(); - Handle(Geom_Plane) aFacePlane = new Geom_Plane(aFacePln); - IntAna_Quadric aQuadric(aFacePln); - UMin = UMax = VMin = VMax = 0; - for(int i = 0; i < 8; i++) { - gp_Lin aLin(aPoints[i], aFacePln.Axis().Direction()); - IntAna_IntConicQuad anIntAna(aLin, aQuadric); - const gp_Pnt& aPntOnFace = anIntAna.Point(1); - Standard_Real aPntU(0), aPntV(0); - GeomLib_Tool::Parameters(aFacePlane, aPntOnFace, Precision::Confusion(), aPntU, aPntV); - if(aPntU < UMin) UMin = aPntU; - if(aPntU > UMax) UMax = aPntU; - if(aPntV < VMin) VMin = aPntV; - if(aPntV > VMax) VMax = aPntV; - } - aShape = BRepLib_MakeFace(aFacePln, UMin, UMax, VMin, VMax).Face(); - } - } - } - } + const TopoDS_Shape& aShape = (*aToolsIt)->impl(); anOperation->AddTool(aShape); } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp index 3a4f577ac..de201f61c 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp @@ -10,13 +10,19 @@ #include +#include #include +#include #include #include #include #include #include +#include +#include #include +#include +#include #include #include #include @@ -28,7 +34,7 @@ //================================================================================================= -double GeomAlgoAPI_ShapeTools::volume(std::shared_ptr theShape) +double GeomAlgoAPI_ShapeTools::volume(const std::shared_ptr theShape) { GProp_GProps aGProps; if(!theShape) { @@ -43,7 +49,7 @@ double GeomAlgoAPI_ShapeTools::volume(std::shared_ptr theShape) } //================================================================================================= -std::shared_ptr GeomAlgoAPI_ShapeTools::centreOfMass(std::shared_ptr theShape) +std::shared_ptr GeomAlgoAPI_ShapeTools::centreOfMass(const std::shared_ptr theShape) { GProp_GProps aGProps; if(!theShape) { @@ -175,7 +181,41 @@ void GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr } //================================================================================================= -std::shared_ptr GeomAlgoAPI_ShapeTools::faceToInfinitePlane(const std::shared_ptr& theFace) +std::list > GeomAlgoAPI_ShapeTools::getBoundingBox(const ListOfShape& theShapes, const double theEnlarge) +{ + // Bounding box of all objects. + Bnd_Box aBndBox; + + // Getting box. + for (ListOfShape::const_iterator anObjectsIt = theShapes.begin(); anObjectsIt != theShapes.end(); anObjectsIt++) { + const TopoDS_Shape& aShape = (*anObjectsIt)->impl(); + BRepBndLib::Add(aShape, aBndBox); + } + + if(theEnlarge != 0.0) { + // We enlarge bounding box just to be sure that plane will be large enough to cut all objects. + aBndBox.Enlarge(theEnlarge); + } + + Standard_Real aXArr[2] = {aBndBox.CornerMin().X(), aBndBox.CornerMax().X()}; + Standard_Real aYArr[2] = {aBndBox.CornerMin().Y(), aBndBox.CornerMax().Y()}; + Standard_Real aZArr[2] = {aBndBox.CornerMin().Z(), aBndBox.CornerMax().Z()}; + std::list > aResultPoints; + int aNum = 0; + for(int i = 0; i < 2; i++) { + for(int j = 0; j < 2; j++) { + for(int k = 0; k < 2; k++) { + std::shared_ptr aPnt(new GeomAPI_Pnt(aXArr[i], aYArr[j], aZArr[k])); + aResultPoints.push_back(aPnt); + } + } + } + + return aResultPoints; +} + +//================================================================================================= +std::shared_ptr GeomAlgoAPI_ShapeTools::faceToInfinitePlane(const std::shared_ptr theFace) { if (!theFace.get()) return std::shared_ptr(); @@ -195,3 +235,56 @@ std::shared_ptr GeomAlgoAPI_ShapeTools::faceToInfinitePlane(const aResult->setImpl(new TopoDS_Shape(anInfiniteFace)); return aResult; } + +//================================================================================================= +std::shared_ptr GeomAlgoAPI_ShapeTools::fitPlaneToBox(const std::shared_ptr thePlane, + const std::list >& thePoints) +{ + std::shared_ptr aResultShape; + + if(!thePlane.get()) { + return aResultShape; + } + + const TopoDS_Shape& aShape = thePlane->impl(); + if(aShape.ShapeType() != TopAbs_FACE) { + return aResultShape; + } + + TopoDS_Face aFace = TopoDS::Face(aShape); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + if(aSurf.IsNull()) { + return aResultShape; + } + + GeomLib_IsPlanarSurface isPlanar(aSurf); + if(!isPlanar.IsPlanar()) { + return aResultShape; + } + + if(thePoints.size() != 8) { + return aResultShape; + } + + const gp_Pln& aFacePln = isPlanar.Plan(); + Handle(Geom_Plane) aFacePlane = new Geom_Plane(aFacePln); + IntAna_Quadric aQuadric(aFacePln); + Standard_Real UMin, UMax, VMin, VMax; + UMin = UMax = VMin = VMax = 0; + for (std::list >::const_iterator aPointsIt = thePoints.begin(); aPointsIt != thePoints.end(); aPointsIt++) { + const gp_Pnt& aPnt = (*aPointsIt)->impl(); + gp_Lin aLin(aPnt, aFacePln.Axis().Direction()); + IntAna_IntConicQuad anIntAna(aLin, aQuadric); + const gp_Pnt& aPntOnFace = anIntAna.Point(1); + Standard_Real aPntU(0), aPntV(0); + GeomLib_Tool::Parameters(aFacePlane, aPntOnFace, Precision::Confusion(), aPntU, aPntV); + if(aPntU < UMin) UMin = aPntU; + if(aPntU > UMax) UMax = aPntU; + if(aPntV < VMin) VMin = aPntV; + if(aPntV > VMax) VMax = aPntV; + } + aResultShape.reset(new GeomAPI_Shape); + aResultShape->setImpl(new TopoDS_Shape(BRepLib_MakeFace(aFacePln, UMin, UMax, VMin, VMax).Face())); + + return aResultShape; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h index c367d6867..d361eb927 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h @@ -21,11 +21,11 @@ class GEOMALGOAPI_EXPORT GeomAlgoAPI_ShapeTools { public: /// \return the total volume of the solids of the current shape or 0.0 if it can be computed. - static double volume(std::shared_ptr theShape); + static double volume(const std::shared_ptr theShape); /// \return the centre of mass of the current face. The coordinates returned for the center of mass /// are expressed in the absolute Cartesian coordinate system. (This function works only for surfaces). - static std::shared_ptr centreOfMass(std::shared_ptr theShape); + static std::shared_ptr centreOfMass(const std::shared_ptr theShape); /** \brief Combines faces with common edges to shells, or solids to compsolids. * \param[in] theCompound compound of shapes. @@ -38,10 +38,26 @@ public: ListOfShape& theCombinedShapes, ListOfShape& theFreeShapes); + /** \brief Calculates bounding box for theShapes + * \return list of eight points. + * \param[in] theShapes list of shapes. + * \param[in] theEnlarge enlarges bounding box size. + */ + static std::list > getBoundingBox(const ListOfShape& theShapes, const double theEnlarge = 0.0); + /** - * Returns infinite plane received from theFace plane + * Returns infinite plane received from theFace plane. */ - static std::shared_ptr faceToInfinitePlane(const std::shared_ptr& theFace); + static std::shared_ptr faceToInfinitePlane(const std::shared_ptr theFace); + + /** \brief Enlarges or reduces plane to fit bounding box. + * \return plane that fits to bounding box. + * \param[in] thePlane base plane. + * \param[in] thePoints bounding box points (shoud be eight). + */ + static std::shared_ptr fitPlaneToBox(const std::shared_ptr thePlane, + const std::list >& thePoints); + }; #endif -- 2.39.2