0026576: Wrong result obtained by intersection algorithm.
authornbv <nbv@opencascade.com>
Tue, 15 Dec 2015 13:24:31 +0000 (16:24 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 17 Dec 2015 15:01:56 +0000 (18:01 +0300)
1. Algorithm of Restriction line decomposition has been created.
2. Algorithm of check of coincidences between Walking and Restriction line has been improved in new function IsCoincide(...) (which replaces IsIn2DBox(...)).
3. Some useful methods have been added in IntPatch_PointLine (and inherited) classes.

Test cases for this issue have been created.

14 files changed:
src/ApproxInt/ApproxInt_KnotTools.cxx
src/GeomInt/GeomInt_IntSS_1.cxx
src/IntPatch/IntPatch_ImpPrmIntersection.cxx
src/IntPatch/IntPatch_PointLine.hxx
src/IntPatch/IntPatch_RLine.cxx
src/IntPatch/IntPatch_RLine.hxx
src/IntPatch/IntPatch_RLine.lxx
src/IntPatch/IntPatch_WLine.hxx
src/IntTools/IntTools_FaceFace.cxx
src/IntWalk/IntWalk_IWalking_1.gxx
tests/bugs/modalg_6/bug26576_1 [new file with mode: 0644]
tests/bugs/modalg_6/bug26576_2 [new file with mode: 0644]
tests/bugs/modalg_6/bug26576_3 [new file with mode: 0644]
tests/bugs/modalg_6/bug26576_4 [new file with mode: 0644]

index bbd42ff..f155c87 100644 (file)
@@ -153,7 +153,7 @@ void ApproxInt_KnotTools::ComputeKnotInds(const NCollection_LocalArray<Standard_
     aMaxCurv = aCurv(i);
   }
 
-#if defined(APPROXINT_KNOTTOOLS_DEBUG) || defined(OCCT_DEBUG)
+#ifdef APPROXINT_KNOTTOOLS_DEBUG
   cout << "Discrete curvature array is" << endl;
   for(i = aCurv.Lower(); i <= aCurv.Upper(); ++i)
   {
index 76e1e88..dbabd3d 100644 (file)
@@ -658,8 +658,8 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
     Handle(IntPatch_WLine) WL = 
       Handle(IntPatch_WLine)::DownCast(L);
 
-#ifdef OCCT_DEBUG
-    //WL->Dump(0);
+#ifdef GEOMINT_INTSS_DEBUG
+    WL->Dump(0);
 #endif
 
     //
index b59c0ab..9b0d36e 100644 (file)
@@ -70,7 +70,7 @@
 
 #include <Extrema_GenLocateExtPS.hxx>
 
-static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
+static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLine,
                                         const Standard_Boolean       IsReversed,
                                         const IntSurf_Quadric&       theQuad,
                                         const Handle(Adaptor3d_TopolTool)& thePDomain,
@@ -97,11 +97,14 @@ static
   Standard_Real U2,
   Standard_Real V2);
 
-static Standard_Boolean IsIn2DBox(const Bnd_Box2d& theBox,
-                                  const Handle(IntPatch_PointLine)& theLine,
-                                  const Standard_Real theUPeriod,
-                                  const Standard_Real theVPeriod,
-                                  const Standard_Boolean isTheSurface1Using);
+static 
+  Standard_Boolean IsCoincide(IntPatch_TheSurfFunction& theFunc,
+                              const Handle(IntPatch_PointLine)& theLine,
+                              const Handle(Adaptor2d_HCurve2d)& theArc,
+                              const Standard_Boolean isTheSurface1Using,
+                              const Standard_Real theToler3D,
+                              const Standard_Real theToler2D,
+                              const Standard_Real thePeriod);
 
 //=======================================================================
 //function : IntPatch_ImpPrmIntersection
@@ -788,8 +791,8 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
         // <-A
         wline = new IntPatch_WLine(thelin,Standard_False,trans1,trans2);
 
-#ifdef OCCT_DEBUG
-        //wline->Dump(0);
+#ifdef INTPATCH_IMPPRMINTERSECTION_DEBUG
+        wline->Dump(0);
 #endif
 
         if (   iwline->HasFirstPoint() 
@@ -1383,78 +1386,112 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
   // Now slin is filled as follows: lower indices correspond to Restriction line,
   // after (higher indices) - only Walking-line.
 
-  const Standard_Real aUPeriodOfSurf1 = Surf1->IsUPeriodic() ? Surf1->UPeriod() : 0.0,
-                      aUPeriodOfSurf2 = Surf2->IsUPeriodic() ? Surf2->UPeriod() : 0.0,
-                      aVPeriodOfSurf1 = Surf1->IsVPeriodic() ? Surf1->VPeriod() : 0.0,
-                      aVPeriodOfSurf2 = Surf2->IsVPeriodic() ? Surf2->VPeriod() : 0.0;
+  const Standard_Real aTol3d = Func.Tolerance(); 
+  const Handle(Adaptor3d_HSurface)& aQSurf = (reversed) ? Surf2 : Surf1;
+  const Handle(Adaptor3d_HSurface)& anOtherSurf = (reversed) ? Surf1 : Surf2;
 
   for (Standard_Integer i = 1; i <= slin.Length(); i++)
   {
-    //BndBox of the points in Restriction line
-    Bnd_Box2d aBRL;
+    const Handle(IntPatch_PointLine)& aL1 = Handle(IntPatch_PointLine)::DownCast(slin(i));
+    const Handle(IntPatch_RLine)& aRL1 = Handle(IntPatch_RLine)::DownCast(aL1);
+
+    if(aRL1.IsNull())
+    {
+      //Walking-Walking cases are not supported
+      break;
+    }
+
+    const Handle(Adaptor2d_HCurve2d)& anArc = aRL1->IsArcOnS1() ? 
+                                              aRL1->ArcOnS1() :
+                                              aRL1->ArcOnS2();
+    if(anArc->Curve2d().GetType() != GeomAbs_Line)
+    {
+      //Restriction line must be isoline.
+      //Other cases are not supported by
+      //existing algorithms.
+
+      break;
+    }
+
+    Standard_Boolean isFirstDeleted = Standard_False;
+
     for(Standard_Integer j = i + 1; j <= slin.Length(); j++)
     {
-      Handle(IntPatch_PointLine) aL1 = Handle(IntPatch_PointLine)::DownCast(slin(i));
       Handle(IntPatch_PointLine) aL2 = Handle(IntPatch_PointLine)::DownCast(slin(j));
-
-      Handle(IntPatch_RLine) aRL1 = Handle(IntPatch_RLine)::DownCast(aL1);
       Handle(IntPatch_RLine) aRL2 = Handle(IntPatch_RLine)::DownCast(aL2);
 
-      if(aRL1.IsNull())
-      {//If Walking-Walking
-        continue;
-      }
-
       //Here aL1 (i-th line) is Restriction-line and aL2 (j-th line) is
       //Restriction or Walking
 
-      if(aBRL.IsVoid())
-      {//Fill aBRL
-        for(Standard_Integer aPRID = 1; aPRID <= aRL1->NbPnts(); aPRID++)
+      if(!aRL2.IsNull())
+      {
+        const Handle(Adaptor2d_HCurve2d)& anArc = aRL2->IsArcOnS1() ?
+                                                  aRL2->ArcOnS1() :
+                                                  aRL2->ArcOnS2();
+        if(anArc->Curve2d().GetType() != GeomAbs_Line)
         {
-          Standard_Real u = 0.0, v = 0.0;
-          if(reversed)
-            aRL1->Point(aPRID).ParametersOnS1(u, v);
-          else
-            aRL1->Point(aPRID).ParametersOnS2(u, v);
+          //Restriction line must be isoline.
+          //Other cases are not supported by
+          //existing algorithms.
 
-          aBRL.Add(gp_Pnt2d(u, v));
+          continue;
         }
+      }
 
-        Standard_Real aXmin = 0.0, aYmin = 0.0, aXMax = 0.0, aYMax = 0.0;
-        aBRL.Get(aXmin, aYmin, aXMax, aYMax);
-        const Standard_Real aDX = aXMax - aXmin,
-                            aDY = aYMax - aYmin;
-
-        const Standard_Real aTolU = reversed? Surf1->UResolution(TolArc) : Surf2->UResolution(TolArc);
-        const Standard_Real aTolV = reversed? Surf1->VResolution(TolArc) : Surf2->VResolution(TolArc);
+      //aDir can be equal to one of following four values only
+      //(because Reastriction line is boundary of rectangular surface):
+      //either {0, 1} or {0, -1} or {1, 0} or {-1, 0}.
+      const gp_Dir2d aDir = anArc->Curve2d().Line().Direction();
 
-        if((aDX > aTolU) && (aDY > aTolV))
-        {//Delete restriction line because it is not isoline.
-          slin.Remove(i);
-          i--;
-          break;
-        }
+      Standard_Real aTol2d = anOtherSurf->UResolution(aTol3d),
+                    aPeriod = anOtherSurf->IsVPeriodic() ? anOtherSurf->VPeriod() : 0.0;
 
-        aXmin -= aTolU;
-        aXMax += aTolU;
-        aYmin -= aTolV;
-        aYMax += aTolV;
-        aBRL.SetVoid();
-        aBRL.Update(aXmin, aYmin, aXMax, aYMax);
+      if(Abs(aDir.X()) < 0.5)
+      {//Restriction directs along V-direction
+        aTol2d = anOtherSurf->VResolution(aTol3d);
+        aPeriod = anOtherSurf->IsUPeriodic() ? anOtherSurf->UPeriod() : 0.0;
       }
 
-      const Standard_Boolean isCoincide = IsIn2DBox(aBRL, aL2,
-                        (reversed? aUPeriodOfSurf1 : aUPeriodOfSurf2),
-                        (reversed? aVPeriodOfSurf1 : aVPeriodOfSurf2), reversed);
+      const Standard_Boolean isCoincide = IsCoincide(Func, aL2, anArc, aRL1->IsArcOnS1(),
+                                                      aTol3d, aTol2d, aPeriod);
 
       if(isCoincide)
-      {//Delete Walking-line
-        slin.Remove(j);
-        j--;
+      {
+        if(aRL2.IsNull())
+        {//Delete Walking-line
+          slin.Remove(j);
+          j--;
+        }
+        else
+        {//Restriction-Restriction
+          const Handle(Adaptor2d_HCurve2d)& anArc2 = aRL2->IsArcOnS1() ?
+                                                     aRL2->ArcOnS1() :
+                                                     aRL2->ArcOnS2();
+
+          const Standard_Real aRange2 = anArc2->LastParameter() - 
+                                        anArc2->FirstParameter();
+          const Standard_Real aRange1 = anArc->LastParameter() -
+                                        anArc->FirstParameter();
+
+          if(aRange2 > aRange1)
+          {
+            isFirstDeleted = Standard_True;
+            break;
+          }
+          else
+          {//Delete j-th line
+            slin.Remove(j);
+            j--;
+          }
+        }
       }
+    } //for(Standard_Integer j = i + 1; j <= slin.Length(); j++)
+
+    if(isFirstDeleted)
+    {//Delete i-th line
+      slin.Remove(i--);
     }
-  }
+  }//for (Standard_Integer i = 1; i <= slin.Length(); i++)
 
   empt = (slin.Length() == 0 && spnt.Length() == 0);
   done = Standard_True;
@@ -1472,14 +1509,14 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
   // post processing for cones and spheres
 
   const Handle(Adaptor3d_TopolTool)& PDomain = (reversed) ? D1 : D2;
-  const Handle(Adaptor3d_HSurface)& aQSurf = (reversed) ? Surf2 : Surf1;
-  const Handle(Adaptor3d_HSurface)& anOtherSurf = (reversed) ? Surf1 : Surf2;
 
   IntPatch_SequenceOfLine dslin;
   Standard_Boolean isDecompose = Standard_False;
   for(Standard_Integer i = 1; i <= slin.Length(); i++ )
   {
-    if(DecomposeResult(slin(i),reversed,Quad,PDomain,aQSurf, anOtherSurf, TolArc,dslin))
+    if(DecomposeResult( Handle(IntPatch_PointLine)::DownCast(slin(i)),
+                                        reversed, Quad, PDomain, aQSurf,
+                                        anOtherSurf, TolArc, dslin))
     {
       isDecompose = Standard_True;
     }
@@ -1549,7 +1586,7 @@ static Standard_Real AdjustUFirst(Standard_Real U1,Standard_Real U2)
 }
 
 // collect vertices, reject equals
-static Handle(IntSurf_LineOn2S) GetVertices(const Handle(IntPatch_WLine)& WLine,
+static Handle(IntSurf_LineOn2S) GetVertices(const Handle(IntPatch_PointLine)& thePLine,
                                             const Standard_Real           TOL3D,
                                             const Standard_Real           TOL2D)
 {
@@ -1559,7 +1596,7 @@ static Handle(IntSurf_LineOn2S) GetVertices(const Handle(IntPatch_WLine)& WLine,
 
   Standard_Real U1 = 0., U2 = 0., V1 = 0., V2 = 0.;
   Standard_Integer i = 0, k = 0;
-  Standard_Integer NbVrt = WLine->NbVertex();
+  Standard_Integer NbVrt = thePLine->NbVertex();
 
   TColStd_Array1OfInteger anVrts(1,NbVrt);
   anVrts.Init(0);
@@ -1569,13 +1606,13 @@ static Handle(IntSurf_LineOn2S) GetVertices(const Handle(IntPatch_WLine)& WLine,
 
     if( anVrts(i) == -1 ) continue;
 
-    const IntPatch_Point& Pi = WLine->Vertex(i);
+    const IntPatch_Point& Pi = thePLine->Vertex(i);
 
     for(k = (i+1); k <= NbVrt; k++) {
 
       if( anVrts(k) == -1 ) continue;
 
-      const IntPatch_Point& Pk = WLine->Vertex(k);
+      const IntPatch_Point& Pk = thePLine->Vertex(k);
 
       if(Pi.Value().Distance(Pk.Value()) <= TOL3D) {
         // suggest the points are equal;
@@ -1604,7 +1641,7 @@ static Handle(IntSurf_LineOn2S) GetVertices(const Handle(IntPatch_WLine)& WLine,
   // copy further processed vertices
   for(i = 1; i <= NbVrt; i++) {
     if( anVrts(i) == -1 ) continue;
-    vertices->Add(WLine->Vertex(i).PntOn2S());
+    vertices->Add(thePLine->Vertex(i).PntOn2S());
   }
   return vertices;
 }
@@ -2325,7 +2362,7 @@ static Standard_Boolean SplitOnSegments(Handle(IntPatch_WLine)&        WLine,
 //            This passage is detected by jump of U-parameter
 //            from point to point.
 //=======================================================================
-static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
+static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLine,
                                         const Standard_Boolean       IsReversed,
                                         const IntSurf_Quadric&       theQuad,
                                         const Handle(Adaptor3d_TopolTool)& thePDomain,
@@ -2334,18 +2371,31 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
                                         const Standard_Real                theArcTol,
                                         IntPatch_SequenceOfLine&           theLines)
 {
+  if(theLine->ArcType() == IntPatch_Restriction)
+  {
+    const Handle(IntPatch_RLine)& aRL = Handle(IntPatch_RLine)::DownCast(theLine);
+    if(!aRL.IsNull())
+    {
+      const Handle(Adaptor2d_HCurve2d)& anArc = aRL->IsArcOnS1() ?
+                                        aRL->ArcOnS1() :
+                                        aRL->ArcOnS2();
+      if(anArc->Curve2d().GetType() != GeomAbs_Line)
+      {
+        //Restriction line must be isoline.
+        //Other cases are not supported by
+        //existing algorithms.
+
+        return Standard_False;
+      }
+    }
+  }
+  
   const Standard_Real aDeltaUmax = M_PI_2;
   const Standard_Real aTOL3D = 1.e-10, 
                       aTOL2D = Precision::PConfusion(),
                       aTOL2DS = Precision::PConfusion();
 
-  if( theLine->ArcType() != IntPatch_Walking )
-  {
-    return Standard_False;
-  }
-
-  Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast (theLine));
-  const Handle(IntSurf_LineOn2S)& aSLine = aWLine->Curve();
+  const Handle(IntSurf_LineOn2S)& aSLine = theLine->Curve();
 
   if(aSLine->NbPoints() <= 2)
   {
@@ -2353,7 +2403,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
   }
   
   //Deletes repeated vertices
-  Handle(IntSurf_LineOn2S) aVLine = GetVertices(aWLine,aTOL3D,aTOL2D);
+  Handle(IntSurf_LineOn2S) aVLine = GetVertices(theLine,aTOL3D,aTOL2D);
   
   Handle(IntSurf_LineOn2S) aSSLine(aSLine);
 
@@ -2362,6 +2412,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
 
   AdjustLine(aSSLine,IsReversed,theQSurf,aTOL2D);
 
+  if(theLine->ArcType() == IntPatch_Walking)
   {
     Standard_Boolean isInserted = Standard_True;
     while(isInserted)
@@ -2376,8 +2427,6 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
   const Standard_Integer aLindex = aSSLine->NbPoints();
   Standard_Integer aFindex = 1, aBindex = 0;
 
-  IntPatch_Point aTPntF, aTPntL;
-
   // build WLine parts (if any)
   Standard_Boolean flNextLine = Standard_True;
   Standard_Boolean hasBeenDecomposed = Standard_False;
@@ -2458,7 +2507,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
 
         {
           Standard_Real aDeltaPar = aURef-aUquad;
-          const Standard_Real anIncr = aPeriod*Sign(1.0, aDeltaPar);
+          const Standard_Real anIncr = Sign(aPeriod, aDeltaPar);
           while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod))
           {
             aUquad += anIncr;
@@ -2467,7 +2516,6 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
         }
 
         aFirstPoint.SetValue(!IsReversed, aUquad, aVquad);
-
         sline->Add(aFirstPoint);
       }
       else
@@ -2621,7 +2669,8 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
             aNewPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), IsReversed, aU0, aV0);
 
             if(!aNewPoint.IsSame(aRefPt, Precision::Confusion()))
-            { //Found pole does not exist in the Walking-line
+            {
+              //Found pole does not exist in the Walking-line
               //It must be added there (with correct 2D-parameters)
               
               //2D-parameters of theparametric surface have already been found (aU0, aV0).
@@ -2729,73 +2778,148 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
                 //Vector with {@ \cos (U_{q}) @, @ \sin (U_{q}) @} coordinates.
                 //Ask to pay attention to the fact that this vector is always normalyzed.
                 gp_Vec2d aV1;
-          
-                if(Abs(aVecDu.Z()) > Abs(aVecDv.Z()))
+
+                if( (Abs(aVecDu.Z()) < Precision::PConfusion()) &&
+                  (Abs(aVecDv.Z()) < Precision::PConfusion()))
                 {
                   //Example of this exception is intersection a plane with a sphere
                   //when the plane tangents the sphere in some pole (i.e. only one 
                   //intersection point, not line). In this case, U-coordinate of the
-                  //sphere is undefined (can be realy anything). On the other hand,
-                  //in this case there are not any Walking-line to be decomposited.
-                  Standard_NumericError_Raise_if(Abs(aVecDu.Z()) < Precision::PConfusion(),
-                    "IntPatch_ImpPrmIntersection.cxx, DecomposeResult(...): "
-                                          "Cannot find UV-coordinate for quadric in the pole");
-                  const Standard_Real aDusDvs = aVecDv.Z()/aVecDu.Z();
-
-                  aV1.SetCoord( aVecDu.X()*aDusDvs - aVecDv.X(),
-                                aVecDu.Y()*aDusDvs - aVecDv.Y());
+                  //sphere is undefined (can be realy anything).
+                  //Another reason is that we have tangent zone around the pole
+                  //(see bug #26576).
+                  //Computation correct value of aUquad is impossible. Therefore,
+                  //we should throw an exception in this case.
+                  //Also, any Walking line cannot be created in this case.
+                  //Hovewer, Restriction line is not created by intersection algorithm.
+                  //It is already exists (above we check simply, if this line is
+                  //intersection line).
+                  //Therefore, we can try to find the aUquad-parameter on (existing)
+                  //Restriction line. Here, we will do it with
+                  //extrapolation algorithm.
+                  //Use interpolation algorithm is wrong because aUquad parameter
+                  //jumps while the line going though the pole.
+
+                  if((theLine->ArcType() == IntPatch_Walking) ||
+                    (aBindex < 3))
+                  {
+                    //We must have at least two previous points
+                    //in order to do linear extrapolation.
+                    Standard_NumericError::
+                      Raise("IntPatch_ImpPrmIntersection.cxx, DecomposeResult(...): "
+                      "Cannot find UV-coordinate for quadric in the pole");
+                  }
+                  else
+                  {
+#ifdef INTPATCH_IMPPRMINTERSECTION_DEBUG
+                    cout << "Cannot find UV-coordinate for quadric in the pole."
+                      " See considered comment above. IntPatch_ImpPrmIntersection.cxx,"
+                      " DecomposeResult(...)" << endl;
+#endif
+
+                    //    *----------*------------x
+                    // QuadPrev   QuadRef     Quad (must be found)
+
+                    const IntSurf_PntOn2S& aPt2S = aSSLine->Value(aBindex-2);
+                    //Quadric point
+                    Standard_Real aUQuadPrev = 0.0, aVQuadPrev = 0.0;
+                    if(IsReversed)
+                    {
+                      aPt2S.ParametersOnS2(aUQuadPrev, aVQuadPrev);
+                    }
+                    else
+                    {
+                      aPt2S.ParametersOnS1(aUQuadPrev, aVQuadPrev);
+                    }
+
+                    Standard_NumericError_Raise_if(
+                      Abs(aVQuadPrev - aVQuadRef) < gp::Resolution(),
+                      "Division by zero");
+
+                    aUquad = 
+                      aUQuadPrev + (aUQuadRef - aUQuadPrev)*
+                      (aVquad - aVQuadPrev)/(aVQuadRef - aVQuadPrev);
+                  }
                 }
                 else
                 {
-                  //Example of this exception is intersection a plane with a sphere
-                  //when the plane tangents the sphere in some pole (i.e. only one 
-                  //intersection point, not line). In this case, U-coordinate of the
-                  //sphere is undefined (can be realy anything). On the other hand,
-                  //in this case there are not any Walking-line to be decomposited.
-                  Standard_NumericError_Raise_if(Abs(aVecDv.Z()) < Precision::PConfusion(),
-                    "IntPatch_ImpPrmIntersection.cxx, DecomposeResult(...): "
-                                          "Cannot find UV-coordinate for quadric in the pole");
-
-                  const Standard_Real aDvsDus = aVecDu.Z()/aVecDv.Z();
-                  aV1.SetCoord( aVecDv.X()*aDvsDus - aVecDu.X(),
-                                aVecDv.Y()*aDvsDus - aVecDu.Y());
-                }
+                  if(Abs(aVecDu.Z()) > Abs(aVecDv.Z()))
+                  {
+                    const Standard_Real aDusDvs = aVecDv.Z()/aVecDu.Z();
 
-                aV1.Normalize();
+                    aV1.SetCoord( aVecDu.X()*aDusDvs - aVecDv.X(),
+                      aVecDu.Y()*aDusDvs - aVecDv.Y());
+                  }
+                  else
+                  {
+                    const Standard_Real aDvsDus = aVecDu.Z()/aVecDv.Z();
+                    aV1.SetCoord( aVecDv.X()*aDvsDus - aVecDu.X(),
+                      aVecDv.Y()*aDvsDus - aVecDu.Y());
+                  }
 
-                if(Abs(aV1.X()) > Abs(aV1.Y()))
-                  aUquad = Sign(asin(aV1.Y()), aVquad);
-                else
-                  aUquad = Sign(acos(aV1.X()), aVquad);
-              }
+                  aV1.Normalize();
+
+                  if(Abs(aV1.X()) > Abs(aV1.Y()))
+                    aUquad = Sign(asin(aV1.Y()), aVquad);
+                  else
+                    aUquad = Sign(acos(aV1.X()), aVquad);
+                }
 
-              {
-                //Adjust found U-paramter to previous point of the Walking-line
-                Standard_Real aDeltaPar = aUQuadRef-aUquad;
-                const Standard_Real anIncr = aPeriod*Sign(1.0, aDeltaPar);
-                while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod))
                 {
-                  aUquad += anIncr;
-                  aDeltaPar = aUQuadRef-aUquad;
+                  //Adjust found U-paramter to previous point of the Walking-line
+                  Standard_Real aDeltaPar = aUQuadRef-aUquad;
+                  const Standard_Real anIncr = Sign(aPeriod, aDeltaPar);
+                  while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod))
+                  {
+                    aUquad += anIncr;
+                    aDeltaPar = aUQuadRef-aUquad;
+                  }
                 }
               }
-              
+
               aNewPoint.SetValue(!IsReversed, aUquad, aVquad);
               
               sline->Add(aNewPoint);
               PrePointExist = PrePoint_POLE;
               PrePoint = aNewPoint;
+            } // if(!aNewPoint.IsSame(aRefPt, Precision::Confusion()))
+            else
+            {
+              if(sline->NbPoints() == 1)
+              {
+                //FIRST point of the sline is the pole of the quadric.
+                //Therefore, there is no point in decomposition.
+
+                PrePoint = aRefPt;
+                AnU1=U1;
+                PrePointExist = PrePoint_POLE;
+              }
             }
-          }
+          } //if(anExtr.SquareDistance() < aTol*aTol)
         }
 
         ////
         break;
