X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGeomAlgoAPI%2FGeomAlgoAPI_ShapeTools.cpp;h=852163df3df21b261cf67792238218d01d92946d;hb=03b823cbbe43236117bc50c34398f3ce273f729b;hp=54835f857cccdaef0bd32fda7b64d5b399b1924a;hpb=0b5646d3d6db37d5e17db76aec12db185c4b24a0;p=modules%2Fshaper.git diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp index 54835f857..852163df3 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp @@ -8,18 +8,33 @@ #include +#include + +#include #include +#include +#include #include #include +#include +#include +#include +#include #include +#include +#include #include #include #include +#include #include #include +#include +#include + //================================================================================================= -double GeomAlgoAPI_ShapeTools::volume(std::shared_ptr theShape) +double GeomAlgoAPI_ShapeTools::volume(const std::shared_ptr theShape) { GProp_GProps aGProps; if(!theShape) { @@ -34,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) { @@ -70,18 +85,28 @@ void GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr aTA = TopAbs_SOLID; } - // Map subshapes and shapes. + // Get free shapes. const TopoDS_Shape& aShapesComp = theCompound->impl(); - BOPCol_IndexedDataMapOfShapeListOfShape aMapEF; - BOPTools::MapShapesAndAncestors(aShapesComp, aTS, aTA, aMapEF); - if(aMapEF.IsEmpty()) { + for(TopoDS_Iterator anIter(aShapesComp); anIter.More(); anIter.Next() ) { + const TopoDS_Shape& aShape = anIter.Value(); + if(aShape.ShapeType() > aTA) { + std::shared_ptr aGeomShape(new GeomAPI_Shape); + aGeomShape->setImpl(new TopoDS_Shape(aShape)); + theFreeShapes.push_back(aGeomShape); + } + } + + // Map subshapes and shapes. + BOPCol_IndexedDataMapOfShapeListOfShape aMapSA; + BOPTools::MapShapesAndAncestors(aShapesComp, aTS, aTA, aMapSA); + if(aMapSA.IsEmpty()) { return; } // Get all shapes with common subshapes and free shapes. NCollection_Map aFreeShapes; NCollection_Vector> aShapesWithCommonSubshapes; - for(BOPCol_IndexedDataMapOfShapeListOfShape::Iterator anIter(aMapEF); anIter.More(); anIter.Next()) { + for(BOPCol_IndexedDataMapOfShapeListOfShape::Iterator anIter(aMapSA); anIter.More(); anIter.Next()) { const TopoDS_Shape& aShape = anIter.Key(); BOPCol_ListOfShape& aListOfShape = anIter.ChangeValue(); if(aListOfShape.IsEmpty()) { @@ -105,7 +130,7 @@ void GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr aListOfShape.Clear(); for(NCollection_List::Iterator aTempIter(aTempList); aTempIter.More(); aTempIter.Next()) { const TopoDS_Shape& aTempShape = aTempIter.Value(); - for(BOPCol_IndexedDataMapOfShapeListOfShape::Iterator anIter(aMapEF); anIter.More(); anIter.Next()) { + for(BOPCol_IndexedDataMapOfShapeListOfShape::Iterator anIter(aMapSA); anIter.More(); anIter.Next()) { BOPCol_ListOfShape& aTempListOfShape = anIter.ChangeValue(); if(aTempListOfShape.IsEmpty()) { continue; @@ -140,10 +165,13 @@ void GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr TopoDS_CompSolid aCSolid; TopoDS_Builder aBuilder; theType == GeomAPI_Shape::COMPSOLID ? aBuilder.MakeCompSolid(aCSolid) : aBuilder.MakeShell(aShell); - const NCollection_Map& aShapesMap = anIter.Value(); - for(NCollection_Map::Iterator aShIter(aShapesMap); aShIter.More(); aShIter.Next()) { - const TopoDS_Shape& aShape = aShIter.Value(); - theType == GeomAPI_Shape::COMPSOLID ? aBuilder.Add(aCSolid, aShape) : aBuilder.Add(aShell, aShape); + NCollection_Map& aShapesMap = anIter.ChangeValue(); + for(TopExp_Explorer anExp(aShapesComp, aTA); anExp.More(); anExp.Next()) { + const TopoDS_Shape& aShape = anExp.Current(); + if(aShapesMap.Contains(aShape)) { + theType == GeomAPI_Shape::COMPSOLID ? aBuilder.Add(aCSolid, aShape) : aBuilder.Add(aShell, aShape); + aShapesMap.Remove(aShape); + } } std::shared_ptr aGeomShape(new GeomAPI_Shape); TopoDS_Shape* aSh = theType == GeomAPI_Shape::COMPSOLID ? new TopoDS_Shape(aCSolid) : new TopoDS_Shape(aShell); @@ -152,10 +180,121 @@ void GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr } // Adding free shapes. - for(NCollection_Map::Iterator aShIter(aFreeShapes); aShIter.More(); aShIter.Next()) { - const TopoDS_Shape& aShape = aShIter.Value(); - std::shared_ptr aGeomShape(new GeomAPI_Shape); - aGeomShape->setImpl(new TopoDS_Shape(aShape)); - theFreeShapes.push_back(aGeomShape); + for(TopExp_Explorer anExp(aShapesComp, aTA); anExp.More(); anExp.Next()) { + const TopoDS_Shape& aShape = anExp.Current(); + if(aFreeShapes.Contains(aShape)) { + std::shared_ptr aGeomShape(new GeomAPI_Shape); + aGeomShape->setImpl(new TopoDS_Shape(aShape)); + theFreeShapes.push_back(aGeomShape); + } + } +} + +//================================================================================================= +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(); + + TopoDS_Face aPlaneFace = TopoDS::Face(theFace->impl()); + if (aPlaneFace.IsNull()) + return std::shared_ptr(); + + Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(aPlaneFace)); + if (aPlane.IsNull()) + return std::shared_ptr(); + + // make an infinity face on the plane + TopoDS_Shape anInfiniteFace = BRepBuilderAPI_MakeFace(aPlane->Pln()).Shape(); + + std::shared_ptr aResult(new GeomAPI_Shape); + 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; }