X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGeomAPI%2FGeomAPI_Shape.cpp;h=e114d961c424f65983dd49dd54d98fb09ac0c045;hb=77ce6d35ac8d2f0fdaecb4f23e0870bf74e36103;hp=4ddbe474e83b8a396880f1cf503837213033f630;hpb=a0fa395fd2a0ddb16cb9aed4dab180f2681b4447;p=modules%2Fshaper.git diff --git a/src/GeomAPI/GeomAPI_Shape.cpp b/src/GeomAPI/GeomAPI_Shape.cpp index 4ddbe474e..e114d961c 100644 --- a/src/GeomAPI/GeomAPI_Shape.cpp +++ b/src/GeomAPI/GeomAPI_Shape.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2020 CEA/DEN, EDF R&D +// Copyright (C) 2014-2024 CEA, EDF // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -55,6 +55,7 @@ #include #include +#include #include #include // for std::transform @@ -148,6 +149,32 @@ bool GeomAPI_Shape::isCompound() const return !aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND; } +bool GeomAPI_Shape::isCollectionOfSolids() const +{ + const TopoDS_Shape& aShape = const_cast(this)->impl(); + if (aShape.IsNull()) + return false; + + if (aShape.ShapeType() == TopAbs_SOLID || + aShape.ShapeType() == TopAbs_COMPSOLID) + return true; + + if (aShape.ShapeType() != TopAbs_COMPOUND) + return false; + + TopTools_ListOfShape aLS; + TopTools_MapOfShape aMFence; + BOPTools_AlgoTools::TreatCompound(aShape, aLS, &aMFence); + TopTools_ListOfShape::Iterator it(aLS); + for (; it.More(); it.Next()) { + const TopoDS_Shape& aSx = it.Value(); + if (aSx.ShapeType() != TopAbs_SOLID && + aSx.ShapeType() != TopAbs_COMPSOLID) + return false; + } + return true; +} + bool GeomAPI_Shape::isCompoundOfSolids() const { const TopoDS_Shape& aShape = const_cast(this)->impl(); @@ -299,23 +326,50 @@ bool GeomAPI_Shape::isPlanar() const BRepBuilderAPI_FindPlane aFindPlane(aShape); bool isFound = aFindPlane.Found() == Standard_True; - if(!isFound && aShapeType == TopAbs_EDGE) { - Standard_Real aFirst, aLast; - Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aFirst, aLast); - Handle(Standard_Type) aType = aCurve->DynamicType(); + if(!isFound) { - if(aType == STANDARD_TYPE(Geom_TrimmedCurve)) { - Handle(Geom_TrimmedCurve) aTrimCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve); - aType = aTrimCurve->BasisCurve()->DynamicType(); - } + auto checkEdge = [](const TopoDS_Shape& theShape){ + if(theShape.ShapeType()!= TopAbs_EDGE) + return false; - if(aType == STANDARD_TYPE(Geom_Line) - || aType == STANDARD_TYPE(Geom_Conic) - || aType == STANDARD_TYPE(Geom_Circle) - || aType == STANDARD_TYPE(Geom_Ellipse) - || aType == STANDARD_TYPE(Geom_Hyperbola) - || aType == STANDARD_TYPE(Geom_Parabola)) { - isFound = true; + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(theShape), aFirst, aLast); + Handle(Standard_Type) aType = aCurve->DynamicType(); + if(aType == STANDARD_TYPE(Geom_TrimmedCurve)) { + Handle(Geom_TrimmedCurve) aTrimCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve); + aType = aTrimCurve->BasisCurve()->DynamicType(); + } + + if(aType == STANDARD_TYPE(Geom_Line) + || aType == STANDARD_TYPE(Geom_Conic) + || aType == STANDARD_TYPE(Geom_Circle) + || aType == STANDARD_TYPE(Geom_Ellipse) + || aType == STANDARD_TYPE(Geom_Hyperbola) + || aType == STANDARD_TYPE(Geom_Parabola)) { + return true; + } + return false; + }; + + if(aShapeType == TopAbs_WIRE){ + //check if wire consist of only one edge + int aNbEdges = 0; + TopExp_Explorer anExp(aShape, TopAbs_EDGE); + for (TopExp_Explorer anExp(aShape, TopAbs_EDGE); anExp.More(); anExp.Next()) { + aNbEdges++; + if(aNbEdges == 1){ + const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current()); + isFound = checkEdge(anEdge); + } + else{ + //if more than one edge, check is not valid + isFound = false; + break; + } + } + } + else if(aShapeType == TopAbs_EDGE){ + isFound = checkEdge(aShape); } } @@ -392,21 +446,25 @@ std::shared_ptr GeomAPI_Shape::solid() const } std::list > -GeomAPI_Shape::subShapes(ShapeType theSubShapeType) const +GeomAPI_Shape::subShapes(const ShapeType theSubShapeType, const bool theOnlyUnique) const { ListOfShape aSubs; const TopoDS_Shape& aShape = impl(); if (aShape.IsNull()) return aSubs; + TopTools_MapOfShape alreadyThere; + // process multi-level compounds if (shapeType() == COMPOUND && theSubShapeType == COMPOUND) { for (TopoDS_Iterator anIt(aShape); anIt.More(); anIt.Next()) { const TopoDS_Shape& aCurrent = anIt.Value(); if (aCurrent.ShapeType() == TopAbs_COMPOUND) { - GeomShapePtr aSub(new GeomAPI_Shape); - aSub->setImpl(new TopoDS_Shape(aCurrent)); - aSubs.push_back(aSub); + if (!theOnlyUnique || alreadyThere.Add(aCurrent)) { + GeomShapePtr aSub(new GeomAPI_Shape); + aSub->setImpl(new TopoDS_Shape(aCurrent)); + aSubs.push_back(aSub); + } } } // add self @@ -417,9 +475,11 @@ GeomAPI_Shape::subShapes(ShapeType theSubShapeType) const else { for (TopExp_Explorer anExp(aShape, (TopAbs_ShapeEnum)theSubShapeType); anExp.More(); anExp.Next()) { - GeomShapePtr aSub(new GeomAPI_Shape); - aSub->setImpl(new TopoDS_Shape(anExp.Current())); - aSubs.push_back(aSub); + if (!theOnlyUnique || alreadyThere.Add(anExp.Current())) { + GeomShapePtr aSub(new GeomAPI_Shape); + aSub->setImpl(new TopoDS_Shape(anExp.Current())); + aSubs.push_back(aSub); + } } } return aSubs; @@ -593,7 +653,19 @@ bool GeomAPI_Shape::computeSize(double& theXmin, double& theYmin, double& theZmi if (aShape.IsNull()) return false; Bnd_Box aBndBox; - BRepBndLib::Add(aShape, aBndBox, false); + // Workaround: compute optimal bounding box for the compounds of edges/vertices, because sometimes + // the bounding box of sketch is calculated if the transformation is applied twice (issue #20167). + bool isShape1D = false; + if (aShape.ShapeType() == TopAbs_COMPOUND) { + isShape1D = true; + for (TopoDS_Iterator anIt(aShape); anIt.More() && isShape1D; anIt.Next()) + if (anIt.Value().ShapeType() < TopAbs_WIRE) + isShape1D = false; + } + if (isShape1D) + BRepBndLib::AddOptimal(aShape, aBndBox, false, true); + else + BRepBndLib::Add(aShape, aBndBox, false); if (aBndBox.IsVoid()) return false; aBndBox.Get(theXmin, theYmin, theZmin, theXmax, theYmax, theZmax);