-      }
+      } //if(Abs(U1-AnU1) > aDeltaUmax)
 
       sline->Add(aSSLine->Value(k));
       PrePoint = aSSLine->Value(k);
       AnU1=U1;
+    } //for(Standard_Integer k = aFindex; k <= aLindex; k++)
+
+    //Creation of new line as part of existing theLine.
+    //This part is defined by sline.
+
+    if(sline->NbPoints() == 1)
+    {
+      flNextLine = Standard_True;
+      aFindex = aBindex;
+
+      //Go to the next part of aSSLine
+      //because we cannot create the line
+      //with single point.
+
+      continue;
     }
 
     IntSurf_PntOn2S aVF, aVL;
@@ -2827,47 +2951,136 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
       }
     }
 
-    Handle(IntPatch_WLine) wline = 
-                        new IntPatch_WLine(sline,Standard_False,
-                        theLine->TransitionOnS1(),theLine->TransitionOnS2());
-
-    gp_Pnt aSPnt(sline->Value(1).Value());
-    sline->Value(1).ParametersOnS1(U1,V1);
-    sline->Value(1).ParametersOnS2(U2,V2);
-    aTPntF.SetValue(aSPnt,theArcTol,Standard_False);
-    aTPntF.SetParameters(U1,V1,U2,V2);
-    aTPntF.SetParameter(1.);
-    wline->AddVertex(aTPntF);
-    wline->SetFirstPoint(1);
-
-    if(hasInternals)
+    if(theLine->ArcType() == IntPatch_Walking)
     {
-      PutIntVertices(wline,sline,IsReversed,aVLine,theArcTol);
-    }
+      IntPatch_Point aTPntF, aTPntL;
+
+      Handle(IntPatch_WLine) wline = 
+                          new IntPatch_WLine(sline,Standard_False,
+                          theLine->TransitionOnS1(),theLine->TransitionOnS2());
+
+      gp_Pnt aSPnt(sline->Value(1).Value());
+      sline->Value(1).ParametersOnS1(U1,V1);
+      sline->Value(1).ParametersOnS2(U2,V2);
+      aTPntF.SetValue(aSPnt,theArcTol,Standard_False);
+      aTPntF.SetParameters(U1,V1,U2,V2);
+      aTPntF.SetParameter(1.);
+      wline->AddVertex(aTPntF);
+      wline->SetFirstPoint(1);
+
+      if(hasInternals)
+      {
+        PutIntVertices(wline,sline,IsReversed,aVLine,theArcTol);
+      }
 
