1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +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);

View File

@ -20,6 +20,7 @@
#include <Standard_Type.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_MapOfOrientedShape.hxx>
IMPLEMENT_STANDARD_RTTIEXT(BRepAlgo_AsDes,MMgt_TShared)
@ -149,12 +150,18 @@ static void ReplaceInList(const TopoDS_Shape& OldS,
const TopoDS_Shape& NewS,
TopTools_ListOfShape& L)
{
TopTools_MapOfOrientedShape aMS;
TopTools_ListIteratorOfListOfShape it(L);
for (; it.More(); it.Next()) {
aMS.Add(it.Value());
}
it.Initialize(L);
while(it.More()) {
if (it.Value().IsSame(OldS)) {
TopAbs_Orientation O = it.Value().Orientation();
L.InsertBefore(NewS.Oriented(O),it);
if (aMS.Add(NewS.Oriented(O))) {
L.InsertBefore(NewS.Oriented(O),it);
}
L.Remove(it);
}
else it.Next();
@ -235,34 +242,52 @@ void BRepAlgo_AsDes::BackReplace(const TopoDS_Shape& OldS,
//function : Replace
//purpose :
//=======================================================================
void BRepAlgo_AsDes::Replace(const TopoDS_Shape& OldS,
const TopoDS_Shape& NewS)
const TopoDS_Shape& NewS)
{
Standard_Boolean InUp;
if (up.IsBound(OldS)) {
InUp = Standard_False;
BackReplace (OldS,NewS,up(OldS),InUp);
if (up.IsBound(NewS)) {
up(NewS).Append(up(OldS));
for (Standard_Integer i = 0; i < 2; ++i) {
TopTools_DataMapOfShapeListOfShape& aMap = !i ? up : down;
TopTools_ListOfShape* pLSOld = aMap.ChangeSeek(OldS);
if (!pLSOld) {
continue;
}
//
Standard_Boolean InUp = !i ? Standard_False : Standard_True;
BackReplace(OldS, NewS, *pLSOld, InUp);
//
TopTools_ListOfShape* pLSNew = aMap.ChangeSeek(NewS);
if (!pLSNew) {
// filter the list
TopTools_MapOfOrientedShape aMS;
TopTools_ListIteratorOfListOfShape aIt(*pLSOld);
for (; aIt.More(); ) {
if (!aMS.Add(aIt.Value())) {
pLSOld->Remove(aIt);
}
else {
aIt.Next();
}
}
aMap.Bind(NewS, *pLSOld);
}
else {
up.Bind(NewS,up(OldS));
// avoid duplicates
TopTools_MapOfOrientedShape aMS;
TopTools_ListIteratorOfListOfShape aIt(*pLSNew);
for (; aIt.More(); aIt.Next()) {
aMS.Add(aIt.Value());
}
//
aIt.Initialize(*pLSOld);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS = aIt.Value();
if (aMS.Add(aS)) {
pLSNew->Append(aS);
}
}
}
up.UnBind(OldS);
}
if (down.IsBound(OldS)) {
InUp = Standard_True;
BackReplace(OldS,NewS,down (OldS),InUp);
if (down.IsBound(NewS)) {
down(NewS).Append(down(OldS));
}
else {
down.Bind(NewS,down(OldS));
}
down.UnBind(OldS);
//
aMap.UnBind(OldS);
}
}

View File

@ -76,6 +76,8 @@
#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <BOPCol_ListOfShape.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <stdio.h>
#ifdef DRAW
@ -100,167 +102,100 @@ static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1,
TopoDS_Edge& E2)
{
TopoDS_Vertex V1[2],V2[2],V;
// Modified by skv - Wed Dec 24 18:08:39 2003 OCC4455 Begin
// TopExp::Vertices(E1,V1[0],V1[1]);
// TopExp::Vertices(E2,V2[0],V2[1]);
//
TopExp::Vertices(E1,V1[0],V1[1], Standard_True);
TopExp::Vertices(E2,V2[0],V2[1], Standard_True);
// The first edge is the current one, the second edge is the next one.
// We check last vertex of the first edge first.
// if (V1[0].IsSame(V2[0]) || V1[0].IsSame(V2[1])) return V1[0];
// if (V1[1].IsSame(V2[0]) || V1[1].IsSame(V2[1])) return V1[1];
if (V1[1].IsSame(V2[0]) || V1[1].IsSame(V2[1])) return V1[1];
if (V1[0].IsSame(V2[0]) || V1[0].IsSame(V2[1])) return V1[0];
// Modified by skv - Wed Dec 24 18:08:40 2003 OCC4455 End
//
return V;
}
//=======================================================================
//function : Store
//purpose :
//purpose : The vertices are added despite of the coincidence with
// already added vertices. When all vertices for all edges
// are added the coinciding chains of vertices should be fused
// using FuseVertices() method.
//=======================================================================
static void Store (const TopoDS_Edge& E1,
const TopoDS_Edge& E2,
TopTools_ListOfShape& LV1,
TopTools_ListOfShape& LV2,
Handle(BRepAlgo_AsDes) AsDes,
Standard_Real Tol)
static void Store (const TopoDS_Edge& E1,
const TopoDS_Edge& E2,
const TopTools_ListOfShape& LV1,
const TopTools_ListOfShape& LV2,
Handle(BRepAlgo_AsDes) AsDes,
Standard_Real Tol,
TopTools_IndexedDataMapOfShapeListOfShape& aDMVV)
{
//-------------------------------------------------------------
// Test if the points of intersection correspond to existing
// vertices. Otherwise add edges in the descendants.
// Note: at this stage only vertices of intersection are in the descendants.
//-------------------------------------------------------------
const TopTools_ListOfShape& VOnE1 = AsDes->Descendant(E1);
const TopTools_ListOfShape& VOnE2 = AsDes->Descendant(E2);
TopTools_ListOfShape NewVOnE1;
TopTools_ListOfShape NewVOnE2;
gp_Pnt P,P1,P2;
TopoDS_Vertex V1,V2;
TopTools_ListIteratorOfListOfShape it, itLV1, itLV2;
BRep_Builder B;
TopAbs_Orientation O1,O2;
Standard_Real U1,U2;
Standard_Boolean OnE1,OnE2;
for (itLV1.Initialize(LV1),itLV2.Initialize(LV2);
itLV1.More();
itLV1.Next() ,itLV2.Next()) {
TopoDS_Vertex V = TopoDS::Vertex(itLV1.Value());
U1 = (BRep_Tool::Degenerated(E1))?
BRep_Tool::Parameter(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), E1) :
BRep_Tool::Parameter(V, E1);
U2 = (BRep_Tool::Degenerated(E2))?
BRep_Tool::Parameter(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), E2) :
BRep_Tool::Parameter(V, E2);
O1 = V.Orientation();
O2 = itLV2.Value().Orientation();
P = BRep_Tool::Pnt(V);
OnE1 = OnE2 = Standard_False;
if (!VOnE1.IsEmpty()) {
//-----------------------------------------------------------------
// Find if the point of intersection corresponds to a vertex of E1.
//-----------------------------------------------------------------
for (it.Initialize(VOnE1); it.More(); it.Next()) {
P1 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
if (P.IsEqual(P1,Tol)) {
V = TopoDS::Vertex(it.Value());
V1 = V;
OnE1 = Standard_True;
BRep_Builder aBB;
for (Standard_Integer i = 0; i < 2; ++i) {
const TopoDS_Edge& aE = !i ? E1 : E2;
const TopTools_ListOfShape& aLV = !i ? LV1 : LV2;
const TopTools_ListOfShape& aLVEx = AsDes->Descendant(aE);
if (aLVEx.IsEmpty()) {
if (aLV.Extent()) AsDes->Add(aE, aLV);
continue;
}
//
TopTools_MapOfShape aMV;
TopTools_ListIteratorOfListOfShape aIt(aLV);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Vertex& aV = TopoDS::Vertex(aIt.Value());
if (!aMV.Add(aV)) {
continue;
}
gp_Pnt aP = BRep_Tool::Pnt(aV);
//
TopTools_ListOfShape aLVC;
TopTools_ListIteratorOfListOfShape aItEx(aLVEx);
for (; aItEx.More(); aItEx.Next()) {
const TopoDS_Vertex& aVEx = TopoDS::Vertex(aItEx.Value());
if (aV.IsSame(aVEx)) {
break;
}
gp_Pnt aPEx = BRep_Tool::Pnt(aVEx);
//
if (aP.IsEqual(aPEx, Tol)) {
aLVC.Append(aVEx);
}
}
}
if (!VOnE2.IsEmpty()) {
if (OnE1) {
//-----------------------------------------------------------------
// Find if the vertex found on E1 is not already on E2.
//-----------------------------------------------------------------
for (it.Initialize(VOnE2); it.More(); it.Next()) {
if (it.Value().IsSame(V)) {
OnE2 = Standard_True;
V2 = V;
break;
//
if (aItEx.More()) {
continue;
}
//
if (aLVC.Extent()) {
TopTools_ListOfShape aLVN;
aLVN.Append(aV);
//
TopTools_ListIteratorOfListOfShape aItLV(aLVC);
for (; aItLV.More(); aItLV.Next()) {
const TopoDS_Shape& aVC = aItLV.Value();
TopTools_ListOfShape* pLV = aDMVV.ChangeSeek(aVC);
if (!pLV) {
aDMVV.Add(aVC, aLVN);
}
else {
pLV->Append(aV);
}
}
}
for (it.Initialize(VOnE2); it.More(); it.Next()) {
//-----------------------------------------------------------------
// Find if the point of intersection corresponds to a vertex of E2.
//-----------------------------------------------------------------
P2 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
if (P.IsEqual(P2,Tol)) {
V = TopoDS::Vertex(it.Value());
V2 = V;
OnE2 = Standard_True;
break;
//
TopTools_ListOfShape* pLV = aDMVV.ChangeSeek(aV);
if (!pLV) {
aDMVV.Add(aV, aLVC);
}
}
}
if (OnE1 && OnE2) {
if (!V1.IsSame(V2)) {
//---------------------------------------------------------------
// Two vertices are actually the same.
// V2 will be replaced by V1.
// update the parameters of vertex on edges.
//---------------------------------------------------------------
Standard_Real UV2;
TopoDS_Edge EWE2;
const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
for (it.Initialize(EdgeWithV2); it.More(); it.Next()) {
EWE2 = TopoDS::Edge(it.Value());
TopoDS_Shape aLocalShape =V2.Oriented(TopAbs_INTERNAL);
UV2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
// UV2 =
// BRep_Tool::Parameter(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),EWE2);
aLocalShape = V1.Oriented(TopAbs_INTERNAL);
B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
// UV2,EWE2,Tol);
else {
pLV->Append(aLVC);
}
AsDes->Replace(V2,V1);
}
//
aBB.UpdateVertex(aV, Tol);
AsDes->Add(aE, aV);
}
if (!OnE1) {
if (OnE2) {
TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
// U1,E1,Tol);
}
NewVOnE1.Append(V.Oriented(O1));
}
if (!OnE2) {
if (OnE1) {
TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
// U2,E2,Tol);
}
NewVOnE2.Append(V.Oriented(O2));
}
#ifdef DRAW
if (Inter2dAffichInt2d) {
if (!OnE1 && !OnE2) {
char name[256];
sprintf(name,"VV_%d",NbNewVertices++);
DBRep::Set(name,V);
}
}
#endif
}
if (!NewVOnE1.IsEmpty()) AsDes->Add(E1,NewVOnE1);
if (!NewVOnE2.IsEmpty()) AsDes->Add(E2,NewVOnE2);
}
//=======================================================================
//function : EdgeInter
//purpose :
@ -272,7 +207,8 @@ static void EdgeInter(const TopoDS_Face& F,
const TopoDS_Edge& E2,
const Handle(BRepAlgo_AsDes)& AsDes,
Standard_Real Tol,
Standard_Boolean WithOri)
Standard_Boolean WithOri,
TopTools_IndexedDataMapOfShapeListOfShape& aDMVV)
{
#ifdef DRAW
if (Inter2dAffichInt2d) {
@ -444,32 +380,26 @@ static void EdgeInter(const TopoDS_Face& F,
if (V1[j].IsNull()) continue;
for (Standard_Integer k = 0; k < 2; k++) {
if (V2[k].IsNull()) continue;
if (V1[j].IsSame(V2[k])) {
if (AsDes->HasAscendant(V1[j])) {
continue;
}
}
//
gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
Standard_Real Dist = P1.Distance(P2);
if (Dist < TolConf) {
Standard_Real aTol =
Max(BRep_Tool::Tolerance(V1[j]), BRep_Tool::Tolerance(V2[k]));
TopoDS_Vertex V = BRepLib_MakeVertex(P1);
U1 = (j == 0) ? f[1] : l[1];
U2 = (k == 0) ? f[2] : l[2];
//
TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
// Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 Begin
Standard_Real aTol = BRep_Tool::Tolerance(V1[j]);
if (!V1[j].IsSame(V2[k])) {
Standard_Real aTol2 = BRep_Tool::Tolerance(V2[k]);
aTol = Max(aTol, aTol2);
}
B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,aTol);
B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,aTol);
// B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
// B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
// U1,E1,Tol);
// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
// U2,E2,Tol);
// Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 End
//
LV1.Prepend(V.Oriented(V1[j].Orientation()));
LV2.Prepend(V.Oriented(V2[k].Orientation()));
}
@ -521,15 +451,9 @@ static void EdgeInter(const TopoDS_Face& F,
//---------------------------------
// Vertex storage in DS.
//---------------------------------
// Modified by skv - Tue Jan 13 15:14:30 2004 Begin
Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
TolStore = Max(TolStore, 10.*Tol);
Store (E1,E2,LV1,LV2,AsDes,TolStore);
// Store (E1,E2,LV1,LV2,AsDes,10.*Tol);
// Store (E1,E2,LV1,LV2,AsDes,Tol);
// Modified by skv - Tue Jan 13 15:14:30 2004 End
Store (E1,E2,LV1,LV2,AsDes,TolStore, aDMVV);
}
}
//=======================================================================
@ -544,7 +468,8 @@ static void RefEdgeInter(const TopoDS_Face& F,
const Handle(BRepAlgo_AsDes)& AsDes,
Standard_Real Tol,
Standard_Boolean WithOri,
gp_Pnt& Pref)
gp_Pnt& Pref,
TopTools_IndexedDataMapOfShapeListOfShape& aDMVV)
{
#ifdef DRAW
if (Inter2dAffichInt2d) {
@ -712,6 +637,12 @@ static void RefEdgeInter(const TopoDS_Face& F,
if (V1[j].IsNull()) continue;
for (Standard_Integer k = 0; k < 2; k++) {
if (V2[k].IsNull()) continue;
if (V1[j].IsSame(V2[k])) {
if (AsDes->HasAscendant(V1[j])) {
continue;
}
}
//
gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
Standard_Real Dist = P1.Distance(P2);
@ -722,10 +653,6 @@ static void RefEdgeInter(const TopoDS_Face& F,
TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
// U1,E1,Tol);
// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
// U2,E2,Tol);
LV1.Prepend(V.Oriented(V1[j].Orientation()));
LV2.Prepend(V.Oriented(V2[k].Orientation()));
}
@ -794,16 +721,9 @@ static void RefEdgeInter(const TopoDS_Face& F,
}
////-----------------------------------------------------
// Modified by skv - Tue Jan 13 15:14:30 2004 Begin
Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
TolStore = Max(TolStore, 10.*Tol);
Store (E1,E2,LV1,LV2,AsDes,TolStore);
// Store (E1,E2,LV1,LV2,AsDes,10.*Tol);
// Store (E1,E2,LV1,LV2,AsDes,Tol);
// Modified by skv - Tue Jan 13 15:14:30 2004 End
Store (E1,E2,LV1,LV2,AsDes,TolStore, aDMVV);
}
}
@ -1403,7 +1323,8 @@ static Standard_Boolean UpdateVertex(TopoDS_Vertex V,
void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)& AsDes,
const TopoDS_Face& F,
const TopTools_IndexedMapOfShape& NewEdges,
const Standard_Real Tol)
const Standard_Real Tol,
TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
{
#ifdef DRAW
NbF2d++;
@ -1445,7 +1366,7 @@ void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)& AsDes,
if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) &&
(NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) {
TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD);
EdgeInter(TopoDS::Face(aLocalShape),BAsurf,E1,E2,AsDes,Tol,Standard_True);
EdgeInter(TopoDS::Face(aLocalShape),BAsurf,E1,E2,AsDes,Tol,Standard_True, theDMVV);
// EdgeInter(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),E1,E2,AsDes,Tol,Standard_True);
}
it2LE.Next();
@ -1470,7 +1391,8 @@ void BRepOffset_Inter2d::ConnexIntByInt
const Handle(BRepAlgo_AsDes)& AsDes,
const Handle(BRepAlgo_AsDes)& AsDes2d,
const Standard_Real Offset,
const Standard_Real Tol)
const Standard_Real Tol,
TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
// Modified by skv - Fri Dec 26 16:53:18 2003 OCC4455 End
{
@ -1584,7 +1506,7 @@ void BRepOffset_Inter2d::ConnexIntByInt
for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
for (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) {
RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),TopoDS::Edge(Exp2.Current()),
AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
AsDes2d,Tol,Standard_True/*Standard_False*/, Pref, theDMVV);
}
}
//
@ -1599,12 +1521,12 @@ void BRepOffset_Inter2d::ConnexIntByInt
//
for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3,
AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
AsDes2d,Tol,Standard_True/*Standard_False*/, Pref, theDMVV);
}
//
for (Exp1.Init(NE2,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3,
AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
AsDes2d,Tol,Standard_True/*Standard_False*/, Pref, theDMVV);
}
}
}
@ -1625,3 +1547,71 @@ void BRepOffset_Inter2d::ConnexIntByInt
}
}
}
//=======================================================================
//function : MakeChain
//purpose :
//=======================================================================
static void MakeChain(const TopoDS_Shape& theV,
const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
TopTools_MapOfShape& theMDone,
BOPCol_ListOfShape& theChain)
{
if (theMDone.Add(theV)) {
theChain.Append(theV);
const TopTools_ListOfShape* pLV = theDMVV.Seek(theV);
if (pLV) {
TopTools_ListIteratorOfListOfShape aIt(*pLV);
for (; aIt.More(); aIt.Next()) {
MakeChain(aIt.Value(), theDMVV, theMDone, theChain);
}
}
}
}
//=======================================================================
//function : FuseVertices
//purpose :
//=======================================================================
void BRepOffset_Inter2d::FuseVertices(const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
const Handle(BRepAlgo_AsDes)& theAsDes)
{
BRep_Builder aBB;
TopTools_MapOfShape aMVDone;
Standard_Integer i, aNb = theDMVV.Extent();
for (i = 1; i <= aNb; ++i) {
const TopoDS_Vertex& aV = TopoDS::Vertex(theDMVV.FindKey(i));
//
// find chain of vertices
BOPCol_ListOfShape aLVChain;
MakeChain(aV, theDMVV, aMVDone, aLVChain);
//
if (aLVChain.Extent() < 2) {
continue;
}
//
// make new vertex
TopoDS_Vertex aVNew;
BOPTools_AlgoTools::MakeVertex(aLVChain, aVNew);
//
TopoDS_Vertex aVNewInt = TopoDS::Vertex(aVNew.Oriented(TopAbs_INTERNAL));
//
BOPCol_ListIteratorOfListOfShape aIt(aLVChain);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aVOld = aIt.Value();
// update the parameters on edges
TopoDS_Vertex aVOldInt = TopoDS::Vertex(aVOld.Oriented(TopAbs_INTERNAL));
const TopTools_ListOfShape& aLE = theAsDes->Ascendant(aVOld);
//
TopTools_ListIteratorOfListOfShape aItLE(aLE);
for (; aItLE.More(); aItLE.Next()) {
const TopoDS_Edge& aE = TopoDS::Edge(aItLE.Value());
Standard_Real aTolE = BRep_Tool::Tolerance(aE);
Standard_Real aT = BRep_Tool::Parameter(aVOldInt, aE);
aBB.UpdateVertex(aVNewInt, aT, aE, aTolE);
}
// and replace the vertex
theAsDes->Replace(aVOld, aVNew);
}
}
}

