From: nbv Date: Tue, 29 Mar 2016 13:38:53 +0000 (+0300) Subject: 0027302: Invalid curves number in intersection result X-Git-Tag: V7_0_winwerth~85 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=b8f67cc23674666a76f7f2b9f1a5fd78abc4cd31 0027302: Invalid curves number in intersection result 1. In frame of the fix for #27282 issue, we have obtained several prolonged curves, which have common point(s). Fix for this issue joins these curves if it is possible. 2. ElCLib::InPeriod(...) method has been improved. Now it has become more faster (in general cases) and more reliable (in frame of FLT_OVERFLOW and DIVISION_BY_ZERO cases processing). Creation of test case for issue #27302 Test case tests\bugs\modalg_6\bug27282_2 has been adjusted in accordance with its new behavior. --- diff --git a/src/ElCLib/ElCLib.cxx b/src/ElCLib/ElCLib.cxx index 121ce56ac5..170dd2d6d9 100644 --- a/src/ElCLib/ElCLib.cxx +++ b/src/ElCLib/ElCLib.cxx @@ -48,20 +48,25 @@ static Standard_Real PIPI = M_PI + M_PI; //======================================================================= //function : InPeriod -//purpose : +//purpose : Value theULast is never returned. //======================================================================= - -Standard_Real ElCLib::InPeriod(const Standard_Real U, - const Standard_Real UFirst, - const Standard_Real ULast) +Standard_Real ElCLib::InPeriod(const Standard_Real theU, + const Standard_Real theUFirst, + const Standard_Real theULast) { - Standard_Real u = U, period = ULast - UFirst; - Standard_Real Eps = Epsilon(period); + if( Precision::IsInfinite(theU) || + Precision::IsInfinite(theUFirst) || + Precision::IsInfinite(theULast)) + {//In order to avoid FLT_Overflow exception + return theU; + } + + const Standard_Real aPeriod = theULast - theUFirst; + + if(aPeriod < Epsilon(theULast)) + return theU; - while (Eps < (UFirst-u)) u += period; - while (Eps > (ULast -u)) u -= period; - if ( u < UFirst) u = UFirst; - return u; + return Max(theUFirst, theU + aPeriod*Ceiling((theUFirst-theU)/aPeriod)); } //======================================================================= diff --git a/src/IntPatch/IntPatch_Intersection.cxx b/src/IntPatch/IntPatch_Intersection.cxx index 719b406bad..5e02c67621 100644 --- a/src/IntPatch/IntPatch_Intersection.cxx +++ b/src/IntPatch/IntPatch_Intersection.cxx @@ -1442,12 +1442,34 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the if(isQuadSet) { + Bnd_Box2d aBx1, aBx2; + const Standard_Real aU1F = theS1->FirstUParameter(), + aU1L = theS1->LastUParameter(), + aV1F = theS1->FirstVParameter(), + aV1L = theS1->LastVParameter(), + aU2F = theS2->FirstUParameter(), + aU2L = theS2->LastUParameter(), + aV2F = theS2->FirstVParameter(), + aV2L = theS2->LastVParameter(); + aBx1.Add(gp_Pnt2d(aU1F, aV1F)); + aBx1.Add(gp_Pnt2d(aU1L, aV1F)); + aBx1.Add(gp_Pnt2d(aU1L, aV1L)); + aBx1.Add(gp_Pnt2d(aU1F, aV1L)); + aBx2.Add(gp_Pnt2d(aU2F, aV2F)); + aBx2.Add(gp_Pnt2d(aU2L, aV2F)); + aBx2.Add(gp_Pnt2d(aU2L, aV2L)); + aBx2.Add(gp_Pnt2d(aU2F, aV2L)); + + aBx1.Enlarge(Precision::PConfusion()); + aBx2.Enlarge(Precision::PConfusion()); + IntPatch_WLineTool:: ExtendTwoWlinesToEachOther(slin, Quad1, Quad2, TolTang, theS1->IsUPeriodic()? theS1->UPeriod() : 0.0, theS2->IsUPeriodic()? theS2->UPeriod() : 0.0, theS1->IsVPeriodic()? theS1->VPeriod() : 0.0, - theS2->IsVPeriodic()? theS2->VPeriod() : 0.0); + theS2->IsVPeriodic()? theS2->VPeriod() : 0.0, + aBx1, aBx2); } for (Standard_Integer i = 1; i <= interii.NbPnts(); i++) diff --git a/src/IntPatch/IntPatch_PointLine.hxx b/src/IntPatch/IntPatch_PointLine.hxx index 71477fe378..9dc3bad2fb 100644 --- a/src/IntPatch/IntPatch_PointLine.hxx +++ b/src/IntPatch/IntPatch_PointLine.hxx @@ -45,8 +45,12 @@ class IntPatch_PointLine : public IntPatch_Line public: - //! Adds a vertex in the list. - Standard_EXPORT virtual void AddVertex (const IntPatch_Point& Pnt) = 0; + //! Adds a vertex in the list. If theIsPrepend == TRUE the new + //! vertex will be added before the first element of vertices sequence. + //! Otherwise, to the end of the sequence + Standard_EXPORT virtual + void AddVertex (const IntPatch_Point& Pnt, + const Standard_Boolean theIsPrepend = Standard_False) = 0; //! Returns the number of intersection points. Standard_EXPORT virtual Standard_Integer NbPnts() const = 0; diff --git a/src/IntPatch/IntPatch_RLine.hxx b/src/IntPatch/IntPatch_RLine.hxx index f91273b128..7c5612464a 100644 --- a/src/IntPatch/IntPatch_RLine.hxx +++ b/src/IntPatch/IntPatch_RLine.hxx @@ -58,8 +58,11 @@ public: //! when the transitions are Undecided. Standard_EXPORT IntPatch_RLine(const Standard_Boolean Tang); - //! To add a vertex in the list. - virtual void AddVertex (const IntPatch_Point& Pnt) Standard_OVERRIDE; + //! Adds a vertex in the list. If theIsPrepend == TRUE the new + //! vertex will be added before the first element of vertices sequence. + //! Otherwise, to the end of the sequence + virtual void AddVertex (const IntPatch_Point& Pnt, + const Standard_Boolean theIsPrepend = Standard_False) Standard_OVERRIDE; //! Replaces the element of range Index in the list //! of points. diff --git a/src/IntPatch/IntPatch_RLine.lxx b/src/IntPatch/IntPatch_RLine.lxx index 70debb4323..e4275eab8a 100644 --- a/src/IntPatch/IntPatch_RLine.lxx +++ b/src/IntPatch/IntPatch_RLine.lxx @@ -32,9 +32,13 @@ inline const Handle(Adaptor2d_HCurve2d)& IntPatch_RLine::ArcOnS2() const //-- Il faut mettre cet include ici , car l include fait un define Handle(Adaptor2d_HCurve2d) ... //-- et en fin de fichier un undef Handle(Adaptor2d_HCurve2d) ... -inline void IntPatch_RLine::AddVertex (const IntPatch_Point& Pnt) +inline void IntPatch_RLine::AddVertex (const IntPatch_Point& thePnt, + const Standard_Boolean theIsPrepend) { - svtx.Append(Pnt); + if(theIsPrepend) + svtx.Prepend(thePnt); + else + svtx.Append(thePnt); } inline void IntPatch_RLine::Replace (const Standard_Integer Index, diff --git a/src/IntPatch/IntPatch_WLine.hxx b/src/IntPatch/IntPatch_WLine.hxx index 4cfeabf081..1dba81867d 100644 --- a/src/IntPatch/IntPatch_WLine.hxx +++ b/src/IntPatch/IntPatch_WLine.hxx @@ -62,8 +62,11 @@ public: //! transitions are Undecided. Standard_EXPORT IntPatch_WLine(const Handle(IntSurf_LineOn2S)& Line, const Standard_Boolean Tang); - //! Adds a vertex in the list. - virtual void AddVertex (const IntPatch_Point& Pnt) Standard_OVERRIDE; + //! Adds a vertex in the list. If theIsPrepend == TRUE the new + //! vertex will be added before the first element of vertices sequence. + //! Otherwise, to the end of the sequence + virtual void AddVertex (const IntPatch_Point& Pnt, + const Standard_Boolean theIsPrepend = Standard_False) Standard_OVERRIDE; //! Set the Point of index in the LineOn2S Standard_EXPORT void SetPoint (const Standard_Integer Index, const IntPatch_Point& Pnt); diff --git a/src/IntPatch/IntPatch_WLine.lxx b/src/IntPatch/IntPatch_WLine.lxx index 6c95ee842f..9eab7c6c6e 100644 --- a/src/IntPatch/IntPatch_WLine.lxx +++ b/src/IntPatch/IntPatch_WLine.lxx @@ -19,9 +19,13 @@ #include -inline void IntPatch_WLine::AddVertex (const IntPatch_Point& Pnt) +inline void IntPatch_WLine::AddVertex (const IntPatch_Point& thePnt, + const Standard_Boolean theIsPrepend) { - svtx.Append(Pnt); + if(theIsPrepend) + svtx.Prepend(thePnt); + else + svtx.Append(thePnt); } inline void IntPatch_WLine::Replace (const Standard_Integer Index, diff --git a/src/IntPatch/IntPatch_WLineTool.cxx b/src/IntPatch/IntPatch_WLineTool.cxx index 9da9e9dd36..e6080a3e8f 100644 --- a/src/IntPatch/IntPatch_WLineTool.cxx +++ b/src/IntPatch/IntPatch_WLineTool.cxx @@ -15,6 +15,19 @@ #include #include +#include + +//Bit-mask is used for information about +//the operation made in +//IntPatch_WLineTool::ExtendTwoWlinesToEachOther() method. +enum +{ + IntPatchWT_EnAll = 0x00, + IntPatchWT_DisLastLast = 0x01, + IntPatchWT_DisLastFirst = 0x02, + IntPatchWT_DisFirstLast = 0x04, + IntPatchWT_DisFirstFirst = 0x08 +}; //======================================================================= //function : MinMax @@ -458,23 +471,24 @@ static Handle(IntPatch_WLine) } //======================================================================= -//function : IsSeam -//purpose : Returns: -// 0 - if interval [theU1, theU2] does not intersect the "seam-edge" -// or if "seam-edge" do not exist; -// 1 - if interval (theU1, theU2) intersect the "seam-edge". -// 2 - if theU1 or/and theU2 lie ON the "seam-edge" +//function : IsOnPeriod +//purpose : Checks, if [theU1, theU2] intersects the period-value +// (k*thePeriod, where k is an integer number (k = 0, +/-1, +/-2, ...). +// +// Returns: +// 0 - if interval [theU1, theU2] does not intersect the "period-value" +// or if thePeriod == 0.0; +// 1 - if interval (theU1, theU2) intersect the "period-value". +// 2 - if theU1 or/and theU2 lie ON the "period-value" // //ATTENTION!!! // If (theU1 == theU2) then this function will return only both 0 or 2. -// -// Static subfunction in IsSeamOrBound. //======================================================================= -static Standard_Integer IsSeam( const Standard_Real theU1, - const Standard_Real theU2, - const Standard_Real thePeriod) +static Standard_Integer IsOnPeriod(const Standard_Real theU1, + const Standard_Real theU2, + const Standard_Real thePeriod) { - if(IsEqual(thePeriod, 0.0)) + if(thePeriod < RealSmall()) return 0; //If interval [theU1, theU2] intersect seam-edge then there exists an integer @@ -590,16 +604,16 @@ static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePtf, return Standard_True; } - if(IsSeam(aU11, aU21, theU1Period)) + if(IsOnPeriod(aU11, aU21, theU1Period)) return Standard_True; - if(IsSeam(aV11, aV21, theV1Period)) + if(IsOnPeriod(aV11, aV21, theV1Period)) return Standard_True; - if(IsSeam(aU12, aU22, theU2Period)) + if(IsOnPeriod(aU12, aU22, theU2Period)) return Standard_True; - if(IsSeam(aV12, aV22, theV2Period)) + if(IsOnPeriod(aV12, aV22, theV2Period)) return Standard_True; /* @@ -634,16 +648,16 @@ static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePtf, if(IsEqual(aV2, theVfSurf2) || IsEqual(aV2, theVlSurf2)) return Standard_True; - if(IsSeam(aU1, aU1, theU1Period)) + if(IsOnPeriod(aU1, aU1, theU1Period)) return Standard_True; - if(IsSeam(aU2, aU2, theU2Period)) + if(IsOnPeriod(aU2, aU2, theU2Period)) return Standard_True; - if(IsSeam(aV1, aV1, theV1Period)) + if(IsOnPeriod(aV1, aV1, theV1Period)) return Standard_True; - if(IsSeam(aV2, aV2, theV2Period)) + if(IsOnPeriod(aV2, aV2, theV2Period)) return Standard_True; return Standard_False; @@ -712,22 +726,42 @@ static Standard_Boolean IsIntersectionPoint(const gp_Pnt& thePmid, //purpose : Adds thePOn2S to the begin of theWline //======================================================================= static void ExtendFirst(const Handle(IntPatch_WLine)& theWline, - const IntSurf_PntOn2S &thePOn2S) + const IntSurf_PntOn2S& theAddedPt) { - theWline->Curve()->InsertBefore(1, thePOn2S); + Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0; + theAddedPt.Parameters(aU1, aV1, aU2, aV2); - IntPatch_Point &aVert = theWline->ChangeVertex(1); + if(theAddedPt.IsSame(theWline->Point(1), Precision::Confusion())) + { + theWline->Curve()->Value(1, theAddedPt); + for(Standard_Integer i = 1; i <= theWline->NbVertex(); i++) + { + IntPatch_Point &aVert = theWline->ChangeVertex(i); + if(aVert.ParameterOnLine() != 1) + break; - Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0; - thePOn2S.Parameters(aU1, aV1, aU2, aV2); + aVert.SetParameters(aU1, aV1, aU2, aV2); + aVert.SetValue(theAddedPt.Value()); + } + + return; + } - aVert.SetParameters(aU1, aV1, aU2, aV2); - aVert.SetValue(thePOn2S.Value()); + theWline->Curve()->InsertBefore(1, theAddedPt); - for(Standard_Integer i = 2; i <= theWline->NbVertex(); i++) + for(Standard_Integer i = 1; i <= theWline->NbVertex(); i++) { - IntPatch_Point &aV = theWline->ChangeVertex(i); - aV.SetParameter(aV.ParameterOnLine()+1); + IntPatch_Point &aVert = theWline->ChangeVertex(i); + + if(aVert.ParameterOnLine() == 1) + { + aVert.SetParameters(aU1, aV1, aU2, aV2); + aVert.SetValue(theAddedPt.Value()); + } + else + { + aVert.SetParameter(aVert.ParameterOnLine()+1); + } } } @@ -736,18 +770,421 @@ static void ExtendFirst(const Handle(IntPatch_WLine)& theWline, //purpose : Adds thePOn2S to the end of theWline //======================================================================= static void ExtendLast(const Handle(IntPatch_WLine)& theWline, - const IntSurf_PntOn2S &thePOn2S) + const IntSurf_PntOn2S& theAddedPt) { - theWline->Curve()->Add(thePOn2S); + Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0; + theAddedPt.Parameters(aU1, aV1, aU2, aV2); + + const Standard_Integer aNbPnts = theWline->NbPnts(); + if(theAddedPt.IsSame(theWline->Point(aNbPnts), Precision::Confusion())) + { + theWline->Curve()->Value(aNbPnts, theAddedPt); + } + else + { + theWline->Curve()->Add(theAddedPt); + } - IntPatch_Point &aVert = theWline->ChangeVertex(theWline->NbVertex()); + for(Standard_Integer i = theWline->NbVertex(); i >= 1; i--) + { + IntPatch_Point &aVert = theWline->ChangeVertex(i); + if(aVert.ParameterOnLine() != aNbPnts) + break; + aVert.SetParameters(aU1, aV1, aU2, aV2); + aVert.SetValue(theAddedPt.Value()); + aVert.SetParameter(theWline->NbPnts()); + } +} + +//========================================================================= +// function: IsOutOfDomain +// purpose : Checks, if 2D-representation of thePOn2S is in surfaces domain, +// defined by bounding-boxes theBoxS1 and theBoxS2 +//========================================================================= +static Standard_Boolean IsOutOfDomain(const Bnd_Box2d& theBoxS1, + const Bnd_Box2d& theBoxS2, + const IntSurf_PntOn2S &thePOn2S, + const Standard_Real theU1Period, + const Standard_Real theU2Period, + const Standard_Real theV1Period, + const Standard_Real theV2Period) +{ Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0; + Standard_Real aU1min = 0.0, aU1max = 0.0, aV1min = 0.0, aV1max = 0.0; + Standard_Real aU2min = 0.0, aU2max = 0.0, aV2min = 0.0, aV2max = 0.0; + thePOn2S.Parameters(aU1, aV1, aU2, aV2); - aVert.SetParameters(aU1, aV1, aU2, aV2); - aVert.SetValue(thePOn2S.Value()); - aVert.SetParameter(theWline->NbPnts()); + theBoxS1.Get(aU1min, aV1min, aU1max, aV1max); + theBoxS2.Get(aU2min, aV2min, aU2max, aV2max); + + aU1 = ElCLib::InPeriod(aU1, aU1min, aU1min + theU1Period); + aV1 = ElCLib::InPeriod(aV1, aV1min, aV1min + theV1Period); + aU2 = ElCLib::InPeriod(aU2, aU2min, aU2min + theU2Period); + aV2 = ElCLib::InPeriod(aV2, aV2min, aV2min + theV2Period); + + return (theBoxS1.IsOut(gp_Pnt2d(aU1, aV1)) || + theBoxS2.IsOut(gp_Pnt2d(aU2, aV2))); +} + +//======================================================================= +//function : CheckArguments +//purpose : Check if extending is possible +// (see IntPatch_WLineTool::ExtendTwoWlinesToEachOther) +//======================================================================= +static Standard_Boolean CheckArguments(const IntSurf_Quadric& theS1, + const IntSurf_Quadric& theS2, + const IntSurf_PntOn2S& thePtWL1, + const IntSurf_PntOn2S& thePtWL2, + IntSurf_PntOn2S& theNewPoint, + const gp_Vec& theVec1, + const gp_Vec& theVec2, + const gp_Vec& theVec3, + const Bnd_Box2d& theBoxS1, + const Bnd_Box2d& theBoxS2, + const Standard_Real theToler3D, + const Standard_Real theU1Period, + const Standard_Real theU2Period, + const Standard_Real theV1Period, + const Standard_Real theV2Period) +{ + const Standard_Real aMaxAngle = M_PI/6; //30 degree + const Standard_Real aSqToler = theToler3D*theToler3D; + + if(theVec3.SquareMagnitude() <= aSqToler) + { + return Standard_False; + } + + if((theVec1.Angle(theVec2) > aMaxAngle) || + (theVec1.Angle(theVec3) > aMaxAngle) || + (theVec2.Angle(theVec3) > aMaxAngle)) + { + return Standard_False; + } + + const gp_Pnt aPmid(0.5*(thePtWL1.Value().XYZ()+thePtWL2.Value().XYZ())); + + Standard_Real aU1=0.0, aV1=0.0, aU2=0.0, aV2=0.0; + + theBoxS1.Get(aU1, aV1, aU2, aV2); + const Standard_Real aU1f = aU1, aV1f = aV1; + theBoxS2.Get(aU1, aV1, aU2, aV2); + const Standard_Real aU2f = aU1, aV2f = aV1; + + if(!IsIntersectionPoint(aPmid, theS1, theS2, thePtWL1, theToler3D, + theU1Period, theU2Period, theV1Period, theV2Period, + aU1, aV1, aU2, aV2)) + { + return Standard_False; + } + + theNewPoint.SetValue(aPmid, aU1, aV1, aU2, aV2); + + if(IsOutOfDomain(theBoxS1, theBoxS2, theNewPoint, + theU1Period, theU2Period, + theV1Period, theV2Period)) + { + return Standard_False; + } + + Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0, + aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0; + + thePtWL1.Parameters(aU11, aV11, aU21, aV21); + thePtWL2.Parameters(aU12, aV12, aU22, aV22); + + if(IsOnPeriod(aU11 - aU1f, aU12 - aU1f, theU1Period) || + IsOnPeriod(aV11 - aV1f, aV12 - aV1f, theV1Period) || + IsOnPeriod(aU21 - aU2f, aU22 - aU2f, theU2Period) || + IsOnPeriod(aV21 - aV2f, aV22 - aV2f, theV2Period)) + { + return Standard_False; + } + + return Standard_True; +} + +//======================================================================= +//function : ExtendTwoWLFirstFirst +//purpose : Performs extending theWLine1 and theWLine2 through their +// respecting start point. +//======================================================================= +static void ExtendTwoWLFirstFirst(const IntSurf_Quadric& theS1, + const IntSurf_Quadric& theS2, + const Handle(IntPatch_WLine)& theWLine1, + const Handle(IntPatch_WLine)& theWLine2, + const IntSurf_PntOn2S& thePtWL1, + const IntSurf_PntOn2S& thePtWL2, + const gp_Vec& theVec1, + const gp_Vec& theVec2, + const gp_Vec& theVec3, + const Bnd_Box2d& theBoxS1, + const Bnd_Box2d& theBoxS2, + const Standard_Real theToler3D, + const Standard_Real theU1Period, + const Standard_Real theU2Period, + const Standard_Real theV1Period, + const Standard_Real theV2Period, + unsigned int &theCheckResult, + Standard_Boolean &theHasBeenJoined) +{ + IntSurf_PntOn2S aPOn2S; + if(!CheckArguments(theS1, theS2, thePtWL1, thePtWL2, aPOn2S, + theVec1, theVec2, theVec3, + theBoxS1, theBoxS2, theToler3D, + theU1Period, theU2Period, theV1Period, theV2Period)) + { + return; + } + + theCheckResult |= (IntPatchWT_DisFirstLast | IntPatchWT_DisLastFirst); + + ExtendFirst(theWLine1, aPOn2S); + ExtendFirst(theWLine2, aPOn2S); + + if(theHasBeenJoined) + return; + + Standard_Real aPrm = theWLine1->Vertex(1).ParameterOnLine(); + while(theWLine1->Vertex(1).ParameterOnLine() == aPrm) + theWLine1->RemoveVertex(1); + + aPrm = theWLine2->Vertex(1).ParameterOnLine(); + while(theWLine2->Vertex(1).ParameterOnLine() == aPrm) + theWLine2->RemoveVertex(1); + + const Standard_Integer aNbPts = theWLine2->NbPnts(); + for(Standard_Integer aNPt = 2; aNPt <= aNbPts; aNPt++) + { + const IntSurf_PntOn2S& aPt = theWLine2->Point(aNPt); + theWLine1->Curve()->InsertBefore(1, aPt); + } + + for(Standard_Integer aNVtx = 1; aNVtx <= theWLine1->NbVertex(); aNVtx++) + { + IntPatch_Point &aVert = theWLine1->ChangeVertex(aNVtx); + const Standard_Real aCurParam = aVert.ParameterOnLine(); + aVert.SetParameter(aNbPts+aCurParam-1); + } + + for(Standard_Integer aNVtx = 1; aNVtx <= theWLine2->NbVertex(); aNVtx++) + { + IntPatch_Point &aVert = theWLine2->ChangeVertex(aNVtx); + const Standard_Real aCurParam = aVert.ParameterOnLine(); + aVert.SetParameter(aNbPts-aCurParam+1); + theWLine1->AddVertex(aVert, Standard_True); + } + + theHasBeenJoined = Standard_True; +} + +//======================================================================= +//function : ExtendTwoWLFirstLast +//purpose : Performs extending theWLine1 through its start point and theWLine2 +// through its end point. +//======================================================================= +static void ExtendTwoWLFirstLast(const IntSurf_Quadric& theS1, + const IntSurf_Quadric& theS2, + const Handle(IntPatch_WLine)& theWLine1, + const Handle(IntPatch_WLine)& theWLine2, + const IntSurf_PntOn2S& thePtWL1, + const IntSurf_PntOn2S& thePtWL2, + const gp_Vec& theVec1, + const gp_Vec& theVec2, + const gp_Vec& theVec3, + const Bnd_Box2d& theBoxS1, + const Bnd_Box2d& theBoxS2, + const Standard_Real theToler3D, + const Standard_Real theU1Period, + const Standard_Real theU2Period, + const Standard_Real theV1Period, + const Standard_Real theV2Period, + unsigned int &theCheckResult, + Standard_Boolean &theHasBeenJoined) +{ + IntSurf_PntOn2S aPOn2S; + if(!CheckArguments(theS1, theS2, thePtWL1, thePtWL2, aPOn2S, + theVec1, theVec2, theVec3, + theBoxS1, theBoxS2, theToler3D, + theU1Period, theU2Period, theV1Period, theV2Period)) + { + return; + } + + theCheckResult |= IntPatchWT_DisLastLast; + + ExtendFirst(theWLine1, aPOn2S); + ExtendLast (theWLine2, aPOn2S); + + if(theHasBeenJoined) + return; + + Standard_Real aPrm = theWLine1->Vertex(1).ParameterOnLine(); + while(theWLine1->Vertex(1).ParameterOnLine() == aPrm) + theWLine1->RemoveVertex(1); + + aPrm = theWLine2->Vertex(theWLine2->NbVertex()).ParameterOnLine(); + while(theWLine2->Vertex(theWLine2->NbVertex()).ParameterOnLine() == aPrm) + theWLine2->RemoveVertex(theWLine2->NbVertex()); + + const Standard_Integer aNbPts = theWLine2->NbPnts(); + for(Standard_Integer aNPt = aNbPts - 1; aNPt >= 1; aNPt--) + { + const IntSurf_PntOn2S& aPt = theWLine2->Point(aNPt); + theWLine1->Curve()->InsertBefore(1, aPt); + } + + for(Standard_Integer aNVtx = 1; aNVtx <= theWLine1->NbVertex(); aNVtx++) + { + IntPatch_Point &aVert = theWLine1->ChangeVertex(aNVtx); + const Standard_Real aCurParam = aVert.ParameterOnLine(); + aVert.SetParameter(aNbPts+aCurParam-1); + } + + for(Standard_Integer aNVtx = theWLine2->NbVertex(); aNVtx >= 1; aNVtx--) + { + const IntPatch_Point &aVert = theWLine2->Vertex(aNVtx); + theWLine1->AddVertex(aVert, Standard_True); + } + + theHasBeenJoined = Standard_True; +} + +//======================================================================= +//function : ExtendTwoWLLastFirst +//purpose : Performs extending theWLine1 through its end point and theWLine2 +// through its start point. +//======================================================================= +static void ExtendTwoWLLastFirst(const IntSurf_Quadric& theS1, + const IntSurf_Quadric& theS2, + const Handle(IntPatch_WLine)& theWLine1, + const Handle(IntPatch_WLine)& theWLine2, + const IntSurf_PntOn2S& thePtWL1, + const IntSurf_PntOn2S& thePtWL2, + const gp_Vec& theVec1, + const gp_Vec& theVec2, + const gp_Vec& theVec3, + const Bnd_Box2d& theBoxS1, + const Bnd_Box2d& theBoxS2, + const Standard_Real theToler3D, + const Standard_Real theU1Period, + const Standard_Real theU2Period, + const Standard_Real theV1Period, + const Standard_Real theV2Period, + unsigned int &theCheckResult, + Standard_Boolean &theHasBeenJoined) +{ + IntSurf_PntOn2S aPOn2S; + if(!CheckArguments(theS1, theS2, thePtWL1, thePtWL2, aPOn2S, + theVec1, theVec2, theVec3, + theBoxS1, theBoxS2, theToler3D, + theU1Period, theU2Period, theV1Period, theV2Period)) + { + return; + } + + theCheckResult |= IntPatchWT_DisLastLast; + + ExtendLast (theWLine1, aPOn2S); + ExtendFirst(theWLine2, aPOn2S); + + if(theHasBeenJoined) + { + return; + } + + Standard_Real aPrm = theWLine1->Vertex(theWLine1->NbVertex()).ParameterOnLine(); + while(theWLine1->Vertex(theWLine1->NbVertex()).ParameterOnLine() == aPrm) + theWLine1->RemoveVertex(theWLine1->NbVertex()); + + aPrm = theWLine2->Vertex(1).ParameterOnLine(); + while(theWLine2->Vertex(1).ParameterOnLine() == aPrm) + theWLine2->RemoveVertex(1); + + const Standard_Integer aNbPts = theWLine1->NbPnts(); + for(Standard_Integer aNPt = 2; aNPt <= theWLine2->NbPnts(); aNPt++) + { + const IntSurf_PntOn2S& aPt = theWLine2->Point(aNPt); + theWLine1->Curve()->Add(aPt); + } + + for(Standard_Integer aNVtx = 1; aNVtx <= theWLine2->NbVertex(); aNVtx++) + { + IntPatch_Point &aVert = theWLine2->ChangeVertex(aNVtx); + const Standard_Real aCurParam = aVert.ParameterOnLine(); + aVert.SetParameter(aNbPts+aCurParam-1); + theWLine1->AddVertex(aVert, Standard_False); + } + + theHasBeenJoined = Standard_True; +} + +//======================================================================= +//function : ExtendTwoWLLastLast +//purpose : +//======================================================================= +static void ExtendTwoWLLastLast(const IntSurf_Quadric& theS1, + const IntSurf_Quadric& theS2, + const Handle(IntPatch_WLine)& theWLine1, + const Handle(IntPatch_WLine)& theWLine2, + const IntSurf_PntOn2S& thePtWL1, + const IntSurf_PntOn2S& thePtWL2, + const gp_Vec& theVec1, + const gp_Vec& theVec2, + const gp_Vec& theVec3, + const Bnd_Box2d& theBoxS1, + const Bnd_Box2d& theBoxS2, + const Standard_Real theToler3D, + const Standard_Real theU1Period, + const Standard_Real theU2Period, + const Standard_Real theV1Period, + const Standard_Real theV2Period, + unsigned int &/*theCheckResult*/, + Standard_Boolean &theHasBeenJoined) +{ + IntSurf_PntOn2S aPOn2S; + if(!CheckArguments(theS1, theS2, thePtWL1, thePtWL2, aPOn2S, + theVec1, theVec2, theVec3, + theBoxS1, theBoxS2, theToler3D, + theU1Period, theU2Period, theV1Period, theV2Period)) + { + return; + } + + //theCheckResult |= IntPatchWT_DisLastLast; + + ExtendLast(theWLine1, aPOn2S); + ExtendLast(theWLine2, aPOn2S); + + if(theHasBeenJoined) + return; + + Standard_Real aPrm = theWLine1->Vertex(theWLine1->NbVertex()).ParameterOnLine(); + while(theWLine1->Vertex(theWLine1->NbVertex()).ParameterOnLine() == aPrm) + theWLine1->RemoveVertex(theWLine1->NbVertex()); + + aPrm = theWLine2->Vertex(theWLine2->NbVertex()).ParameterOnLine(); + while(theWLine2->Vertex(theWLine2->NbVertex()).ParameterOnLine() == aPrm) + theWLine2->RemoveVertex(theWLine2->NbVertex()); + + const Standard_Integer aNbPts = theWLine1->NbPnts() + theWLine2->NbPnts(); + for(Standard_Integer aNPt = theWLine2->NbPnts()-1; aNPt >= 1; aNPt--) + { + const IntSurf_PntOn2S& aPt = theWLine2->Point(aNPt); + theWLine1->Curve()->Add(aPt); + } + + for(Standard_Integer aNVtx = theWLine2->NbVertex(); aNVtx >= 1; aNVtx--) + { + IntPatch_Point &aVert = theWLine2->ChangeVertex(aNVtx); + const Standard_Real aCurParam = aVert.ParameterOnLine(); + aVert.SetParameter(aNbPts - aCurParam); + theWLine1->AddVertex(aVert, Standard_False); + } + + theHasBeenJoined = Standard_True; } //========================================================================= @@ -1054,7 +1491,8 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin, //======================================================================= //function : ExtendTwoWlinesToEachOther -//purpose : +//purpose : Performs extending theWLine1 and theWLine2 through their +// respecting end point. //======================================================================= void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& theSlin, const IntSurf_Quadric& theS1, @@ -1063,15 +1501,13 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the const Standard_Real theU1Period, const Standard_Real theU2Period, const Standard_Real theV1Period, - const Standard_Real theV2Period) + const Standard_Real theV2Period, + const Bnd_Box2d& theBoxS1, + const Bnd_Box2d& theBoxS2) { if(theSlin.Length() < 2) return; - const Standard_Real aMaxAngle = M_PI/6; //30 degree - const Standard_Real aSqToler = theToler3D*theToler3D; - Standard_Real aU1=0.0, aV1=0.0, aU2=0.0, aV2=0.0; - gp_Pnt aPmid; gp_Vec aVec1, aVec2, aVec3; for(Standard_Integer aNumOfLine1 = 1; aNumOfLine1 <= theSlin.Length(); aNumOfLine1++) @@ -1086,6 +1522,12 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts(); + if(aWLine1->Vertex(1).ParameterOnLine() != 1) + continue; + + if(aWLine1->Vertex(aWLine1->NbVertex()).ParameterOnLine() != aWLine1->NbPnts()) + continue; + for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1; aNumOfLine2 <= theSlin.Length(); aNumOfLine2++) { @@ -1095,21 +1537,20 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the if(aWLine2.IsNull()) continue; + if(aWLine2->Vertex(1).ParameterOnLine() != 1) + continue; + + if(aWLine2->Vertex(aWLine2->NbVertex()).ParameterOnLine() != aWLine2->NbPnts()) + continue; + //Enable/Disable of some ckeck. Bit-mask is used for it. //E.g. if 1st point of aWLine1 matches with //1st point of aWLine2 then we do not need in check //1st point of aWLine1 and last point of aWLine2 etc. - enum - { - IntPatchWT_EnAll = 0x00, - IntPatchWT_DisLastLast = 0x01, - IntPatchWT_DisLastFirst = 0x02, - IntPatchWT_DisFirstLast = 0x04, - IntPatchWT_DisFirstFirst = 0x08 - }; - unsigned int aCheckResult = IntPatchWT_EnAll; + Standard_Boolean hasBeenJoined = Standard_False; + const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts(); const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1); @@ -1130,55 +1571,11 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the aVec2.SetXYZ(aPntFWL2.Value().XYZ() - aPntFp1WL2.Value().XYZ()); aVec3.SetXYZ(aPntFWL1.Value().XYZ() - aPntFWL2.Value().XYZ()); - if(aVec3.SquareMagnitude() > aSqToler) - { - if( (aVec1.Angle(aVec2) < aMaxAngle) && - (aVec1.Angle(aVec3) < aMaxAngle) && - (aVec2.Angle(aVec3) < aMaxAngle)) - { - aPmid.SetXYZ(0.5*(aPntFWL1.Value().XYZ()+aPntFWL2.Value().XYZ())); - if(IsIntersectionPoint(aPmid, theS1, theS2, aPntFWL1, theToler3D, - theU1Period, theU2Period, theV1Period, theV2Period, - aU1, aV1, aU2, aV2)) - { - IntSurf_PntOn2S aPOn2S; - aPOn2S.SetValue(aPmid, aU1, aV1, aU2, aV2); - - Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0, - aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0; - aPntFWL1.Parameters(aU11, aV11, aU21, aV21); - aPntFWL2.Parameters(aU12, aV12, aU22, aV22); - - if(!IsSeam(aU11, aU12, theU1Period) && - !IsSeam(aV11, aV12, theV1Period) && - !IsSeam(aU21, aU22, theU2Period) && - !IsSeam(aV21, aV22, theV2Period)) - { - aCheckResult |= (IntPatchWT_DisFirstLast | - IntPatchWT_DisLastFirst); - - if(!aPOn2S.IsSame(aPntFWL1, Precision::Confusion())) - { - ExtendFirst(aWLine1, aPOn2S); - } - else - { - aWLine1->Curve()->Value(1, aPOn2S); - } - - if(!aPOn2S.IsSame(aPntFWL2, Precision::Confusion())) - { - ExtendFirst(aWLine2, aPOn2S); - } - else - { - aWLine2->Curve()->Value(1, aPOn2S); - } - } - } - } - }//if(aVec3.SquareMagnitude() > aSqToler) cond. - }//if(!(aCheckResult & 0x08)) cond. + ExtendTwoWLFirstFirst(theS1, theS2, aWLine1, aWLine2, aPntFWL1, aPntFWL2, + aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D, + theU1Period, theU2Period, theV1Period, theV2Period, + aCheckResult, hasBeenJoined); + } if(!(aCheckResult & IntPatchWT_DisFirstLast)) {// First/Last @@ -1186,54 +1583,11 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the aVec2.SetXYZ(aPntLWL2.Value().XYZ() - aPntLm1WL2.Value().XYZ()); aVec3.SetXYZ(aPntFWL1.Value().XYZ() - aPntLWL2.Value().XYZ()); - if(aVec3.SquareMagnitude() > aSqToler) - { - if((aVec1.Angle(aVec2) < aMaxAngle) && - (aVec1.Angle(aVec3) < aMaxAngle) && - (aVec2.Angle(aVec3) < aMaxAngle)) - { - aPmid.SetXYZ(0.5*(aPntFWL1.Value().XYZ()+aPntLWL2.Value().XYZ())); - if(IsIntersectionPoint(aPmid, theS1, theS2, aPntFWL1, theToler3D, - theU1Period, theU2Period, theV1Period, theV2Period, - aU1, aV1, aU2, aV2)) - { - IntSurf_PntOn2S aPOn2S; - aPOn2S.SetValue(aPmid, aU1, aV1, aU2, aV2); - - Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0, - aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0; - aPntFWL1.Parameters(aU11, aV11, aU21, aV21); - aPntLWL2.Parameters(aU12, aV12, aU22, aV22); - - if(!IsSeam(aU11, aU12, theU1Period) && - !IsSeam(aV11, aV12, theV1Period) && - !IsSeam(aU21, aU22, theU2Period) && - !IsSeam(aV21, aV22, theV2Period)) - { - aCheckResult |= IntPatchWT_DisLastLast; - - if(!aPOn2S.IsSame(aPntFWL1, Precision::Confusion())) - { - ExtendFirst(aWLine1, aPOn2S); - } - else - { - aWLine1->Curve()->Value(1, aPOn2S); - } - - if(!aPOn2S.IsSame(aPntLWL2, Precision::Confusion())) - { - ExtendLast(aWLine2, aPOn2S); - } - else - { - aWLine2->Curve()->Value(aWLine2->NbPnts(), aPOn2S); - } - } - } - } - }//if(aVec3.SquareMagnitude() > aSqToler) cond. - }//if(!(aCheckResult & 0x04)) cond. + ExtendTwoWLFirstLast(theS1, theS2, aWLine1, aWLine2, aPntFWL1, aPntLWL2, + aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D, + theU1Period, theU2Period, theV1Period, theV2Period, + aCheckResult, hasBeenJoined); + } if(!(aCheckResult & IntPatchWT_DisLastFirst)) {// Last/First @@ -1241,54 +1595,11 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the aVec2.SetXYZ(aPntFp1WL2.Value().XYZ() - aPntFWL2.Value().XYZ()); aVec3.SetXYZ(aPntFWL2.Value().XYZ() - aPntLWL1.Value().XYZ()); - if(aVec3.SquareMagnitude() > aSqToler) - { - if((aVec1.Angle(aVec2) < aMaxAngle) && - (aVec1.Angle(aVec3) < aMaxAngle) && - (aVec2.Angle(aVec3) < aMaxAngle)) - { - aPmid.SetXYZ(0.5*(aPntLWL1.Value().XYZ()+aPntFWL2.Value().XYZ())); - if(IsIntersectionPoint(aPmid, theS1, theS2, aPntLWL1, theToler3D, - theU1Period, theU2Period, theV1Period, theV2Period, - aU1, aV1, aU2, aV2)) - { - IntSurf_PntOn2S aPOn2S; - aPOn2S.SetValue(aPmid, aU1, aV1, aU2, aV2); - - Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0, - aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0; - aPntLWL1.Parameters(aU11, aV11, aU21, aV21); - aPntFWL2.Parameters(aU12, aV12, aU22, aV22); - - if(!IsSeam(aU11, aU12, theU1Period) && - !IsSeam(aV11, aV12, theV1Period) && - !IsSeam(aU21, aU22, theU2Period) && - !IsSeam(aV21, aV22, theV2Period)) - { - aCheckResult |= IntPatchWT_DisLastLast; - - if(!aPOn2S.IsSame(aPntLWL1, Precision::Confusion())) - { - ExtendLast(aWLine1, aPOn2S); - } - else - { - aWLine1->Curve()->Value(aWLine1->NbPnts(), aPOn2S); - } - - if(!aPOn2S.IsSame(aPntFWL2, Precision::Confusion())) - { - ExtendFirst(aWLine2, aPOn2S); - } - else - { - aWLine2->Curve()->Value(1, aPOn2S); - } - } - } - } - }//if(aVec3.SquareMagnitude() > aSqToler) cond. - }//if(!(aCheckResult & 0x02)) cond. + ExtendTwoWLLastFirst(theS1, theS2, aWLine1, aWLine2, aPntLWL1, aPntFWL2, + aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D, + theU1Period, theU2Period, theV1Period, theV2Period, + aCheckResult, hasBeenJoined); + } if(!(aCheckResult & IntPatchWT_DisLastLast)) {// Last/Last @@ -1296,52 +1607,17 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the aVec2.SetXYZ(aPntLm1WL2.Value().XYZ() - aPntLWL2.Value().XYZ()); aVec3.SetXYZ(aPntLWL2.Value().XYZ() - aPntLWL1.Value().XYZ()); - if(aVec3.SquareMagnitude() > aSqToler) - { - if((aVec1.Angle(aVec2) < aMaxAngle) && - (aVec1.Angle(aVec3) < aMaxAngle) && - (aVec2.Angle(aVec3) < aMaxAngle)) - { - aPmid.SetXYZ(0.5*(aPntLWL1.Value().XYZ()+aPntLWL2.Value().XYZ())); - if(IsIntersectionPoint(aPmid, theS1, theS2, aPntLWL1, theToler3D, - theU1Period, theU2Period, theV1Period, theV2Period, - aU1, aV1, aU2, aV2)) - { - IntSurf_PntOn2S aPOn2S; - aPOn2S.SetValue(aPmid, aU1, aV1, aU2, aV2); - - Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0, - aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0; - aPntLWL1.Parameters(aU11, aV11, aU21, aV21); - aPntLWL2.Parameters(aU12, aV12, aU22, aV22); - - if(!IsSeam(aU11, aU12, theU1Period) && - !IsSeam(aV11, aV12, theV1Period) && - !IsSeam(aU21, aU22, theU2Period) && - !IsSeam(aV21, aV22, theV2Period)) - { - if(!aPOn2S.IsSame(aPntLWL1, Precision::Confusion())) - { - ExtendLast(aWLine1, aPOn2S); - } - else - { - aWLine1->Curve()->Value(aWLine1->NbPnts(), aPOn2S); - } - - if(!aPOn2S.IsSame(aPntLWL2, Precision::Confusion())) - { - ExtendLast(aWLine2, aPOn2S); - } - else - { - aWLine2->Curve()->Value(aWLine2->NbPnts(), aPOn2S); - } - } - } - } - }//if(aVec3.SquareMagnitude() > aSqToler) cond. - }//if(!(aCheckResult & 0x01)) cond. + ExtendTwoWLLastLast(theS1, theS2, aWLine1, aWLine2, aPntLWL1, aPntLWL2, + aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D, + theU1Period, theU2Period, theV1Period, theV2Period, + aCheckResult, hasBeenJoined); + } + + if(hasBeenJoined) + { + theSlin.Remove(aNumOfLine2); + aNumOfLine2--; + } } } } diff --git a/src/IntPatch/IntPatch_WLineTool.hxx b/src/IntPatch/IntPatch_WLineTool.hxx index 75a8e739bf..865913c761 100644 --- a/src/IntPatch/IntPatch_WLineTool.hxx +++ b/src/IntPatch/IntPatch_WLineTool.hxx @@ -78,11 +78,9 @@ public: const Standard_Real theVlSurf2); -//! Concatenates two some Walking lines from theSlin if it is possible. -//! This method does not create single line from several. It allows every -//! extended line to be started/finished in strictly determined point -//! (in the place of joint of two lines). As result, some gaps between two lines -//! will vanish. +//! Extends every line from theSlin (if it is possible) to be started/finished +//! in strictly determined point (in the place of joint of two lines). +//! As result, some gaps between two lines will vanish. //! The Walking lines are supposed (algorithm will do nothing for not-Walking line) //! to be computed as a result of intersection of two quadrics. //! The quadrics definition is accepted in input parameters. @@ -93,7 +91,9 @@ public: const Standard_Real theU1Period, const Standard_Real theU2Period, const Standard_Real theV1Period, - const Standard_Real theV2Period); + const Standard_Real theV2Period, + const Bnd_Box2d& theBoxS1, + const Bnd_Box2d& theBoxS2); }; #endif \ No newline at end of file diff --git a/tests/bugs/modalg_6/bug27282_2 b/tests/bugs/modalg_6/bug27282_2 index 2b48d65028..da6fbca1b6 100644 --- a/tests/bugs/modalg_6/bug27282_2 +++ b/tests/bugs/modalg_6/bug27282_2 @@ -1,5 +1,3 @@ -puts "TODO OCC27302 ALL: Error: Curve Number is bad!" - puts "============" puts "OCC27282" puts "============" @@ -8,7 +6,7 @@ puts "" ## [Regression to 6.9.1] smesh/bugs_00/A6: Cut produces an empty shape ############################### -set MaxTol 4.8106951786435371e-006 +set MaxTol 4.8106952270863644e-006 set GoodNbCurv 1 restore [locate_data_file bug27282_cmpd.brep] a @@ -27,7 +25,7 @@ checkreal ToleranceReached ${Toler} ${MaxTol} 0.0 0.1 checkview -screenshot -2d -path ${imagedir}/${test_image}.png if {${NbCurv} != ${GoodNbCurv}} { - puts "Error: Curve Number is bad!" + puts "Error: Number of curves is bad!" for {set i 1} {$i < ${NbCurv}} {incr i} { for {set j [expr $i+1]} {$j <= $NbCurv} {incr j} { @@ -43,5 +41,5 @@ if {${NbCurv} != ${GoodNbCurv}} { } } } else { - checklength c_1 -l 833.56846559428755 + checklength c_1 -l 833.56846557106064 } \ No newline at end of file diff --git a/tests/bugs/modalg_6/bug27302 b/tests/bugs/modalg_6/bug27302 new file mode 100644 index 0000000000..efd39e59aa --- /dev/null +++ b/tests/bugs/modalg_6/bug27302 @@ -0,0 +1,48 @@ +puts "============" +puts "OCC27302" +puts "============" +puts "" +############################### +## Invalid curves number in intersection result +############################### + +set MaxTol 9.9579577516847715e-005 +set GoodNbCurv 1 + +restore [locate_data_file CTO900_pro12913a.rle] a +restore [locate_data_file CTO900_pro12913b.rle] b + +explode a f +explode b f + +smallview +don a_34 b_9 +fit + +set log [bopcurves a_34 b_9 -2d] + +regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv + +checkreal ToleranceReached ${Toler} ${MaxTol} 0.0 0.1 + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png + +if {${NbCurv} != ${GoodNbCurv}} { + puts "Error: Number of curves is bad!" + + for {set i 1} {$i < ${NbCurv}} {incr i} { + for {set j [expr $i+1]} {$j <= $NbCurv} {incr j} { + mkedge e1 c_$i + mkedge e2 c_$j + + dset dd_val 100.0*${Toler} + distmini dd e1 e2 + + if { [dval dd_val] > ${Toler} } { + puts "Error: Intersection result is not closed" + } + } + } +} else { + checklength c_1 -l 86.536841230136204 +} \ No newline at end of file