X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGeomAPI%2FGeomAPI_Shape.cpp;h=78a10ac3c5ffb0bb6940a29828e1a07dca6c034d;hb=645e2cb70c0e40290725f28fdc5fec8a93338d28;hp=fc736ac749e379a753d92ebd081d988d59d5430b;hpb=1e2eaa713f139d2617c80eba9ede62d4e9976bb7;p=modules%2Fshaper.git diff --git a/src/GeomAPI/GeomAPI_Shape.cpp b/src/GeomAPI/GeomAPI_Shape.cpp index fc736ac74..78a10ac3c 100644 --- a/src/GeomAPI/GeomAPI_Shape.cpp +++ b/src/GeomAPI/GeomAPI_Shape.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2019 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -12,25 +12,27 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "GeomAPI_Shape.h" +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -50,6 +52,9 @@ #include #include +#include +#include + #include #include // for std::transform @@ -98,6 +103,15 @@ bool GeomAPI_Shape::isSame(const std::shared_ptr theShape) const return MY_SHAPE->IsSame(theShape->impl()) == Standard_True; } +bool GeomAPI_Shape::isSameGeometry(const std::shared_ptr theShape) const +{ + if (isFace()) + return face()->isSameGeometry(theShape); + else if (isEdge()) + return edge()->isSameGeometry(theShape); + return false; +} + bool GeomAPI_Shape::isVertex() const { const TopoDS_Shape& aShape = const_cast(this)->impl(); @@ -148,6 +162,7 @@ bool GeomAPI_Shape::isCompoundOfSolids() const return isAtLeastOne; } +// LCOV_EXCL_START GeomAPI_Shape::ShapeType GeomAPI_Shape::typeOfCompoundShapes() const { const TopoDS_Shape& aShape = const_cast(this)->impl(); @@ -164,6 +179,7 @@ GeomAPI_Shape::ShapeType GeomAPI_Shape::typeOfCompoundShapes() const } return (GeomAPI_Shape::ShapeType) aType; } +// LCOV_EXCL_STOP // adds the nopt-compound elements recursively to the list static void addSimpleToList(const TopoDS_Shape& theShape, NCollection_List& theList) @@ -385,12 +401,29 @@ GeomAPI_Shape::subShapes(ShapeType theSubShapeType) const if (aShape.IsNull()) return aSubs; - for (TopExp_Explorer anExp(aShape, (TopAbs_ShapeEnum)theSubShapeType); - anExp.More(); anExp.Next()) { + // 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); + } + } + // add self GeomShapePtr aSub(new GeomAPI_Shape); - aSub->setImpl(new TopoDS_Shape(anExp.Current())); + aSub->setImpl(new TopoDS_Shape(aShape)); aSubs.push_back(aSub); } + 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); + } + } return aSubs; } @@ -438,21 +471,21 @@ GeomAPI_Shape::ShapeType GeomAPI_Shape::shapeType() const GeomAPI_Shape::ShapeType GeomAPI_Shape::shapeTypeByStr(std::string theType) { std::transform(theType.begin(), theType.end(), theType.begin(), ::toupper); - if (theType == "COMPOUND") + if (theType == "COMPOUND" || theType == "COMPOUNDS") return COMPOUND; - if (theType == "COMPSOLID") + if (theType == "COMPSOLID" || theType == "COMPSOLIDS") return COMPSOLID; - if (theType == "SOLID") + if (theType == "SOLID" || theType == "SOLIDS") return SOLID; - if (theType == "SHELL") + if (theType == "SHELL" || theType == "SHELLS") return SHELL; - if (theType == "FACE") + if (theType == "FACE" || theType == "FACES") return FACE; - if (theType == "WIRE") + if (theType == "WIRE" || theType == "WIRES") return WIRE; - if (theType == "EDGE") + if (theType == "EDGE" || theType == "EDGES") return EDGE; - if (theType == "VERTEX") + if (theType == "VERTEX" || theType == "VERTICES") return VERTEX; return SHAPE; // default } @@ -563,18 +596,63 @@ bool GeomAPI_Shape::computeSize(double& theXmin, double& theYmin, double& theZmi if (aShape.IsNull()) return false; Bnd_Box aBndBox; - BRepBndLib::Add(aShape, aBndBox); + BRepBndLib::Add(aShape, aBndBox, false); + if (aBndBox.IsVoid()) + return false; aBndBox.Get(theXmin, theYmin, theZmin, theXmax, theYmax, theZmax); return true; } -std::string GeomAPI_Shape::getShapeStream() const +GeomPointPtr GeomAPI_Shape::middlePoint() const +{ + GeomPointPtr aMiddlePoint; + + switch (shapeType()) { + case VERTEX: + aMiddlePoint = vertex()->point(); + break; + case EDGE: + aMiddlePoint = edge()->middlePoint(); + break; + case WIRE: + aMiddlePoint = wire()->middlePoint(); + break; + case FACE: + aMiddlePoint = face()->middlePoint(); + break; + case SHELL: + aMiddlePoint = shell()->middlePoint(); + break; + case SOLID: + aMiddlePoint = solid()->middlePoint(); + break; + default: { + // get middle point as center of the bounding box + double aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ; + computeSize(aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ); + aMiddlePoint = GeomPointPtr(new GeomAPI_Pnt( + (aMinX + aMaxX) * 0.5, (aMinY + aMaxY) * 0.5, (aMinZ + aMaxZ) * 0.5)); + } + } + + return aMiddlePoint; +} + +// LCOV_EXCL_START +std::string GeomAPI_Shape::getShapeStream(const bool theWithTriangulation) const { std::ostringstream aStream; const TopoDS_Shape& aShape = const_cast(this)->impl(); - BRepTools::Write(aShape, aStream); + if (!theWithTriangulation) { // make a copy of shape without triangulation + BRepBuilderAPI_Copy aCopy(aShape, Standard_False, Standard_False); + const TopoDS_Shape& aCopyShape = aCopy.Shape(); + BRepTools::Write(aCopyShape, aStream); + } else { + BRepTools::Write(aShape, aStream); + } return aStream.str(); } +// LCOV_EXCL_STOP GeomShapePtr GeomAPI_Shape::intersect(const GeomShapePtr theShape) const { @@ -628,3 +706,73 @@ void GeomAPI_Shape::translate(const std::shared_ptr theDir, const d TopoDS_Shape aResult = MY_SHAPE->Moved(aTranslation); setImpl(new TopoDS_Shape(aResult)); } + +void GeomAPI_Shape::move(const std::shared_ptr theTransformation) +{ + TopoDS_Shape aResult = MY_SHAPE->Moved(theTransformation->impl()); + setImpl(new TopoDS_Shape(aResult)); +} + +bool GeomAPI_Shape::isSelfIntersected(const int theLevelOfCheck) const +{ + BOPAlgo_CheckerSI aCSI; // checker of self-interferences + aCSI.SetLevelOfCheck(theLevelOfCheck); + TopTools_ListOfShape aList; + const TopoDS_Shape& aThisShape = const_cast(this)->impl(); + aList.Append(aThisShape); + aCSI.SetArguments(aList); + aCSI.Perform(); + if (aCSI.HasErrors() || aCSI.DS().Interferences().Extent() > 0) { + return true; + } + + return false; +} + +bool GeomAPI_Shape::Comparator::operator()(const std::shared_ptr& theShape1, + const std::shared_ptr& theShape2) const +{ + const TopoDS_Shape& aShape1 = theShape1->impl(); + const TopoDS_Shape& aShape2 = theShape2->impl(); + bool isLess = aShape1.TShape() < aShape2.TShape(); + if (aShape1.TShape() == aShape2.TShape()) { + Standard_Integer aHash1 = aShape1.Location().HashCode(IntegerLast()); + Standard_Integer aHash2 = aShape2.Location().HashCode(IntegerLast()); + isLess = aHash1 < aHash2; + } + return isLess; +} + +bool GeomAPI_Shape::ComparatorWithOri::operator()( + const std::shared_ptr& theShape1, + const std::shared_ptr& theShape2) const +{ + const TopoDS_Shape& aShape1 = theShape1->impl(); + const TopoDS_Shape& aShape2 = theShape2->impl(); + bool isLess = aShape1.TShape() < aShape2.TShape(); + if (aShape1.TShape() == aShape2.TShape()) { + Standard_Integer aHash1 = aShape1.Location().HashCode(IntegerLast()); + Standard_Integer aHash2 = aShape2.Location().HashCode(IntegerLast()); + isLess = (aHash1 < aHash2) || + (aHash1 == aHash2 && aShape1.Orientation() < aShape2.Orientation()); + } + return isLess; +} + +int GeomAPI_Shape::Hash::operator()(const std::shared_ptr& theShape) const +{ + const TopoDS_Shape& aShape = theShape->impl(); + return aShape.HashCode(IntegerLast()); +} + +bool GeomAPI_Shape::Equal::operator()(const std::shared_ptr& theShape1, + const std::shared_ptr& theShape2) const +{ + const TopoDS_Shape& aShape1 = theShape1->impl(); + const TopoDS_Shape& aShape2 = theShape2->impl(); + + Standard_Integer aHash1 = aShape1.Location().HashCode(IntegerLast()); + Standard_Integer aHash2 = aShape2.Location().HashCode(IntegerLast()); + + return aShape1.TShape() == aShape2.TShape() && aHash1 == aHash2; +}