View File

@ -24,6 +24,7 @@
#include <TopTools_IndexedMapOfShape.hxx>
#include <Standard_Real.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
class BRepAlgo_AsDes;
class TopoDS_Face;
class BRepOffset_Offset;
@ -41,11 +42,21 @@ public:
//! Computes the intersections between the edges stored
//! is AsDes as descendants of <F> . Intersections is computed
//! between two edges if one of them is bound in NewEdges.
//! When all faces of the shape are treated the intersection
//! vertices have to be fused using the FuseVertices method.
//! theDMVV contains the vertices that should be fused
Standard_EXPORT static void Compute (const Handle(BRepAlgo_AsDes)& AsDes,
const TopoDS_Face& F,
const TopTools_IndexedMapOfShape& NewEdges,
const Standard_Real Tol);
const Standard_Real Tol,
TopTools_IndexedDataMapOfShapeListOfShape& theDMVV);
//! Computes the intersection between the offset edges
//! stored in AsDes as descendatnds on <F>. All intersection
//! vertices will be stored in AsDes2d. When all faces of the
//! shape are treated the intersection vertices have to be fused
//! using the FuseVertices method.
//! theDMVV contains the vertices that should be fused.
Standard_EXPORT static void ConnexIntByInt (const TopoDS_Face& FI,
BRepOffset_Offset& OFI,
TopTools_DataMapOfShapeShape& MES,
@ -53,10 +64,14 @@ public:
const Handle(BRepAlgo_AsDes)& AsDes,
const Handle(BRepAlgo_AsDes)& AsDes2d,
const Standard_Real Offset,
const Standard_Real Tol);
const Standard_Real Tol,
TopTools_IndexedDataMapOfShapeListOfShape& theDMVV);
//! Fuses the chains of vertices in the theDMVV
//! and updates AsDes by replacing the old vertices
//! with the new ones.
Standard_EXPORT static void FuseVertices(const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
const Handle(BRepAlgo_AsDes)& theAsDes);
protected:

