X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGeomAlgoAPI%2FGeomAlgoAPI_Prism.cpp;h=49204ee9032404f5fc90e19786ca27e61c2f2617;hb=f0cec241aae9ca16d86e166f45cb5c4987d2c792;hp=33a77beb33846957f7f6f969cf3cb9aa8cf85895;hpb=eaa6779b2bea637795bb09a420f64a2deee5b51e;p=modules%2Fshaper.git diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp index 33a77beb3..49204ee90 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp @@ -21,19 +21,38 @@ #include #include #include +#include +#include +#include +#include #include #include +#include #include #include #include +#include #include +#include +#include #include #include #include -#include -//================================================================================================= +static void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo, + const TopoDS_Shape& theBase, + const TopAbs_ShapeEnum theType, + BRepPrimAPI_MakePrism* thePrismBuilder); + +static void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo, + const TopoDS_Shape& theResult, + const TopAbs_ShapeEnum theType, + const TopoDS_Face& theToFace, + const TopoDS_Face& theFromFace); + + +//================================================================================================== GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape, const double theToSize, const double theFromSize) @@ -41,7 +60,7 @@ GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape, build(theBaseShape, std::shared_ptr(), GeomShapePtr(), theToSize, GeomShapePtr(), theFromSize); } -//================================================================================================= +//================================================================================================== GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape, const std::shared_ptr theDirection, const double theToSize, @@ -50,7 +69,7 @@ GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseS build(theBaseShape, theDirection, GeomShapePtr(), theToSize, GeomShapePtr(), theFromSize); } -//================================================================================================= +//================================================================================================== GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape, const GeomShapePtr theToShape, const double theToSize, @@ -60,7 +79,7 @@ GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape, build(theBaseShape, std::shared_ptr(), theToShape, theToSize, theFromShape, theFromSize); } -//================================================================================================= +//================================================================================================== GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseShape, const std::shared_ptr theDirection, const GeomShapePtr theToShape, @@ -71,7 +90,7 @@ GeomAlgoAPI_Prism::GeomAlgoAPI_Prism(const GeomShapePtr theBaseS build(theBaseShape, theDirection, theToShape, theToSize, theFromShape, theFromSize); } -//================================================================================================= +//================================================================================================== void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, const std::shared_ptr theDirection, const GeomShapePtr& theToShape, @@ -100,6 +119,11 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, case TopAbs_SHELL: aShapeTypeToExp = TopAbs_FACE; break; + case TopAbs_COMPOUND: + aShapeTypeToExp = TopAbs_COMPOUND; + break; + default: + return; } // Getting direction. @@ -109,24 +133,54 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, GeomShapePtr aBasePlane; const bool isBoundingShapesSet = theFromShape.get() || theToShape.get(); BRepBuilderAPI_FindPlane aFindPlane(aBaseShape); - if(aBaseShape.ShapeType() == TopAbs_VERTEX || aBaseShape.ShapeType() == TopAbs_EDGE || - aFindPlane.Found() != Standard_True) { - // Direction and both bounding planes should be set or empty. - if(!theDirection.get() || (isBoundingShapesSet && (!theToShape.get() || !theFromShape.get()))) { - return; - } - + if(theDirection.get()) { aBaseDir = theDirection; aDirVec = theDirection->impl(); } else { - Handle(Geom_Plane) aPlane = aFindPlane.Plane(); + if(aBaseShape.ShapeType() == TopAbs_VERTEX + || aBaseShape.ShapeType() == TopAbs_EDGE + || aFindPlane.Found() == Standard_False) { + return; + } + + Handle(Geom_Plane) aPlane; + if(aBaseShape.ShapeType() == TopAbs_FACE || aBaseShape.ShapeType() == TopAbs_SHELL) { + TopExp_Explorer anExp(aBaseShape, TopAbs_FACE); + const TopoDS_Shape& aFace = anExp.Current(); + Handle(Geom_Surface) aSurface = BRep_Tool::Surface(TopoDS::Face(aFace)); + if(aSurface->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { + Handle(Geom_RectangularTrimmedSurface) aTrimSurface = + Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface); + aSurface = aTrimSurface->BasisSurface(); + } + if(aSurface->DynamicType() != STANDARD_TYPE(Geom_Plane)) { + return; + } + aPlane = Handle(Geom_Plane)::DownCast(aSurface); + } else { + aPlane = aFindPlane.Plane(); + } gp_Pnt aLoc = aPlane->Axis().Location(); aDirVec = aPlane->Axis().Direction(); - aBaseLoc.reset(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); aBaseDir.reset(new GeomAPI_Dir(aDirVec.X(), aDirVec.Y(), aDirVec.Z())); - aBasePlane = GeomAlgoAPI_FaceBuilder::planarFace(aBaseLoc, aBaseDir); } + if(!aBaseLoc.get()) { + gp_Pnt aLoc; + gp_XYZ aDirXYZ = aDirVec.XYZ(); + Standard_Real aMinParam = Precision::Infinite(); + for(TopExp_Explorer anExp(aBaseShape, TopAbs_VERTEX); anExp.More(); anExp.Next()) { + const TopoDS_Shape& aVertex = anExp.Current(); + gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVertex)); + double aParam = aDirXYZ.Dot(aPnt.XYZ()); + if(aParam < aMinParam) { + aMinParam = aParam; + aLoc = aPnt; + } + } + aBaseLoc.reset(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); + } + aBasePlane = GeomAlgoAPI_FaceBuilder::planarFace(aBaseLoc, aBaseDir); TopoDS_Shape aResult; if(!isBoundingShapesSet) { @@ -155,28 +209,24 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, aResult = aPrismBuilder->Shape(); // Setting naming. - for(TopExp_Explorer anExp(aMovedBase, aShapeTypeToExp); anExp.More(); anExp.Next()) { - const TopoDS_Shape& aFace = anExp.Current(); - GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape); - aFromShape->setImpl(new TopoDS_Shape(aPrismBuilder->FirstShape(aFace))); - aToShape->setImpl(new TopoDS_Shape(aPrismBuilder->LastShape(aFace))); - this->addFromShape(aFromShape); - this->addToShape(aToShape); + if(aShapeTypeToExp == TopAbs_COMPOUND) { + storeGenerationHistory(this, aMovedBase, TopAbs_EDGE, aPrismBuilder); + storeGenerationHistory(this, aMovedBase, TopAbs_FACE, aPrismBuilder); + } else { + storeGenerationHistory(this, aMovedBase, aShapeTypeToExp, aPrismBuilder); } } else { GeomShapePtr aBoundingFromShape = theFromShape ? theFromShape : aBasePlane; GeomShapePtr aBoundingToShape = theToShape ? theToShape : aBasePlane; // Moving prism bounding faces according to "from" and "to" sizes. - std::shared_ptr aFromFace(new GeomAPI_Face(aBoundingFromShape)); - std::shared_ptr aFromPln = aFromFace->getPlane(); - std::shared_ptr aFromLoc = aFromPln->location(); - std::shared_ptr aFromDir = aFromPln->direction(); + std::shared_ptr aFromPln = GeomAPI_Face(aBoundingFromShape).getPlane(); + std::shared_ptr aFromLoc = aFromPln->location(); + std::shared_ptr aFromDir = aFromPln->direction(); - std::shared_ptr aToFace(new GeomAPI_Face(aBoundingToShape)); - std::shared_ptr aToPln = aToFace->getPlane(); - std::shared_ptr aToLoc = aToPln->location(); - std::shared_ptr aToDir = aToPln->direction(); + std::shared_ptr aToPln = GeomAPI_Face(aBoundingToShape).getPlane(); + std::shared_ptr aToLoc = aToPln->location(); + std::shared_ptr aToDir = aToPln->direction(); bool aSign = aFromLoc->xyz()->dot(aBaseDir->xyz()) > aToLoc->xyz()->dot(aBaseDir->xyz()); @@ -290,6 +340,8 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, TopoDS_Solid aToSolid, aFromSolid; const TopoDS_Shape& aToShape = aBoundingToShape->impl(); const TopoDS_Shape& aFromShape = aBoundingFromShape->impl(); + TopoDS_Face aToFace = TopoDS::Face(aToShape); + TopoDS_Face aFromFace = TopoDS::Face(aFromShape); BRep_Builder aBoundingBuilder; aBoundingBuilder.MakeShell(aToShell); aBoundingBuilder.Add(aToShell, aToShape); @@ -307,16 +359,18 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, return; } this->appendAlgo(std::shared_ptr(new GeomAlgoAPI_MakeShape(aToCutBuilder))); - const TopTools_ListOfShape& aToShapes = aToCutBuilder->Modified(aToShape); - for(TopTools_ListIteratorOfListOfShape anIt(aToShapes); anIt.More(); anIt.Next()) { - GeomShapePtr aShape(new GeomAPI_Shape()); - aShape->setImpl(new TopoDS_Shape(anIt.Value())); - this->addToShape(aShape); - } aResult = aToCutBuilder->Shape(); if(aResult.ShapeType() == TopAbs_COMPOUND) { aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); } + if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) { + const TopTools_ListOfShape& aToShapes = aToCutBuilder->Modified(aToShape); + for(TopTools_ListIteratorOfListOfShape anIt(aToShapes); anIt.More(); anIt.Next()) { + GeomShapePtr aGeomSh(new GeomAPI_Shape()); + aGeomSh->setImpl(new TopoDS_Shape(anIt.Value())); + this->addToShape(aGeomSh); + } + } // Cutting with from plane. BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid); @@ -325,40 +379,40 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, return; } this->appendAlgo(std::shared_ptr(new GeomAlgoAPI_MakeShape(aFromCutBuilder))); - const TopTools_ListOfShape& aFromShapes = aFromCutBuilder->Modified(aFromShape); - for(TopTools_ListIteratorOfListOfShape anIt(aFromShapes); anIt.More(); anIt.Next()) { - GeomShapePtr aShape(new GeomAPI_Shape()); - aShape->setImpl(new TopoDS_Shape(anIt.Value())); - this->addFromShape(aShape); - } aResult = aFromCutBuilder->Shape(); - - TopoDS_Iterator anIt(aResult); - if(!anIt.More()) { + TopoDS_Iterator aCheckIt(aResult); + if(!aCheckIt.More()) { return; } if(aResult.ShapeType() == TopAbs_COMPOUND) { aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); } + if(aShapeTypeToExp == TopAbs_FACE || aShapeTypeToExp == TopAbs_COMPOUND) { + const TopTools_ListOfShape& aFromShapes = aFromCutBuilder->Modified(aFromShape); + for(TopTools_ListIteratorOfListOfShape anIt(aFromShapes); anIt.More(); anIt.Next()) { + GeomShapePtr aGeomSh(new GeomAPI_Shape()); + aGeomSh->setImpl(new TopoDS_Shape(anIt.Value())); + this->addFromShape(aGeomSh); + } + } + + // Naming for extrusion from vertex, edge. + if(aShapeTypeToExp == TopAbs_COMPOUND) { + storeGenerationHistory(this, aResult, TopAbs_EDGE, aToFace, aFromFace); + storeGenerationHistory(this, aResult, TopAbs_FACE, aToFace, aFromFace); + } else { + storeGenerationHistory(this, aResult, aShapeTypeToExp, aToFace, aFromFace); + } + if(aResult.ShapeType() == TopAbs_COMPOUND) { - GeomShapePtr aCompound(new GeomAPI_Shape); - aCompound->setImpl(new TopoDS_Shape(aResult)); + std::shared_ptr aGeomShape(new GeomAPI_Shape); + aGeomShape->setImpl(new TopoDS_Shape(aResult)); ListOfShape aCompSolids, aFreeSolids; - GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids); - if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) { - aResult = aCompSolids.front()->impl(); - } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) { - TopoDS_Compound aResultComp; - TopoDS_Builder aBuilder; - aBuilder.MakeCompound(aResultComp); - for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) { - aBuilder.Add(aResultComp, (*anIter)->impl()); - } - for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) { - aBuilder.Add(aResultComp, (*anIter)->impl()); - } - aResult = aResultComp; - } + aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape, + GeomAPI_Shape::COMPSOLID, + aCompSolids, + aFreeSolids); + aResult = aGeomShape->impl(); } } @@ -366,8 +420,67 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, if(aResult.IsNull()) { return; } - GeomShapePtr aShape(new GeomAPI_Shape()); - aShape->setImpl(new TopoDS_Shape(aResult)); - this->setShape(aShape); + aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); + GeomShapePtr aGeomSh(new GeomAPI_Shape()); + aGeomSh->setImpl(new TopoDS_Shape(aResult)); + this->setShape(aGeomSh); this->setDone(true); } + +// Auxilary functions: +//================================================================================================== +void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo, + const TopoDS_Shape& theBase, + const TopAbs_ShapeEnum theType, + BRepPrimAPI_MakePrism* thePrismBuilder) +{ + for(TopExp_Explorer anExp(theBase, theType); anExp.More(); anExp.Next()) { + const TopoDS_Shape& aShape = anExp.Current(); + GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape); + aFromShape->setImpl(new TopoDS_Shape(thePrismBuilder->FirstShape(aShape))); + aToShape->setImpl(new TopoDS_Shape(thePrismBuilder->LastShape(aShape))); + thePrismAlgo->addFromShape(aFromShape); + thePrismAlgo->addToShape(aToShape); + } +} + +//================================================================================================== +void storeGenerationHistory(GeomAlgoAPI_Prism* thePrismAlgo, + const TopoDS_Shape& theResult, + const TopAbs_ShapeEnum theType, + const TopoDS_Face& theToFace, + const TopoDS_Face& theFromFace) +{ + for(TopExp_Explorer anExp(theResult, theType); anExp.More(); anExp.Next()) { + const TopoDS_Shape& aShape = anExp.Current(); + GeomShapePtr aGeomSh(new GeomAPI_Shape()); + if(theType == TopAbs_VERTEX) { + gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape)); + IntTools_Context anIntTools; + if(anIntTools.IsValidPointForFace(aPnt, theToFace, Precision::Confusion()) == Standard_True) { + aGeomSh->setImpl(new TopoDS_Shape(aShape)); + thePrismAlgo->addToShape(aGeomSh); + } + if(anIntTools.IsValidPointForFace(aPnt, theFromFace, Precision::Confusion()) == Standard_True) { + aGeomSh->setImpl(new TopoDS_Shape(aShape)); + thePrismAlgo->addFromShape(aGeomSh); + } + } else if(theType == TopAbs_EDGE) { + TopoDS_Edge anEdge = TopoDS::Edge(aShape); + BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, theToFace); + anEdgeCheck.Perform(); + if(anEdgeCheck.MaxDistance() < Precision::Confusion()) { + aGeomSh->setImpl(new TopoDS_Shape(aShape)); + thePrismAlgo->addToShape(aGeomSh); + } + anEdgeCheck.Init(anEdge, theFromFace); + anEdgeCheck.Perform(); + if(anEdgeCheck.MaxDistance() < Precision::Confusion()) { + aGeomSh->setImpl(new TopoDS_Shape(aShape)); + thePrismAlgo->addFromShape(aGeomSh); + } + } else { + break; + } + } +}