mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-03 17:56:21 +03:00
0028102: Problem cutting a plate with several holes (670)
Algorithm of processing cases when point of splitting Walking-line is near to the boundary of the intersection domain but does not match this boundary has been improved.
This commit is contained in:
parent
93445088d8
commit
779d6bc6a5
@ -2415,6 +2415,109 @@ static Standard_Boolean SplitOnSegments(Handle(IntPatch_WLine)& WLine,
|
||||
return result;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsPointOnBoundary
|
||||
//purpose : Returns TRUE if point <theParam> matches <theBoundary +/- thePeriod>
|
||||
// with given tolerance criterion.
|
||||
// For not-periodic case, thePeriod must be equal to 0.0.
|
||||
//=======================================================================
|
||||
static Standard_Boolean IsPointOnBoundary(const Standard_Real theToler2D,
|
||||
const Standard_Real theBoundary,
|
||||
const Standard_Real thePeriod,
|
||||
const Standard_Real theParam)
|
||||
{
|
||||
Standard_Real aDelta = Abs(theParam - theBoundary);
|
||||
if (thePeriod != 0.0)
|
||||
{
|
||||
aDelta = fmod(aDelta, thePeriod);
|
||||
|
||||
// 0 <= aDelta < thePeriod
|
||||
return ((aDelta < theToler2D) || ((thePeriod - aDelta) < theToler2D));
|
||||
}
|
||||
|
||||
// Here, thePeriod == 0.0, aDelta > 0.0
|
||||
|
||||
return (aDelta < theToler2D);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DetectOfBoundaryAchievement
|
||||
//purpose : Can change values of theNewLine (by adding the computed point on boundary,
|
||||
// which parameter will be adjusted) and theIsOnBoundary variables.
|
||||
//=======================================================================
|
||||
static void DetectOfBoundaryAchievement(const Handle(Adaptor3d_HSurface)& theQSurf, // quadric
|
||||
const Standard_Boolean theIsReversed,
|
||||
const Handle(IntSurf_LineOn2S)& theSourceLine,
|
||||
const Standard_Integer thePointIndex,
|
||||
const Standard_Real theToler2D,
|
||||
Handle(IntSurf_LineOn2S)& theNewLine,
|
||||
Standard_Boolean& theIsOnBoundary)
|
||||
{
|
||||
const Standard_Real aUPeriod = theQSurf->IsUPeriodic() ? theQSurf->UPeriod() : 0.0,
|
||||
aVPeriod = theQSurf->IsVPeriodic() ? theQSurf->VPeriod() : 0.0;
|
||||
const Standard_Real aUf = theQSurf->FirstUParameter(),
|
||||
aUl = theQSurf->LastUParameter(),
|
||||
aVf = theQSurf->FirstVParameter(),
|
||||
aVl = theQSurf->LastVParameter();
|
||||
|
||||
const IntSurf_PntOn2S &aPPrev = theSourceLine->Value(thePointIndex - 1),
|
||||
&aPCurr = theSourceLine->Value(thePointIndex);
|
||||
Standard_Real aUPrev, aVPrev, aUCurr, aVCurr;
|
||||
if (theIsReversed)
|
||||
{
|
||||
aPPrev.ParametersOnS2(aUPrev, aVPrev); // S2 - quadric, set U,V by Pnt3D
|
||||
aPCurr.ParametersOnS2(aUCurr, aVCurr); // S2 - quadric, set U,V by Pnt3D
|
||||
}
|
||||
else
|
||||
{
|
||||
aPPrev.ParametersOnS1(aUPrev, aVPrev); // S1 - quadric, set U,V by Pnt3D
|
||||
aPCurr.ParametersOnS1(aUCurr, aVCurr); // S1 - quadric, set U,V by Pnt3D
|
||||
}
|
||||
|
||||
// Ignore cases when the WLine goes along the surface boundary completely.
|
||||
|
||||
if (IsPointOnBoundary(theToler2D, aUf, aUPeriod, aUCurr) &&
|
||||
!IsPointOnBoundary(theToler2D, aUf, aUPeriod, aUPrev))
|
||||
{
|
||||
theIsOnBoundary = Standard_True;
|
||||
}
|
||||
else if (IsPointOnBoundary(theToler2D, aUl, aUPeriod, aUCurr) &&
|
||||
!IsPointOnBoundary(theToler2D, aUl, aUPeriod, aUPrev))
|
||||
{
|
||||
theIsOnBoundary = Standard_True;
|
||||
}
|
||||
else if (IsPointOnBoundary(theToler2D, aVf, aVPeriod, aVCurr) &&
|
||||
!IsPointOnBoundary(theToler2D, aVf, aVPeriod, aVPrev))
|
||||
{
|
||||
theIsOnBoundary = Standard_True;
|
||||
}
|
||||
else if (IsPointOnBoundary(theToler2D, aVl, aVPeriod, aVCurr) &&
|
||||
!IsPointOnBoundary(theToler2D, aVl, aVPeriod, aVPrev))
|
||||
{
|
||||
theIsOnBoundary = Standard_True;
|
||||
}
|
||||
|
||||
if (theIsOnBoundary)
|
||||
{
|
||||
// Adjust, to avoid bad jumping of the WLine.
|
||||
|
||||
const Standard_Real aDu = (aUPrev - aUCurr);
|
||||
const Standard_Real aDv = (aVPrev - aVCurr);
|
||||
if (aUPeriod > 0.0 && (2.0*Abs(aDu) > aUPeriod))
|
||||
{
|
||||
aUCurr += Sign(aUPeriod, aDu);
|
||||
}
|
||||
|
||||
if (aVPeriod > 0.0 && (2.0*Abs(aDv) > aVPeriod))
|
||||
{
|
||||
aVCurr += Sign(aVPeriod, aDv);
|
||||
}
|
||||
|
||||
IntSurf_PntOn2S aPoint = aPCurr;
|
||||
aPoint.SetValue(!theIsReversed, aUCurr, aVCurr);
|
||||
theNewLine->Add(aPoint);
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
//function : DecomposeResult
|
||||
//purpose : Split <theLine> in the places where it passes through seam edge
|
||||
@ -2499,7 +2602,6 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
// reset variables
|
||||
flNextLine = Standard_False;
|
||||
Standard_Boolean isDecomposited = Standard_False;
|
||||
Standard_Real U1 = 0., U2 = 0., V1 = 0., V2 = 0.;
|
||||
|
||||
Handle(IntSurf_LineOn2S) sline = new IntSurf_LineOn2S();
|
||||
|
||||
@ -2546,18 +2648,33 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
continue;
|
||||
}
|
||||
|
||||
if(IsReversed)
|
||||
//Check whether the current point is on the boundary of theQSurf.
|
||||
//If that is TRUE then the Walking-line will be decomposed in this point.
|
||||
//However, this boundary is not singular-point (like seam or pole of sphere).
|
||||
//Therefore, its processing will be simplified.
|
||||
Standard_Boolean isOnBoundary = Standard_False;
|
||||
|
||||
// Values of sline and isOnBoundary can be changed by this function
|
||||
DetectOfBoundaryAchievement(theQSurf, IsReversed, aSSLine,
|
||||
k, aTOL2D, sline, isOnBoundary);
|
||||
|
||||
aPrePointExist = IsSeamOrPole(theQSurf, aSSLine, IsReversed, k - 1, aDeltaUmax);
|
||||
|
||||
if (isOnBoundary && (aPrePointExist != IntPatch_SPntPoleSeamU))
|
||||
{
|
||||
aSSLine->Value(k).ParametersOnS2(U1,V1); // S2 - quadric, set U,V by Pnt3D
|
||||
}
|
||||
else
|
||||
{
|
||||
aSSLine->Value(k).ParametersOnS1(U1,V1); // S1 - quadric, set U,V by Pnt3D
|
||||
// If the considered point is on seam then its UV-parameters
|
||||
// are defined to within the surface period. Therefore, we can
|
||||
// trust already computed parameters of this point.
|
||||
// However, if this point (which is on the surface boundary) is
|
||||
// a sphere pole or cone apex then its (point's) parameters
|
||||
// have to be recomputed in the code below
|
||||
// (see IntPatch_SpecialPoints::AddSingularPole() method).
|
||||
// E.g. see "bugs modalg_6 bug26684_2" test case.
|
||||
|
||||
aPrePointExist = IntPatch_SPntNone;
|
||||
}
|
||||
|
||||
aPrePointExist = IsSeamOrPole(theQSurf, aSSLine, IsReversed, k-1, aDeltaUmax);
|
||||
|
||||
if(aPrePointExist != IntPatch_SPntNone)
|
||||
if (aPrePointExist != IntPatch_SPntNone)
|
||||
{
|
||||
aBindex = k;
|
||||
isDecomposited = Standard_True;
|
||||
@ -2601,14 +2718,14 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
anInfBound(1, 3), aSupBound(1, 3);
|
||||
|
||||
//Parameters on parametric surface
|
||||
Standard_Real aUp = 0.0, aVp = 0.0;
|
||||
Standard_Real aUp = 0.0, aVp = 0.0, aUq = 0.0, aVq = 0.0;
|
||||
if(IsReversed)
|
||||
{
|
||||
aSSLine->Value(k).ParametersOnS1(aUp, aVp);
|
||||
aSSLine->Value(k).Parameters(aUp, aVp, aUq, aVq);
|
||||
}
|
||||
else
|
||||
{
|
||||
aSSLine->Value(k).ParametersOnS2(aUp, aVp);
|
||||
aSSLine->Value(k).Parameters(aUq, aVq, aUp, aVp);
|
||||
}
|
||||
|
||||
aTol(1) = thePSurf->UResolution(theArcTol);
|
||||
@ -2616,7 +2733,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
aTol(3) = theQSurf->UResolution(theArcTol);
|
||||
aStartPoint(1) = 0.5*(aU0 + aUp);
|
||||
aStartPoint(2) = 0.5*(aV0 + aVp);
|
||||
aStartPoint(3) = 0.5*(aUQuadRef + U1);
|
||||
aStartPoint(3) = 0.5*(aUQuadRef + aUq);
|
||||
anInfBound(1) = thePSurf->FirstUParameter();
|
||||
anInfBound(2) = thePSurf->FirstVParameter();
|
||||
anInfBound(3) = theQSurf->FirstUParameter();
|
||||
@ -2631,7 +2748,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
}
|
||||
else if(aPrePointExist == IntPatch_SPntPoleSeamU)
|
||||
{
|
||||
aPrePointExist = IntPatch_SPntNone;
|
||||
aPrePointExist = IntPatch_SPntNone;
|
||||
|
||||
IntPatch_Point aVert;
|
||||
aVert.SetValue(aRefPt);
|
||||
@ -2642,6 +2759,15 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
{
|
||||
aPrePointExist = IntPatch_SPntPole;
|
||||
aLastType = IntPatch_SPntPole;
|
||||
if (isOnBoundary)
|
||||
{
|
||||
// It is necessary to replace earlier added point on
|
||||
// the surface boundary with the pole. For that,
|
||||
// here we delete excess point. New point will be added later.
|
||||
isOnBoundary = Standard_False;
|
||||
sline->RemovePoint(sline->NbPoints());
|
||||
}
|
||||
|
||||
aCompareTol2D = -1.0;
|
||||
} //if(IntPatch_AddSpecialPoints::AddSingularPole(...))
|
||||
else
|
||||
@ -2673,14 +2799,14 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
anInfBound(1, 3), aSupBound(1, 3);
|
||||
|
||||
//Parameters on parametric surface
|
||||
Standard_Real aUp = 0.0, aVp = 0.0;
|
||||
if(IsReversed)
|
||||
Standard_Real aUp = 0.0, aVp = 0.0, aUq = 0.0, aVq = 0.0;
|
||||
if (IsReversed)
|
||||
{
|
||||
aSSLine->Value(k).ParametersOnS1(aUp, aVp);
|
||||
aSSLine->Value(k).Parameters(aUp, aVp, aUq, aVq);
|
||||
}
|
||||
else
|
||||
{
|
||||
aSSLine->Value(k).ParametersOnS2(aUp, aVp);
|
||||
aSSLine->Value(k).Parameters(aUq, aVq, aUp, aVp);
|
||||
}
|
||||
|
||||
aTol(1) = thePSurf->UResolution(theArcTol);
|
||||
@ -2688,7 +2814,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
aTol(3) = theQSurf->VResolution(theArcTol);
|
||||
aStartPoint(1) = 0.5*(aU0 + aUp);
|
||||
aStartPoint(2) = 0.5*(aV0 + aVp);
|
||||
aStartPoint(3) = 0.5*(aVQuadRef + V1);
|
||||
aStartPoint(3) = 0.5*(aVQuadRef + aVq);
|
||||
anInfBound(1) = thePSurf->FirstUParameter();
|
||||
anInfBound(2) = thePSurf->FirstVParameter();
|
||||
anInfBound(3) = theQSurf->FirstVParameter();
|
||||
@ -2704,28 +2830,46 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
|
||||
if(!aNewPoint.IsSame(aRefPt, aCompareTol3D, aCompareTol2D))
|
||||
{
|
||||
if (isOnBoundary)
|
||||
break;
|
||||
|
||||
sline->Add(aNewPoint);
|
||||
aPrePointExist = aLastType;
|
||||
PrePoint = aNewPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sline->NbPoints() == 1)
|
||||
if (isOnBoundary || (sline->NbPoints() == 1))
|
||||
{
|
||||
//FIRST point of the sline is the pole of the quadric.
|
||||
//Therefore, there is no point in decomposition.
|
||||
|
||||
// If the considered point is on surface boundary then
|
||||
// it is already marked as vertex. So, decomposition is
|
||||
// not required, too.
|
||||
|
||||
PrePoint = aRefPt;
|
||||
aPrePointExist = aLastType;
|
||||
aPrePointExist = isOnBoundary ? IntPatch_SPntNone : aLastType;
|
||||
}
|
||||
}
|
||||
|
||||
////
|
||||
break;
|
||||
} //if(Abs(U1-AnU1) > aDeltaUmax)
|
||||
} //if (aPrePointExist != IntPatch_SPntNone) cond.
|
||||
|
||||
sline->Add(aSSLine->Value(k));
|
||||
PrePoint = aSSLine->Value(k);
|
||||
|
||||
if (isOnBoundary)
|
||||
{
|
||||
aBindex = k;
|
||||
isDecomposited = Standard_True;
|
||||
aPrePointExist = IntPatch_SPntNone;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
sline->Add(aSSLine->Value(k));
|
||||
}
|
||||
} //for(Standard_Integer k = aFindex; k <= aLindex; k++)
|
||||
|
||||
//Creation of new line as part of existing theLine.
|
||||
@ -2780,12 +2924,12 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
new IntPatch_WLine(sline,Standard_False,
|
||||
theLine->TransitionOnS1(),theLine->TransitionOnS2());
|
||||
|
||||
Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
|
||||
gp_Pnt aSPnt(sline->Value(1).Value());
|
||||
sline->Value(1).ParametersOnS1(U1,V1);
|
||||
sline->Value(1).ParametersOnS2(U2,V2);
|
||||
sline->Value(1).Parameters(aU1, aV1, aU2, aV2);
|
||||
aTPntF.SetValue(aSPnt,theArcTol,Standard_False);
|
||||
aTPntF.SetParameters(U1,V1,U2,V2);
|
||||
aTPntF.SetParameter(1.);
|
||||
aTPntF.SetParameters(aU1, aV1, aU2, aV2);
|
||||
aTPntF.SetParameter(1.0);
|
||||
wline->AddVertex(aTPntF);
|
||||
wline->SetFirstPoint(1);
|
||||
|
||||
@ -2795,10 +2939,9 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
}
|
||||
|
||||
aSPnt = sline->Value(sline->NbPoints()).Value();
|
||||
sline->Value(sline->NbPoints()).ParametersOnS1(U1,V1);
|
||||
sline->Value(sline->NbPoints()).ParametersOnS2(U2,V2);
|
||||
sline->Value(sline->NbPoints()).Parameters(aU1, aV1, aU2, aV2);
|
||||
aTPntL.SetValue(aSPnt,theArcTol,Standard_False);
|
||||
aTPntL.SetParameters(U1,V1,U2,V2);
|
||||
aTPntL.SetParameters(aU1, aV1, aU2, aV2);
|
||||
aTPntL.SetParameter(sline->NbPoints());
|
||||
wline->AddVertex(aTPntL);
|
||||
wline->SetLastPoint(wline->NbVertex());
|
||||
@ -2856,24 +2999,25 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
|
||||
for(Standard_Integer aFLIndex = 0; aFLIndex < 2; aFLIndex++)
|
||||
{
|
||||
Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
|
||||
if(aFLIndex == 0)
|
||||
{
|
||||
aRFirst.Parameters(U1, V1, U2, V2);
|
||||
aRFirst.Parameters(aU1, aV1, aU2, aV2);
|
||||
aSPnt.SetXYZ(aRFirst.Value().XYZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
aRLast.Parameters(U1, V1, U2, V2);
|
||||
aRLast.Parameters(aU1, aV1, aU2, aV2);
|
||||
aSPnt.SetXYZ(aRLast.Value().XYZ());
|
||||
}
|
||||
|
||||
if(IsReversed)
|
||||
{
|
||||
aPSurf.SetCoord(U1, V1);
|
||||
aPSurf.SetCoord(aU1, aV1);
|
||||
}
|
||||
else
|
||||
{
|
||||
aPSurf.SetCoord(U2, V2);
|
||||
aPSurf.SetCoord(aU2, aV2);
|
||||
}
|
||||
|
||||
Standard_Real aPar = ElCLib::Parameter(aLin, aPSurf);
|
||||
@ -2891,7 +3035,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
|
||||
|
||||
aTPnt.SetParameter(aPar);
|
||||
aTPnt.SetValue(aSPnt,theArcTol,Standard_False);
|
||||
aTPnt.SetParameters(U1, V1, U2, V2);
|
||||
aTPnt.SetParameters(aU1, aV1, aU2, aV2);
|
||||
|
||||
aRLine->AddVertex(aTPnt);
|
||||
}
|
||||
|
28
tests/bugs/modalg_7/bug28102_1
Normal file
28
tests/bugs/modalg_7/bug28102_1
Normal file
@ -0,0 +1,28 @@
|
||||
puts "========"
|
||||
puts "OCC28102"
|
||||
puts "========"
|
||||
puts ""
|
||||
#######################################################
|
||||
# Problem cutting a plate with several holes (670)
|
||||
#######################################################
|
||||
|
||||
restore [locate_data_file bug28102_plate.brep] pl0
|
||||
restore [locate_data_file bug28102_holes.brep] hl
|
||||
|
||||
# Incomplete section
|
||||
bsection result pl0 hl
|
||||
|
||||
regexp {nb alone Vertices : ([-0-9.+eE]+)} [checksection result] full nbv
|
||||
if { $nbv != 0 } { puts "Error : Section is incorrect" }
|
||||
|
||||
checknbshapes result -vertex 268 -edge 268
|
||||
|
||||
checkprops result -l 11.5694
|
||||
|
||||
regexp {Tolerance MAX=([-0-9.+eE]+)} [tolerance result] full toler
|
||||
|
||||
if {$toler > 1.0e-5} {
|
||||
puts "Error: Tolerance of section is too large"
|
||||
}
|
||||
|
||||
checkview -display result -2d -path ${imagedir}/${test_image}.png
|
24
tests/bugs/modalg_7/bug28102_2
Normal file
24
tests/bugs/modalg_7/bug28102_2
Normal file
@ -0,0 +1,24 @@
|
||||
puts "========"
|
||||
puts "OCC28102"
|
||||
puts "========"
|
||||
puts ""
|
||||
#######################################################
|
||||
# Problem cutting a plate with several holes (670)
|
||||
#######################################################
|
||||
|
||||
restore [locate_data_file bug28102_plate.brep] pl0
|
||||
restore [locate_data_file bug28102_holes.brep] hl
|
||||
|
||||
bclearobjects
|
||||
bcleartools
|
||||
baddobjects pl0
|
||||
baddtools hl
|
||||
bfillds
|
||||
|
||||
bbop result 2
|
||||
|
||||
checknbshapes result -vertex 274 -edge 275 -face 2 -shell 1
|
||||
|
||||
checkprops result -s 13.3806
|
||||
|
||||
checkview -display result -2d -path ${imagedir}/${test_image}.png
|
Loading…
x
Reference in New Issue
Block a user