X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blobdiff_plain;f=src%2FIntPatch%2FIntPatch_ImpImpIntersection_4.gxx;h=8fe2d216a3c02de357d4e21f9636a70db21bacd3;hp=cbd5928e6958baa4e4629b57ecd55fa39e5fa185;hb=590b3f041629f9da76807ba45ba9dc353af6713d;hpb=8662560e2c9c83de9ed97b522bebcad2cfc87b92 diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx index cbd5928e69..8fe2d216a3 100644 --- a/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx +++ b/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx @@ -29,12 +29,10 @@ static void ShortCosForm( const Standard_Real theCosFactor, Standard_Real& theCoeff, Standard_Real& theAngle); // -static - Standard_Boolean ExploreCurve(const gp_Cylinder& aCy, - const gp_Cone& aCo, - IntAna_Curve& aC, - const Standard_Real aTol, - IntAna_ListOfCurve& aLC); +static Standard_Boolean ExploreCurve(const gp_Cone& theCo, + IntAna_Curve& aC, + const Standard_Real aTol, + IntAna_ListOfCurve& aLC); static Standard_Boolean InscribePoint(const Standard_Real theUfTarget, const Standard_Real theUlTarget, @@ -511,13 +509,6 @@ private: const Standard_Boolean myIsReverse; }; -static - Standard_Boolean ExploreCurve(const gp_Cylinder& aCy, - const gp_Cone& aCo, - IntAna_Curve& aC, - const Standard_Real aTol, - IntAna_ListOfCurve& aLC); - static void SeekAdditionalPoints( const IntSurf_Quadric& theQuad1, const IntSurf_Quadric& theQuad2, const Handle(IntSurf_LineOn2S)& theLine, @@ -840,6 +831,7 @@ void ProcessBounds(const Handle(IntPatch_ALine)& alig, //-- ligne coura if (!procf) { d=ptf.Distance(ptsol.Value()); if (d <= Tol) { + ptsol.SetTolerance(Tol); if (!ptsol.IsMultiple()) { //-- le point ptsol (de aligold) est declare multiple sur aligold Multpoint = Standard_True; @@ -858,6 +850,7 @@ void ProcessBounds(const Handle(IntPatch_ALine)& alig, //-- ligne coura } if (!procl) { if (ptl.Distance(ptsol.Value()) <= Tol) { + ptsol.SetTolerance(Tol); if (!ptsol.IsMultiple()) { Multpoint = Standard_True; ptsol.SetMultiple(Standard_True); @@ -888,6 +881,8 @@ void ProcessBounds(const Handle(IntPatch_ALine)& alig, //-- ligne coura } } } + + ptsol.SetTolerance(Tol); if (!procf && !procl) { Quad1.Parameters(ptf,U1,V1); Quad2.Parameters(ptf,U2,V2); @@ -2815,6 +2810,7 @@ static IntPatch_ImpImpIntersection::IntStatus { aL2S[i] = new IntSurf_LineOn2S(); aWLine[i] = new IntPatch_WLine(aL2S[i], Standard_False); + aWLine[i]->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLImpImp); aWLFindStatus[i] = WLFStatus_Absent; isAddingWLEnabled[i] = Standard_True; aU2[i] = aV1[i] = aV2[i] = 0.0; @@ -3367,7 +3363,13 @@ static IntPatch_ImpImpIntersection::IntStatus aP.SetTolerance(aTol3D); aP.SetValue(aWLine[i]->Point(1).Value()); - theSPnt.Append(aP); + //Check whether the added point exists. + //It is enough to check the last point. + if (theSPnt.IsEmpty() || + !theSPnt.Last().PntOn2S().IsSame(aP.PntOn2S(), Precision::Confusion())) + { + theSPnt.Append(aP); + } } else if (aWLine[i]->NbPnts() > 1) { @@ -3381,6 +3383,90 @@ static IntPatch_ImpImpIntersection::IntStatus if (aPf.IsSame(aPl, Precision::Confusion())) isGood = Standard_False; } + else if (aWLine[i]->NbPnts() > 2) + { + // Sometimes points of the WLine are distributed + // linearly and uniformly. However, such position + // of the points does not always describe the real intersection + // curve. I.e. real tangents at the ends of the intersection + // curve can significantly deviate from this "line" direction. + // Here we are processing this case by inserting additional points + // to the beginning/end of the WLine to make it more precise. + // See description to the issue #30082. + + const Standard_Real aSqTol3D = aTol3D*aTol3D; + for (Standard_Integer j = 0; j < 2; j++) + { + // If j == 0 ==> add point at begin of WLine. + // If j == 1 ==> add point at end of WLine. + + for (;;) + { + if (aWLine[i]->NbPnts() >= aNbMaxPoints) + { + break; + } + + // Take 1st and 2nd point to compute the "line" direction. + // For our convenience, we make 2nd point be the ends of the WLine + // because it will be used for computation of the normals + // to the surfaces. + const Standard_Integer anIdx1 = j ? aWLine[i]->NbPnts() - 1 : 2; + const Standard_Integer anIdx2 = j ? aWLine[i]->NbPnts() : 1; + + const gp_Pnt &aP1 = aWLine[i]->Point(anIdx1).Value(); + const gp_Pnt &aP2 = aWLine[i]->Point(anIdx2).Value(); + + const gp_Vec aDir(aP1, aP2); + + if (aDir.SquareMagnitude() < aSqTol3D) + { + break; + } + + // Compute tangent in first/last point of the WLine. + // We do not take into account the flag "isReversed" + // because strict direction of the tangent is not + // important here (we are interested in the tangent + // line itself and nothing to fear if its direction + // is reversed). + const gp_Vec aN1 = aQuad1.Normale(aP2); + const gp_Vec aN2 = aQuad2.Normale(aP2); + const gp_Vec aTg(aN1.Crossed(aN2)); + + if (aTg.SquareMagnitude() < Precision::SquareConfusion()) + { + // Tangent zone + break; + } + + // Check of the bending + Standard_Real anAngle = aDir.Angle(aTg); + + if (anAngle > M_PI_2) + anAngle -= M_PI; + + if (Abs(anAngle) > 0.25) // ~ 14deg. + { + const Standard_Integer aNbPntsPrev = aWLine[i]->NbPnts(); + SeekAdditionalPoints(aQuad1, aQuad2, aWLine[i]->Curve(), + anEquationCoeffs, i, 3, anIdx1, anIdx2, + aTol2D, aPeriod, isReversed); + + if (aWLine[i]->NbPnts() == aNbPntsPrev) + { + // No points have been added. ==> Exit from a loop. + break; + } + } + else + { + // Good result has been achieved. ==> Exit from a loop. + break; + } + } // for (;;) + } + } if (isGood) { @@ -3388,8 +3474,8 @@ static IntPatch_ImpImpIntersection::IntStatus isAddedIntoWL[i] = Standard_True; SeekAdditionalPoints(aQuad1, aQuad2, aWLine[i]->Curve(), anEquationCoeffs, i, aNbPoints, 1, - aWLine[i]->NbPnts(), aTol2D, aPeriod, - isReversed); + aWLine[i]->NbPnts(), aTol2D, aPeriod, + isReversed); aWLine[i]->ComputeVertexParameters(aTol3D); theSlin.Append(aWLine[i]); @@ -3421,8 +3507,8 @@ static IntPatch_ImpImpIntersection::IntStatus const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aWLine1->NbPnts()); const IntSurf_PntOn2S aPntCur = theSPnt.Value(aNbPnt).PntOn2S(); - if (aPntCur.IsSame(aPntFWL1, Precision::Confusion()) || - aPntCur.IsSame(aPntLWL1, Precision::Confusion())) + if (aPntCur.IsSame(aPntFWL1, aTol3D) || + aPntCur.IsSame(aPntLWL1, aTol3D)) { theSPnt.Remove(aNbPnt); aNbPnt--; @@ -3452,6 +3538,7 @@ static IntPatch_ImpImpIntersection::IntStatus Handle(IntSurf_LineOn2S) aL2S = new IntSurf_LineOn2S(); Handle(IntPatch_WLine) aWLine = new IntPatch_WLine(aL2S, Standard_False); + aWLine->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLImpImp); //Define the index of WLine, which lies the point aPnt2S in. Standard_Integer anIndex = 0; @@ -3501,7 +3588,7 @@ static IntPatch_ImpImpIntersection::IntStatus // another point in the interval [anUC, anUsup] if anUC is intersection point and // in the interval [anUmid, anUC], otherwise. - Standard_Real anAddedPar[2] = { anUmid, anUmid }; + Standard_Real anAddedPar[2] = {isReversed ? u2 : u1, isReversed ? u2 : u1}; for (Standard_Integer aParID = 0; aParID < 2; aParID++) { @@ -4136,7 +4223,7 @@ Standard_Boolean IntCyCo(const IntSurf_Quadric& Quad1, //curvsol = anaint.Curve(i); aC=anaint.Curve(i); aLC.Clear(); - ExploreCurve(Cy, Co, aC, 10.*Tol, aLC); + ExploreCurve(Co, aC, 10.*Tol, aLC); // aIt.Initialize(aLC); for (; aIt.More(); aIt.Next()) { @@ -4209,61 +4296,69 @@ Standard_Boolean IntCyCo(const IntSurf_Quadric& Quad1, } //======================================================================= //function : ExploreCurve -//purpose : +//purpose : Splits aC on several curves in the cone apex points. //======================================================================= -Standard_Boolean ExploreCurve(const gp_Cylinder& ,//aCy, - const gp_Cone& aCo, - IntAna_Curve& aC, - const Standard_Real aTol, - IntAna_ListOfCurve& aLC) - +Standard_Boolean ExploreCurve(const gp_Cone& theCo, + IntAna_Curve& theCrv, + const Standard_Real theTol, + IntAna_ListOfCurve& theLC) { - Standard_Boolean bFind=Standard_False; - Standard_Real aTheta, aT1, aT2, aDst; - gp_Pnt aPapx, aPx; - // - //aC.Dump(); - // - aLC.Clear(); - aLC.Append(aC); - // - aPapx=aCo.Apex(); - // - aC.Domain(aT1, aT2); + const Standard_Real aSqTol = theTol*theTol; + const gp_Pnt aPapx(theCo.Apex()); + + Standard_Real aT1, aT2; + theCrv.Domain(aT1, aT2); + + theLC.Clear(); // - aPx=aC.Value(aT1); - aDst=aPx.Distance(aPapx); - if (aDstaTol) { - return !bFind; + + if ((aT2 - aT1) > Precision::PConfusion()) + { + IntAna_Curve aC1 = theCrv; + aC1.SetDomain(aT1, aT2); + theLC.Append(aC1); } - // - // need to be splitted at aTheta - IntAna_Curve aC1, aC2; - // - aC1=aC; - aC1.SetDomain(aT1, aTheta); - aC2=aC; - aC2.SetDomain(aTheta, aT2); - // - aLC.Clear(); - aLC.Append(aC1); - aLC.Append(aC2); - // - return bFind; + + return Standard_True; }