-    aSPnt =  sline->Value(sline->NbPoints()).Value();
-    sline->Value(sline->NbPoints()).ParametersOnS1(U1,V1);
-    sline->Value(sline->NbPoints()).ParametersOnS2(U2,V2);
-    aTPntL.SetValue(aSPnt,theArcTol,Standard_False);
-    aTPntL.SetParameters(U1,V1,U2,V2);
-    aTPntL.SetParameter(sline->NbPoints());
-    wline->AddVertex(aTPntL);
-    wline->SetLastPoint(sline->NbPoints());
+      aSPnt =  sline->Value(sline->NbPoints()).Value();
+      sline->Value(sline->NbPoints()).ParametersOnS1(U1,V1);
+      sline->Value(sline->NbPoints()).ParametersOnS2(U2,V2);
+      aTPntL.SetValue(aSPnt,theArcTol,Standard_False);
+      aTPntL.SetParameters(U1,V1,U2,V2);
+      aTPntL.SetParameter(sline->NbPoints());
+      wline->AddVertex(aTPntL);
+      wline->SetLastPoint(sline->NbPoints());
 
-    IntPatch_SequenceOfLine segm;
-    Standard_Boolean isSplited = SplitOnSegments(wline,Standard_False,
-                    theLine->TransitionOnS1(),theLine->TransitionOnS2(),theArcTol,segm);
+      IntPatch_SequenceOfLine segm;
+      Standard_Boolean isSplited = SplitOnSegments(wline,Standard_False,
+                      theLine->TransitionOnS1(),theLine->TransitionOnS2(),theArcTol,segm);
 
