1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-19 13:40:49 +03:00

0027540: Run-to-run differences in the 3D Offset algorithm

Calculating the offset vertices by the superposition of intersection vertices
between pairs of edges (BRepOffset_Inter2d::FuseVertices()).

To obtain stable result when calculating the superposition of vertices
they are sorted (BOPTools_AlgoTools::MakeVertex()).

The support of vertices has been added in nexplode command.

Small correction of tests cases for issue CR27540
This commit is contained in:
emv
2016-05-27 11:19:25 +03:00
committed by bugmaster
parent 625e195819
commit b0fbc5796a
17 changed files with 533 additions and 262 deletions

View File

@@ -63,17 +63,9 @@
#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <NCollection_Array1.hxx>
#include <algorithm>
//
//
//
//
//
//
//
//
//
//
//
static
Standard_Real AngleWithRef(const gp_Dir& theD1,
@@ -115,6 +107,25 @@ static
const BOPTools_ListOfCoupleOfShape& theLCS,
const gp_Pnt& aP);
//=======================================================================
// function: BOPTools_AlgoTools_ComparePoints
// purpose: implementation of IsLess() function for two points
//=======================================================================
struct BOPTools_AlgoTools_ComparePoints {
bool operator()(const gp_Pnt& theP1, const gp_Pnt& theP2)
{
for (Standard_Integer i = 1; i <= 3; ++i) {
if (theP1.Coord(i) < theP2.Coord(i)) {
return Standard_True;
}
else if (theP1.Coord(i) > theP2.Coord(i)) {
return Standard_False;
}
}
return Standard_False;
}
};
//=======================================================================
// function: MakeConnexityBlocks
// purpose:
@@ -1525,8 +1536,8 @@ void BOPTools_AlgoTools::MakeVertex(const BOPCol_ListOfShape& aLV,
aEps=RealEpsilon();
for (m=0; m<aNb; ++m) {
aV[m]=(!m)?
*((TopoDS_Vertex*)(&aLV.First())):
*((TopoDS_Vertex*)(&aLV.Last()));
*((TopoDS_Vertex*)(&aLV.First())):
*((TopoDS_Vertex*)(&aLV.Last()));
aP[m]=BRep_Tool::Pnt(aV[m]);
aR[m]=BRep_Tool::Tolerance(aV[m]);
}
@@ -1559,28 +1570,38 @@ void BOPTools_AlgoTools::MakeVertex(const BOPCol_ListOfShape& aLV,
return;
}// else if (aNb==2) {
//
else { // if (aNb>2)
Standard_Real aTi, aDi, aDmax;
gp_Pnt aPi, aP;
gp_XYZ aXYZ(0.,0.,0.), aXYZi;
BOPCol_ListIteratorOfListOfShape aIt;
else { // if (aNb>2)
// compute the point
//
aIt.Initialize(aLV);
for (; aIt.More(); aIt.Next()) {
TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
aPi=BRep_Tool::Pnt(aVi);
aXYZi=aPi.XYZ();
aXYZ=aXYZ+aXYZi;
// issue 0027540 - sum of doubles may depend on the order
// of addition, thus sort the coordinates for stable result
Standard_Integer i;
NCollection_Array1<gp_Pnt> aPoints(0, aNb-1);
BOPCol_ListIteratorOfListOfShape aIt(aLV);
for (i = 0; aIt.More(); aIt.Next(), ++i) {
const TopoDS_Vertex& aVi = *((TopoDS_Vertex*)(&aIt.Value()));
gp_Pnt aPi = BRep_Tool::Pnt(aVi);
aPoints(i) = aPi;
}
//
std::sort(aPoints.begin(), aPoints.end(), BOPTools_AlgoTools_ComparePoints());
//
gp_XYZ aXYZ(0., 0., 0.);
for (i = 0; i < aNb; ++i) {
aXYZ += aPoints(i).XYZ();
}
aXYZ.Divide((Standard_Real)aNb);
aP.SetXYZ(aXYZ);
//
gp_Pnt aP(aXYZ);
//
// compute the tolerance for the new vertex
Standard_Real aTi, aDi, aDmax;
//
aDmax=-1.;
aIt.Initialize(aLV);
for (; aIt.More(); aIt.Next()) {
TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
aPi=BRep_Tool::Pnt(aVi);
gp_Pnt aPi=BRep_Tool::Pnt(aVi);
aTi=BRep_Tool::Tolerance(aVi);
aDi=aP.SquareDistance(aPi);
aDi=sqrt(aDi);