1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Compare commits

...

1 Commits

Author SHA1 Message Date
nbv
4fd471ed41 0029144: BOP PaveFiller hangs in some case
1. Method IntWalk_PWalking::ExtendLineInCommonZone(...) now is not called if the already found intersection point is on surface boundary.
As result, the intersection line going along any boundary will never be extended. It is appropriate for high-level OCCT-algorithm because they will take the boundary (not computed line) as intersection result.

2. Method IntTools_BeanFaceIntersector::ComputeRangeFromStartPoint(...) has been corrected in order to avoid infinite loop described in the issue. The algorithm of obtaining the neighborhood of the intersection point has been improved.

3. Now, IsInside(...) static function (see BOPAlgo_BuilderFace.cxx file) does not need a 2D-curve for classified edge on the face. It allows avoiding exceptions in cases when the curve creation is impossible.

4. Post-processing has been added to join several common blocks to one. Method BOPDS_DS::RemoveCommonBlock(...) has been added in order to avoid duplication after joining.
2017-10-10 11:53:01 +03:00
13 changed files with 306 additions and 43 deletions

View File

@@ -810,7 +810,6 @@ Standard_Boolean IsInside(const TopoDS_Shape& theHole,
Handle(IntTools_Context)& theContext)
{
Standard_Boolean bRet;
Standard_Real aT, aU, aV;
TopAbs_State aState;
TopExp_Explorer aExp;
@@ -824,20 +823,19 @@ Standard_Boolean IsInside(const TopoDS_Shape& theHole,
BOPTools::MapShapes(aF2, TopAbs_EDGE, aME2);//AA
//
aExp.Init(theHole, TopAbs_EDGE);
if (aExp.More()) {
const TopoDS_Edge& aE =(*(TopoDS_Edge *)(&aExp.Current()));
if (aME2.Contains(aE)) {
if (aExp.More())
{
const TopoDS_Edge& aE = (*(TopoDS_Edge *) (&aExp.Current()));
if (aME2.Contains(aE))
{
return bRet;
}
if (!BRep_Tool::Degenerated(aE)) {
if (!BRep_Tool::Degenerated(aE))
{
//
aT=BOPTools_AlgoTools2D::IntermediatePoint(aE);
BOPTools_AlgoTools2D::PointOnSurface(aE, aF2, aT, aU, aV, theContext);
aP2D.SetCoord(aU, aV);
//
IntTools_FClass2d& aClsf=theContext->FClass2d(aF2);
aState=aClsf.Perform(aP2D);
bRet=(aState==TopAbs_IN);
gp_Pnt aP3D;
BOPTools_AlgoTools::PointOnEdge(aE, BOPTools_AlgoTools2D::IntermediatePoint(aE), aP3D);
bRet = theContext->IsPointInFace(aP3D, aF2, BRep_Tool::Tolerance(aE));
}
}
//

View File

@@ -30,6 +30,7 @@
#include <BOPAlgo_Algo.hxx>
#include <BOPCol_BaseAllocator.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopTools_DataMapOfShapeListOfShape.hxx>
#include <Standard_Integer.hxx>
#include <BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks.hxx>
#include <Standard_Boolean.hxx>
@@ -493,7 +494,8 @@ protected:
Standard_Boolean myIsPrimary;
Standard_Boolean myAvoidBuildPCurve;
BOPAlgo_GlueEnum myGlue;
TopTools_DataMapOfShapeListOfShape myMapOfErigins;
NCollection_DataMap<Standard_Integer, NCollection_List<Handle(BOPDS_PaveBlock)>> myMapICB;
private:

View File

@@ -680,6 +680,42 @@ void BOPAlgo_PaveFiller::MakeBlocks()
// into all faces, not participated in creation of that edge, as IN edge
PutSEInOtherFaces();
//
{
NCollection_DataMap<TopoDS_Edge, Handle(BOPDS_CommonBlock)> aMapEC;
BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
Standard_Integer aNbPBP = aPBP.Extent();
//
for (i = 0; i < aNbPBP; ++i)
{
BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
BOPDS_ListIteratorOfListOfPaveBlock aItPB;
aItPB.Initialize(aLPB);
for (; aItPB.More(); aItPB.Next())
{
const Handle(BOPDS_PaveBlock) &aPB = aItPB.Value();
if (!myDS->IsCommonBlock(aPB))
continue;
const Standard_Integer anEIdx = aPB->Edge();
const TopoDS_Edge &anE = TopoDS::Edge(myDS->Shape(anEIdx));
Handle(BOPDS_CommonBlock) *aCB = aMapEC.ChangeSeek(anE);
if (!aCB)
{
aCB = aMapEC.Bound(anE, myDS->CommonBlock(aPB));
continue;
}
myDS->RemoveCommonBlock(aPB);
(*aCB)->AddPaveBlock(aPB);
myDS->SetCommonBlock(aPB, *aCB);
}
}
}
//-----------------------------------------------------scope t
aMVStick.Clear();
aMPBOnIn.Clear();
@@ -1042,22 +1078,11 @@ void BOPAlgo_PaveFiller::PostTreatFF
iE=myDS->Append(aSI);
}
//
// update real edge tolerance according to distances in common block if any
if (aPDS->IsCommonBlock(aPBRx)) {
const Handle(BOPDS_CommonBlock)& aCB = aPDS->CommonBlock(aPBRx);
Standard_Real *pTol = aMCBTol.ChangeSeek(aCB);
if (!pTol) {
Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, aPDS, aPF.Context());
pTol = aMCBTol.Bound(aCB, aTol);
}
//
if (aNC.Tolerance() < *pTol) {
aNC.SetTolerance(*pTol);
}
}
// append new PaveBlock to aLPBC
Handle(BOPDS_PaveBlock) *pPBC = aMEPB.ChangeSeek(iE);
if (!pPBC) {
// append new PaveBlock to aLPBC
if (!pPBC)
{
pPBC = aMEPB.Bound(iE, new BOPDS_PaveBlock());
BOPDS_Pave aPaveR1, aPaveR2;
aPaveR1 = aPBRx->Pave1();
@@ -1070,13 +1095,44 @@ void BOPAlgo_PaveFiller::PostTreatFF
(*pPBC)->SetEdge(iE);
}
//
if (bOld) {
if (bOld)
{
(*pPBC)->SetOriginalEdge(aPB1->OriginalEdge());
aDMExEdges.ChangeFind(aPB1).Append(*pPBC);
}
else {
else
{
aLPBC.Append(*pPBC);
}
// update real edge tolerance according to distances in common block if any
if (aPDS->IsCommonBlock(aPBRx))
{
const Handle(BOPDS_CommonBlock)& aCB = aPDS->CommonBlock(aPBRx);
const Standard_Integer anIdxOriE = aPB1->OriginalEdge();
if (pPBC && (anIdxOriE > 0))
{
// If original edge exists
NCollection_List<Handle(BOPDS_PaveBlock)> *aListOfPB = myMapICB.ChangeSeek(iE);
if (aListOfPB == 0)
{
aListOfPB = myMapICB.Bound(iE, NCollection_List<Handle(BOPDS_PaveBlock)>());
}
aListOfPB->Append(*pPBC);
}
Standard_Real *pTol = aMCBTol.ChangeSeek(aCB);
if (!pTol) {
Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, aPDS, aPF.Context());
pTol = aMCBTol.Bound(aCB, aTol);
}
//
if (aNC.Tolerance() < *pTol) {
aNC.SetTolerance(*pTol);
}
}
}
}
}
@@ -2414,18 +2470,35 @@ void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
anEF.SetContext(myContext);
anEF.Perform();
//
const IntTools_SequenceOfCommonPrts& aCPrts=anEF.CommonParts();
if (aCPrts.Length() == 1) {
const IntTools_SequenceOfCommonPrts& aCPrts = anEF.CommonParts();
if (aCPrts.Length() == 1)
{
Standard_Boolean bCoinc = (aCPrts(1).Type() == TopAbs_EDGE);
if (bCoinc) {
if (bCB) {
if (bCoinc)
{
if (bCB)
{
aCB = myDS->CommonBlock(aPBChangeValue);
} else {
const NCollection_List<Handle(BOPDS_PaveBlock)> *aListOfPB = myMapICB.Seek(aPBChangeValue->Edge());
if (aListOfPB)
{
NCollection_List<Handle(BOPDS_PaveBlock)>::Iterator anItr(*aListOfPB);
for (; anItr.More(); anItr.Next())
{
Handle(BOPDS_PaveBlock) &aCurrPB = anItr.ChangeValue();
aCB->AddPaveBlock(aCurrPB);
myDS->SetCommonBlock(aCurrPB, aCB);
}
}
aCB->AddFace(nF);
}
else
{
aCB = new BOPDS_CommonBlock;
aCB->AddPaveBlock(aPBChangeValue);
aCB->AddFace(nF);
myDS->SetCommonBlock(aPBChangeValue, aCB);
}
aCB->AddFace(nF);
//
aMPBIn.Add(aPBChangeValue);
}

View File

@@ -691,12 +691,15 @@ void BOPAlgo_PaveFiller::MakePCurves()
Standard_Integer aNb = aVMPC.Extent();
for (i = 0; i < aNb; ++i)
{
if (aVMPC(i).HasErrors())
const TopoDS_Face& aF = TopoDS::Face(aVMPC(i).Face());
const TopoDS_Edge& aE = TopoDS::Edge(aVMPC(i).Edge());
if (!BOPTools_AlgoTools2D::HasCurveOnSurface(aE, aF) ||
aVMPC(i).HasErrors())
{
TopoDS_Compound aWC;
BRep_Builder().MakeCompound(aWC);
BRep_Builder().Add(aWC, aVMPC(i).Edge());
BRep_Builder().Add(aWC, aVMPC(i).Face());
BRep_Builder().Add(aWC, aE);
BRep_Builder().Add(aWC, aF);
AddWarning(new BOPAlgo_AlertBuildingPCurveFailed(aWC));
}
}

View File

@@ -1165,6 +1165,18 @@ void BOPDS_DS::SetCommonBlock(const Handle(BOPDS_PaveBlock)& thePB,
}
}
//=======================================================================
//function : RemoveCommonBlock
//purpose :
//=======================================================================
void BOPDS_DS::RemoveCommonBlock(const Handle(BOPDS_PaveBlock)& thePB)
{
//if (!IsCommonBlock(thePB))
// return;
myMapPBCB.UnBind(thePB);
}
//
// FaceInfo
//

View File

@@ -468,6 +468,10 @@ Standard_EXPORT virtual ~BOPDS_DS();
//! of the existing vertices have been increased.
Standard_EXPORT Standard_Boolean IsValidShrunkData(const Handle(BOPDS_PaveBlock)& thePB);
//! Removes the Common-block from the myMapPBCB map.
Standard_EXPORT void RemoveCommonBlock(const Handle(BOPDS_PaveBlock)& thePB);
protected:

View File

@@ -1657,6 +1657,10 @@ Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
}
}
//
if(aLCEFx.IsEmpty())
return Standard_False;
// F2
BOPTools_AlgoTools::GetFaceOff(aE1, aF1, aLCEFx, aF2, theContext);
//

View File

@@ -32,6 +32,8 @@
#include <gp.hxx>
#include <gp_Vec2d.hxx>
#include <Precision.hxx>
//======================================================================
#define EPSDIST Tol
#define EPSNUL TolConf
@@ -164,8 +166,15 @@ void IntImpParGen_Intersector::And_Domaine_Objet1_Intersections(const ImpTool& T
Resultat2.SetValue(NbResultats, Inter2_And_Domain2.Value(indice_2));
}
else { //====== la borne2 et la borne1 sont hors domaine =====
if (param1<TheImpCurveDomain.FirstParameter()
&& param2>TheImpCurveDomain.LastParameter()) {
const Standard_Real aParF = TheImpCurveDomain.HasFirstPoint() ?
TheImpCurveDomain.FirstParameter() :
-Precision::Infinite();
const Standard_Real aParL = TheImpCurveDomain.HasLastPoint() ?
TheImpCurveDomain.LastParameter() :
Precision::Infinite();
if (param1<aParF && param2>aParL)
{
Standard_Real t;
NbResultats++;
t = TheImpCurveDomain.FirstParameter();

View File

@@ -1337,14 +1337,16 @@ void IntTools_BeanFaceIntersector::ComputeRangeFromStartPoint(const Standard_Boo
if(BoundaryCondition && (isboundaryindex || !isvalidindex))
break;
}
else {
else
{
aDeltaRestrictor = aDelta;
}
// if point found decide to increase aDelta using derivative of distance function
//
aDelta = (pointfound) ? (aDelta * 2.) : (aDelta * 0.5);
// (aDelta*2) and (aDelta/(3/2)) to avoid infinite loop
aDelta = (pointfound) ? (aDelta * 2.0) : (aDelta * 0.6667);
aDelta = (aDelta < aDeltaRestrictor) ? aDelta : aDeltaRestrictor;
aCurPar = (ToIncreaseParameter) ? (aPrevPar + aDelta) : (aPrevPar - aDelta);

View File

@@ -1653,6 +1653,20 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso,
const Standard_Boolean theDirectionFlag)
{
// Caro1 and Caro2
const Handle(Adaptor3d_HSurface)& Caro1 = myIntersectionOn2S.Function().AuxillarSurface1();
const Handle(Adaptor3d_HSurface)& Caro2 = myIntersectionOn2S.Function().AuxillarSurface2();
//
const Standard_Real UFirst1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
const Standard_Real VFirst1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
const Standard_Real ULast1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1);
const Standard_Real VLast1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1);
const Standard_Real UFirst2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
const Standard_Real VFirst2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
const Standard_Real ULast2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2);
const Standard_Real VLast2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2);
Standard_Boolean bOutOfTangentZone = Standard_False;
Standard_Boolean bStop = !myIntersectionOn2S.IsTangent();
Standard_Integer dIncKey = 1;
@@ -1664,6 +1678,42 @@ Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsop
Standard_Integer uvit = 0;
IntSurf_SequenceOfPntOn2S aSeqOfNewPoint;
previousPoint.Parameters(Param(1), Param(2), Param(3), Param(4));
if (Param(1) - UFirst1 < ResoU1)
{
return bOutOfTangentZone;
}
else if (Param(2) - VFirst1 < ResoV1)
{
return bOutOfTangentZone;
}
else if (Param(3) - UFirst2 < ResoU2)
{
return bOutOfTangentZone;
}
else if (Param(4) - VFirst2 < ResoV2)
{
return bOutOfTangentZone;
}
if (Param(1) - ULast1 > -ResoU1)
{
return bOutOfTangentZone;
}
else if (Param(2) - VLast1 > -ResoV1)
{
return bOutOfTangentZone;
}
else if (Param(3) - ULast2 > -ResoU2)
{
return bOutOfTangentZone;
}
else if (Param(4) - VLast2 > -ResoV2)
{
return bOutOfTangentZone;
}
while (!bStop) {
nbIterWithoutAppend++;

View File

@@ -0,0 +1,42 @@
puts "========"
puts "OCC29093"
puts "========"
puts ""
#################################
# BOP PaveFiller hungs and constantly consumes memory
#################################
puts "TODO OCC28989 ALL : Error! Big tolerance value!"
puts "TODO OCC29145 ALL : Faulty shapes in variables faulty_1 to faulty_"
bclearobjects;
bcleartools;
restore [locate_data_file bug29093_hung.brep] a
explode a So
baddobjects a_1
baddtools a_2 a_3 a_4 a_5 a_6 a_7 a_8 a_9 a_10 a_11 a_12 a_13 a_14
dchrono cr restart
bfillds
bbuild result
dchrono cr stop counter bbuild
regexp {Tolerance +MAX=([-0-9.+eE]+)} [tolerance result] full MaxTol
# Maximal tolerance value must be updated after the fix.
# Current tolerance value is 803.89403359886296.
if {${MaxTol} > 1.0e-4} {
puts "Error! Big tolerance value!"
}
checkshape result
smallview
donly result
fit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,32 @@
puts "========"
puts "OCC29093"
puts "========"
puts ""
#################################
# BOP PaveFiller hungs and constantly consumes memory
#################################
puts "TODO OCC29145 ALL : Faulty shapes in variables faulty_1 to faulty_"
bclearobjects;
bcleartools;
restore [locate_data_file bug29093_hung2.brep] a
explode a So
baddobjects a_1
baddtools a_2 a_3 a_4 a_5 a_6 a_7 a_8 a_9 a_10 a_11 a_12 a_13 a_14
dchrono cr restart
bfillds
bbuild result
dchrono cr stop counter bbuild
checkshape result
smallview
donly result
fit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,32 @@
puts "========"
puts "OCC29093"
puts "========"
puts ""
#################################
# BOP PaveFiller hungs and constantly consumes memory
#################################
puts "TODO OCC29145 ALL : Faulty shapes in variables faulty_1 to faulty_"
bclearobjects;
bcleartools;
restore [locate_data_file bug29093_hung3.brep] a
explode a So
baddobjects a_1
baddtools a_2 a_3 a_4 a_5 a_6 a_7 a_8 a_9 a_10 a_11 a_12 a_13 a_14
dchrono cr restart
bfillds
bbuild result
dchrono cr stop counter bbuild
checkshape result
smallview
donly result
fit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png