-    if(!isSplited)
-    {
-      theLines.Append(wline);
+      if(!isSplited)
+      {
+        theLines.Append(wline);
+      }
+      else
+      {
+        Standard_Integer nbsegms = segm.Length();
+        Standard_Integer iseg = 0;
+        for(iseg = 1; iseg <= nbsegms; iseg++)
+          theLines.Append(segm(iseg));
+      }
     }
     else
-    {
-      Standard_Integer nbsegms = segm.Length();
-      Standard_Integer iseg = 0;
-      for(iseg = 1; iseg <= nbsegms; iseg++)
-        theLines.Append(segm(iseg));
+    {//theLine->ArcType() == IntPatch_Restriction
+      if(!isDecomposited && !hasBeenDecomposed)
+      {
+        //The line has not been changed
+        theLines.Append(Handle(IntPatch_RLine)::DownCast(theLine));
+        return hasBeenDecomposed;
+      }
+
+      IntPatch_Point aTPnt;
+      gp_Pnt2d aPSurf;
+      gp_Pnt aSPnt;
+
+      Handle(IntPatch_RLine) aRLine = new IntPatch_RLine(*Handle(IntPatch_RLine)::DownCast(theLine));
+      
+      aRLine->ClearVertexes();
+      aRLine->SetCurve(sline);
+
+      if(hasInternals)
+      {
+        PutIntVertices(aRLine,sline,IsReversed,aVLine,theArcTol);
+      }
+
+      const Handle(Adaptor2d_HCurve2d)& anArc = aRLine->IsArcOnS1() ?
+                                                aRLine->ArcOnS1() :
+                                                aRLine->ArcOnS2();
+
+      Standard_Real aFPar = anArc->FirstParameter(),
+                    aLPar = anArc->LastParameter();
+
+      const IntSurf_PntOn2S &aRFirst = sline->Value(1),
+                            &aRLast = sline->Value(sline->NbPoints());
+
+      const gp_Lin2d aLin(anArc->Curve2d().Line());
+      
+      for(Standard_Integer aFLIndex = 0; aFLIndex < 2; aFLIndex++)
+      {
+        if(aFLIndex == 0)
+        {
+          aRFirst.Parameters(U1, V1, U2, V2);
+          aSPnt.SetXYZ(aRFirst.Value().XYZ());
+        }
+        else
+        {
+          aRLast.Parameters(U1, V1, U2, V2);
+          aSPnt.SetXYZ(aRLast.Value().XYZ());
+        }
+
+        if(IsReversed)
+        {
+          aPSurf.SetCoord(U1, V1);
+        }
+        else
+        {
+          aPSurf.SetCoord(U2, V2);
+        }
+
+        Standard_Real aPar = ElCLib::Parameter(aLin, aPSurf);
+
+        if(aFLIndex == 0)
+        {
+          aFPar = Max(aFPar, aPar);
+          aPar = aFPar;
+        }
+        else
+        {
+          aLPar = Min(aLPar, aPar);
+          aPar = aLPar;
+        }
+
+        aTPnt.SetParameter(aPar);
+        aTPnt.SetValue(aSPnt,theArcTol,Standard_False);
+        aTPnt.SetParameters(U1, V1, U2, V2);
+
+        aRLine->AddVertex(aTPnt);
+      }
+
+      aRLine->SetFirstPoint(1);
+      aRLine->SetLastPoint(sline->NbPoints());
+
+      anArc->Trim(aFPar, aLPar, theArcTol);
+
+      theLines.Append(aRLine);
     }
 
     if(isDecomposited)
@@ -2880,57 +3093,157 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
   return hasBeenDecomposed;
 }
 