View File

@ -1189,14 +1189,18 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
//---------------------------------------------------------------------------------
// Extension of neighbor edges of new edges and intersection between neighbors.
//--------------------------------------------------------------------------------
TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes();
for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next())
{
const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(FI);
BRepOffset_Inter2d::ConnexIntByInt (FI, MapSF(FI), MES, Build,
AsDes, AsDes2d, myOffset, aCurrFaceTol);
AsDes, AsDes2d, myOffset, aCurrFaceTol, aDMVV);
}
//
// fuse vertices on edges
BRepOffset_Inter2d::FuseVertices(aDMVV, AsDes2d);
//-----------------------------------------------------------
// Great restriction of new edges and update of AsDes.
//------------------------------------------ ----------------
@ -1326,12 +1330,13 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
}
}
aDMVV.Clear();
TopTools_ListIteratorOfListOfShape itLFE(LFE);
for (; itLFE.More(); itLFE.Next())
{
const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value());
Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(NEF);
BRepOffset_Inter2d::Compute(AsDes, NEF, NewEdges, aCurrFaceTol);
BRepOffset_Inter2d::Compute(AsDes, NEF, NewEdges, aCurrFaceTol, aDMVV);
}
//----------------------------------------------
// Intersections 2d on caps.
@ -1341,9 +1346,10 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
{
const TopoDS_Face& Cork = TopoDS::Face(myFaces(i));
Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(Cork);
BRepOffset_Inter2d::Compute(AsDes, Cork, NewEdges, aCurrFaceTol);
BRepOffset_Inter2d::Compute(AsDes, Cork, NewEdges, aCurrFaceTol, aDMVV);
}
//
BRepOffset_Inter2d::FuseVertices(aDMVV, AsDes);
//-------------------------------
// Unwinding of extended Faces.
//-------------------------------
@ -2909,12 +2915,15 @@ void BRepOffset_MakeOffset::Intersection2D(const TopTools_IndexedMapOfShape& Mod
//-----------------------------------------------
// Intersection of edges 2 by 2.
//-----------------------------------------------
TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
Standard_Integer i;
for (i = 1; i <= Modif.Extent(); i++) {
const TopoDS_Face& F = TopoDS::Face(Modif(i));
BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,myTol);
BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,myTol, aDMVV);
}
//
BRepOffset_Inter2d::FuseVertices(aDMVV, myAsDes);
//
#ifdef OCCT_DEBUG
if (AffichInt2d) {
DEBVerticesControl (NewEdges,myAsDes);

View File

@ -1726,7 +1726,7 @@ void BiTgte_Blend::ComputeCenters()
// -------------------------------------------------------------------
// Proceed with MakeLoops
TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
BRepOffset_Type OT = BRepOffset_Concave;
if (myRadius < 0.) OT = BRepOffset_Convex;
@ -1779,7 +1779,8 @@ void BiTgte_Blend::ComputeCenters()
BRepOffset_Inter2d::Compute(myAsDes,
CurOF,
myEdges,
myTol);
myTol,
aDMVV);
}
}
@ -1811,8 +1812,12 @@ void BiTgte_Blend::ComputeCenters()
BRepOffset_Inter2d::Compute(myAsDes,
CurOF,
myEdges,
myTol);
myTol,
aDMVV);
}
//
// fuse vertices on edges stored in AsDes
BRepOffset_Inter2d::FuseVertices(aDMVV, myAsDes);
// ------------
// unwinding
// ------------

