From 86462f3ae59b1e8ea17da35cb00d94dafbca974b Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 12 Dec 2017 13:12:37 +0300 Subject: [PATCH] Sort list of images after modifying a shape before name them --- src/GeomAlgoAPI/CMakeLists.txt | 2 + .../GeomAlgoAPI_SortListOfShapes.cpp | 180 ++++++++++++++++++ .../GeomAlgoAPI_SortListOfShapes.h | 39 ++++ src/Model/Model_BodyBuilder.cpp | 4 + 4 files changed, 225 insertions(+) create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_SortListOfShapes.cpp create mode 100644 src/GeomAlgoAPI/GeomAlgoAPI_SortListOfShapes.h diff --git a/src/GeomAlgoAPI/CMakeLists.txt b/src/GeomAlgoAPI/CMakeLists.txt index f2b4f4330..c9f493d71 100644 --- a/src/GeomAlgoAPI/CMakeLists.txt +++ b/src/GeomAlgoAPI/CMakeLists.txt @@ -75,6 +75,7 @@ SET(PROJECT_HEADERS GeomAlgoAPI_Circ2dBuilder.h GeomAlgoAPI_UnifySameDomain.h GeomAlgoAPI_Fillet.h + GeomAlgoAPI_SortListOfShapes.h ) SET(PROJECT_SOURCES @@ -128,6 +129,7 @@ SET(PROJECT_SOURCES GeomAlgoAPI_Circ2dBuilder.cpp GeomAlgoAPI_UnifySameDomain.cpp GeomAlgoAPI_Fillet.cpp + GeomAlgoAPI_SortListOfShapes.cpp ) SET(PROJECT_LIBRARIES diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_SortListOfShapes.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_SortListOfShapes.cpp new file mode 100644 index 000000000..f75b9ae65 --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_SortListOfShapes.cpp @@ -0,0 +1,180 @@ +// Copyright (C) 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 "GeomAlgoAPI_SortListOfShapes.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +class CompareShapes +{ + std::map myShapes; + std::map myUVBounds; + + bool compareEdges(const GeomShapePtr& theLHS, const GeomShapePtr& theRHS) + { + const TopoDS_Edge& aLHSEdge = TopoDS::Edge(theLHS->impl()); + const TopoDS_Edge& aRHSEdge = TopoDS::Edge(theRHS->impl()); + + double aLF, aLE, aRF, aRE; + Handle(Geom_Curve) aLHSCurve = BRep_Tool::Curve(aLHSEdge, aLF, aLE); + Handle(Geom_Curve) aRHSCurve = BRep_Tool::Curve(aRHSEdge, aRF, aRE); + + if (aLHSCurve == aRHSCurve) { + // compare by first parameter + if (isLessWithTol(aLF, aRF, Precision::PConfusion())) + return true; + else if (isLessWithTol(aRF, aLF, Precision::PConfusion())) + return false; + // compare by last parameter + return isLessWithTol(aLE, aRE, Precision::PConfusion()); + } + // different underlying curves => compare bounding boxe + return compareByBoundingBox(theLHS, theRHS); + } + + bool compareFaces(const GeomShapePtr& theLHS, const GeomShapePtr& theRHS) + { + const TopoDS_Face& aLHSFace = TopoDS::Face(theLHS->impl()); + const TopoDS_Face& aRHSFace = TopoDS::Face(theRHS->impl()); + + Handle(Geom_Surface) aLHSSurf = BRep_Tool::Surface(aLHSFace); + Handle(Geom_Surface) aRHSSurf = BRep_Tool::Surface(aRHSFace); + + if (aLHSSurf == aRHSSurf) { + // compare parametric space for faces on the same surface + Bnd_Box2d aLHSBox = boundingBoxUV(aLHSFace); + Bnd_Box2d aRHSBox = boundingBoxUV(aRHSFace); + + double aLHSBB[4], aRHSBB[4]; + aLHSBox.Get(aLHSBB[0], aLHSBB[1], aLHSBB[2], aLHSBB[3]); + aRHSBox.Get(aRHSBB[0], aRHSBB[1], aRHSBB[2], aRHSBB[3]); + for (int anIndex = 0; anIndex < 4; ++anIndex) { + if (isLessWithTol(aLHSBB[anIndex], aRHSBB[anIndex], Precision::PConfusion())) + return true; + else if (isLessWithTol(aRHSBB[anIndex], aLHSBB[anIndex], Precision::PConfusion())) + return false; + } + // equal parametric boxes + return false; + } + // different underlying surfaces => compare bounding boxes + return compareByBoundingBox(theLHS, theRHS); + } + + bool compareByBoundingBox(const GeomShapePtr& theLHS, const GeomShapePtr& theRHS) + { + Bnd_Box aLHSBox = boundingBox(theLHS); + Bnd_Box aRHSBox = boundingBox(theRHS); + + gp_Pnt aLHSMin = aLHSBox.CornerMin(); + gp_Pnt aLHSMax = aLHSBox.CornerMax(); + + gp_Pnt aRHSMin = aRHSBox.CornerMin(); + gp_Pnt aRHSMax = aRHSBox.CornerMax(); + + if (isLess(aLHSMin, aRHSMin)) + return true; + else if (isLess(aRHSMin, aLHSMin)) + return false; + + return isLess(aLHSMax, aRHSMax); + } + + bool isLessWithTol(const double theLHS, const double theRHS, const double theTolerance) + { + return theLHS + theTolerance < theRHS; + } + + bool isLess(const gp_Pnt& theLHS, const gp_Pnt& theRHS) + { + for (int anIndex = 1; anIndex <= 3; ++anIndex) { + if (isLessWithTol(theLHS.Coord(anIndex), theRHS.Coord(anIndex), Precision::Confusion())) + return true; + else if (isLessWithTol(theRHS.Coord(anIndex), theLHS.Coord(anIndex), Precision::Confusion())) + return false; + } + // equal points + return false; + } + + Bnd_Box boundingBox(const GeomShapePtr& theShape) + { + const TopoDS_Shape& aShape = theShape->impl(); + TopoDS_TShape* aS = aShape.TShape().get(); + std::map::iterator aFound = myShapes.find(aS); + if (aFound == myShapes.end()) { + Bnd_Box aBB; + BRepBndLib::Add(aShape, aBB); + myShapes[aS] = aBB; + aFound = myShapes.find(aS); + } + return aFound->second; + } + + Bnd_Box2d boundingBoxUV(const TopoDS_Face& theFace) + { + TopoDS_TShape* aFacePtr = theFace.TShape().get(); + std::map::iterator aFound = myUVBounds.find(aFacePtr); + if (aFound == myUVBounds.end()) { + Bnd_Box2d aBB; + BRepTools::AddUVBounds(theFace, aBB); + myUVBounds[aFacePtr] = aBB; + aFound = myUVBounds.find(aFacePtr); + } + return aFound->second; + } + +public: + // Verify theLHS is less than theRHS + bool operator() (const GeomShapePtr& theLHS, const GeomShapePtr& theRHS) + { + if (theLHS->shapeType() == theRHS->shapeType()) { + // edges and faces are compared by geometric properties + if (theLHS->shapeType() == GeomAPI_Shape::EDGE) + return compareEdges(theLHS, theRHS); + else if (theLHS->shapeType() == GeomAPI_Shape::FACE) + return compareFaces(theLHS, theRHS); + // all other comparisons are made by bounding boxes + return compareByBoundingBox(theLHS, theRHS); + } + + // shapes of different types are compared by the type + return theLHS->shapeType() < theRHS->shapeType(); + } +}; + + +void GeomAlgoAPI_SortListOfShapes::sort(ListOfShape& theShapes) +{ + CompareShapes aComparator; + theShapes.sort(aComparator); +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_SortListOfShapes.h b/src/GeomAlgoAPI/GeomAlgoAPI_SortListOfShapes.h new file mode 100644 index 000000000..0159b81fc --- /dev/null +++ b/src/GeomAlgoAPI/GeomAlgoAPI_SortListOfShapes.h @@ -0,0 +1,39 @@ +// Copyright (C) 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 +// + +#ifndef GeomAlgoAPI_SortListOfShapes_H_ +#define GeomAlgoAPI_SortListOfShapes_H_ + +#include "GeomAlgoAPI.h" + +#include + +/// \class GeomAlgoAPI_SortListOfShapes +/// \ingroup DataAlgo +/// \brief Performs sorting of shapes according to geometric properties. +class GeomAlgoAPI_SortListOfShapes +{ + public: + /// \brief Sorts list of shapes in accordance with their geometric properties. + /// \param[in/out] theShapes list of shapes. + GEOMALGOAPI_EXPORT static void sort(ListOfShape& theShapes); +}; + +#endif diff --git a/src/Model/Model_BodyBuilder.cpp b/src/Model/Model_BodyBuilder.cpp index 2adab6e8f..140019217 100755 --- a/src/Model/Model_BodyBuilder.cpp +++ b/src/Model/Model_BodyBuilder.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include // DEB //#include @@ -397,6 +398,9 @@ void Model_BodyBuilder::loadAndOrientModifiedShapes ( std::shared_ptr aRShape(new GeomAPI_Shape()); aRShape->setImpl((new TopoDS_Shape(aRoot))); theMS->modified(aRShape, aList); + // sort the list of images before naming + GeomAlgoAPI_SortListOfShapes::sort(aList); + // to trace situation where several objects are produced by one parent (#2317) int aSameParentShapes = -1; std::list >::const_iterator -- 2.39.2