-static Standard_Boolean IsIn2DBox(const Bnd_Box2d& theBox,
-                                  const Handle(IntPatch_PointLine)& theLine,
-                                  const Standard_Real theUPeriod,
-                                  const Standard_Real theVPeriod,
-                                  const Standard_Boolean isTheSurface1Using)
+//=======================================================================
+//function : CheckSegmSegm
+//purpose  : Returns TRUE if the segment [theParF, theParL] is included
+//            in the segment [theRefParF, theRefParL] segment.
+//=======================================================================
+static Standard_Boolean CheckSegmSegm(const Standard_Real theRefParF,
+                                      const Standard_Real theRefParL,
+                                      const Standard_Real theParF,
+                                      const Standard_Real theParL)
 {
-  const Standard_Integer aNbPnts = theLine->NbPnts();
+  if((theParF < theRefParF) || (theParF > theRefParL))
+  {
+    return Standard_False;
+  }
 
-  const Standard_Real aDeltaUPeriod[] = {0.0, -theUPeriod, 2.0*theUPeriod};
-  const Standard_Real aDeltaVPeriod[] = {0.0, -theVPeriod, 2.0*theVPeriod};
+  if((theParL < theRefParF) || (theParL > theRefParL))
+  {
+    return Standard_False;
+  }
 
-  const Standard_Integer aSzOfUPArr = sizeof(aDeltaUPeriod)/sizeof(aDeltaUPeriod[0]);
-  const Standard_Integer aSzOfVPArr = sizeof(aDeltaVPeriod)/sizeof(aDeltaVPeriod[0]);
+  return Standard_True;
+}
+
+//=======================================================================
+//function : IsCoincide
+//purpose  : Check, if theLine is coincided with theArc (in 2d-space).
+//
+// Attention!!!
+//            Cases when theArc is not 2d-line adaptor are suppored by
+//          TopOpeBRep classes only (i.e. are archaic).
+//=======================================================================
+Standard_Boolean IsCoincide(IntPatch_TheSurfFunction& theFunc,
+                            const Handle(IntPatch_PointLine)& theLine,
+                            const Handle(Adaptor2d_HCurve2d)& theArc,
+                            const Standard_Boolean isTheSurface1Using, //Surf1 is parametric?
+                            const Standard_Real theToler3D,
+                            const Standard_Real theToler2D,
+                            const Standard_Real thePeriod) // Period of parametric surface in direction which is perpendicular to theArc direction.
+{
+  if(theLine->ArcType() == IntPatch_Restriction)
+  {//Restriction-restriction processing
+    const Handle(IntPatch_RLine)& aRL2 = Handle(IntPatch_RLine)::DownCast(theLine);
+    const Handle(Adaptor2d_HCurve2d)& anArc = aRL2->IsArcOnS1() ? aRL2->ArcOnS1() : aRL2->ArcOnS2();
+    
+    if(anArc->Curve2d().GetType() != GeomAbs_Line)
+    {
+      //Restriction line must be isoline.
+      //Other cases are not supported by
+      //existing algorithms.
+
+      return Standard_False;
+    }
+
+    const gp_Lin2d aLin1(theArc->Curve2d().Line()),
+                   aLin2(anArc->Curve2d().Line());
+
+    if(!aLin1.Direction().IsParallel(aLin2.Direction(), Precision::Angular()))
+    {
+      return Standard_False;
+    }
+
+    const Standard_Real aDist = 
+            theArc->Curve2d().Line().Distance(anArc->Curve2d().Line());
+    if((aDist < theToler2D) || (Abs(aDist - thePeriod) < theToler2D))
+    {
+      const Standard_Real aRf = theArc->FirstParameter(),
+                          aRl = theArc->LastParameter();
+      const Standard_Real aParf = anArc->FirstParameter(),
+                          aParl = anArc->LastParameter();
+      const gp_Pnt2d aP1(ElCLib::Value(aParf, aLin2)),
+                     aP2(ElCLib::Value(aParl, aLin2));
+
+      Standard_Real aParam1 = ElCLib::Parameter(aLin1, aP1),
+                    aParam2 = ElCLib::Parameter(aLin1, aP2);
+
+      if(CheckSegmSegm(aRf, aRl, aParam1, aParam2))
+        return Standard_True;
+
+      //Lines are parallel. Therefore, there is no point in
+      //projecting points to another line in order to check
+      //if segment second line is included in segment of first one.
+
+      return CheckSegmSegm(aParam1, aParam2, aRf, aRl);
+    }
+
+    return Standard_False;
+  }
+
+  const Standard_Integer aNbPnts = theLine->NbPnts();
+  const Standard_Real aUAf = theArc->FirstParameter(),
+                      aUAl = theArc->LastParameter();
+  const gp_Lin2d anArcLin(theArc->Curve2d().Line());
+
+  math_Vector aX(1, 2), aVal(1, 1);
 
   for(Standard_Integer aPtID = 1; aPtID <= aNbPnts; aPtID++)
   {
-    Standard_Real aU = 0.0, aV = 0.0;
+    Standard_Real aUf = 0.0, aVf = 0.0;
     if(isTheSurface1Using)
-      theLine->Point(aPtID).ParametersOnS1(aU, aV);
+      theLine->Point(aPtID).ParametersOnS1(aUf, aVf);
     else
-      theLine->Point(aPtID).ParametersOnS2(aU, aV);
+      theLine->Point(aPtID).ParametersOnS2(aUf, aVf);
+
+    //Take 2d-point in parametric surface (because theArc is
+    //2d-line in parametric surface).
+    const gp_Pnt2d aPloc(aUf, aVf);
+
+    const Standard_Real aRParam = ElCLib::Parameter(anArcLin, aPloc);
 
-    if(!theBox.IsOut(gp_Pnt2d(aU, aV)))
+    if((aRParam < aUAf) || (aRParam > aUAl))
+      return Standard_False;
+
+    const gp_Pnt2d aPmin(ElCLib::Value(aRParam, anArcLin));
+    
+    const Standard_Real aDist = aPloc.Distance(aPmin);
+    if((aDist < theToler2D) || (Abs(aDist - thePeriod) < theToler2D))
+    {//Considered point is in Restriction line.
+     //Go to the next point.
       continue;
+    }
+
+    //Check if intermediate points between aPloc and theArc are
+    //intersection point (i.e. if aPloc is in tangent zone between
+    //two intersected surfaces).
+
+    const Standard_Real aUl = aPmin.X(), aVl = aPmin.Y();
 
-    Standard_Boolean isInscribe = Standard_False;
+    const Standard_Integer aNbPoints = 4;
+    const Standard_Real aStepU = (aUl - aUf)/aNbPoints,
+                        aStepV = (aVl - aVf)/aNbPoints;
 
-    for(Standard_Integer aUind = 0; !isInscribe && (aUind < aSzOfUPArr); aUind++)
+    Standard_Real aU = aUf+aStepU, aV = aVf+aStepV;
+    for(Standard_Integer i = 1; i < aNbPoints; i++)
     {
-      if((aUind > 0) && (aDeltaUPeriod[aUind] == 0.0))
+      aX.Value(1) = aU;
+      aX.Value(2) = aV;
+
+      if(!theFunc.Value(aX, aVal))
       {
-        break;
+        return Standard_False;
       }
 
-      aU += aDeltaUPeriod[aUind];
-
-      for(Standard_Integer aVind = 0; !isInscribe && (aVind < aSzOfVPArr); aVind++)
+      if(Abs(aVal(1)) > theToler3D)
       {
-        if((aVind > 0) && (aDeltaVPeriod[aVind] == 0.0))
-        {
-          break;
-        }
-
-        aV += aDeltaVPeriod[aVind];
-
-        isInscribe = !theBox.IsOut(gp_Pnt2d(aU, aV));
+        return Standard_False;
       }
+      
+      aU += aStepU;
+      aV += aStepV;
     }
-
-    if(!isInscribe)
-      return Standard_False;
   }
+
   return Standard_True;
-}
+}
\ No newline at end of file
index 8d0a4dc..3d5561e 100644 (file)
@@ -21,6 +21,7 @@
 #include <Standard_Type.hxx>
 
 #include <IntPatch_Line.hxx>