View File

@ -584,6 +584,11 @@ static Standard_Integer nexplode(Draw_Interpretor& di,
typ = TopAbs_EDGE;
break;
case 'V' :
case 'v' :
typ = TopAbs_VERTEX;
break;
default :
return 1;
}
@ -604,20 +609,26 @@ static Standard_Integer nexplode(Draw_Interpretor& di,
}
Exp.Next();
}
//
TColStd_Array1OfInteger OrderInd(1,MaxShapes);
// gp_Pnt GPoint;
gp_Pnt GPoint;
GProp_GProps GPr;
// Standard_Integer InOfminX = 1,aTemp;
Standard_Integer aTemp;
TColStd_Array1OfReal MidXYZ(1,MaxShapes); //X,Y,Z;
Standard_Boolean NoSort = Standard_True;
// Computing of CentreOfMass
//
// Computing of CentreOfMass for edge and face
// and for vertex use its point
for (Index=1; Index <= MaxShapes; Index++) {
OrderInd.SetValue(Index,Index);
BRepGProp::LinearProperties(aShapes(Index),GPr);
gp_Pnt GPoint = GPr.CentreOfMass();
const TopoDS_Shape& aS = aShapes(Index);
if (aS.ShapeType() != TopAbs_VERTEX) {
BRepGProp::LinearProperties(aS, GPr);
GPoint = GPr.CentreOfMass();
}
else {
GPoint = BRep_Tool::Pnt(TopoDS::Vertex(aS));
}
MidXYZ.SetValue(Index, GPoint.X()*999 + GPoint.Y()*99 +
GPoint.Z()*0.9);
}
@ -1288,7 +1299,7 @@ void DBRep::BasicCommands(Draw_Interpretor& theCommands)
theCommands.Add("compound","compound [name1 name2 ..] compound",__FILE__,compound,g);
theCommands.Add("add","add name1 name2",__FILE__,add,g);
theCommands.Add("explode","explode name [Cd/C/So/Sh/F/W/E/V]",__FILE__,explode,g);
theCommands.Add("nexplode","stable numbered explode for edge and face: nexplode name [F/E]",__FILE__,nexplode,g);
theCommands.Add("nexplode","stable numbered explode for vertex, edge and face: nexplode name [V/E/F]",__FILE__,nexplode,g);
theCommands.Add("exwire","exwire wirename",__FILE__,exwire,g);
theCommands.Add("emptycopy","emptycopy [copyshape] originalshape",__FILE__,emptycopy,g);
theCommands.Add("check","check shape1 shape2 ...",__FILE__,check,g);

