From: pkv Date: Thu, 7 Mar 2013 09:36:14 +0000 (+0400) Subject: 0023471: Intersection algorithm produces overlapping intersection curves X-Git-Tag: V6_6_0_beta~39 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=a7dd5d0fbd3aa420c94ccb4f4ab838fb7a9f3392 0023471: Intersection algorithm produces overlapping intersection curves Test correction --- diff --git a/src/IntPatch/IntPatch_PrmPrmIntersection.cxx b/src/IntPatch/IntPatch_PrmPrmIntersection.cxx index a9f799f9c3..59bd2d9659 100755 --- a/src/IntPatch/IntPatch_PrmPrmIntersection.cxx +++ b/src/IntPatch/IntPatch_PrmPrmIntersection.cxx @@ -61,6 +61,15 @@ static const Handle(Adaptor3d_HSurface)& Surf2, IntPatch_SequenceOfLine& aSLin); +static Standard_Boolean IsPointOnLine(const IntSurf_PntOn2S &thePOn2S, + const Handle(IntPatch_WLine) &theWLine, + const Standard_Real Deflection); + +static void AddWLine(IntPatch_SequenceOfLine &theLines, + const Handle(IntPatch_WLine) &theWLine, + const Standard_Real Deflection); + + //================================================================================== // function : // purpose : @@ -144,7 +153,6 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Standard_Integer nbLigSec = Interference.NbSectionLines(); Standard_Integer nbTanZon = Interference.NbTangentZones(); - Standard_Integer NbPntOn2SOnLine; Standard_Integer NbLigCalculee = 0; Standard_Real U1,U2,V1,V2; @@ -292,56 +300,11 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& NbLigCalculee = SLin.Length(); Standard_Integer l; for( l=1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { - Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.ChangeValue(l)); - if( (testwline->IsOutSurf1Box(gp_Pnt2d(pu1,pv1))==Standard_False) && - (testwline->IsOutSurf2Box(gp_Pnt2d(pu2,pv2))==Standard_False) && - (testwline->IsOutBox(StartPOn2S.Value())==Standard_False) ) { - NbPntOn2SOnLine = testwline->NbPnts(); - Standard_Integer ll; - for( ll=1; (ll < NbPntOn2SOnLine) && (dminiPointLigne >= SeuildPointLigne); ll++) { - const gp_Pnt &Pa = testwline->Point(ll).Value(); - const gp_Pnt &Pb = testwline->Point(ll+1).Value(); - const gp_Pnt &PStart = StartPOn2S.Value(); - gp_Vec AM(Pa,PStart); - gp_Vec MB(PStart,Pb); - Standard_Real AMMB = AM.Dot(MB); - if(AMMB > 0.0) { - gp_Dir ABN(Pb.X()-Pa.X(),Pb.Y()-Pa.Y(),Pb.Z()-Pa.Z()); - Standard_Real lan = ABN.X()*AM.X()+ABN.Y()*AM.Y()+ABN.Z()*AM.Z(); - gp_Vec AH(lan*ABN.X(),lan*ABN.Y(),lan*ABN.Z()); - gp_Vec HM(AM.X()-AH.X(),AM.Y()-AH.Y(),AM.Z()-AH.Z()); - Standard_Real d = 0.0; - if(HM.X() < Deflection) { - d+=HM.X()*HM.X(); - if(HM.Y() < Deflection) { - d+=HM.Y()*HM.Y(); - if(HM.Z() < Deflection) - d+=HM.Z()*HM.Z(); - else - d=Deflection2; - } - else - d=Deflection2; - } - else - d=Deflection2; + const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l)); - if(d SeuildPointLigne) { @@ -350,10 +313,19 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& if(PW.NbPoints()>2) { RejetLigne = Standard_False; Point3dDebut = PW.Value(1).Value(); - Point3dFin = PW.Value(PW.NbPoints()).Value(); + const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints()); + Point3dFin = PointFin.Value(); for( ver = 1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver)); - const IntSurf_PntOn2S& verPointDebut = verwline->Point(1); + + // Check end point if it is on existing line. + // Start point is checked before. + if (IsPointOnLine(PointFin, verwline, Deflection)) { + RejetLigne = Standard_True; + break; + } + + const IntSurf_PntOn2S& verPointDebut = verwline->Point(1); const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts()); if( Point3dDebut.Distance(verPointDebut.Value()) <= TolTangency ) { if(Point3dFin.Distance(verPointFin.Value()) <= TolTangency) @@ -407,7 +379,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& } lignetrouvee = Standard_True; - SLin.Append(wline); + AddWLine(SLin, wline, Deflection); empt = Standard_False; }// !RejetLigne }// PW.NbPoints()>2 @@ -466,56 +438,11 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& dminiPointLigne = SeuildPointLigne + SeuildPointLigne; Standard_Integer l; for( l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { - Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.ChangeValue(l)); - if( (testwline->IsOutSurf1Box(gp_Pnt2d(pu1,pv1))==Standard_False) && - (testwline->IsOutSurf2Box(gp_Pnt2d(pu2,pv2))==Standard_False) && - (testwline->IsOutBox(StartPOn2S.Value())==Standard_False) ) { - NbPntOn2SOnLine = testwline->NbPnts(); - Standard_Integer ll; - for( ll = 1; (ll < NbPntOn2SOnLine) && (dminiPointLigne >= SeuildPointLigne); ll++) { - const gp_Pnt& Pa = testwline->Point(ll).Value(); - const gp_Pnt& Pb = testwline->Point(ll+1).Value(); - const gp_Pnt& PStart=StartPOn2S.Value(); - gp_Vec AM(Pa,PStart); - gp_Vec MB(PStart,Pb); - Standard_Real AMMB = AM.Dot(MB); - if(AMMB > 0.0) { - gp_Dir ABN(Pb.X()-Pa.X(),Pb.Y()-Pa.Y(),Pb.Z()-Pa.Z()); - Standard_Real lan = ABN.X()*AM.X()+ABN.Y()*AM.Y()+ABN.Z()*AM.Z(); - gp_Vec AH(lan*ABN.X(),lan*ABN.Y(),lan*ABN.Z()); - gp_Vec HM(AM.X()-AH.X(),AM.Y()-AH.Y(),AM.Z()-AH.Z()); - Standard_Real d = 0.0; - if(HM.X() < Deflection) { - d+=HM.X()*HM.X(); - if(HM.Y() < Deflection) { - d+=HM.Y()*HM.Y(); - if(HM.Z() < Deflection) - d+=HM.Z()*HM.Z(); - else - d=Deflection2; - } - else - d=Deflection2; - } - else - d=Deflection2; + const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l)); - if(d SeuildPointLigne) { @@ -524,9 +451,18 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& if(PW.NbPoints()>2) { RejetLigne = Standard_False; Point3dDebut = PW.Value(1).Value(); - Point3dFin = PW.Value(PW.NbPoints()).Value(); + const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints()); + Point3dFin = PointFin.Value(); for(ver=1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver)); + + // Check end point if it is on existing line. + // Start point is checked before. + if (IsPointOnLine(PointFin, verwline, Deflection)) { + RejetLigne = Standard_True; + break; + } + const IntSurf_PntOn2S& verPointDebut = verwline->Point(1); const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts()); if(Point3dDebut.Distance(verPointDebut.Value()) < TolTangency) @@ -581,7 +517,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& wline->AddVertex(vtx); } - SLin.Append(wline); + AddWLine(SLin, wline, Deflection); empt = Standard_False; }// if !RejetLigne }// PW.NbPoints()>2 @@ -700,7 +636,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& NbLigCalculee = SLin.Length(); Standard_Integer l; for( l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { - Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.ChangeValue(l)); + const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l)); if( (testwline->IsOutSurf1Box(gp_Pnt2d(pu1,pv1))==Standard_False) && (testwline->IsOutSurf2Box(gp_Pnt2d(pu2,pv2))==Standard_False) && (testwline->IsOutBox(StartPOn2S.Value())==Standard_False) ) { @@ -869,7 +805,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& dminiPointLigne = SeuildPointLigne + SeuildPointLigne; Standard_Integer l; for( l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { - Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.ChangeValue(l)); + const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l)); if( (testwline->IsOutSurf1Box(gp_Pnt2d(pu1,pv1))==Standard_False) && (testwline->IsOutSurf2Box(gp_Pnt2d(pu2,pv2))==Standard_False) && (testwline->IsOutBox(StartPOn2S.Value())==Standard_False) ) { @@ -1422,56 +1358,11 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& NbLigCalculee = SLin.Length(); Standard_Integer l; for( l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { - Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.ChangeValue(l)); - if( (testwline->IsOutSurf1Box(gp_Pnt2d(pu1,pv1))==Standard_False) && - (testwline->IsOutSurf2Box(gp_Pnt2d(pu2,pv2))==Standard_False) && - (testwline->IsOutBox(StartPOn2S.Value())==Standard_False) ) { - NbPntOn2SOnLine = testwline->NbPnts(); - Standard_Integer ll; - for( ll = 1; (ll < NbPntOn2SOnLine) && (dminiPointLigne >= SeuildPointLigne); ll++) { - const gp_Pnt &Pa = testwline->Point(ll).Value(); - const gp_Pnt &Pb = testwline->Point(ll+1).Value(); - const gp_Pnt &PStart = StartPOn2S.Value(); - gp_Vec AM(Pa,PStart); - gp_Vec MB(PStart,Pb); - Standard_Real AMMB = AM.Dot(MB); - if(AMMB > 0.0) { - gp_Dir ABN(Pb.X()-Pa.X(),Pb.Y()-Pa.Y(),Pb.Z()-Pa.Z()); - Standard_Real lan = ABN.X()*AM.X()+ABN.Y()*AM.Y()+ABN.Z()*AM.Z(); - gp_Vec AH(lan*ABN.X(),lan*ABN.Y(),lan*ABN.Z()); - gp_Vec HM(AM.X()-AH.X(),AM.Y()-AH.Y(),AM.Z()-AH.Z()); - Standard_Real d = 0.0; - if(HM.X() < Deflection) { - d+=HM.X()*HM.X(); - if(HM.Y() < Deflection) { - d+=HM.Y()*HM.Y(); - if(HM.Z() < Deflection) - d+=HM.Z()*HM.Z(); - else - d=Deflection2; - } - else - d=Deflection2; - } - else - d=Deflection2; - - if(d SeuildPointLigne) { @@ -1480,9 +1371,18 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& if(PW.NbPoints()>2) { RejetLigne = Standard_False; Point3dDebut = PW.Value(1).Value(); - Point3dFin = PW.Value(PW.NbPoints()).Value(); + const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints()); + Point3dFin = PointFin.Value(); for( ver = 1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver)); + + // Check end point if it is on existing line. + // Start point is checked before. + if (IsPointOnLine(PointFin, verwline, Deflection)) { + RejetLigne = Standard_True; + break; + } + const IntSurf_PntOn2S& verPointDebut = verwline->Point(1); const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts()); if(Point3dDebut.Distance(verPointDebut.Value()) <= TolTangency) { @@ -1673,7 +1573,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& } }// SLin.Length > 0 - SLin.Append(wline); + AddWLine(SLin, wline, Deflection); empt = Standard_False; }// !RejetLigne }// PW points > 2 @@ -2125,56 +2025,11 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur NbLigCalculee = SLin.Length(); Standard_Integer l; for( l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { - Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.ChangeValue(l)); - if( (testwline->IsOutSurf1Box(gp_Pnt2d(pu1,pv1))==Standard_False) && - (testwline->IsOutSurf2Box(gp_Pnt2d(pu2,pv2))==Standard_False) && - (testwline->IsOutBox(StartPOn2S.Value())==Standard_False) ) { - NbPntOn2SOnLine = testwline->NbPnts(); - Standard_Integer ll; - for( ll = 1; (ll < NbPntOn2SOnLine) && (dminiPointLigne >= SeuildPointLigne); ll++) { - const gp_Pnt &Pa = testwline->Point(ll).Value(); - const gp_Pnt &Pb = testwline->Point(ll+1).Value(); - const gp_Pnt &PStart = StartPOn2S.Value(); - gp_Vec AM(Pa,PStart); - gp_Vec MB(PStart,Pb); - Standard_Real AMMB = AM.Dot(MB); - if(AMMB > 0.0) { - gp_Dir ABN(Pb.X()-Pa.X(),Pb.Y()-Pa.Y(),Pb.Z()-Pa.Z()); - Standard_Real lan = ABN.X()*AM.X()+ABN.Y()*AM.Y()+ABN.Z()*AM.Z(); - gp_Vec AH(lan*ABN.X(),lan*ABN.Y(),lan*ABN.Z()); - gp_Vec HM(AM.X()-AH.X(),AM.Y()-AH.Y(),AM.Z()-AH.Z()); - Standard_Real d = 0.0; - if(HM.X() < Deflection) { - d+=HM.X()*HM.X(); - if(HM.Y() < Deflection) { - d+=HM.Y()*HM.Y(); - if(HM.Z() < Deflection) - d+=HM.Z()*HM.Z(); - else - d=Deflection2; - } - else - d=Deflection2; - } - else - d=Deflection2; - - if(d SeuildPointLigne) { @@ -2425,7 +2280,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur } }// SLin.Length > 0 - SLin.Append(wline); + AddWLine(SLin, wline, Deflection); empt = Standard_False; }// !RejetLigne }// PW points > 2 @@ -2506,70 +2361,12 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur for(Standard_Integer l=1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { - Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.ChangeValue(l)); - - if( (testwline->IsOutSurf1Box(gp_Pnt2d(pu1,pv1))==Standard_False) - &&(testwline->IsOutSurf2Box(gp_Pnt2d(pu2,pv2))==Standard_False) - &&(testwline->IsOutBox(StartPOn2S.Value())==Standard_False)) { - - - //-- Handle(IntPatch_WLine) testwline=Handle(IntPatch_WLine)::DownCast(SLin.Value(l)); - NbPntOn2SOnLine = testwline->NbPnts(); - for(Standard_Integer ll=1; - (ll < NbPntOn2SOnLine) && (dminiPointLigne >= SeuildPointLigne); - ll++) { - const gp_Pnt& Pa = testwline->Point(ll).Value(); - const gp_Pnt& Pb = testwline->Point(ll+1).Value(); - const gp_Pnt& PStart=StartPOn2S.Value(); - gp_Vec AM(Pa,PStart); - gp_Vec MB(PStart,Pb); - Standard_Real AMMB = AM.Dot(MB); - if(AMMB > 0.0) { - gp_Dir ABN(Pb.X()-Pa.X(),Pb.Y()-Pa.Y(),Pb.Z()-Pa.Z()); - Standard_Real lan = ABN.X()*AM.X()+ABN.Y()*AM.Y()+ABN.Z()*AM.Z(); - gp_Vec AH(lan*ABN.X(),lan*ABN.Y(),lan*ABN.Z()); - gp_Vec HM(AM.X()-AH.X(),AM.Y()-AH.Y(),AM.Z()-AH.Z()); - - Standard_Real d = 0.0; - if(HM.X() < Deflection) { - d+=HM.X()*HM.X(); - if(HM.Y() < Deflection) { - d+=HM.Y()*HM.Y(); - if(HM.Z() < Deflection) { - d+=HM.Z()*HM.Z(); - } - else { - d=Deflection2; - } - } - else { - d=Deflection2; - } - } - else { - d=Deflection2; - } - if(d SeuildPointLigne) { @@ -2590,11 +2387,20 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur //----------------------------------------------- RejetLigne = Standard_False; Point3dDebut = PW.Value(1).Value(); - Point3dFin = PW.Value(PW.NbPoints()).Value(); + const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints()); + Point3dFin = PointFin.Value(); for(ver=1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver)); //-- Handle(IntPatch_WLine) verwline=Handle(IntPatch_WLine)::DownCast(SLin.Value(ver)); + + // Check end point if it is on existing line. + // Start point is checked before. + if (IsPointOnLine(PointFin, verwline, Deflection)) { + RejetLigne = Standard_True; + break; + } + const IntSurf_PntOn2S& verPointDebut = verwline->Point(1); const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts()); if(Point3dDebut.Distance(verPointDebut.Value()) < TolTangency) { @@ -2656,7 +2462,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur } //--------------- - SLin.Append(wline); + AddWLine(SLin, wline, Deflection); empt = Standard_False; } @@ -2685,7 +2491,6 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur SLin.Clear(); Standard_Real Deflection2 = Deflection*Deflection; - Standard_Integer NbPntOn2SOnLine; Standard_Integer NbLigCalculee = 0; Standard_Real U1,U2,V1,V2; Standard_Real pu1,pu2,pv1,pv2; @@ -2738,73 +2543,13 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur for(Standard_Integer l=1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { - const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l)); - - if( (testwline->IsOutSurf1Box(gp_Pnt2d(pu1,pv1))==Standard_False) - &&(testwline->IsOutSurf2Box(gp_Pnt2d(pu2,pv2))==Standard_False) - &&(testwline->IsOutBox(StartPOn2S.Value())==Standard_False)) { - - NbPntOn2SOnLine = testwline->NbPnts(); - for(Standard_Integer ll=1; - (ll < NbPntOn2SOnLine) && (dminiPointLigne >= SeuildPointLigne); - ll++) { - - const gp_Pnt& Pa = testwline->Point(ll).Value(); - const gp_Pnt& Pb = testwline->Point(ll+1).Value(); - const gp_Pnt& PStart=StartPOn2S.Value(); - gp_Vec AM(Pa,PStart); - gp_Vec MB(PStart,Pb); - Standard_Real AMMB = AM.Dot(MB); - if(AMMB > 0.0) { - gp_Dir ABN(Pb.X()-Pa.X(),Pb.Y()-Pa.Y(),Pb.Z()-Pa.Z()); - Standard_Real lan = ABN.X()*AM.X()+ABN.Y()*AM.Y()+ABN.Z()*AM.Z(); - gp_Vec AH(lan*ABN.X(),lan*ABN.Y(),lan*ABN.Z()); - gp_Vec HM(AM.X()-AH.X(),AM.Y()-AH.Y(),AM.Z()-AH.Z()); - - Standard_Real d = 0.0; - if(HM.X() < Deflection) { - d+=HM.X()*HM.X(); - if(HM.Y() < Deflection) { - d+=HM.Y()*HM.Y(); - if(HM.Z() < Deflection) { - d+=HM.Z()*HM.Z(); - } - else { - d=Deflection2; - } - } - else { - d=Deflection2; - } - } - else { - d=Deflection2; - } - if(d SeuildPointLigne) { //--------------------------------------------------- @@ -2822,11 +2567,20 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur //----------------------------------------------- RejetLigne = Standard_False; Point3dDebut = PW.Value(1).Value(); - Point3dFin = PW.Value(PW.NbPoints()).Value(); + const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints()); + Point3dFin = PointFin.Value(); for(ver=1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver)); //-- Handle(IntPatch_WLine) verwline=Handle(IntPatch_WLine)::DownCast(SLin.Value(ver)); + + // Check end point if it is on existing line. + // Start point is checked before. + if (IsPointOnLine(PointFin, verwline, Deflection)) { + RejetLigne = Standard_True; + break; + } + const IntSurf_PntOn2S& verPointDebut = verwline->Point(1); const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts()); if(Point3dDebut.Distance(verPointDebut.Value()) < TolTangency) { @@ -2888,7 +2642,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur } //--------------- - SLin.Append(wline); + AddWLine(SLin, wline, Deflection); empt = Standard_False; } @@ -3396,3 +3150,138 @@ void IntPatch_PrmPrmIntersection::PointDepart(Handle(IntSurf_LineOn2S)& LineOn2S } while(ok); } + +//================================================================================== +// function : IsPointOnLine +// purpose : +//================================================================================== + +Standard_Boolean IsPointOnLine(const IntSurf_PntOn2S &thePOn2S, + const Handle(IntPatch_WLine) &theWLine, + const Standard_Real Deflection) +{ + Standard_Boolean isOnLine = Standard_False; + Standard_Real Deflection2 = Deflection*Deflection; + Standard_Real pu1, pu2, pv1, pv2; + + thePOn2S.Parameters(pu1, pv1, pu2, pv2); + + if ((theWLine->IsOutSurf1Box(gp_Pnt2d(pu1, pv1)) == Standard_False) && + (theWLine->IsOutSurf2Box(gp_Pnt2d(pu2, pv2)) == Standard_False) && + (theWLine->IsOutBox(thePOn2S.Value()) == Standard_False)) { + const Standard_Integer NbPntOn2SOnLine = theWLine->NbPnts(); + Standard_Integer ll; + + for (ll=1; ll < NbPntOn2SOnLine && !isOnLine; ll++) { + const gp_Pnt &Pa = theWLine->Point(ll).Value(); + const gp_Pnt &Pb = theWLine->Point(ll+1).Value(); + const gp_Pnt &PStart = thePOn2S.Value(); + const gp_Vec AM(Pa, PStart); + const gp_Vec MB(PStart,Pb); + const Standard_Real AMMB = AM.Dot(MB); + + if(AMMB > 0.0) { + gp_Dir ABN(Pb.X() - Pa.X(), Pb.Y() - Pa.Y(), Pb.Z() - Pa.Z()); + Standard_Real lan = ABN.X()*AM.X() + ABN.Y()*AM.Y() + ABN.Z()*AM.Z(); + gp_Vec AH(lan*ABN.X(), lan*ABN.Y(), lan*ABN.Z()); + gp_Vec HM(AM.X() - AH.X(), AM.Y() - AH.Y(), AM.Z() - AH.Z()); + Standard_Real d = 0.0; + + if(HM.X() < Deflection) { + d += HM.X()*HM.X(); + + if(HM.Y() < Deflection) { + d += HM.Y()*HM.Y(); + + if(HM.Z() < Deflection) { + d += HM.Z()*HM.Z(); + } else { + d = Deflection2; + } + } else { + d = Deflection2; + } + } else { + d = Deflection2; + } + + if(d < Deflection2) { + isOnLine = Standard_True; + } + } else { + Standard_Real dab = Pa.SquareDistance(Pb); + Standard_Real dap = Pa.SquareDistance(PStart); + + if(dap < dab) { + isOnLine = Standard_True; + } else { + Standard_Real dbp = Pb.SquareDistance(PStart); + + if(dbp < dab) { + isOnLine = Standard_True; + } + } + } + } + } + + return isOnLine; +} + +//================================================================================== +// function : AddWLine +// purpose : +//================================================================================== + +void AddWLine(IntPatch_SequenceOfLine &theLines, + const Handle(IntPatch_WLine) &theWLine, + const Standard_Real Deflection) +{ + Standard_Integer i = 1; + Standard_Integer aNbLines = theLines.Length(); + Standard_Boolean isToRemove; + + // Check each line of theLines if it is on theWLine. + while (i <= aNbLines) { + Handle(IntPatch_WLine) aWLine = + Handle(IntPatch_WLine)::DownCast(theLines.Value(i)); + + isToRemove = Standard_False; + + if (aWLine.IsNull() == Standard_False) { + // Check the middle point. + Standard_Integer aMidIndex = (aWLine->NbPnts() + 1)/2; + + if (aMidIndex > 0) { + const IntSurf_PntOn2S &aPnt = aWLine->Point(aMidIndex); + + if (IsPointOnLine(aPnt, theWLine, Deflection)) { + // Middle point is on theWLine. Check vertices. + isToRemove = Standard_True; + + Standard_Integer j; + const Standard_Integer aNbVtx = aWLine->NbVertex(); + + for (j = 1; j <= aNbVtx; j++) { + const IntPatch_Point &aPoint = aWLine->Vertex(j); + + if (!IsPointOnLine(aPoint.PntOn2S(), theWLine, Deflection)) { + isToRemove = Standard_False; + break; + } + } + } + } + } + + if (isToRemove) { + theLines.Remove(i); + aNbLines--; + } else { + i++; + } + } + + // Add theWLine to the sequence of lines. + theLines.Append(theWLine); +} diff --git a/tests/bugs/moddata_2/bug567 b/tests/bugs/moddata_2/bug567 index dbfa54d72b..e8f5fe2b1c 100755 --- a/tests/bugs/moddata_2/bug567 +++ b/tests/bugs/moddata_2/bug567 @@ -11,11 +11,19 @@ puts "" restore [locate_data_file OCC567a.draw] s1 restore [locate_data_file OCC567b.draw] s2 +if { [string compare $tcl_platform(platform) "windows"] == 0 } { + puts "OS = Windows NT" + set N_repeat 10 +} else { + puts "OS = Linux" + set N_repeat 11 +} + if { [catch {intersect i s1 s2 } catch_result] } { puts "Faulty OCC565: function intersection works wrongly with infinite Surfaces" } else { set j 1 - repeat 11 { + repeat ${N_repeat} { set err [lindex [whatis i_$j] 5] if { $err != "curve"} { puts " Faulty OCC565: function intersection works wrongly with infinite Surfaces" diff --git a/tests/bugs/moddata_3/bug23471 b/tests/bugs/moddata_3/bug23471 new file mode 100755 index 0000000000..6652e3f147 --- /dev/null +++ b/tests/bugs/moddata_3/bug23471 @@ -0,0 +1,18 @@ +puts "============" +puts "CR23471" +puts "============" +puts "" +####################################################################### +# Intersection algorithm produces overlapping intersection curves +####################################################################### + +restore [locate_data_file OCC22790-cx.brep] b + +explode b +mksurface s1 b_1 +mksurface s2 b_3 +intersect res s1 s2 + +if ![info exists res] { + puts "Error : there are more then 1 curve" +}