+#include <IntPatch_Point.hxx>
 #include <Standard_Boolean.hxx>
 #include <IntSurf_TypeTrans.hxx>
 #include <IntSurf_Situation.hxx>
@@ -28,6 +29,7 @@
 class Standard_DomainError;
 class Standard_OutOfRange;
 class IntSurf_PntOn2S;
+class IntSurf_LineOn2S;
 
 
 class IntPatch_PointLine;
@@ -43,15 +45,26 @@ class IntPatch_PointLine : public IntPatch_Line
 
 public:
 
-  
+  //! Adds a vertex in the list.
+  Standard_EXPORT virtual void AddVertex (const IntPatch_Point& Pnt) = 0;
+
   //! Returns the number of intersection points.
   Standard_EXPORT virtual Standard_Integer NbPnts() const = 0;
-  
+
+  //! Returns number of vertices (IntPatch_Point) of the line
+  Standard_EXPORT virtual Standard_Integer NbVertex() const = 0;
+
   //! Returns the intersection point of range Index.
   Standard_EXPORT virtual const IntSurf_PntOn2S& Point (const Standard_Integer Index) const = 0;
 
+  //! Returns the vertex of range Index on the line.
+  Standard_EXPORT virtual const IntPatch_Point& Vertex (const Standard_Integer Index) const = 0;
 
+  //! Removes vertices from the line
+  Standard_EXPORT virtual void ClearVertexes() = 0;
 
+  //! Returns set of intersection points
+  Standard_EXPORT virtual Handle(IntSurf_LineOn2S) Curve() const = 0;
 
   DEFINE_STANDARD_RTTIEXT(IntPatch_PointLine,IntPatch_Line)
 
index fea931d..dafe0fe 100644 (file)
@@ -345,6 +345,70 @@ void IntPatch_RLine::ComputeVertexParameters(const Standard_Real )
 #endif
 }
 
+void IntPatch_RLine::Dump(const Standard_Integer theMode) const
+{ 
+  cout<<" ----------- D u m p    I n t P a t c h  _  R L i n e  -(begin)------"<<endl;
+  const Standard_Integer aNbPoints = NbPnts();
+  const Standard_Integer aNbVertex = NbVertex();
 
+  switch(theMode)
+  {
+  case 0:
+    printf("Num    [X  Y  Z]     [U1  V1]   [U2  V2]\n");
+    for(Standard_Integer i=1; i<=aNbPoints; i++)
+    {
+      Standard_Real u1,v1,u2,v2;
+      Point(i).Parameters(u1,v1,u2,v2);
+      printf("%4d  [%+10.20f %+10.20f %+10.20f]  [%+10.20f %+10.20f]  [%+10.20f %+10.20f]\n",
+              i,Point(i).Value().X(),Point(i).Value().Y(),Point(i).Value().Z(),
+              u1,v1,u2,v2);
+    }
+    
+    for(Standard_Integer i=1;i<=aNbVertex;i++)
+    {
+      Vertex(i).Dump();
+      Standard_Real  polr = Vertex(i).ParameterOnLine();
+      Standard_Integer pol = static_cast<Standard_Integer>(polr);
+
+      if(pol>=1 && pol<=aNbVertex)
+      {
+        cout<<"----> IntSurf_PntOn2S : "<<
+                      polr <<", Pnt (" << Vertex(pol).Value().X() << "," <<
+                                          Vertex(pol).Value().Y() << "," <<
+                                          Vertex(pol).Value().Z() <<")" <<endl;
+      }
+    }
+
+    break;
+  case 1:
+    for(Standard_Integer i = 1; i <= aNbPoints; i++)
+    {
+      Standard_Real u1,v1,u2,v2;
+      Point(i).Parameters(u1,v1,u2,v2);
+      printf("point p%d %+10.20f %+10.20f %+10.20f\n",
+              i,Point(i).Value().X(),Point(i).Value().Y(),Point(i).Value().Z());
+    }
 
+    break;
+  case 2:
+    for(Standard_Integer i = 1; i <= aNbPoints; i++)
+    {
+      Standard_Real u1,v1,u2,v2;
+      Point(i).Parameters(u1,v1,u2,v2);
+      printf("point p%d %+10.20f %+10.20f\n", i, u1, v1);
+    }
+
+    break;
+  default:
+    for(Standard_Integer i = 1; i <= aNbPoints; i++)
+    {
+      Standard_Real u1,v1,u2,v2;
+      Point(i).Parameters(u1,v1,u2,v2);
+      printf("point p%d %+10.20f %+10.20f\n", i, u2, v2);
+    }
+
+    break;
+  }
+  cout<<"\n--------------------------------------------------- (end) -------"<<endl;  
+}
 
index 93b1edf..78ae7fe 100644 (file)
@@ -59,7 +59,7 @@ public:
   Standard_EXPORT IntPatch_RLine(const Standard_Boolean Tang);
   
   //! To add a vertex in the list.
-    void AddVertex (const IntPatch_Point& Pnt);
+  virtual void AddVertex (const IntPatch_Point& Pnt);
   
   //! Replaces the element of range Index in the list
   //! of points.
@@ -117,18 +117,19 @@ public:
   //! An exception is raised when HasLastPoint returns False.
     const IntPatch_Point& LastPoint() const;
   
-    Standard_Integer NbVertex() const;
+  //! Returns number of vertices (IntPatch_Point) of the line
+  virtual Standard_Integer NbVertex() const;
   
   //! Returns the vertex of range Index on the line.
-    const IntPatch_Point& Vertex (const Standard_Integer Index) const;
+  virtual const IntPatch_Point& Vertex (const Standard_Integer Index) const;
   
     Standard_Boolean HasPolygon() const;
   
   //! Returns the number of intersection points.
-    Standard_Integer NbPnts() const Standard_OVERRIDE;
+  virtual Standard_Integer NbPnts() const Standard_OVERRIDE;
   
   //! Returns the intersection point of range Index.
-    const IntSurf_PntOn2S& Point (const Standard_Integer Index) const Standard_OVERRIDE;
+  virtual const IntSurf_PntOn2S& Point (const Standard_Integer Index) const Standard_OVERRIDE;
   
   //! Set the Point of index <Index> in the LineOn2S
   Standard_EXPORT void SetPoint (const Standard_Integer Index, const IntPatch_Point& Pnt);
