X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGeomAPI%2FGeomAPI_Shape.cpp;h=c1df335558bd9f4f7680e158f68a43984bd27619;hb=4df4bd61da1ea5d357671c819a8ced6ec9ba77ac;hp=1c97ef8b42ec78f4211e03035d2212d0595e0ace;hpb=4aa37ed1eb429f7391098b5202922d43e85fcc30;p=modules%2Fshaper.git diff --git a/src/GeomAPI/GeomAPI_Shape.cpp b/src/GeomAPI/GeomAPI_Shape.cpp index 1c97ef8b4..c1df33555 100644 --- a/src/GeomAPI/GeomAPI_Shape.cpp +++ b/src/GeomAPI/GeomAPI_Shape.cpp @@ -1,14 +1,30 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: GeomAPI_Shape.cpp -// Created: 23 Apr 2014 -// Author: Mikhail PONIKAROV +// Copyright (C) 2014-2017 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// 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 +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// #include "GeomAPI_Shape.h" #include +#include #include #include +#include #include #include #include @@ -25,8 +41,12 @@ #include #include #include +#include #include +#include // for std::transform + +#include #define MY_SHAPE implPtr() @@ -35,6 +55,13 @@ GeomAPI_Shape::GeomAPI_Shape() { } +std::shared_ptr GeomAPI_Shape::emptyCopied() const +{ + GeomShapePtr aShape(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(MY_SHAPE->EmptyCopied())); + return aShape; +} + bool GeomAPI_Shape::isNull() const { return MY_SHAPE->IsNull() == Standard_True; @@ -52,6 +79,18 @@ bool GeomAPI_Shape::isEqual(const std::shared_ptr theShape) const return MY_SHAPE->IsEqual(theShape->impl()) == Standard_True; } +bool GeomAPI_Shape::isSame(const std::shared_ptr theShape) const +{ + if (!theShape.get()) + return false; + if (isNull()) + return theShape->isNull(); + if (theShape->isNull()) + return false; + + return MY_SHAPE->IsSame(theShape->impl()) == Standard_True; +} + bool GeomAPI_Shape::isVertex() const { const TopoDS_Shape& aShape = const_cast(this)->impl(); @@ -90,6 +129,76 @@ bool GeomAPI_Shape::isCompoundOfSolids() const return isAtLeastOne; } +// adds the nopt-compound elements recursively to the list +static void addSimpleToList(const TopoDS_Shape& theShape, NCollection_List& theList) +{ + if (!theShape.IsNull()) { + if (theShape.ShapeType() == TopAbs_COMPOUND) { + for(TopoDS_Iterator aSubs(theShape); aSubs.More(); aSubs.Next()) { + addSimpleToList(aSubs.Value(), theList); + } + } else { + theList.Append(theShape); + } + } +} + +bool GeomAPI_Shape::isConnectedTopology() const +{ + const TopoDS_Shape& aShape = const_cast(this)->impl(); + if (aShape.IsNull() || aShape.ShapeType() != TopAbs_COMPOUND) + return false; + // list of simple elements that are not detected in connection to others + NCollection_List aNotConnected; + addSimpleToList(aShape, aNotConnected); + if (aNotConnected.IsEmpty()) // an empty compound + return false; + + // collect here the group of connected subs, starting with one first element + NCollection_List aNewConnected; + aNewConnected.Append(aNotConnected.First()); + aNotConnected.RemoveFirst(); + // iterate until some new element become connected + while(!aNewConnected.IsEmpty() && !aNotConnected.IsEmpty()) { + NCollection_List aNew; // very new connected to new connected + NCollection_List::Iterator aNotIter(aNotConnected); + while(aNotIter.More()) { + // optimization to avoid TopExp_Explorer double-cycle, collect all vertices in the list first + NCollection_List aNotVertices; + for(TopExp_Explorer anExp1(aNotIter.Value(), TopAbs_VERTEX); anExp1.More(); anExp1.Next()) { + aNotVertices.Append(anExp1.Current()); + } + + bool aConnected = false; + NCollection_List::Iterator aNewIter(aNewConnected); + for(; !aConnected && aNewIter.More(); aNewIter.Next()) { + // checking topological connecion of aNotIter and aNewIter + // (if shapes are connected, vertices are connected for sure) + TopExp_Explorer anExp2(aNewIter.Value(), TopAbs_VERTEX); + for(; !aConnected && anExp2.More(); anExp2.Next()) { + NCollection_List::Iterator aNotIter(aNotVertices); + for(; aNotIter.More(); aNotIter.Next()) { + if (aNotIter.Value().IsSame(anExp2.Current())) { + aConnected = true; + break; + } + } + } + } + if (aConnected) { + aNew.Append(aNotIter.Value()); + aNotConnected.Remove(aNotIter); + } else { + aNotIter.Next(); + } + } + // remove all new connected and put to this list very new connected + aNewConnected.Clear(); + aNewConnected.Append(aNew); + } + return aNotConnected.IsEmpty() == Standard_True; +} + bool GeomAPI_Shape::isSolid() const { const TopoDS_Shape& aShape = const_cast(this)->impl(); @@ -131,7 +240,8 @@ bool GeomAPI_Shape::isPlanar() const Handle(Standard_Type) aType = aSurface->DynamicType(); if(aType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { - Handle(Geom_RectangularTrimmedSurface) aTrimSurface = Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface); + Handle(Geom_RectangularTrimmedSurface) aTrimSurface = + Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface); aType = aTrimSurface->BasisSurface()->DynamicType(); } return (aType == STANDARD_TYPE(Geom_Plane)) == Standard_True; @@ -204,6 +314,28 @@ GeomAPI_Shape::ShapeType GeomAPI_Shape::shapeType() const return aST; } +GeomAPI_Shape::ShapeType GeomAPI_Shape::shapeTypeByStr(std::string theType) +{ + std::transform(theType.begin(), theType.end(), theType.begin(), ::toupper); + if (theType == "COMPOUND") + return COMPOUND; + if (theType == "COMPSOLID") + return COMPSOLID; + if (theType == "SOLID") + return SOLID; + if (theType == "SHELL") + return SHELL; + if (theType == "FACE") + return FACE; + if (theType == "WIRE") + return WIRE; + if (theType == "EDGE") + return EDGE; + if (theType == "VERTEX") + return VERTEX; + return SHAPE; // default +} + std::string GeomAPI_Shape::shapeTypeStr() const { ShapeType aShapeType = shapeType(); @@ -211,39 +343,39 @@ std::string GeomAPI_Shape::shapeTypeStr() const switch(aShapeType) { case COMPOUND: { - aShapeTypeStr = "Compound"; + aShapeTypeStr = "COMPOUND"; break; } case COMPSOLID: { - aShapeTypeStr = "CompSolid"; + aShapeTypeStr = "COMPSOLID"; break; } case SOLID: { - aShapeTypeStr = "Solid"; + aShapeTypeStr = "SOLID"; break; } case SHELL: { - aShapeTypeStr = "Shell"; + aShapeTypeStr = "SHELL"; break; } case FACE: { - aShapeTypeStr = "Face"; + aShapeTypeStr = "FACE"; break; } case WIRE: { - aShapeTypeStr = "Wire"; + aShapeTypeStr = "WIRE"; break; } case EDGE: { - aShapeTypeStr = "Edge"; + aShapeTypeStr = "EDGE"; break; } case VERTEX: { - aShapeTypeStr = "Vertex"; + aShapeTypeStr = "VERTEX"; break; } case SHAPE: { - aShapeTypeStr = "Shape"; + aShapeTypeStr = "SHAPE"; break; } } @@ -251,6 +383,31 @@ std::string GeomAPI_Shape::shapeTypeStr() const return aShapeTypeStr; } +GeomAPI_Shape::Orientation GeomAPI_Shape::orientation() const +{ + TopAbs_Orientation anOrientation = MY_SHAPE->Orientation(); + + switch(anOrientation) { + case TopAbs_FORWARD: return FORWARD; + case TopAbs_REVERSED: return REVERSED; + case TopAbs_INTERNAL: return INTERNAL; + case TopAbs_EXTERNAL: return EXTERNAL; + default: return FORWARD; + } +} + +void GeomAPI_Shape::setOrientation(const GeomAPI_Shape::Orientation theOrientation) +{ + TopAbs_Orientation anOrientation = MY_SHAPE->Orientation(); + + switch(theOrientation) { + case FORWARD: MY_SHAPE->Orientation(TopAbs_FORWARD); break; + case REVERSED: MY_SHAPE->Orientation(TopAbs_REVERSED); break; + case INTERNAL: MY_SHAPE->Orientation(TopAbs_INTERNAL); break; + case EXTERNAL: MY_SHAPE->Orientation(TopAbs_EXTERNAL); break; + } +} + bool GeomAPI_Shape::isSubShape(const std::shared_ptr theShape) const { if(!theShape.get()) { @@ -290,3 +447,56 @@ std::string GeomAPI_Shape::getShapeStream() const BRepTools::Write(aShape, aStream); return aStream.str(); } + +GeomShapePtr GeomAPI_Shape::intersect(const GeomShapePtr theShape) const +{ + const TopoDS_Shape& aShape1 = const_cast(this)->impl(); + const TopoDS_Shape& aShape2 = theShape->impl(); + + BRepAlgoAPI_Section aCommon(aShape1, aShape2); + if (!aCommon.IsDone()) + return GeomShapePtr(); + + TopoDS_Shape aResult = aCommon.Shape(); + if (aResult.ShapeType() == TopAbs_COMPOUND) { + NCollection_List aSubs; + addSimpleToList(aResult, aSubs); + if(aSubs.Size() == 1) { + aResult = aSubs.First(); + } else if(aSubs.Size() == 0) { + return GeomShapePtr(); + } + } + + GeomShapePtr aResShape(new GeomAPI_Shape); + aResShape->setImpl(new TopoDS_Shape(aResult)); + return aResShape; +} + +bool GeomAPI_Shape::isIntersect(const GeomShapePtr theShape) const +{ + if(!theShape.get()) { + return false; + } + + const TopoDS_Shape& aShape1 = const_cast(this)->impl(); + const TopoDS_Shape& aShape2 = theShape->impl(); + + BRepExtrema_DistShapeShape aDist(aShape1, aShape2); + aDist.Perform(); + if(aDist.IsDone() && aDist.Value() < Precision::Confusion()) { + return true; + } + + return false; +} + +void GeomAPI_Shape::translate(const std::shared_ptr theDir, const double theOffset) +{ + gp_Dir aDir = theDir->impl(); + gp_Vec aTrsfVec(aDir.XYZ() * theOffset); + gp_Trsf aTranslation; + aTranslation.SetTranslation(aTrsfVec); + TopoDS_Shape aResult = MY_SHAPE->Moved(aTranslation); + setImpl(new TopoDS_Shape(aResult)); +}