X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGeomAlgoAPI%2FGeomAlgoAPI_Prism.cpp;h=49204ee9032404f5fc90e19786ca27e61c2f2617;hb=f0cec241aae9ca16d86e166f45cb5c4987d2c792;hp=45e0adfebd1e93672ab87a0ea390d4a417535411;hpb=c66d90377083e2611816b72500533d4ffbc73e19;p=modules%2Fshaper.git diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp index 45e0adfeb..49204ee90 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,20 @@ #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) @@ -46,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, @@ -55,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, @@ -65,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, @@ -76,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, @@ -105,30 +119,56 @@ 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. - gp_Pnt aLoc; gp_Vec aDirVec; std::shared_ptr aBaseLoc; std::shared_ptr aBaseDir; 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 should be set. - if(!theDirection.get()) { + if(theDirection.get()) { + aBaseDir = theDirection; + aDirVec = theDirection->impl(); + } else { + if(aBaseShape.ShapeType() == TopAbs_VERTEX + || aBaseShape.ShapeType() == TopAbs_EDGE + || aFindPlane.Found() == Standard_False) { return; } - aBaseDir = theDirection; - aDirVec = theDirection->impl(); + 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())); + } + 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)); @@ -138,19 +178,8 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, aLoc = aPnt; } } - } else { - if(!theDirection.get()) { - Handle(Geom_Plane) aPlane = aFindPlane.Plane(); - aLoc = aPlane->Axis().Location(); - aDirVec = aPlane->Axis().Direction(); - - aBaseDir.reset(new GeomAPI_Dir(aDirVec.X(), aDirVec.Y(), aDirVec.Z())); - } else { - aBaseDir = theDirection; - aDirVec = theDirection->impl(); - } + aBaseLoc.reset(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); } - aBaseLoc.reset(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); aBasePlane = GeomAlgoAPI_FaceBuilder::planarFace(aBaseLoc, aBaseDir); TopoDS_Shape aResult; @@ -180,13 +209,11 @@ 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& aShape = anExp.Current(); - GeomShapePtr aFromShape(new GeomAPI_Shape), aToShape(new GeomAPI_Shape); - aFromShape->setImpl(new TopoDS_Shape(aPrismBuilder->FirstShape(aShape))); - aToShape->setImpl(new TopoDS_Shape(aPrismBuilder->LastShape(aShape))); - 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; @@ -336,7 +363,7 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, if(aResult.ShapeType() == TopAbs_COMPOUND) { aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); } - if(aShapeTypeToExp == TopAbs_FACE) { + 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()); @@ -360,7 +387,7 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, if(aResult.ShapeType() == TopAbs_COMPOUND) { aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); } - if(aShapeTypeToExp == TopAbs_FACE) { + 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()); @@ -370,61 +397,22 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, } // Naming for extrusion from vertex, edge. - for(TopExp_Explorer anExp(aResult, aShapeTypeToExp); anExp.More(); anExp.Next()) { - const TopoDS_Shape& aShape = anExp.Current(); - if(aShapeTypeToExp == TopAbs_VERTEX) { - gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape)); - IntTools_Context anIntTools; - if(anIntTools.IsValidPointForFace(aPnt, aToFace, Precision::Confusion()) == Standard_True) { - GeomShapePtr aGeomSh(new GeomAPI_Shape()); - aGeomSh->setImpl(new TopoDS_Shape(aShape)); - this->addToShape(aGeomSh); - } - if(anIntTools.IsValidPointForFace(aPnt, aFromFace, Precision::Confusion()) == Standard_True) { - GeomShapePtr aGeomSh(new GeomAPI_Shape()); - aGeomSh->setImpl(new TopoDS_Shape(aShape)); - this->addFromShape(aGeomSh); - } - } else if(aShapeTypeToExp == TopAbs_EDGE) { - TopoDS_Edge anEdge = TopoDS::Edge(aShape); - BRepLib_CheckCurveOnSurface anEdgeCheck(anEdge, aToFace); - anEdgeCheck.Perform(); - if(anEdgeCheck.MaxDistance() < Precision::Confusion()) { - GeomShapePtr aGeomSh(new GeomAPI_Shape()); - aGeomSh->setImpl(new TopoDS_Shape(aShape)); - this->addToShape(aGeomSh); - } - anEdgeCheck.Init(anEdge, aFromFace); - anEdgeCheck.Perform(); - if(anEdgeCheck.MaxDistance() < Precision::Confusion()) { - GeomShapePtr aGeomSh(new GeomAPI_Shape()); - aGeomSh->setImpl(new TopoDS_Shape(aShape)); - this->addFromShape(aGeomSh); - } - } else { - break; - } + 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(); } } @@ -432,8 +420,67 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, if(aResult.IsNull()) { return; } + 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; + } + } +}