@@ -139,8 +140,25 @@ public:
   //! else a new point in the line is inserted.
   Standard_EXPORT void ComputeVertexParameters (const Standard_Real Tol);
 
-
-
+  //! Returns set of intersection points
+  Standard_EXPORT virtual Handle(IntSurf_LineOn2S) Curve() const;
+
+  //! Removes vertices from the line (i.e. cleans svtx member)
+  virtual void ClearVertexes()
+  {
+    svtx.Clear();
+  }
+
+  void SetCurve(const Handle(IntSurf_LineOn2S)& theNewCurve)
+  {
+    curv = theNewCurve;
+  }
+
+  //! if (theMode == 0) then prints the information about WLine
+  //! if (theMode == 1) then prints the list of 3d-points
+  //! if (theMode == 2) then prints the list of 2d-points on the 1st surface
+  //! Otherwise,             prints list of 2d-points on the 2nd surface
+  Standard_EXPORT void Dump(const Standard_Integer theMode) const;
 
   DEFINE_STANDARD_RTTIEXT(IntPatch_RLine,IntPatch_PointLine)
 
index e5be2b6..82c3e13 100644 (file)
@@ -118,3 +118,8 @@ inline const IntSurf_PntOn2S& IntPatch_RLine::Point (const Standard_Integer Inde
   if (curv.IsNull()) {Standard_DomainError::Raise();}
   return curv->Value(Index);
 }
+
+inline Handle(IntSurf_LineOn2S) IntPatch_RLine::Curve() const
+{ 
+  return(curv);
+}
index 60d50a9..2be189c 100644 (file)
@@ -63,7 +63,7 @@ public:
   Standard_EXPORT IntPatch_WLine(const Handle(IntSurf_LineOn2S)& Line, const Standard_Boolean Tang);
   
   //! Adds a vertex in the list.
-    void AddVertex (const IntPatch_Point& Pnt);
+  virtual void AddVertex (const IntPatch_Point& Pnt);
   
   //! Set the Point of index <Index> in the LineOn2S
   Standard_EXPORT void SetPoint (const Standard_Integer Index, const IntPatch_Point& Pnt);
@@ -79,10 +79,10 @@ public:
     void SetLastPoint (const Standard_Integer IndLast);
   
   //! Returns the number of intersection points.
-    Standard_Integer NbPnts() const Standard_OVERRIDE;
+  virtual Standard_Integer NbPnts() const Standard_OVERRIDE;
   
   //! Returns the intersection point of range Index.
-    const IntSurf_PntOn2S& Point (const Standard_Integer Index) const Standard_OVERRIDE;
+  virtual const IntSurf_PntOn2S& Point (const Standard_Integer Index) const Standard_OVERRIDE;
   
   //! Returns True if the line has a known First point.
   //! This point is given by the method FirstPoint().
@@ -108,10 +108,11 @@ public:
   //! of vertices.
     const IntPatch_Point& LastPoint (Standard_Integer& Indlast) const;
   
-    Standard_Integer NbVertex() const;
+  //! Returns number of vertices (IntPatch_Point) of the line
+  virtual Standard_Integer NbVertex() const;
   
   //! Returns the vertex of range Index on the line.
-    const IntPatch_Point& Vertex (const Standard_Integer Index) const;
+  virtual const IntPatch_Point& Vertex (const Standard_Integer Index) const;
   
   //! Set the parameters of all the vertex on the line.
   //! if a vertex is already in the line,
@@ -119,7 +120,8 @@ public:
   //! else a new point in the line is inserted.
   Standard_EXPORT void ComputeVertexParameters (const Standard_Real Tol, const Standard_Boolean hasBeenAdded = Standard_False);
   
-  Standard_EXPORT Handle(IntSurf_LineOn2S) Curve() const;
+  //! Returns set of intersection points
+  Standard_EXPORT virtual Handle(IntSurf_LineOn2S) Curve() const;
   
   Standard_EXPORT Standard_Boolean IsOutSurf1Box (const gp_Pnt2d& P1);
   
@@ -149,7 +151,8 @@ public:
   
   Standard_EXPORT const Handle(Adaptor2d_HCurve2d)& GetArcOnS2() const;
   
-  Standard_EXPORT void ClearVertexes();
+  //! Removes vertices from the line (i.e. cleans svtx member)
+  virtual void ClearVertexes();
   
   Standard_EXPORT void RemoveVertex (const Standard_Integer theIndex);
   
index c309e91..32e7483 100644 (file)
 #include <IntTools_WLineTool.hxx>
 #include <IntPatch_WLineTool.hxx>
 
