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:
@@ -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);
|
||||
|
Reference in New Issue
Block a user