]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Sort list of images after modifying a shape before name them
authorazv <azv@opencascade.com>
Tue, 12 Dec 2017 10:12:37 +0000 (13:12 +0300)
committerazv <azv@opencascade.com>
Tue, 12 Dec 2017 11:49:09 +0000 (14:49 +0300)
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI_SortListOfShapes.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_SortListOfShapes.h [new file with mode: 0644]
src/Model/Model_BodyBuilder.cpp

index f2b4f43305e5c6c298197e99f38dd43fc05c7f7e..c9f493d712e08a7e8cc469a3a8e322bdede4aa60 100644 (file)
@@ -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 (file)
index 0000000..f75b9ae
--- /dev/null
@@ -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<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "GeomAlgoAPI_SortListOfShapes.h"
+
+#include <Bnd_Box.hxx>
+#include <Bnd_Box2d.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepBndLib.hxx>
+#include <BRepTools.hxx>
+#include <gp_Pnt.hxx>
+#include <Precision.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+
+#include <algorithm>
+#include <map>
+
+class CompareShapes
+{
+  std::map<TopoDS_TShape*, Bnd_Box> myShapes;
+  std::map<TopoDS_TShape*, Bnd_Box2d> myUVBounds;
+
+  bool compareEdges(const GeomShapePtr& theLHS, const GeomShapePtr& theRHS)
+  {
+    const TopoDS_Edge& aLHSEdge = TopoDS::Edge(theLHS->impl<TopoDS_Shape>());
+    const TopoDS_Edge& aRHSEdge = TopoDS::Edge(theRHS->impl<TopoDS_Shape>());
+
+    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<TopoDS_Shape>());
+    const TopoDS_Face& aRHSFace = TopoDS::Face(theRHS->impl<TopoDS_Shape>());
+
+    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_Shape>();
+    TopoDS_TShape* aS = aShape.TShape().get();
+    std::map<TopoDS_TShape*, Bnd_Box>::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<TopoDS_TShape*, Bnd_Box2d>::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 (file)
index 0000000..0159b81
--- /dev/null
@@ -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<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef GeomAlgoAPI_SortListOfShapes_H_
+#define GeomAlgoAPI_SortListOfShapes_H_
+
+#include "GeomAlgoAPI.h"
+
+#include <GeomAPI_Shape.h>
+
+/// \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
index 2adab6e8ff9ee133bb22f613d2571599b681e3b6..14001921701af889675476cb6fa5d7484bc0964a 100755 (executable)
@@ -49,6 +49,7 @@
 #include <BRep_Tool.hxx>
 #include <GeomAPI_Shape.h>
 #include <GeomAlgoAPI_MakeShape.h>
+#include <GeomAlgoAPI_SortListOfShapes.h>
 #include <Config_PropManager.h>
 // DEB
 //#include <TCollection_AsciiString.hxx>
@@ -397,6 +398,9 @@ void Model_BodyBuilder::loadAndOrientModifiedShapes (
     std::shared_ptr<GeomAPI_Shape> 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<std::shared_ptr<GeomAPI_Shape> >::const_iterator