-//#ifdef OCCT_DEBUG_DUMPWLINE
-//static
-//  void DumpWLine(const Handle(IntPatch_WLine)& aWLine);
-//#endif
-////
 static
   void TolR3d(const TopoDS_Face& ,
               const TopoDS_Face& ,
@@ -893,6 +888,9 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
 
   typl=L->ArcType();
 
+  if(typl == IntPatch_Restriction)
+    bAvoidLineConstructor = Standard_True;
+
   //
   // Line Constructor
   if(!bAvoidLineConstructor) {
@@ -1492,8 +1490,8 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
     Handle(IntPatch_WLine) WL = 
       Handle(IntPatch_WLine)::DownCast(L);
 
-#ifdef OCCT_DEBUG
-    //WL->Dump(0);
+#ifdef INTTOOLS_FACEFACE_DEBUG
+    WL->Dump(0);
 #endif
 
     //
@@ -2011,6 +2009,11 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
     {
       Handle(IntPatch_RLine) RL = 
         Handle(IntPatch_RLine)::DownCast(L);
+
+#ifdef INTTOOLS_FACEFACE_DEBUG
+    RL->Dump(0);
+#endif
+
       Handle(Geom_Curve) aC3d;
       Handle(Geom2d_Curve) aC2d1, aC2d2;
       Standard_Real aTolReached;
@@ -3073,30 +3076,6 @@ Standard_Integer IndexType(const GeomAbs_SurfaceType aType)
   } 
   return aIndex;
 }
-#ifdef OCCT_DEBUG_DUMPWLINE
-//=======================================================================
-//function : DumpWLine
-//purpose  : 
-//=======================================================================
-void DumpWLine(const Handle(IntPatch_WLine)& aWLine)
-{
-  Standard_Integer i, aNbPnts; 
-  Standard_Real aX, aY, aZ, aU1, aV1, aU2, aV2;
-  //
-  printf(" *WLine\n");
-  aNbPnts=aWLine->NbPnts();
-  for (i=1; i<=aNbPnts; ++i) {
-    const IntSurf_PntOn2S aPntOn2S=aWLine->Point(i);
-    const gp_Pnt& aP3D=aPntOn2S.Value();
-    aP3D.Coord(aX, aY, aZ);
-    aPntOn2S.Parameters(aU1, aV1, aU2, aV2);
-    //
-    printf("point p_%d %lf %lf %lf\n", i, aX, aY, aZ);
-    //printf("point p_%d %20.15lf %20.15lf %20.15lf %20.15lf %20.15lf %20.15lf %20.15lf\n",
-        //   i, aX, aY, aZ, aU1, aV1, aU2, aV2);
-  }
-}
-#endif
 
 //=======================================================================
 // Function : FindMaxDistance
index 9ee234c..5b3b7d8 100644 (file)
@@ -40,8 +40,7 @@ static Standard_Boolean IsTangentExtCheck(TheIWFunction& theFunc,
                                           const Standard_Real theVinf,
                                           const Standard_Real theVsup)
 {
-  //Factor 2.0 is chosen because we compare distance(s) between TWO faces
-  const Standard_Real aTol = 2.0*Precision::Confusion();
+  const Standard_Real aTol = theFunc.Tolerance();
   const Standard_Integer aNbItems = 4;
   const Standard_Real aParU[aNbItems] = { Min(theU + theStepU, theUsup),
                                           Max(theU - theStepU, theUinf),
diff --git a/tests/bugs/modalg_6/bug26576_1 b/tests/bugs/modalg_6/bug26576_1
new file mode 100644 (file)
index 0000000..a85e65d
--- /dev/null
@@ -0,0 +1,56 @@
+puts "============"
+puts "OCC26576"
+puts "============"
+puts ""
+###############################
+## Wrong result obtained by intersection algorithm.
+###############################
+
+pload DCAF
+
+Open [locate_data_file bug26576_study1_new_geom.cbf] D
+
+GetShape D 0:1:484:1:1:2 b1
+GetShape D 0:1:478:1:1:2 b2
+
+explode b1 f
+explode b2 f
+copy b1_1 b1
+copy b2_2 b2
+donly b1 b2
+
+#Wrong value of Tolerance Reached. 
+
+set log [bopcurves b1 b2 -2d]
+regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Tolerance_Reached NbCurv
+
+set GoodNbCurv 2
+
+set expected_Tolerance_Reached 2.4466119525954045e-008
+set tol_abs_Tolerance_Reached 1.0e-7
+set tol_rel_Tolerance_Reached 0.0
+checkreal "Tolerance Reached" ${Tolerance_Reached} ${expected_Tolerance_Reached} ${tol_abs_Tolerance_Reached} ${tol_rel_Tolerance_Reached}
+
+if {${NbCurv} != ${GoodNbCurv}} {
+  puts "Error: ${GoodNbCurv} curves are expected but ${NbCurv} are found!"
+}
+
+#Overlapping intersection curves.
+
+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
+
+    set coe [checkoverlapedges e1 e2 $Tolerance_Reached]
+
+    puts "c_$i<->c_$j: $coe"
+    if { [regexp "Edges is not overlaped" $coe] != 1 } {
+      puts "Error: c_$i and c_$j are overlaped"
+    }
+  }
+}
+
+smallview
+fit
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_6/bug26576_2 b/tests/bugs/modalg_6/bug26576_2
new file mode 100644 (file)
index 0000000..19f61ac
--- /dev/null
@@ -0,0 +1,47 @@
+puts "============"
+puts "OCC26576"
+puts "============"
+puts ""
+###############################
+## Wrong result obtained by intersection algorithm.
+###############################
+
+pload DCAF
+
+Open [locate_data_file bug26576_study1_new_geom.cbf] D
+
+GetShape D 0:1:484:1:1:2 b1
+GetShape D 0:1:478:1:1:2 b2
+
+#General fuse
+
+bclearobjects
+bcleartools
+baddobjects b1
+baddtools b2
+bfillds
+
+bbuild result
+
+smallview
+donly result
+fit
+
+checkshape result
+
+set nbshapes_expected "
+Number of shapes in shape
+ VERTEX    : 4
+ EDGE      : 12
+ WIRE      : 10
+ FACE      : 8
+ SHELL     : 4
+ SOLID     : 4
+ COMPSOLID : 0
+ COMPOUND  : 1
+ SHAPE     : 43
+"
+
+checknbshapes result -ref ${nbshapes_expected} -t -m "General fuse"
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_6/bug26576_3 b/tests/bugs/modalg_6/bug26576_3
new file mode 100644 (file)
index 0000000..936519d
--- /dev/null
@@ -0,0 +1,61 @@
+puts "============"
+puts "OCC26576"
+puts "============"
+puts ""
+###############################
+## Wrong result obtained by intersection algorithm.
+###############################
+
+pload DCAF
+
+Open [locate_data_file bug26576_study1_new_geom.cbf] D
+
+GetShape D 0:1:484:1:1:2 b1_src
+GetShape D 0:1:478:1:1:2 b2_src
+
+save b1_src $imagedir/bug26576_b1.brep
+save b2_src $imagedir/bug26576_b2.brep
+
+restore $imagedir/bug26576_b1.brep b1
+restore $imagedir/bug26576_b2.brep b2
+
+explode b1 f
+explode b2 f
+copy b1_1 b2
+copy b2_2 b1
+
+#Wrong value of Tolerance Reached. 
+
+set log [bopcurves b1 b2 -2d]
+regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Tolerance_Reached NbCurv
+
+set GoodNbCurv 2
+
+set expected_Tolerance_Reached 2.4466119525954045e-008
+set tol_abs_Tolerance_Reached 1.0e-7
+set tol_rel_Tolerance_Reached 0.0
+checkreal "Tolerance Reached" ${Tolerance_Reached} ${expected_Tolerance_Reached} ${tol_abs_Tolerance_Reached} ${tol_rel_Tolerance_Reached}
+
+if {${NbCurv} != ${GoodNbCurv}} {
+  puts "Error: ${GoodNbCurv} curves are expected but ${NbCurv} are found!"
+}
+
+#Overlapping intersection curves.
+
+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
+
+    set coe [checkoverlapedges e1 e2 $Tolerance_Reached]
+
+    puts "$i<->$j: $coe"
+    if { [regexp "Edges is not overlaped" $coe] != 1 } {
+      puts "Error: c_$i and c_$j are overlaped"
+    }
+  }
+}
+
+smallview
+fit
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_6/bug26576_4 b/tests/bugs/modalg_6/bug26576_4
new file mode 100644 (file)
index 0000000..55ec976
--- /dev/null
@@ -0,0 +1,74 @@
+puts "============"
+puts "OCC26576"
+puts "============"
+puts ""
+###############################
+## Wrong result obtained by intersection algorithm.
+###############################
+
+set GoodNbCurv 2
+
+circle cc 1.5 3.125 0 0 0 1 1 0 0 0.25
+trim cc cc 0 3.14159265358979
+revsurf ss1 cc 1.5 3.125 0 -1 0 0
+
+plane ss2 3.48352775473762 1.7282347013387 0 0 0 -1 -1 0 0
+
+set IntCurv [intersect intres ss1 ss2]
+set NbIntCurv [llength ${IntCurv}]
+
+if { ${NbIntCurv} != ${GoodNbCurv} } {
+    puts "Error in geometric intersection: ${GoodNbCurv} curves are expected but ${NbIntCurv} are found!"
+} else {
+    puts "OK : Geometric intersection is good."
+}
+
+# For getting tolerance value
+mkface b1 ss1
+mkface b2 ss2
+donly b1
+
+set log [bopcurves b1 b2 -2d]
+regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Tolerance_Reached NbCurv
+
+set expected_Tolerance_Reached 1.9321146113460029e-008
+set tol_abs_Tolerance_Reached 1.0e-7
+set tol_rel_Tolerance_Reached 0.0
+checkreal "Tolerance Reached" ${Tolerance_Reached} ${expected_Tolerance_Reached} ${tol_abs_Tolerance_Reached} ${tol_rel_Tolerance_Reached}
+
+if {${NbCurv} != ${GoodNbCurv}} {
+  puts "Error: ${GoodNbCurv} curves are expected but ${NbCurv} are found!"
+}
+
+#Overlapping intersection curves.
+
+if { $Tolerance_Reached < 1.0e-7 } { set Tolerance_Reached 1.0e-7 }
+
+for {set i 1} {$i < ${NbCurv}} {incr i} {
+  for {set j [expr $i+1]} {$j <= $NbCurv} {incr j} {
+    mkedge eb1 c_$i
+    mkedge eb2 c_$j
+    
+    mkedge ei1 intres_$i
+    mkedge ei2 intres_$j
+
+    set coeb [checkoverlapedges eb1 eb2 $Tolerance_Reached]
+    set coei [checkoverlapedges ei1 ei2 $Tolerance_Reached]    
+
+    puts "$i<->$j: $coeb"
+    puts "$i<->$j: $coei"
+    if { [regexp "Edges is not overlaped" $coeb] != 1 } {
+      puts "Error: c_$i and c_$j are overlaped"
+    }
+    
+    if { [regexp "Edges is not overlaped" $coei] != 1 } {
+      puts "Error: intres_$i and intres_$j are overlaped"
+    }
+    
+    erase eb1 eb2 ei1 ei2
+  }
+}
+
+smallview
+fit
+set only_screen_axo 1