Mantis issue 0021110: Low efficiency of the explode.

This commit is contained in:
jfa 2011-04-19 13:33:25 +00:00
parent c26ca04e30
commit 7de39bacb2
2 changed files with 148 additions and 3 deletions

View File

@ -118,6 +118,8 @@
#include <gp_Pnt.hxx>
#include <vector>
#include <algorithm>
#include <functional>
#include <Standard_NullObject.hxx>
#include <Standard_Failure.hxx>
@ -133,6 +135,8 @@
#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
}
//=======================================================================

View File

@ -33,19 +33,28 @@
#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);