X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGeomAlgoAPI%2FGeomAlgoAPI_ShapeTools.cpp;h=7c0f462e086a033cd980920130a521a79856ba09;hb=fea65cc1c8e35809be630fb1ab2adcd4fd27cc1e;hp=e6a89baa122854fa3a6a81d8ef1cb740f91e4680;hpb=3f1a42a51c7de1911c75453ff7134593d7d2c6b1;p=modules%2Fshaper.git diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp index e6a89baa1..7c0f462e0 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp @@ -8,8 +8,9 @@ #include "GeomAlgoAPI_SketchBuilder.h" +#include #include -#include +#include #include #include @@ -22,17 +23,19 @@ #include #include #include +#include #include +#include #include +#include #include -#include #include +#include #include #include #include #include #include -#include #include #include #include @@ -48,10 +51,14 @@ #include #include #include +#include + +#include +#include +#include -namespace GeomAlgoAPI_ShapeTools { //================================================================================================== -double volume(const std::shared_ptr theShape) +double GeomAlgoAPI_ShapeTools::volume(const std::shared_ptr theShape) { GProp_GProps aGProps; if(!theShape.get()) { @@ -67,7 +74,7 @@ double volume(const std::shared_ptr theShape) } //================================================================================================== -std::shared_ptr centreOfMass(const std::shared_ptr theShape) +std::shared_ptr GeomAlgoAPI_ShapeTools::centreOfMass(const std::shared_ptr theShape) { GProp_GProps aGProps; if(!theShape) { @@ -91,10 +98,10 @@ std::shared_ptr centreOfMass(const std::shared_ptr t } //================================================================================================== -std::shared_ptr combineShapes(const std::shared_ptr theCompound, - const GeomAPI_Shape::ShapeType theType, - ListOfShape& theCombinedShapes, - ListOfShape& theFreeShapes) +std::shared_ptr GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr theCompound, + const GeomAPI_Shape::ShapeType theType, + ListOfShape& theCombinedShapes, + ListOfShape& theFreeShapes) { GeomShapePtr aResult = theCompound; @@ -222,7 +229,9 @@ std::shared_ptr combineShapes(const std::shared_ptr 1 || (theCombinedShapes.size() >= 1 && theFreeShapes.size() >= 1)) { + } else if(theCombinedShapes.size() == 0 && theFreeShapes.size() == 1) { + aResult = theFreeShapes.front(); + } else { TopoDS_Compound aResultComp; TopoDS_Builder aBuilder; aBuilder.MakeCompound(aResultComp); @@ -270,7 +279,7 @@ static TopoDS_Compound makeCompound(const NCollection_List theShap } //================================================================================================== -std::shared_ptr groupSharedTopology(const std::shared_ptr theCompound) +std::shared_ptr GeomAlgoAPI_ShapeTools::groupSharedTopology(const std::shared_ptr theCompound) { GeomShapePtr aResult = theCompound; @@ -315,30 +324,46 @@ std::shared_ptr groupSharedTopology(const std::shared_ptr>::Iterator anIt(aGroups); anIt.More(); anIt.Next()) { - TopoDS_Compound aGroupCompound = makeCompound(anIt.Value()); + if(aGroups.Size() == 1) { + NCollection_List aGroup = aGroups.First(); GeomShapePtr aGeomShape(new GeomAPI_Shape()); - aGeomShape->setImpl(new TopoDS_Shape(aGroupCompound)); + aGeomShape->setImpl(new TopoDS_Shape(makeCompound(aGroup))); + ListOfShape aCompSolids, aFreeSolids; aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape, - GeomAPI_Shape::COMPSOLID, - aCompSolids, - aFreeSolids); - aBuilder.Add(aCompound, aGeomShape->impl()); - } + GeomAPI_Shape::COMPSOLID, + aCompSolids, + aFreeSolids); + aResult = aGeomShape; + } else { + TopoDS_Compound aCompound; + BRep_Builder aBuilder; + aBuilder.MakeCompound(aCompound); + ListOfShape aCompSolids, aFreeSolids; + for(NCollection_Vector>::Iterator anIt(aGroups); anIt.More(); anIt.Next()) { + NCollection_List aGroup = anIt.Value(); + GeomShapePtr aGeomShape(new GeomAPI_Shape()); + if(aGroup.Size() == 1) { + aGeomShape->setImpl(new TopoDS_Shape(aGroup.First())); + } else { + aGeomShape->setImpl(new TopoDS_Shape(makeCompound(aGroup))); + aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape, + GeomAPI_Shape::COMPSOLID, + aCompSolids, + aFreeSolids); + } + aBuilder.Add(aCompound, aGeomShape->impl()); + } - if(!aCompound.IsNull()) { - aResult->setImpl(new TopoDS_Shape(aCompound)); + if(!aCompound.IsNull()) { + aResult->setImpl(new TopoDS_Shape(aCompound)); + } } return aResult; } //================================================================================================== -std::list > getBoundingBox(const ListOfShape& theShapes, const double theEnlarge) +std::list > GeomAlgoAPI_ShapeTools::getBoundingBox(const ListOfShape& theShapes, const double theEnlarge) { // Bounding box of all objects. Bnd_Box aBndBox; @@ -372,7 +397,7 @@ std::list > getBoundingBox(const ListOfShape& theSh } //================================================================================================== -std::shared_ptr faceToInfinitePlane(const std::shared_ptr theFace) +std::shared_ptr GeomAlgoAPI_ShapeTools::faceToInfinitePlane(const std::shared_ptr theFace) { if (!theFace.get()) return std::shared_ptr(); @@ -394,33 +419,33 @@ std::shared_ptr faceToInfinitePlane(const std::shared_ptr fitPlaneToBox(const std::shared_ptr thePlane, - const std::list >& thePoints) +std::shared_ptr GeomAlgoAPI_ShapeTools::fitPlaneToBox(const std::shared_ptr thePlane, + const std::list >& thePoints) { - std::shared_ptr aResultShape; + std::shared_ptr aResultFace; if(!thePlane.get()) { - return aResultShape; + return aResultFace; } const TopoDS_Shape& aShape = thePlane->impl(); if(aShape.ShapeType() != TopAbs_FACE) { - return aResultShape; + return aResultFace; } TopoDS_Face aFace = TopoDS::Face(aShape); Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); if(aSurf.IsNull()) { - return aResultShape; + return aResultFace; } GeomLib_IsPlanarSurface isPlanar(aSurf); if(!isPlanar.IsPlanar()) { - return aResultShape; + return aResultFace; } if(thePoints.size() != 8) { - return aResultShape; + return aResultFace; } const gp_Pln& aFacePln = isPlanar.Plan(); @@ -440,16 +465,16 @@ std::shared_ptr fitPlaneToBox(const std::shared_ptr VMax) VMax = aPntV; } - aResultShape.reset(new GeomAPI_Shape); - aResultShape->setImpl(new TopoDS_Shape(BRepLib_MakeFace(aFacePln, UMin, UMax, VMin, VMax).Face())); + aResultFace.reset(new GeomAPI_Face()); + aResultFace->setImpl(new TopoDS_Face(BRepLib_MakeFace(aFacePln, UMin, UMax, VMin, VMax).Face())); - return aResultShape; + return aResultFace; } //================================================================================================== -void findBounds(const std::shared_ptr theShape, - std::shared_ptr& theV1, - std::shared_ptr& theV2) +void GeomAlgoAPI_ShapeTools::findBounds(const std::shared_ptr theShape, + std::shared_ptr& theV1, + std::shared_ptr& theV2) { if(!theShape.get()) { std::shared_ptr aVertex(new GeomAPI_Vertex); @@ -471,10 +496,10 @@ void findBounds(const std::shared_ptr theShape, } //================================================================================================== -void makeFacesWithHoles(const std::shared_ptr theOrigin, - const std::shared_ptr theDirection, - const ListOfShape& theWires, - ListOfShape& theFaces) +void GeomAlgoAPI_ShapeTools::makeFacesWithHoles(const std::shared_ptr theOrigin, + const std::shared_ptr theDirection, + const ListOfShape& theWires, + ListOfShape& theFaces) { BRepBuilderAPI_MakeFace aMKFace(gp_Pln(theOrigin->impl(), theDirection->impl())); @@ -503,7 +528,7 @@ void makeFacesWithHoles(const std::shared_ptr theOrigin, } //================================================================================================== -std::shared_ptr findPlane(const ListOfShape& theShapes) +std::shared_ptr GeomAlgoAPI_ShapeTools::findPlane(const ListOfShape& theShapes) { TopoDS_Compound aCompound; BRep_Builder aBuilder; @@ -531,8 +556,8 @@ std::shared_ptr findPlane(const ListOfShape& theShapes) } //================================================================================================== -bool isSubShapeInsideShape(const std::shared_ptr theSubShape, - const std::shared_ptr theBaseShape) +bool GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(const std::shared_ptr theSubShape, + const std::shared_ptr theBaseShape) { if(!theSubShape.get() || !theBaseShape.get()) { return false; @@ -600,4 +625,92 @@ bool isSubShapeInsideShape(const std::shared_ptr theSubShape, return true; } -} //namespace GeomAlgoAPI_ShapeTools + +//================================================================================================== +bool GeomAlgoAPI_ShapeTools::isShapeValid(const std::shared_ptr theShape) +{ + if(!theShape.get()) { + return false; + } + + BRepCheck_Analyzer aChecker(theShape->impl()); + return (aChecker.IsValid() == Standard_True); +} + +//================================================================================================== +std::shared_ptr GeomAlgoAPI_ShapeTools::getFaceOuterWire(const std::shared_ptr theFace) +{ + GeomShapePtr anOuterWire; + + if(!theFace.get() || !theFace->isFace()) { + return anOuterWire; + } + + TopoDS_Face aFace = TopoDS::Face(theFace->impl()); + TopoDS_Wire aWire = BRepTools::OuterWire(aFace); + + anOuterWire.reset(new GeomAPI_Shape()); + anOuterWire->setImpl(new TopoDS_Shape(aWire)); + + return anOuterWire; +} + +//================================================================================================== +bool GeomAlgoAPI_ShapeTools::isParallel(const std::shared_ptr theEdge, + const std::shared_ptr theFace) +{ + if(!theEdge.get() || !theFace.get()) { + return false; + } + + TopoDS_Edge anEdge = TopoDS::Edge(theEdge->impl()); + TopoDS_Face aFace = TopoDS::Face(theFace->impl()); + + BRepExtrema_ExtCF anExt(anEdge, aFace); + return anExt.IsParallel() == Standard_True; +} + +//================================================================================================== +void GeomAlgoAPI_ShapeTools::splitShape(const std::shared_ptr& theBaseShape, + const std::set >& thePoints, + std::set >& theShapes) +{ + // General Fuse to split edge by vertices + BOPAlgo_Builder aBOP; + TopoDS_Edge aBaseEdge = theBaseShape->impl(); + // Rebuild closed edge to place vertex to one of split points. + // This will prevent edge to be split on seam vertex. + if (BRep_Tool::IsClosed(aBaseEdge)) + { + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aBaseEdge, aFirst, aLast); + + std::set >::const_iterator aPIt = thePoints.begin(); + gp_Pnt aPoint((*aPIt)->x(), (*aPIt)->y(), (*aPIt)->z()); + + TopAbs_Orientation anOrientation = aBaseEdge.Orientation(); + aBaseEdge = BRepBuilderAPI_MakeEdge(aCurve, aPoint, aPoint).Edge(); + aBaseEdge.Orientation(anOrientation); + } + aBOP.AddArgument(aBaseEdge); + + std::set >::const_iterator aPtIt = thePoints.begin(); + for (; aPtIt != thePoints.end(); ++aPtIt) { + std::shared_ptr aPnt = *aPtIt; + TopoDS_Vertex aV = BRepBuilderAPI_MakeVertex(gp_Pnt(aPnt->x(), aPnt->y(), aPnt->z())); + aBOP.AddArgument(aV); + } + + aBOP.Perform(); + if (aBOP.ErrorStatus()) + return; + + // Collect splits + const TopTools_ListOfShape& aSplits = aBOP.Modified(aBaseEdge); + TopTools_ListIteratorOfListOfShape anIt(aSplits); + for (; anIt.More(); anIt.Next()) { + std::shared_ptr anEdge(new GeomAPI_Shape); + anEdge->setImpl(new TopoDS_Shape(anIt.Value())); + theShapes.insert(anEdge); + } +}