]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
Mantis issue 0021110: Low efficiency of the explode. Start_BR_19998_21191_NEW_ENV
authorjfa <jfa@opencascade.com>
Tue, 19 Apr 2011 13:33:25 +0000 (13:33 +0000)
committerjfa <jfa@opencascade.com>
Tue, 19 Apr 2011 13:33:25 +0000 (13:33 +0000)
src/GEOMImpl/GEOMImpl_IShapesOperations.cxx
src/GEOMImpl/GEOMImpl_IShapesOperations.hxx

index 3620ecf3aa70937c52b8282981523732c1b2619f..6c126293aab4e31477fd893ba223ff9a3fadb9c7 100644 (file)
 #include <gp_Pnt.hxx>
 
 #include <vector>
+#include <algorithm>
+#include <functional>
 
 #include <Standard_NullObject.hxx>
 #include <Standard_Failure.hxx>
 #include <BRepClass3d_SolidClassifier.hxx>
 #include <Precision.hxx>
 
+#define STD_SORT_ALGO 1
+
 //=============================================================================
 /*!
  *   constructor:
@@ -3717,6 +3721,106 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
   return aResult;
 }
 
+//=======================================================================
+//function : ShapeToDouble
+//purpose  : used by CompareShapes::operator()
+//=======================================================================
+std::pair<double, double> ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting)
+{
+  // Computing of CentreOfMass
+  gp_Pnt GPoint;
+  double Len;
+
+  if (S.ShapeType() == TopAbs_VERTEX) {
+    GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S));
+    Len = (double)S.Orientation();
+  }
+  else {
+    GProp_GProps GPr;
+    // BEGIN: fix for Mantis issue 0020842
+    if (isOldSorting) {
+      BRepGProp::LinearProperties(S, GPr);
+    }
+    else {
+      if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
+        BRepGProp::LinearProperties(S, GPr);
+      }
+      else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
+        BRepGProp::SurfaceProperties(S, GPr);
+      }
+      else {
+        BRepGProp::VolumeProperties(S, GPr);
+      }
+    }
+    // END: fix for Mantis issue 0020842
+    GPoint = GPr.CentreOfMass();
+    Len = GPr.Mass();
+  }
+
+  double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9;
+  return std::make_pair(dMidXYZ, Len);
+}
+
+//=======================================================================
+//function : CompareShapes::operator()
+//purpose  : used by std::sort(), called from SortShapes()
+//=======================================================================
+bool GEOMImpl_IShapesOperations::CompareShapes::operator()(const TopoDS_Shape& theShape1,
+                                                           const TopoDS_Shape& theShape2)
+{
+  if (!myMap.IsBound(theShape1)) {
+    myMap.Bind(theShape1, ShapeToDouble(theShape1, myIsOldSorting));
+  }
+
+  if (!myMap.IsBound(theShape2)) {
+    myMap.Bind(theShape2, ShapeToDouble(theShape2, myIsOldSorting));
+  }
+
+  std::pair<double, double> val1 = myMap.Find(theShape1);
+  std::pair<double, double> val2 = myMap.Find(theShape2);
+
+  double tol = Precision::Confusion();
+  bool exchange = Standard_False;
+
+  double dMidXYZ = val1.first - val2.first;
+  if (dMidXYZ >= tol) {
+    exchange = Standard_True;
+  }
+  else if (Abs(dMidXYZ) < tol) {
+    double dLength = val1.second - val2.second;
+    if (dLength >= tol) {
+      exchange = Standard_True;
+    }
+    else if (Abs(dLength) < tol && theShape1.ShapeType() <= TopAbs_FACE) {
+      // PAL17233
+      // equal values possible on shapes such as two halves of a sphere and
+      // a membrane inside the sphere
+      Bnd_Box box1,box2;
+      BRepBndLib::Add(theShape1, box1);
+      if (!box1.IsVoid()) {
+        BRepBndLib::Add(theShape2, box2);
+        Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
+        if (dSquareExtent >= tol) {
+          exchange = Standard_True;
+        }
+        else if (Abs(dSquareExtent) < tol) {
+          Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
+          box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+          val1 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9;
+          box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+          val2 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9;
+          if ((val1 - val2) >= tol) {
+            exchange = Standard_True;
+          }
+        }
+      }
+    }
+  }
+
+  //return val1 < val2;
+  return !exchange;
+}
+
 //=======================================================================
 //function : SortShapes
 //purpose  :
@@ -3724,6 +3828,26 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL,
                                             const Standard_Boolean isOldSorting)
 {
+#ifdef STD_SORT_ALGO
+  std::vector<TopoDS_Shape> aShapesVec;
+  aShapesVec.reserve(SL.Extent());
+
+  TopTools_ListIteratorOfListOfShape it (SL);
+  for (; it.More(); it.Next()) {
+    aShapesVec.push_back(it.Value());
+  }
+  SL.Clear();
+
+  CompareShapes shComp (isOldSorting);
+  std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp);
+  //std::sort(aShapesVec.begin(), aShapesVec.end(), shComp);
+
+  std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin();
+  for (; anIter != aShapesVec.end(); ++anIter) {
+    SL.Append(*anIter);
+  }
+#else
+  // old implementation
   Standard_Integer MaxShapes = SL.Extent();
   TopTools_Array1OfShape  aShapes (1,MaxShapes);
   TColStd_Array1OfInteger OrderInd(1,MaxShapes);
@@ -3765,8 +3889,7 @@ void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL,
       GPoint = GPr.CentreOfMass();
       Length.SetValue(Index, GPr.Mass());
     }
-    MidXYZ.SetValue(Index,
-                    GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
+    MidXYZ.SetValue(Index, GPoint.X()*999.0 + GPoint.Y()*99.0 + GPoint.Z()*0.9);
     //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
   }
 
@@ -3833,6 +3956,7 @@ void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL,
 
   for (Index=1; Index <= MaxShapes; Index++)
     SL.Append( aShapes( OrderInd(Index) ));
+#endif
 }
 
 //=======================================================================
index 53583e14cc270e82575cb8a5888d5c6f30e92da0..f9c6726184c9c1073f6e0a83f7d6d05362a1e4fd 100644 (file)
 
 #include "GEOMAlgo_State.hxx"
 
+#include <TopoDS_Shape.hxx>
 #include <TopTools_ListOfShape.hxx>
+#include <NCollection_DataMap.hxx>
 #include <TColStd_HSequenceOfTransient.hxx>
 #include <TColStd_HSequenceOfInteger.hxx>
 
-#include <list>
 #include <Handle_Geom_Surface.hxx>
 
 #include <gp_Pnt.hxx>
 
+#include <list>
+#include <functional>
+
 class GEOM_Engine;
 class Handle(GEOM_Object);
 class Handle(TColStd_HArray1OfInteger);
 
+inline Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
+{
+  return S1.IsSame(S2);
+}
+
 class GEOMImpl_IShapesOperations : public GEOM_IOperations
 {
  public:
@@ -342,6 +351,18 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations
    * \brief Sort shapes in the list by their coordinates.
    * \param SL The list of shapes to sort.
    */
+  struct CompareShapes : public std::binary_function<TopoDS_Shape, TopoDS_Shape, bool>
+  {
+    CompareShapes (bool isOldSorting)
+      : myIsOldSorting(isOldSorting) {}
+
+    bool operator()(const TopoDS_Shape& lhs, const TopoDS_Shape& rhs);
+
+    typedef NCollection_DataMap<TopoDS_Shape, std::pair<double, double> > NCollection_DataMapOfShapeDouble;
+    NCollection_DataMapOfShapeDouble myMap;
+    bool myIsOldSorting;
+  };
+
   Standard_EXPORT static void SortShapes (TopTools_ListOfShape& SL,
                                           const Standard_Boolean isOldSorting = Standard_True);