1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-16 10:08:36 +03:00

0024495: Crash during performeng boolean operation on attached shape for Windows VC2010 64 bit

Recursion in the method Path in BOPAlgo_WireSplitter has been replaced with cycle.
This commit is contained in:
emv 2013-12-25 15:14:54 +04:00 committed by bugmaster
parent 6a866b3268
commit b7357c8b55

View File

@ -326,9 +326,9 @@ static
//======================================================================= //=======================================================================
void Path (const GeomAdaptor_Surface& aGAS, void Path (const GeomAdaptor_Surface& aGAS,
const TopoDS_Face& myFace, const TopoDS_Face& myFace,
const TopoDS_Vertex& aVa, const TopoDS_Vertex& aVFirst,
const TopoDS_Edge& aEOuta, const TopoDS_Edge& aEFirst,
BOPAlgo_EdgeInfo& anEdgeInfo, BOPAlgo_EdgeInfo& aEIFirst,
BOPCol_SequenceOfShape& aLS, BOPCol_SequenceOfShape& aLS,
BOPCol_SequenceOfShape& aVertVa, BOPCol_SequenceOfShape& aVertVa,
BOPCol_SequenceOfPnt2d& aCoordVa, BOPCol_SequenceOfPnt2d& aCoordVa,
@ -341,230 +341,235 @@ void Path (const GeomAdaptor_Surface& aGAS,
Standard_Real aTol2D, aTol2D2; Standard_Real aTol2D, aTol2D2;
Standard_Real aTol2, aD2, aTwoPI; Standard_Real aTol2, aD2, aTwoPI;
Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed; Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed;
TopoDS_Vertex aVb; TopoDS_Vertex aVa, aVb;
TopoDS_Edge aEOutb; TopoDS_Edge aEOuta;
BOPAlgo_ListIteratorOfListOfEdgeInfo anIt; BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
// //
aVa = aVFirst;
aEOuta = aEFirst;
BOPAlgo_EdgeInfo* anEdgeInfo = &aEIFirst;
//
aTwoPI = M_PI + M_PI; aTwoPI = M_PI + M_PI;
aTol=1.e-7; aTol=1.e-7;
// //
// append block // append block
// //
// Do not escape through edge from which you enter for (;;) {
aNb=aLS.Length(); // Do not escape through edge from which you enter
if (aNb==1) { aNb=aLS.Length();
const TopoDS_Shape& anEPrev=aLS(aNb); if (aNb==1) {
if (anEPrev.IsSame(aEOuta)) { const TopoDS_Shape& anEPrev=aLS(aNb);
return; if (anEPrev.IsSame(aEOuta)) {
return;
}
} }
}
//
anEdgeInfo.SetPassed(Standard_True);
aLS.Append(aEOuta);
aVertVa.Append(aVa);
TopoDS_Vertex pVa=aVa;
pVa.Orientation(TopAbs_FORWARD);
gp_Pnt2d aPa=Coord2d(pVa, aEOuta, myFace);
aCoordVa.Append(aPa);
GetNextVertex (pVa, aEOuta, aVb);
gp_Pnt2d aPb=Coord2d(aVb, aEOuta, myFace);
const BOPAlgo_ListOfEdgeInfo& aLEInfoVb=mySmartMap.FindFromKey(aVb);
//
aTol=2.*Tolerance2D(aVb, aGAS);
aTol2=10.*aTol*aTol;
TopoDS_Vertex aV1, aV2;
TopExp::Vertices(aEOuta, aV1, aV2);
Standard_Boolean bIsClosedEdge = aV1.IsNull() || aV2.IsNull() || aV1.IsSame(aV2);
Standard_Boolean bIsDegenerated = BRep_Tool::Degenerated(aEOuta);
Standard_Boolean bIsSeam = BRep_Tool::IsClosed(aEOuta, myFace);
anIt.Initialize(aLEInfoVb);
for (; anIt.More(); anIt.Next()) {
const BOPAlgo_EdgeInfo& anEI = anIt.Value();
const TopoDS_Edge& aE = anEI.Edge();
bIsDegenerated = bIsDegenerated || BRep_Tool::Degenerated(aE);
bIsSeam = bIsSeam || BRep_Tool::IsClosed(aE, myFace);
aV1.Nullify();
aV2.Nullify();
TopExp::Vertices(aE, aV1, aV2);
bIsClosedEdge = bIsClosedEdge || aV1.IsNull() || aV2.IsNull() || aV1.IsSame(aV2);
}
//
aNb=aLS.Length();
if (aNb>0) {
// //
BOPCol_ListOfShape aBuf; anEdgeInfo->SetPassed(Standard_True);
aLS.Append(aEOuta);
aVertVa.Append(aVa);
TopoDS_Vertex pVa=aVa;
pVa.Orientation(TopAbs_FORWARD);
gp_Pnt2d aPa=Coord2d(pVa, aEOuta, myFace);
aCoordVa.Append(aPa);
GetNextVertex (pVa, aEOuta, aVb);
gp_Pnt2d aPb=Coord2d(aVb, aEOuta, myFace);
const BOPAlgo_ListOfEdgeInfo& aLEInfoVb=mySmartMap.FindFromKey(aVb);
// //
for (i=aNb; i>0; --i) { aTol=2.*Tolerance2D(aVb, aGAS);
const TopoDS_Shape& aVPrev=aVertVa(i); aTol2=10.*aTol*aTol;
const gp_Pnt2d& aPaPrev=aCoordVa(i);
const TopoDS_Shape& aEPrev=aLS(i);
aBuf.Append(aEPrev); TopoDS_Vertex aV1, aV2;
TopExp::Vertices(aEOuta, aV1, aV2);
Standard_Boolean bIsClosedEdge = aV1.IsNull() || aV2.IsNull() || aV1.IsSame(aV2);
Standard_Boolean bIsDegenerated = BRep_Tool::Degenerated(aEOuta);
Standard_Boolean bIsSeam = BRep_Tool::IsClosed(aEOuta, myFace);
anIsSameV=aVPrev.IsSame(aVb); anIt.Initialize(aLEInfoVb);
anIsSameV2d=Standard_False; for (; anIt.More(); anIt.Next()) {
const BOPAlgo_EdgeInfo& anEI = anIt.Value();
if (anIsSameV) { const TopoDS_Edge& aE = anEI.Edge();
anIsSameV2d = Standard_True; bIsDegenerated = bIsDegenerated || BRep_Tool::Degenerated(aE);
// bIsSeam = bIsSeam || BRep_Tool::IsClosed(aE, myFace);
aD2=aPaPrev.SquareDistance(aPb); aV1.Nullify();
anIsSameV2d =aD2<aTol2; aV2.Nullify();
if(anIsSameV2d && TopExp::Vertices(aE, aV1, aV2);
(bIsDegenerated || bIsSeam || bIsClosedEdge)) { bIsClosedEdge = bIsClosedEdge || aV1.IsNull() || aV2.IsNull() || aV1.IsSame(aV2);
Standard_Real udist = fabs(aPaPrev.X() - aPb.X()); }
Standard_Real vdist = fabs(aPaPrev.Y() - aPb.Y()); //
Standard_Real aTolU = 2. * UTolerance2D(aVb, aGAS); aNb=aLS.Length();
Standard_Real aTolV = 2. * VTolerance2D(aVb, aGAS); if (aNb>0) {
//
if((udist > aTolU) ||
(vdist > aTolV)) {
anIsSameV2d = Standard_False;
}
}
}//if (anIsSameV) {
// //
if (anIsSameV && anIsSameV2d) { BOPCol_ListOfShape aBuf;
Standard_Integer iPriz; //
iPriz=1; for (i=aNb; i>0; --i) {
if (aBuf.Extent()==2) { const TopoDS_Shape& aVPrev=aVertVa(i);
if(aBuf.First().IsSame(aBuf.Last())) { const gp_Pnt2d& aPaPrev=aCoordVa(i);
iPriz=0; const TopoDS_Shape& aEPrev=aLS(i);
aBuf.Append(aEPrev);
anIsSameV=aVPrev.IsSame(aVb);
anIsSameV2d=Standard_False;
if (anIsSameV) {
anIsSameV2d = Standard_True;
//
aD2=aPaPrev.SquareDistance(aPb);
anIsSameV2d =aD2<aTol2;
if(anIsSameV2d &&
(bIsDegenerated || bIsSeam || bIsClosedEdge)) {
Standard_Real udist = fabs(aPaPrev.X() - aPb.X());
Standard_Real vdist = fabs(aPaPrev.Y() - aPb.Y());
Standard_Real aTolU = 2. * UTolerance2D(aVb, aGAS);
Standard_Real aTolV = 2. * VTolerance2D(aVb, aGAS);
//
if((udist > aTolU) ||
(vdist > aTolV)) {
anIsSameV2d = Standard_False;
}
} }
} }//if (anIsSameV) {
if (iPriz) {
TopoDS_Wire aW;
BOPAlgo_WireSplitter::MakeWire(aBuf, aW);
aCB.ChangeLoops().Append(aW);
}
// //
aNbj=i-1; if (anIsSameV && anIsSameV2d) {
if (aNbj<1) { Standard_Integer iPriz;
iPriz=1;
if (aBuf.Extent()==2) {
if(aBuf.First().IsSame(aBuf.Last())) {
iPriz=0;
}
}
if (iPriz) {
TopoDS_Wire aW;
BOPAlgo_WireSplitter::MakeWire(aBuf, aW);
aCB.ChangeLoops().Append(aW);
}
//
aNbj=i-1;
if (aNbj<1) {
//
aLS.Clear();
aVertVa.Clear();
aCoordVa.Clear();
//
return;
}
//
BOPCol_SequenceOfShape aLSt, aVertVat;
BOPCol_SequenceOfPnt2d aCoordVat;
//
aVb=(*(TopoDS_Vertex *)(&aVertVa(i)));
//
for (j=1; j<=aNbj; ++j) {
aLSt.Append(aLS(j));
aVertVat.Append(aVertVa(j));
aCoordVat.Append(aCoordVa(j));
}
// //
aLS.Clear(); aLS.Clear();
aVertVa.Clear(); aVertVa.Clear();
aCoordVa.Clear(); aCoordVa.Clear();
aLS=aLSt;
aVertVa=aVertVat;
aCoordVa=aCoordVat;
// //
break;
}
}
}
//
aTol2D=2.*Tolerance2D(aVb, aGAS);
aTol2D2=1000.*aTol2D*aTol2D;//100.*aTol2D*aTol2D;
//
// anAngleIn in Vb from edge aEOuta
const BOPAlgo_ListOfEdgeInfo& aLEInfo=mySmartMap.FindFromKey(aVb);
//
anAngleIn=AngleIn(aEOuta, aLEInfo);
BOPCol_SequenceOfReal aRecomputedAngles;
Standard_Boolean bRecomputeAngle =
RecomputeAngles(aLEInfo, myFace, aPb, aVb, aGAS, aEOuta,
(bIsDegenerated || bIsSeam || bIsClosedEdge),
aTol2D, aRecomputedAngles);
//
// aEOutb
BOPAlgo_EdgeInfo *pEdgeInfo=NULL;
//
aMinAngle=100.;
anIsFound=Standard_False;
Standard_Integer aCurIndexE = 0;
anIt.Initialize(aLEInfo);
for (; anIt.More(); anIt.Next()) {
BOPAlgo_EdgeInfo& anEI=anIt.ChangeValue();
const TopoDS_Edge& aE=anEI.Edge();
anIsOut=!anEI.IsIn();
anIsNotPassed=!anEI.Passed();
if (anIsOut && anIsNotPassed) {
aCurIndexE++;
//
// Is there one way to go out of the vertex
// we have to use it only.
Standard_Integer iCnt;
iCnt=NbWaysOut (aLEInfo);
//
if (!iCnt) {
// no way to go . (Error)
return; return;
} }
// //
BOPCol_SequenceOfShape aLSt, aVertVat; if (iCnt==1) {
BOPCol_SequenceOfPnt2d aCoordVat; // the one and only way to go out .
// pEdgeInfo=&anEI;
aVb=(*(TopoDS_Vertex *)(&aVertVa(i))); anIsFound=Standard_True;
// break;
for (j=1; j<=aNbj; ++j) {
aLSt.Append(aLS(j));
aVertVat.Append(aVertVa(j));
aCoordVat.Append(aCoordVa(j));
} }
// //
aLS.Clear(); if (aE.IsSame(aEOuta)) {
aVertVa.Clear(); anAngle = aTwoPI;
aCoordVa.Clear(); } else {
// Look for minimal angle and make the choice.
aLS=aLSt; gp_Pnt2d aP2Dx;
aVertVa=aVertVat; //
aCoordVa=aCoordVat; aP2Dx=Coord2dVf(aE, myFace);
// //
break; aD2=aP2Dx.SquareDistance(aPb);
} if (aD2 > aTol2D2){
} continue;
}
//
aTol2D=2.*Tolerance2D(aVb, aGAS);
aTol2D2=1000.*aTol2D*aTol2D;//100.*aTol2D*aTol2D;
//
// anAngleIn in Vb from edge aEOuta
const BOPAlgo_ListOfEdgeInfo& aLEInfo=mySmartMap.FindFromKey(aVb);
//
anAngleIn=AngleIn(aEOuta, aLEInfo);
BOPCol_SequenceOfReal aRecomputedAngles;
Standard_Boolean bRecomputeAngle =
RecomputeAngles(aLEInfo, myFace, aPb, aVb, aGAS, aEOuta,
(bIsDegenerated || bIsSeam || bIsClosedEdge),
aTol2D, aRecomputedAngles);
//
// aEOutb
BOPAlgo_EdgeInfo *pEdgeInfo=NULL;
//
aMinAngle=100.;
anIsFound=Standard_False;
Standard_Integer aCurIndexE = 0;
anIt.Initialize(aLEInfo);
for (; anIt.More(); anIt.Next()) {
BOPAlgo_EdgeInfo& anEI=anIt.ChangeValue();
const TopoDS_Edge& aE=anEI.Edge();
anIsOut=!anEI.IsIn();
anIsNotPassed=!anEI.Passed();
if (anIsOut && anIsNotPassed) {
aCurIndexE++;
//
// Is there one way to go out of the vertex
// we have to use it only.
Standard_Integer iCnt;
iCnt=NbWaysOut (aLEInfo);
//
if (!iCnt) {
// no way to go . (Error)
return ;
}
//
if (iCnt==1) {
// the one and only way to go out .
pEdgeInfo=&anEI;
anIsFound=Standard_True;
break;
}
//
if (aE.IsSame(aEOuta)) {
anAngle = aTwoPI;
} else {
// Look for minimal angle and make the choice.
gp_Pnt2d aP2Dx;
//
aP2Dx=Coord2dVf(aE, myFace);
//
aD2=aP2Dx.SquareDistance(aPb);
if (aD2 > aTol2D2){
continue;
}
//
//
anAngleOut=anEI.Angle();
//
if(bRecomputeAngle) {
if(aCurIndexE <= aRecomputedAngles.Length()) {
anAngleOut = aRecomputedAngles.Value(aCurIndexE);
} }
//
//
anAngleOut=anEI.Angle();
//
if(bRecomputeAngle) {
if(aCurIndexE <= aRecomputedAngles.Length()) {
anAngleOut = aRecomputedAngles.Value(aCurIndexE);
}
}
anAngle=ClockWiseAngle(anAngleIn, anAngleOut);
}
if (anAngle < aMinAngle) {
aMinAngle=anAngle;
pEdgeInfo=&anEI;
anIsFound=Standard_True;
} }
anAngle=ClockWiseAngle(anAngleIn, anAngleOut);
}
if (anAngle < aMinAngle) {
aMinAngle=anAngle;
pEdgeInfo=&anEI;
anIsFound=Standard_True;
} }
} // for (; anIt.More(); anIt.Next())
//
if (!anIsFound) {
// no way to go . (Error)
return;
} }
} // for (; anIt.More(); anIt.Next()) //
// aVa = aVb;
if (!anIsFound) { aEOuta = pEdgeInfo->Edge();
// no way to go . (Error) anEdgeInfo = pEdgeInfo;
return;
} }
aEOutb=pEdgeInfo->Edge();
//
Path (aGAS, myFace, aVb, aEOutb, *pEdgeInfo, aLS,
aVertVa, aCoordVa, aCB, mySmartMap);
} }
//======================================================================= //=======================================================================
// function: ClockWiseAngle // function: ClockWiseAngle
@ -736,7 +741,7 @@ Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo)
} }
// //
BOPTools_AlgoTools2D::CurveOnSurface (anEdge, myFace, aC2D, BOPTools_AlgoTools2D::CurveOnSurface (anEdge, myFace, aC2D,
aFirst, aLast, aToler); aFirst, aLast, aToler);
dt=2.*Tolerance2D(aV, aGAS); dt=2.*Tolerance2D(aV, aGAS);
// //
//for case chl/927/r9 //for case chl/927/r9