View File

@ -0,0 +1,67 @@
puts "=========================================================="
puts "0027540: Run-to-run differences in the 3D Offset algorithm"
puts "=========================================================="
puts ""
pload MODELING
restore [locate_data_file bug27540_shapes1.brep] s
explode s
# make offset operations on two shapes
# first shape
offsetparameter 1e-7 c i
# set offset 10 for top faces (normal direction 0 0 1), 0 for all other faces
offsetload s_1 0
set faces [explode s_1 f]
foreach f $faces {
mksurface surf $f
set found [regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
if {$found && abs($z - 1) < 1.e-7} {
offsetonface $f 10
}
}
offsetperform result1
checkprops result1 -s 3.26459e+006
checkprops result1 -v 1.067e+008
checknbshapes result1 -vertex 28 -edge 44 -wire 20 -face 19 -shell 1 -solid 1
# second shape
offsetparameter 1e-7 c i
# set offset 10 for top faces (normal direction 0 0 1), 0 for all other faces
offsetload s_2 0
set faces [explode s_2 f]
foreach f $faces {
mksurface surf $f
set found [regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
if {$found && abs($z - 1) < 1.e-7} {
offsetonface $f 10
}
}
offsetperform result2
checkprops result2 -s 3.26459e+006
checkprops result2 -v 1.067e+008
checknbshapes result2 -vertex 28 -edge 44 -wire 20 -face 19 -shell 1 -solid 1
# compare the results
set vertices1 [nexplode result1 v]
set vertices2 [nexplode result2 v]
set nbv1 [llength $vertices1]
for {set i 0} {$i < $nbv1} {incr i} {
set v1 [lindex $vertices1 $i]
set v2 [lindex $vertices2 $i]
mkpoint px $v1
set dump_v1 [dump px]
mkpoint px $v2
set dump_v2 [dump px]
if {$dump_v1 != $dump_v2} {
puts "Error: the results are not the same - $v1 and $v2"
}
}

View File

@ -0,0 +1,67 @@
puts "=========================================================="
puts "0027540: Run-to-run differences in the 3D Offset algorithm"
puts "=========================================================="
puts ""
pload MODELING
restore [locate_data_file bug27540_shapes2.brep] s
explode s
# make offset operations on two shapes
# first shape
offsetparameter 1e-7 c i
# set offset 30 for top faces (normal direction 0 0 1), 10 for all other faces
offsetload s_1 10
set faces [explode s_1 f]
foreach f $faces {
mksurface surf $f
set found [regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
if {$found && abs($z - 1) < 1.e-7} {
offsetonface $f 30
}
}
offsetperform result1
checkprops result1 -s 3.76166e+006
checkprops result1 -v 1.74521e+008
checknbshapes result1 -vertex 36 -edge 56 -wire 24 -face 23 -shell 1 -solid 1
# second shape
offsetparameter 1e-7 c i
# set offset 30 for top faces (normal direction 0 0 1), 10 for all other faces
offsetload s_2 10
set faces [explode s_2 f]
foreach f $faces {
mksurface surf $f
set found [regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
if {$found && abs($z - 1) < 1.e-7} {
offsetonface $f 30
}
}
offsetperform result2
checkprops result2 -s 3.76166e+006
checkprops result2 -v 1.74521e+008
checknbshapes result2 -vertex 36 -edge 56 -wire 24 -face 23 -shell 1 -solid 1
# compare the results
set vertices1 [nexplode result1 v]
set vertices2 [nexplode result2 v]
set nbv1 [llength $vertices1]
for {set i 0} {$i < $nbv1} {incr i} {
set v1 [lindex $vertices1 $i]
set v2 [lindex $vertices2 $i]
mkpoint px $v1
set dump_v1 [dump px]
mkpoint px $v2
set dump_v2 [dump px]
if {$dump_v1 != $dump_v2} {
puts "Error: the results are not the same - $v1 and $v2"
}
}

View File

@ -0,0 +1,67 @@
puts "=========================================================="
puts "0027540: Run-to-run differences in the 3D Offset algorithm"
puts "=========================================================="
puts ""
pload MODELING
restore [locate_data_file bug27540_shapes3.brep] s
explode s
# make offset operations on two shapes
# first shape
offsetparameter 1e-7 c i
# set offset 20 for top faces (normal direction 0 0 1), 0 for all other faces
offsetload s_1 0
set faces [explode s_1 f]
foreach f $faces {
mksurface surf $f
set found [regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
if {$found && abs($z - 1) < 1.e-7} {
offsetonface $f 20
}
}
offsetperform result1
checkprops result1 -s 464088
checkprops result1 -v 1.29909e+007
checknbshapes result1 -vertex 48 -edge 74 -wire 32 -face 30 -shell 1 -solid 1
# second shape
offsetparameter 1e-7 c i
# set offset 20 for top faces (normal direction 0 0 1), 0 for all other faces
offsetload s_2 0
set faces [explode s_2 f]
foreach f $faces {
mksurface surf $f
set found [regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
if {$found && abs($z - 1) < 1.e-7} {
offsetonface $f 20
}
}
offsetperform result2
checkprops result2 -s 464088
checkprops result2 -v 1.29909e+007
checknbshapes result2 -vertex 48 -edge 74 -wire 32 -face 30 -shell 1 -solid 1
# compare the results
set vertices1 [nexplode result1 v]
set vertices2 [nexplode result2 v]
set nbv1 [llength $vertices1]
for {set i 0} {$i < $nbv1} {incr i} {
set v1 [lindex $vertices1 $i]
set v2 [lindex $vertices2 $i]
mkpoint px $v1
set dump_v1 [dump px]
mkpoint px $v2
set dump_v2 [dump px]
if {$dump_v1 != $dump_v2} {
puts "Error: the results are not the same - $v1 and $v2"
}
}

View File

@ -1,7 +1,5 @@
puts "TODO ?OCC23068 ALL: ERROR. offsetperform operation not done."
puts "TODO ?OCC23068 ALL: Error: The command cannot be built"
puts "TODO ?OCC23068 ALL: result is not a topological shape!!!"
puts "TODO ?OCC23068 ALL: TEST INCOMPLETE"
puts "TODO ?OCC23068 ALL: Error : The volume of result shape "
## ======================================
## Grid : CCV002

View File

@ -1,5 +1,6 @@
puts "TODO OCC25406 ALL: Error : The volume of result shape is"
puts "TODO OCC25406 ALL: Faulty shapes in variables faulty_1 to"
puts "TODO OCC25406 Windows: Faulty shapes in variables faulty_1 to"
puts "TODO OCC25406 ALL: Error: bsection of the result and s is not equal to zero"
ellipse w1 0 0 0 15 10
mkedge w1 w1 0 pi/2

View File

@ -1,5 +1,6 @@
puts "TODO OCC23068 ALL: Error : The volume of result shape is"
puts "TODO OCC23068 ALL: Faulty shapes in variables faulty_1 to"
puts "TODO OCC23068 Windows: Faulty shapes in variables faulty_1 to"
puts "TODO OCC23068 ALL: Error: bsection of the result and s is not equal to zero"
ellipse w1 0 0 0 15 10
mkedge w1 w1 0 pi/2

View File

@ -1,5 +1,3 @@
puts "TODO OCC26577 All: Error : is WRONG because number of EDGE entities in shape"
puts "TODO OCC26577 All: Error : is WRONG because number of SHELL entities in shape"
restore [locate_data_file bug26663_test_offset_K2.brep] s
OFFSETSHAPE ${off_param} {} ${calcul} ${type}
checknbshapes result -ref [lrange [nbshapes s] 8 19]

View File

@ -1,4 +1,3 @@
puts "TODO OCC26577 All: Error : is WRONG because number of EDGE entities in shape"
puts "TODO OCC26577 All: Faulty shapes in variables faulty_1 to faulty"
restore [locate_data_file bug26663_test_offset_L3.brep] s
OFFSETSHAPE ${off_param} {} ${calcul} ${type}

View File

@ -1,5 +1,3 @@
puts "TODO OCC26577 All: Error : is WRONG because number of EDGE entities in shape"
puts "TODO OCC26577 All: Error : is WRONG because number of SHELL entities in shape"
restore [locate_data_file bug26663_test_offset_L7.brep] s
OFFSETSHAPE ${off_param} {} ${calcul} ${type}
checknbshapes result -ref [lrange [nbshapes s] 8 19]

View File

@ -1,4 +1,3 @@
puts "TODO OCC26577 All: Error : is WRONG because number of EDGE entities in shape"
puts "TODO OCC26577 All: Faulty shapes in variables faulty_1 to faulty"
restore [locate_data_file bug26663_test_offset_L9.brep] s
OFFSETSHAPE ${off_param} {} ${calcul} ${type}