From 7de39bacb29cf00bffb90c317da3806d6a8f0476 Mon Sep 17 00:00:00 2001 From: jfa Date: Tue, 19 Apr 2011 13:33:25 +0000 Subject: [PATCH] Mantis issue 0021110: Low efficiency of the explode. --- src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 128 +++++++++++++++++++- src/GEOMImpl/GEOMImpl_IShapesOperations.hxx | 23 +++- 2 files changed, 148 insertions(+), 3 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index 3620ecf3a..6c126293a 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -118,6 +118,8 @@ #include #include +#include +#include #include #include @@ -133,6 +135,8 @@ #include #include +#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 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 val1 = myMap.Find(theShape1); + std::pair 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 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::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 } //======================================================================= diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index 53583e14c..f9c672618 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@ -33,19 +33,28 @@ #include "GEOMAlgo_State.hxx" +#include #include +#include #include #include -#include #include #include +#include +#include + 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 + { + CompareShapes (bool isOldSorting) + : myIsOldSorting(isOldSorting) {} + + bool operator()(const TopoDS_Shape& lhs, const TopoDS_Shape& rhs); + + typedef NCollection_DataMap > NCollection_DataMapOfShapeDouble; + NCollection_DataMapOfShapeDouble myMap; + bool myIsOldSorting; + }; + Standard_EXPORT static void SortShapes (TopTools_ListOfShape& SL, const Standard_Boolean isOldSorting = Standard_True); -- 2.39.2