0029511: Section fails for these two faces
authorjgv <jgv@opencascade.com>
Fri, 30 Mar 2018 10:30:44 +0000 (13:30 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 14 Jun 2018 11:03:08 +0000 (14:03 +0300)
Modified method: Approx_ComputeLine::Compute
Check of multicurve is now always unconditional, the procedure of check is modified to avoid infinite loops.

Modified classes: GeomLib_CheckBSplineCurve and GeomLib_Check2dBSplineCurve
Correction of poles at the ends of curve is modified to fit the direction of tangent defined by two first points or two last points of walking line.

Also modified:

BOPAlgo_PaveFiller: modified methods PostTreatFF, RemoveUsedVertices - now unused vertices are included in the list of vertices to be absorbed by other ones.

20 files changed:
src/AppDef/AppDef_Compute.hxx
src/Approx/Approx_ComputeLine.gxx
src/BOPAlgo/BOPAlgo_PaveFiller.hxx
src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
src/BRepApprox/BRepApprox_TheComputeLineBezierOfApprox.hxx
src/GeomInt/GeomInt_IntSS.lxx
src/GeomInt/GeomInt_TheComputeLineBezierOfWLApprox.hxx
src/GeomLib/GeomLib_Check2dBSplineCurve.cxx
src/GeomLib/GeomLib_Check2dBSplineCurve.hxx
src/GeomLib/GeomLib_CheckBSplineCurve.cxx
src/GeomLib/GeomLib_CheckBSplineCurve.hxx
src/IntTools/IntTools_FaceFace.cxx
src/TopOpeBRepTool/TopOpeBRepTool_CurveTool.cxx
tests/bugs/modalg_5/bug24585_1
tests/bugs/modalg_6/bug27079_3 [new file with mode: 0644]
tests/bugs/modalg_6/bug27079_4 [new file with mode: 0644]
tests/bugs/modalg_6/bug27431
tests/bugs/modalg_7/bug27648 [new file with mode: 0644]
tests/bugs/modalg_7/bug28216
tests/bugs/modalg_7/bug29511 [new file with mode: 0644]

index bf37a6f..29fe92b 100644 (file)
@@ -181,7 +181,6 @@ private:
   AppParCurves_Constraint myfirstC;
   AppParCurves_Constraint mylastC;
   Standard_Integer myMultiLineNb;
-  Standard_Integer myNbPlusOnePoint;
   Standard_Boolean myIsClear;
 
 
index 21ecbf7..fdc4f14 100644 (file)
@@ -133,6 +133,8 @@ static Standard_Boolean CheckMultiCurve(const AppParCurves_MultiCurve& theMultiC
 {
   const Standard_Integer nbp3d = LineTool::NbP3d(theLine);
   const Standard_Integer nbp2d = LineTool::NbP2d(theLine);
+
+  const Standard_Real coeff = 4.; //2*2
   
   if (nbp3d > 1) //only simple cases are analysed
     return Standard_True;
@@ -207,6 +209,15 @@ static Standard_Boolean CheckMultiCurve(const AppParCurves_MultiCurve& theMultiC
     //Check: may be it is a real loop
     if (LoopFound)
     {
+#ifdef DRAW
+      for (Standard_Integer ipoint = theIndfirst; ipoint <= theIndlast; ipoint++)
+      {
+        LineTool::Value(theLine, ipoint, tabP);
+        gp_Pnt aPnt = tabP(1);
+        sprintf(name, "p%d", ipoint);
+        DrawTrSurf::Set(name, aPnt);
+      }
+#endif
       for (Standard_Integer FirstInd = theIndfirst;
            FirstInd <= theIndlast - 2; FirstInd++)
       {
@@ -243,6 +254,7 @@ static Standard_Boolean CheckMultiCurve(const AppParCurves_MultiCurve& theMultiC
     {
       //search <indbad>
       Standard_Real MaxSqDist = 0.;
+      Standard_Real MinSqDist = RealLast();
       for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++)
       {
         LineTool::Value(theLine, k-1, tabP);
@@ -255,24 +267,31 @@ static Standard_Boolean CheckMultiCurve(const AppParCurves_MultiCurve& theMultiC
           MaxSqDist = aSqDist;
           indbads[1] = k;
         }
+        if (aSqDist > gp::Resolution() &&
+            aSqDist < MinSqDist)
+          MinSqDist = aSqDist;
       }
-      for (Standard_Integer indcur = 2; indcur <= NbCur; indcur++)
-      {
-        MaxSqDist = 0.;
-        for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++)
+      Standard_Real Relation = MaxSqDist / MinSqDist;
+      if (Relation < coeff)
+        LoopFound = Standard_False;
+      else
+        for (Standard_Integer indcur = 2; indcur <= NbCur; indcur++)
         {
-          LineTool::Value(theLine, k-1, tabP2d);
-          gp_Pnt2d PrevPnt = tabP2d(indcur-1);
-          LineTool::Value(theLine, k, tabP2d);
-          gp_Pnt2d CurPnt  = tabP2d(indcur-1);
-          Standard_Real aSqDist = PrevPnt.SquareDistance(CurPnt);
-          if (aSqDist > MaxSqDist)
+          MaxSqDist = 0.;
+          for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++)
           {
-            MaxSqDist = aSqDist;
-            indbads[indcur] = k;
+            LineTool::Value(theLine, k-1, tabP2d);
+            gp_Pnt2d PrevPnt = tabP2d(indcur-1);
+            LineTool::Value(theLine, k, tabP2d);
+            gp_Pnt2d CurPnt  = tabP2d(indcur-1);
+            Standard_Real aSqDist = PrevPnt.SquareDistance(CurPnt);
+            if (aSqDist > MaxSqDist)
+            {
+              MaxSqDist = aSqDist;
+              indbads[indcur] = k;
+            }
           }
         }
-      }
     }
   } //if (myNbP3d == 1)
   else //2d case
@@ -307,6 +326,15 @@ static Standard_Boolean CheckMultiCurve(const AppParCurves_MultiCurve& theMultiC
     //Check: may be it is a real loop
     if (LoopFound)
     {
+#ifdef DRAW
+      for (Standard_Integer ipoint = theIndfirst; ipoint <= theIndlast; ipoint++)
+      {
+        LineTool::Value(theLine, ipoint, tabP2d);
+        gp_Pnt2d aPnt2d = tabP2d(1);
+        sprintf(name, "p%d", ipoint);
+        DrawTrSurf::Set(name, aPnt2d);
+      }
+#endif
       for (Standard_Integer FirstInd = theIndfirst;
            FirstInd <= theIndlast - 2; FirstInd++)
       {
@@ -345,6 +373,7 @@ static Standard_Boolean CheckMultiCurve(const AppParCurves_MultiCurve& theMultiC
       for (Standard_Integer indcur = 1; indcur <= NbCur; indcur++)
       {
         Standard_Real MaxSqDist = 0.;
+        Standard_Real MinSqDist = RealLast();
         for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++)
         {
           LineTool::Value(theLine, k-1, tabP2d);
@@ -357,21 +386,27 @@ static Standard_Boolean CheckMultiCurve(const AppParCurves_MultiCurve& theMultiC
             MaxSqDist = aSqDist;
             indbads[indcur] = k;
           }
+          if (aSqDist > gp::Resolution() &&
+              aSqDist < MinSqDist)
+            MinSqDist = aSqDist;
         }
+        Standard_Real Relation = MaxSqDist / MinSqDist;
+        if (Relation < coeff)
+          LoopFound = Standard_False;
       }
     }
   }
 
   //Define <indbad>
-  if (indbads[1] != 0 && indbads[2] != 0)
-  {
-    if (indbads[1] != indbads[2])
-      LoopFound = Standard_False;
-    else if (indbads[3] != 0 && indbads[1] != indbads[3])
-      LoopFound = Standard_False;
-  }
-  if (LoopFound)
-    theIndbad = indbads[1];
+  for (Standard_Integer i = 1; i <= 3; i++)
+    if (indbads[i] != 0)
+    {
+      theIndbad = indbads[i];
+      break;
+    }
+
+  if (!LoopFound)
+    theIndbad = 0;
   
   return (!LoopFound);
 }
@@ -650,7 +685,6 @@ Approx_ComputeLine::Approx_ComputeLine
                     const Standard_Boolean cutting,
                     const Standard_Boolean Squares)
 : myMultiLineNb (0),
-  myNbPlusOnePoint (0),
   myIsClear (Standard_False)
 {
   myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(), 
@@ -684,7 +718,6 @@ Approx_ComputeLine::Approx_ComputeLine
                     const Standard_Boolean cutting,
                     const Standard_Boolean Squares)
 : myMultiLineNb (0),
-  myNbPlusOnePoint (0),
   myIsClear (Standard_False)
 {
   myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(), 
@@ -716,7 +749,6 @@ Approx_ComputeLine::Approx_ComputeLine
                     const Approx_ParametrizationType parametrization,
                     const Standard_Boolean Squares)
 : myMultiLineNb (0),
-  myNbPlusOnePoint (0),
   myIsClear (Standard_False)
 {
   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
@@ -745,7 +777,6 @@ Approx_ComputeLine::Approx_ComputeLine
                     const Approx_ParametrizationType parametrization,
                     const Standard_Boolean Squares)
 : myMultiLineNb (0),
-  myNbPlusOnePoint (0),
   myIsClear (Standard_False)
 {
   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
@@ -778,7 +809,6 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
     Tolers3d.Clear();
     Tolers2d.Clear();
     myMultiLineNb = 0;
-    //myNbPlusOnePoint = 0;
   }
   else myIsClear = Standard_False;
 
@@ -825,7 +855,6 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
     {
       myIsClear = Standard_True;
       //++myMultiLineNb;
-      myNbPlusOnePoint++;
       Perform(anOtherLine0);
       alldone = Standard_True;
     }
@@ -927,7 +956,6 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
             {
               myIsClear = Standard_True;
               //++myMultiLineNb;
-              myNbPlusOnePoint++;
               Par = SavePar;
               Perform(anOtherLine2);
               Ok = Standard_True;
@@ -955,7 +983,6 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
               {
                 myIsClear = Standard_True;
                 //++myMultiLineNb;
-                myNbPlusOnePoint++;
                 Perform (anOtherLine2);
                 Ok = Standard_True;
               }
@@ -997,7 +1024,6 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
               {
                 myIsClear = Standard_True;
                 //++myMultiLineNb;
-                myNbPlusOnePoint++;
                 Perform(anOtherLine3);
                 myfirstpt = mylastpt;
                 mylastpt = Thelastpt;
@@ -1108,22 +1134,8 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
        }
 
        TheMultiCurve = AppParCurves_MultiCurve();
-        MultiLine anOtherLine4;
-        Standard_Boolean isOtherLine4Made = Standard_False;
         Standard_Integer indbad = 0;
        Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d, indbad);
-        if (indbad != 0)
-        {
-          isOtherLine4Made = LineTool::MakeMLOneMorePoint (Line, myfirstpt, mylastpt, indbad, anOtherLine4);
-        }
-        if (isOtherLine4Made)
-        {
-          myIsClear = Standard_True;
-          //++myMultiLineNb;
-          myNbPlusOnePoint++;
-          Perform (anOtherLine4);
-          Ok = Standard_True;
-        }
         if (myfirstpt == Thelastpt)
         {
           Finish = Standard_True;
@@ -1310,8 +1322,7 @@ Standard_Boolean Approx_ComputeLine::Compute(const MultiLine& Line,
 #ifdef OCCT_DEBUG
         if (mydebug) DUMP(mySCU);
 #endif
-        if (myNbPlusOnePoint != 0 &&
-            !CheckMultiCurve(mySCU, Line,
+        if (!CheckMultiCurve(mySCU, Line,
                              fpt, lpt,
                              indbad))
         {
index 6269e6d..9218521 100644 (file)
@@ -341,7 +341,7 @@ protected:
   //! Removes indices of vertices that are already on the
   //! curve <theNC> from the map <theMV>.
   //! It is used in PutEFPavesOnCurve and PutStickPavesOnCurve methods.
-  Standard_EXPORT void RemoveUsedVertices (BOPDS_Curve& theNC, TColStd_MapOfInteger& theMV);
+  Standard_EXPORT void RemoveUsedVertices (const BOPDS_Curve& theNC, TColStd_MapOfInteger& theMV);
   
 
   //! Puts the pave nV on the curve theNC.
index 36e1c9f..66fcea7 100644 (file)
@@ -781,11 +781,45 @@ void BOPAlgo_PaveFiller::PostTreatFF
   aPF.SetNonDestructive(myNonDestructive);
   //
   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
+  Standard_Integer aNbFF = aFFs.Length();
   //
+
+  //Find unused vertices
+  TopTools_IndexedMapOfShape VertsUnused;
+  TColStd_MapOfInteger IndMap;
+  for (Standard_Integer i = 0; i < aNbFF; i++)
+  {
+    BOPDS_InterfFF& aFF = aFFs(i);
+    Standard_Integer nF1, nF2;
+    aFF.Indices(nF1, nF2);
+    
+    TColStd_MapOfInteger aMV, aMVEF, aMI;
+    GetStickVertices(nF1, nF2, aMV, aMVEF, aMI);
+    BOPDS_VectorOfCurve& aVC = aFF.ChangeCurves();
+    Standard_Integer aNbC = aVC.Length();
+    for (j = 0; j < aNbC; j++)
+    {
+      BOPDS_Curve& aNC = aVC.ChangeValue(j);
+      RemoveUsedVertices(aNC, aMV);
+    }
+
+    TColStd_MapIteratorOfMapOfInteger itmap(aMV);
+    for(; itmap.More(); itmap.Next())
+    {
+      Standard_Integer indV = itmap.Value();
+      const TopoDS_Shape& aVertex = myDS->Shape(indV);
+      if (IndMap.Add(indV))
+        VertsUnused.Add(aVertex);
+      else
+        VertsUnused.RemoveKey(aVertex);
+    }
+  }
+  /////////////////////
+  
   Standard_Integer aNbME = theMicroEdges.Extent();
   Standard_Integer aNbVOnRPB = theVertsOnRejectedPB.Extent();
   // 0
-  if (aNbS==1 && (aNbME == 0) && (aNbVOnRPB == 0)) {
+  if (aNbS==1 && (aNbME == 0) && (aNbVOnRPB == 0) && VertsUnused.IsEmpty()) {
     const TopoDS_Shape& aS=theMSCPB.FindKey(1);
     const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromIndex(1);
     //
@@ -887,16 +921,22 @@ void BOPAlgo_PaveFiller::PostTreatFF
 
   // Add vertices put on the real section curves to unify them with the
   // vertices of the edges, by which these sections curves have been rejected
-  for (Standard_Integer i = 1; i <= aNbVOnRPB; ++i)
+  // and with unused vertices
+  const TopTools_IndexedMapOfShape* VerMap [2] = {&theVertsOnRejectedPB, &VertsUnused};
+  for (Standard_Integer imap = 0; imap < 2; imap++)
   {
-    TopoDS_Shape aVer = theVertsOnRejectedPB(i);
-    Standard_Integer iVer = myDS->Index(aVer);
-    const Standard_Integer* pSD = aDMNewSD.Seek(iVer);
-    if (pSD)
-      aVer = myDS->Shape(*pSD);
-
-    if (anAddedSD.Add(aVer))
-      aLS.Append(aVer);
+    Standard_Integer NbVer = VerMap[imap]->Extent();
+    for (Standard_Integer i = 1; i <= NbVer; ++i)
+    {
+      TopoDS_Shape aVer = VerMap[imap]->FindKey(i);
+      Standard_Integer iVer = myDS->Index(aVer);
+      const Standard_Integer* pSD = aDMNewSD.Seek(iVer);
+      if (pSD)
+        aVer = myDS->Shape(*pSD);
+      
+      if (anAddedSD.Add(aVer))
+        aLS.Append(aVer);
+    }
   }
   //
   // 2 Fuse shapes
@@ -2091,23 +2131,24 @@ void BOPAlgo_PaveFiller::GetFullShapeMap(const Standard_Integer nF,
 // function: RemoveUsedVertices
 // purpose: 
 //=======================================================================
-void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC,
+void BOPAlgo_PaveFiller::RemoveUsedVertices(const BOPDS_Curve& aNC,
                                             TColStd_MapOfInteger& aMV)
 {
   if (!aMV.Extent()) {
     return;
   }
-  Standard_Integer nV;
-  BOPDS_Pave aPave;
-  BOPDS_ListIteratorOfListOfPave aItLP;
-  //
-  Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
-  const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
-  aItLP.Initialize(aLP);
-  for (;aItLP.More();aItLP.Next()) {
-    aPave = aItLP.Value();
-    nV = aPave.Index();
-    aMV.Remove(nV);
+
+  const BOPDS_ListOfPaveBlock& aLPBC = aNC.PaveBlocks();
+  BOPDS_ListIteratorOfListOfPaveBlock itPB(aLPBC);
+  for (; itPB.More(); itPB.Next())
+  {
+    const BOPDS_ListOfPave& aLP = itPB.Value()->ExtPaves();
+    BOPDS_ListIteratorOfListOfPave aItLP(aLP);
+    for (;aItLP.More();aItLP.Next()) {
+      BOPDS_Pave aPave = aItLP.Value();
+      Standard_Integer nV = aPave.Index();
+      aMV.Remove(nV);
+    }
   }
 }
 
index a75b0ae..25406db 100644 (file)
@@ -179,7 +179,6 @@ private:
   AppParCurves_Constraint myfirstC;
   AppParCurves_Constraint mylastC;
   Standard_Integer myMultiLineNb;
-  Standard_Integer myNbPlusOnePoint;
   Standard_Boolean myIsClear;
 
 
index 91295a1..6cd30cd 100644 (file)
@@ -26,8 +26,8 @@ inline GeomInt_IntSS::GeomInt_IntSS ()
  : myNbrestr(0),
    myTolReached2d(0.0),
    myTolReached3d(0.0),
-   myTolCheck(0.0000001),
-   myTolAngCheck(0.3)
+   myTolCheck(1.e-7),
+   myTolAngCheck(1.e-6)
 {}
 
 //=======================================================================
@@ -43,8 +43,8 @@ inline GeomInt_IntSS::GeomInt_IntSS ()
  : myNbrestr(0),
    myTolReached2d(0.0),
    myTolReached3d(0.0),
-   myTolCheck(0.0000001),
-   myTolAngCheck(0.3)
+   myTolCheck(1.e-7),
+   myTolAngCheck(1.e-6)
 {
   Perform(S1,S2,Tol,Approx,ApproxS1,ApproxS2);
 }
index acc5e5d..ef76a5e 100644 (file)
@@ -182,7 +182,6 @@ private:
   AppParCurves_Constraint myfirstC;
   AppParCurves_Constraint mylastC;
   Standard_Integer myMultiLineNb;
-  Standard_Integer myNbPlusOnePoint;
   Standard_Boolean myIsClear;
 
 
index 929b855..958c999 100644 (file)
 //purpose  : 
 //=======================================================================
 GeomLib_Check2dBSplineCurve::GeomLib_Check2dBSplineCurve(const Handle(Geom2d_BSplineCurve)& Curve,
-                                                    const Standard_Real Tolerance,
-                                                    const Standard_Real AngularTolerance)
-:myCurve(Curve),
-myDone(Standard_False),
-myFixFirstTangent(Standard_False),
-myFixLastTangent(Standard_False),
-myAngularTolerance(Abs(AngularTolerance)),
-myTolerance(Abs(Tolerance)),
-myFirstPole(1.0,0.0e0),
-myLastPole(1.0e0,0.0e0)
+                                                         const Standard_Real Tolerance,
+                                                         const Standard_Real AngularTolerance)
+ : myCurve(Curve),
+   myDone(Standard_False),
+   myFixFirstTangent(Standard_False),
+   myFixLastTangent(Standard_False),
+   myAngularTolerance(Abs(AngularTolerance)),
+   myTolerance(Abs(Tolerance)),
+   myIndSecondPole(-1),
+   myIndPrelastPole(-1)
 {
-  
-
   Standard_Integer ii,
     num_poles ;
   Standard_Real tangent_magnitude,
     value,
-    angular_value,
-    factor,
     vector_magnitude ;
-  num_poles = Curve->NbPoles() ;
+  num_poles = myCurve->NbPoles() ;
+  
   if (( ! myCurve->IsPeriodic() )&& num_poles >= 4) {
     
-    gp_Vec2d tangent,
-      diff,
-      a_vector;
-    for (ii = 1 ; ii <= 2 ; ii++) {
-      tangent.SetCoord(ii,myCurve->Pole(2).Coord(ii) - myCurve->Pole(1).Coord(ii))  ;
-      a_vector.SetCoord(ii, myCurve->Pole(3).Coord(ii) - myCurve->Pole(1).Coord(ii)) ;
-    }
+    gp_Vec2d tangent, tangent_normalized,
+      a_vector, avector_normalized;
+
+    const Standard_Real CrossProdTol = myAngularTolerance;
+    
+    //Near first
+    tangent = gp_Vec2d(myCurve->Pole(1), myCurve->Pole(2));
     tangent_magnitude = tangent.Magnitude() ;
-    vector_magnitude = a_vector.Magnitude() ;
-    if (tangent_magnitude > myTolerance &&
-       vector_magnitude > myTolerance)
+    if (tangent_magnitude > myTolerance)
+      tangent_normalized = tangent/tangent_magnitude;
+    
+    for (ii = 3; ii <= num_poles; ii++)
+    {
+      a_vector = gp_Vec2d(myCurve->Pole(1), myCurve->Pole(ii));
+      vector_magnitude = a_vector.Magnitude() ;
+      
+      if (tangent_magnitude > myTolerance &&
+          vector_magnitude  > myTolerance)
       {
+        avector_normalized = a_vector/vector_magnitude;
+
+        Standard_Real CrossProd = tangent_normalized ^ avector_normalized;
+        if (Abs(CrossProd) > CrossProdTol)
+          break;
+        
         value = tangent.Dot(a_vector) ;
-        if ( value < 0.0e0) {
-         for (ii = 1 ; ii <= 2 ; ii++) {
-           diff.SetCoord(ii, (tangent.Coord(ii) / tangent_magnitude) + (a_vector.Coord(ii) / vector_magnitude)) ; 
-          } 
-         angular_value = 
-           diff.Magnitude() ;
-          if (angular_value < myAngularTolerance) {
-           myFixFirstTangent = Standard_True ;
-           factor = 1.0e0 ;
-           if (tangent_magnitude > 0.5e0 * vector_magnitude) {
-             factor = 0.5e0 *  vector_magnitude / tangent_magnitude ;
-           }
-           for (ii = 1 ; ii <= 2 ; ii++) {
-             myFirstPole.SetCoord(ii, myCurve->Pole(1).Coord(ii)  - factor * tangent.Coord(ii))  ;
-           }
-          }
-         
-       }
+        if ( value < 0.0e0)
+        {
+          myFixFirstTangent = Standard_True ;
+          myIndSecondPole = ii;
+          break;
+        }
       }
-    for (ii = 1 ; ii <= 2 ; ii++) {
-      tangent.SetCoord(ii,myCurve->Pole(num_poles-1).Coord(ii) - myCurve->Pole(num_poles).Coord(ii))  ;
-      a_vector.SetCoord(ii, myCurve->Pole(num_poles-2).Coord(ii) - myCurve->Pole(num_poles).Coord(ii)) ;
     }
+
+    //Near last
+    tangent = gp_Vec2d(myCurve->Pole(num_poles), myCurve->Pole(num_poles-1));
     tangent_magnitude = tangent.Magnitude() ;
-    vector_magnitude = a_vector.Magnitude() ;
+    if (tangent_magnitude > myTolerance)
+      tangent_normalized = tangent/tangent_magnitude;
+
+    for (ii = num_poles-2; ii >= 1; ii--)
+    {
+      a_vector = gp_Vec2d(myCurve->Pole(num_poles), myCurve->Pole(ii));
+      vector_magnitude = a_vector.Magnitude() ;
     
-    if (tangent_magnitude > myTolerance &&
-       vector_magnitude > myTolerance)
+      if (tangent_magnitude > myTolerance &&
+          vector_magnitude  > myTolerance)
       {
+        avector_normalized = a_vector/vector_magnitude;
+
+        Standard_Real CrossProd = tangent_normalized ^ avector_normalized;
+        if (Abs(CrossProd) > CrossProdTol)
+          break;
+        
         value = tangent.Dot(a_vector) ;
-       if (value < 0.0e0) {
-         for (ii = 1 ; ii <= 2 ; ii++) {
-           diff.SetCoord(ii, (tangent.Coord(ii) / tangent_magnitude) + (a_vector.Coord(ii) / vector_magnitude)) ; 
-          } 
-         angular_value = 
-           diff.Magnitude() ;
-         if ( angular_value < myAngularTolerance) {
-           myFixLastTangent = Standard_True ;
-           factor = 1.0e0 ;
-           if (tangent_magnitude > 0.5e0 * vector_magnitude) {
-             factor = 0.5e0 *  vector_magnitude / tangent_magnitude ;
-           }
-           for (ii = 1 ; ii <= 2 ; ii++) {
-             myLastPole.SetCoord(ii, myCurve->Pole(num_poles).Coord(ii)  - factor * tangent.Coord(ii))  ;
-           }
-         }
-         
+        if (value < 0.0e0)
+        {
+          myFixLastTangent = Standard_True ;
+          myIndPrelastPole = ii;
+          break;
         }
       }
-    
-  }
+    }
+  } //if (( ! myCurve->IsPeriodic() )&& num_poles >= 4)
   else {
     myDone = Standard_True ;
   }
 }
-  
+
 //=======================================================================
 //function : NeedTangentFix
 //purpose  : 
@@ -129,52 +127,71 @@ void GeomLib_Check2dBSplineCurve::NeedTangentFix(Standard_Boolean & FirstFlag,
                                               Standard_Boolean & LastFlag) const 
 {
   FirstFlag = myFixFirstTangent ;
-  LastFlag = myFixLastTangent ;
+  LastFlag  = myFixLastTangent ;
 }
+
 //=======================================================================
 //function : FixTangent
 //purpose  : 
 //=======================================================================
 
 Handle(Geom2d_BSplineCurve)  GeomLib_Check2dBSplineCurve::FixedTangent(const Standard_Boolean FirstFlag,
-                                                                const Standard_Boolean LastFlag)
-{ 
+                                                                       const Standard_Boolean LastFlag)
+{
   Handle(Geom2d_BSplineCurve) new_curve ;
   if ((myFixFirstTangent && FirstFlag) ||(myFixLastTangent && LastFlag)) {
     new_curve =
       Handle(Geom2d_BSplineCurve)::DownCast(myCurve->Copy()) ;
     
+    FixTangentOnCurve(new_curve, FirstFlag, LastFlag);
   }
-  if (myFixFirstTangent && FirstFlag) {
-    new_curve->SetPole(2,
-                    myFirstPole) ;
-  }
-  if (myFixLastTangent && LastFlag) {
-    Standard_Integer num_poles = myCurve->NbPoles() ;
-    new_curve->SetPole(num_poles-1,
-                    myLastPole) ;
-  }
-  
-  myDone = Standard_True ;
   return new_curve ;
-}                                 
+}
+
 //=======================================================================
 //function : FixTangent
 //purpose  : 
 //=======================================================================
 
 void GeomLib_Check2dBSplineCurve::FixTangent(const Standard_Boolean FirstFlag,
-                                                                const Standard_Boolean LastFlag)
-{ 
+                                             const Standard_Boolean LastFlag)
+{
+  FixTangentOnCurve(myCurve, FirstFlag, LastFlag);
+}
+
+//=======================================================================
+//function : FixTangentOnCurve
+//purpose  : 
+//=======================================================================
 
+void GeomLib_Check2dBSplineCurve::FixTangentOnCurve(Handle(Geom2d_BSplineCurve)& theCurve,
+                                                    const Standard_Boolean FirstFlag,
+                                                    const Standard_Boolean LastFlag)
+{ 
   if (myFixFirstTangent && FirstFlag) {
-    myCurve->SetPole(2,
-                    myFirstPole) ;
+    gp_XY XY1 = theCurve->Pole(1).XY();
+    gp_XY XY2 = theCurve->Pole(myIndSecondPole).XY();
+    Standard_Real NbSamples = myIndSecondPole - 1;
+    for (Standard_Integer i = 2; i < myIndSecondPole; i++)
+    {
+      Standard_Real ii = i-1;
+      gp_Pnt2d aNewPole((1. - ii/NbSamples)*XY1 + ii/NbSamples*XY2);
+      theCurve->SetPole(i, aNewPole);
+    }
   }
+  
   if (myFixLastTangent && LastFlag) {
-    Standard_Integer num_poles = myCurve->NbPoles() ;
-    myCurve->SetPole(num_poles-1,
-                    myLastPole) ;
+    Standard_Integer num_poles = theCurve->NbPoles() ;
+    
+    gp_XY XY1 = theCurve->Pole(num_poles).XY();
+    gp_XY XY2 = theCurve->Pole(myIndPrelastPole).XY();
+    Standard_Real NbSamples = num_poles - myIndPrelastPole;
+    for (Standard_Integer i = num_poles-1; i > myIndPrelastPole; i--)
+    {
+      Standard_Real ii = num_poles-i;
+      gp_Pnt2d aNewPole((1. - ii/NbSamples)*XY1 + ii/NbSamples*XY2);
+      theCurve->SetPole(i, aNewPole);
+    }
   }
   
   myDone = Standard_True ;
index 5d416d6..200bccc 100644 (file)
@@ -38,7 +38,9 @@ public:
   DEFINE_STANDARD_ALLOC
 
   
-  Standard_EXPORT GeomLib_Check2dBSplineCurve(const Handle(Geom2d_BSplineCurve)& Curve, const Standard_Real Tolerance, const Standard_Real AngularTolerance);
+  Standard_EXPORT GeomLib_Check2dBSplineCurve(const Handle(Geom2d_BSplineCurve)& Curve,
+                                              const Standard_Real Tolerance,
+                                              const Standard_Real AngularTolerance);
   
     Standard_Boolean IsDone() const;
   
@@ -64,6 +66,9 @@ protected:
 
 private:
 
+  void FixTangentOnCurve(Handle(Geom2d_BSplineCurve)& theCurve,
+                         const Standard_Boolean FirstFlag,
+                         const Standard_Boolean LastFlag);
 
 
   Handle(Geom2d_BSplineCurve) myCurve;
@@ -72,10 +77,9 @@ private:
   Standard_Boolean myFixLastTangent;
   Standard_Real myAngularTolerance;
   Standard_Real myTolerance;
-  gp_Pnt2d myFirstPole;
-  gp_Pnt2d myLastPole;
-
 
+  Standard_Integer myIndSecondPole;
+  Standard_Integer myIndPrelastPole;
 };
 
 
index 78f5c8f..cc6ab66 100644 (file)
 GeomLib_CheckBSplineCurve::GeomLib_CheckBSplineCurve(const Handle(Geom_BSplineCurve)& Curve,
                                                     const Standard_Real Tolerance,
                                                     const Standard_Real AngularTolerance)
-:myCurve(Curve),
-myDone(Standard_False),
-myFixFirstTangent(Standard_False),
-myFixLastTangent(Standard_False),
-myAngularTolerance(Abs(AngularTolerance)),
-myTolerance(Abs(Tolerance)),
-myFirstPole(1.0,0.0e0,0.e0),
-myLastPole(1.0e0,0.0e0,0.e0)
+ : myCurve(Curve),
+   myDone(Standard_False),
+   myFixFirstTangent(Standard_False),
+   myFixLastTangent(Standard_False),
+   myAngularTolerance(Abs(AngularTolerance)),
+   myTolerance(Abs(Tolerance)),
+   myIndSecondPole(-1),
+   myIndPrelastPole(-1)
 {
-  
-
   Standard_Integer ii,
     num_poles ;
   Standard_Real tangent_magnitude,
     value,
-    angular_value,
-    factor,
     vector_magnitude ;
-  num_poles = Curve->NbPoles() ;
+  num_poles = myCurve->NbPoles() ;
+  
   if (( ! myCurve->IsPeriodic() )&& num_poles >= 4) {
     
-    gp_Vec tangent,
-      diff,
-      a_vector;
-    for (ii = 1 ; ii <= 3 ; ii++) {
-      tangent.SetCoord(ii,myCurve->Pole(2).Coord(ii) - myCurve->Pole(1).Coord(ii))  ;
-      a_vector.SetCoord(ii, myCurve->Pole(3).Coord(ii) - myCurve->Pole(1).Coord(ii)) ;
-    }
+    gp_Vec tangent, tangent_normalized,
+      a_vector, avector_normalized;
+    
+    const Standard_Real CrossProdSqTol = myAngularTolerance*myAngularTolerance;
+    
+    //Near first
+    tangent = gp_Vec(myCurve->Pole(1), myCurve->Pole(2));
     tangent_magnitude = tangent.Magnitude() ;
-    vector_magnitude = a_vector.Magnitude() ;
-    if (tangent_magnitude > myTolerance &&
-       vector_magnitude > myTolerance)
+    if (tangent_magnitude > myTolerance)
+      tangent_normalized = tangent/tangent_magnitude;
+    
+    for (ii = 3; ii <= num_poles; ii++)
+    {
+      a_vector = gp_Vec(myCurve->Pole(1), myCurve->Pole(ii));
+      vector_magnitude = a_vector.Magnitude() ;
+      
+      if (tangent_magnitude > myTolerance &&
+          vector_magnitude  > myTolerance)
       {
+        avector_normalized = a_vector/vector_magnitude;
+
+        gp_Vec CrossProd = tangent_normalized ^ avector_normalized;
+        Standard_Real CrossProdSqLength = CrossProd.SquareMagnitude();
+        if (CrossProdSqLength > CrossProdSqTol)
+          break;
+        
         value = tangent.Dot(a_vector) ;
-        if ( value < 0.0e0) {
-         for (ii = 1 ; ii <= 3 ; ii++) {
-           diff.SetCoord(ii, (tangent.Coord(ii) / tangent_magnitude) + (a_vector.Coord(ii) / vector_magnitude)) ; 
-          } 
-         angular_value = 
-           diff.Magnitude() ;
-          if (angular_value < myAngularTolerance) {
-           myFixFirstTangent = Standard_True ;
-           factor = 1.0e0 ;
-           if (tangent_magnitude > 0.5e0 * vector_magnitude) {
-             factor = 0.5e0 *  vector_magnitude / tangent_magnitude ;
-           }
-           for (ii = 1 ; ii <= 3 ; ii++) {
-             myFirstPole.SetCoord(ii, myCurve->Pole(1).Coord(ii)  - factor * tangent.Coord(ii))  ;
-           }
-          }
-         
+        if ( value < 0.0e0)
+        {
+          myFixFirstTangent = Standard_True ;
+          myIndSecondPole = ii;
+          break;
        }
       }
-    for (ii = 1 ; ii <= 3 ; ii++) {
-      tangent.SetCoord(ii,myCurve->Pole(num_poles-1).Coord(ii) - myCurve->Pole(num_poles).Coord(ii))  ;
-      a_vector.SetCoord(ii, myCurve->Pole(num_poles-2).Coord(ii) - myCurve->Pole(num_poles).Coord(ii)) ;
     }
+
+    //Near last
+    tangent = gp_Vec(myCurve->Pole(num_poles), myCurve->Pole(num_poles-1));
     tangent_magnitude = tangent.Magnitude() ;
-    vector_magnitude = a_vector.Magnitude() ;
-    
-    if (tangent_magnitude > myTolerance &&
-       vector_magnitude > myTolerance)
+    if (tangent_magnitude > myTolerance)
+      tangent_normalized = tangent/tangent_magnitude;
+
+    for (ii = num_poles-2; ii >= 1; ii--)
+    {
+      a_vector = gp_Vec(myCurve->Pole(num_poles), myCurve->Pole(ii));
+      vector_magnitude = a_vector.Magnitude() ;
+      
+      if (tangent_magnitude > myTolerance &&
+          vector_magnitude  > myTolerance)
       {
+        avector_normalized = a_vector/vector_magnitude;
+
+        gp_Vec CrossProd = tangent_normalized ^ avector_normalized;
+        Standard_Real CrossProdSqLength = CrossProd.SquareMagnitude();
+        if (CrossProdSqLength > CrossProdSqTol)
+          break;
+          
         value = tangent.Dot(a_vector) ;
-       if (value < 0.0e0) {
-         for (ii = 1 ; ii <= 3 ; ii++) {
-           diff.SetCoord(ii, (tangent.Coord(ii) / tangent_magnitude) + (a_vector.Coord(ii) / vector_magnitude)) ; 
-          } 
-         angular_value = 
-           diff.Magnitude() ;
-         if ( angular_value < myAngularTolerance) {
-           myFixLastTangent = Standard_True ;
-           factor = 1.0e0 ;
-           if (tangent_magnitude > 0.5e0 * vector_magnitude) {
-             factor = 0.5e0 *  vector_magnitude / tangent_magnitude ;
-           }
-           for (ii = 1 ; ii <= 3 ; ii++) {
-             myLastPole.SetCoord(ii, myCurve->Pole(num_poles).Coord(ii)  - factor * tangent.Coord(ii))  ;
-           }
-         }
-         
+       if (value < 0.0e0)
+        {
+          myFixLastTangent = Standard_True ;
+          myIndPrelastPole = ii;
+          break;
         }
       }
-    
-  }
+    }
+  } //if (( ! myCurve->IsPeriodic() )&& num_poles >= 4)
   else {
     myDone = Standard_True ;
   }
@@ -128,52 +128,71 @@ void GeomLib_CheckBSplineCurve::NeedTangentFix(Standard_Boolean & FirstFlag,
                                               Standard_Boolean & LastFlag) const 
 {
   FirstFlag = myFixFirstTangent ;
-  LastFlag = myFixLastTangent ;
+  LastFlag  = myFixLastTangent ;
 }
+
 //=======================================================================
-//function : FixTangent
+//function : FixedTangent
 //purpose  : 
 //=======================================================================
 
 Handle(Geom_BSplineCurve)  GeomLib_CheckBSplineCurve::FixedTangent(const Standard_Boolean FirstFlag,
-                                                                const Standard_Boolean LastFlag)
+                                                                   const Standard_Boolean LastFlag)
 { 
   Handle(Geom_BSplineCurve) new_curve ;
   if ((myFixFirstTangent && FirstFlag) ||(myFixLastTangent && LastFlag)) {
     new_curve =
       Handle(Geom_BSplineCurve)::DownCast(myCurve->Copy()) ;
     
+    FixTangentOnCurve(new_curve, FirstFlag, LastFlag);
   }
-  if (myFixFirstTangent && FirstFlag) {
-    new_curve->SetPole(2,
-                    myFirstPole) ;
-  }
-  if (myFixLastTangent && LastFlag) {
-    Standard_Integer num_poles = myCurve->NbPoles() ;
-    new_curve->SetPole(num_poles-1,
-                    myLastPole) ;
-  }
-  
-  myDone = Standard_True ;
   return new_curve ;
-}                                 
+}
+
 //=======================================================================
 //function : FixTangent
 //purpose  : 
 //=======================================================================
 
 void GeomLib_CheckBSplineCurve::FixTangent(const Standard_Boolean FirstFlag,
-                                          const Standard_Boolean LastFlag)
+                                           const Standard_Boolean LastFlag)
+{
+  FixTangentOnCurve(myCurve, FirstFlag, LastFlag);
+}
+
+//=======================================================================
+//function : FixTangentOnCurve
+//purpose  : 
+//=======================================================================
+
+void GeomLib_CheckBSplineCurve::FixTangentOnCurve(Handle(Geom_BSplineCurve)& theCurve,
+                                                  const Standard_Boolean FirstFlag,
+                                                  const Standard_Boolean LastFlag)
 { 
-  
   if (myFixFirstTangent && FirstFlag) {
-    myCurve->SetPole(2,
-                    myFirstPole) ;
+    gp_XYZ XYZ1 = theCurve->Pole(1).XYZ();
+    gp_XYZ XYZ2 = theCurve->Pole(myIndSecondPole).XYZ();
+    Standard_Real NbSamples = myIndSecondPole - 1;
+    for (Standard_Integer i = 2; i < myIndSecondPole; i++)
+    {
+      Standard_Real ii = i-1;
+      gp_Pnt aNewPole((1. - ii/NbSamples)*XYZ1 + ii/NbSamples*XYZ2);
+      theCurve->SetPole(i, aNewPole);
+    }
   }
+  
   if (myFixLastTangent && LastFlag) {
-    Standard_Integer num_poles = myCurve->NbPoles() ;
-    myCurve->SetPole(num_poles-1,
-                    myLastPole) ;
+    Standard_Integer num_poles = theCurve->NbPoles() ;
+    
+    gp_XYZ XYZ1 = theCurve->Pole(num_poles).XYZ();
+    gp_XYZ XYZ2 = theCurve->Pole(myIndPrelastPole).XYZ();
+    Standard_Real NbSamples = num_poles - myIndPrelastPole;
+    for (Standard_Integer i = num_poles-1; i > myIndPrelastPole; i--)
+    {
+      Standard_Real ii = num_poles-i;
+      gp_Pnt aNewPole((1. - ii/NbSamples)*XYZ1 + ii/NbSamples*XYZ2);
+      theCurve->SetPole(i, aNewPole);
+    }
   }
   
   myDone = Standard_True ;
index b99a995..b046faf 100644 (file)
@@ -38,7 +38,9 @@ public:
   DEFINE_STANDARD_ALLOC
 
   
-  Standard_EXPORT GeomLib_CheckBSplineCurve(const Handle(Geom_BSplineCurve)& Curve, const Standard_Real Tolerance, const Standard_Real AngularTolerance);
+  Standard_EXPORT GeomLib_CheckBSplineCurve(const Handle(Geom_BSplineCurve)& Curve,
+                                            const Standard_Real Tolerance,
+                                            const Standard_Real AngularTolerance);
   
     Standard_Boolean IsDone() const;
   
@@ -64,6 +66,9 @@ protected:
 
 private:
 
+  void FixTangentOnCurve(Handle(Geom_BSplineCurve)& theCurve,
+                         const Standard_Boolean FirstFlag,
+                         const Standard_Boolean LastFlag);
 
 
   Handle(Geom_BSplineCurve) myCurve;
@@ -72,10 +77,9 @@ private:
   Standard_Boolean myFixLastTangent;
   Standard_Real myAngularTolerance;
   Standard_Real myTolerance;
-  gp_Pnt myFirstPole;
-  gp_Pnt myLastPole;
-
 
+  Standard_Integer myIndSecondPole;
+  Standard_Integer myIndPrelastPole;
 };
 
 
index 8726f0a..96d14a6 100644 (file)
@@ -717,8 +717,8 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
   IntPatch_IType typl;
   Handle(Geom_Curve) newc;
   //
-  const Standard_Real TOLCHECK   =0.0000001;
-  const Standard_Real TOLANGCHECK=0.1;
+  const Standard_Real TOLCHECK    = 1.e-7;
+  const Standard_Real TOLANGCHECK = 1.e-6;
   //
   rejectSurface = Standard_False;
   reApprox = Standard_False;
index 24307fb..5f76fea 100644 (file)
@@ -309,6 +309,9 @@ Standard_Boolean  TopOpeBRepTool_CurveTool::MakeCurves
  Handle(Geom2d_Curve)& PC1new, Handle(Geom2d_Curve)& PC2new,
  Standard_Real& TolReached3d, Standard_Real& TolReached2d) const
 {
+  const Standard_Real TOLCHECK    = 1.e-7;
+  const Standard_Real TOLANGCHECK = 1.e-6;
+  
   Standard_Boolean CompC3D = myGeomTool.CompC3D();
 
   //cout << "MakeCurves begin" << endl;
@@ -681,7 +684,7 @@ Standard_Boolean  TopOpeBRepTool_CurveTool::MakeCurves
 
   Handle(Geom_BSplineCurve) Curve (Handle(Geom_BSplineCurve)::DownCast(C3Dnew));
   if(!Curve.IsNull()) {
-    GeomLib_CheckBSplineCurve cbsc(Curve, 1.e-7, 0.1);
+    GeomLib_CheckBSplineCurve cbsc(Curve, TOLCHECK, TOLANGCHECK);
     cbsc.NeedTangentFix(bf, bl);
 
 #ifdef OCCT_DEBUG
@@ -697,7 +700,7 @@ Standard_Boolean  TopOpeBRepTool_CurveTool::MakeCurves
   
   Handle(Geom2d_BSplineCurve) Curve2df (Handle(Geom2d_BSplineCurve)::DownCast(PC1new));
   if(!Curve2df.IsNull()) {
-    GeomLib_Check2dBSplineCurve cbsc2df(Curve2df, 1.e-7, 0.1);
+    GeomLib_Check2dBSplineCurve cbsc2df(Curve2df, TOLCHECK, TOLANGCHECK);
     cbsc2df.NeedTangentFix(bf, bl);
 #ifdef OCCT_DEBUG
     if (TopOpeBRepTool_GettraceCHKBSPL()) {
@@ -712,7 +715,7 @@ Standard_Boolean  TopOpeBRepTool_CurveTool::MakeCurves
   
   Handle(Geom2d_BSplineCurve) Curve2ds (Handle(Geom2d_BSplineCurve)::DownCast(PC2new));
   if(!Curve2ds.IsNull()) {
-    GeomLib_Check2dBSplineCurve cbsc2ds(Curve2ds, 1.e-7, 0.1);
+    GeomLib_Check2dBSplineCurve cbsc2ds(Curve2ds, TOLCHECK, TOLANGCHECK);
     cbsc2ds.NeedTangentFix(bf, bl);
 #ifdef OCCT_DEBUG
     if (TopOpeBRepTool_GettraceCHKBSPL()) {
index 7cf6870..9c85984 100644 (file)
@@ -6,7 +6,6 @@ puts ""
 # Wrong pcurve of the section curve
 ###########################################################
 
-set ExpectedTol 9.8986150909815383e-05
 set NbCurv_OK 1
 
 restore [locate_data_file bug24585_b1.brep] b1
@@ -23,9 +22,9 @@ if {${NbCurv} != ${NbCurv_OK}} {
   puts "Error: ${NbCurv_OK} curve(s) expected, but ${NbCurv} found."
 }
 
-set tol_abs 0.0
-set tol_rel 0.01
-checkreal "Tolerance Reached" ${Toler} ${ExpectedTol} ${tol_abs} ${tol_rel}
+if { ${Toler} > 5.e-5} {
+   puts "Error: bad tolerance of result"
+}
 
 bounds c2d1_1 U1 U2
 2dcvalue c2d1_1 U1 U_begin V_begin
diff --git a/tests/bugs/modalg_6/bug27079_3 b/tests/bugs/modalg_6/bug27079_3
new file mode 100644 (file)
index 0000000..db7200a
--- /dev/null
@@ -0,0 +1,25 @@
+puts "============"
+puts "OCC27079"
+puts "============"
+puts ""
+##################################################################
+# Bad approximation of intersection curves with variable curvature
+##################################################################
+
+restore [locate_data_file bug27079_s1.draw] s1
+restore [locate_data_file bug27079_s2.draw] s2
+trim ts1 s1 -5 5 0 20
+mkface f1 ts1
+mkface f2 s2
+
+smallview
+donly f1 f2
+fit
+
+bop f1 f2
+bopsection result
+
+checkprops result -l 13.7747
+checknbshapes result -vertex 4 -edge 3
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_6/bug27079_4 b/tests/bugs/modalg_6/bug27079_4
new file mode 100644 (file)
index 0000000..9e3783a
--- /dev/null
@@ -0,0 +1,26 @@
+puts "============"
+puts "OCC27079"
+puts "============"
+puts ""
+##################################################################
+# Bad approximation of intersection curves with variable curvature
+##################################################################
+
+restore [locate_data_file bug27079_s3.draw] s3
+restore [locate_data_file bug27079_s4.draw] s4
+trim  ts3 s3 pi-pi/30 pi -5 -2
+mkface f1 ts3
+mkface f2 s4
+
+smallview
+donly f1 f2
+fit
+
+bop f1 f2
+bopsection result
+
+checksection result
+checkprops result -l 8.5688
+checknbshapes result -vertex 2 -edge 2
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
index 311bafb..5d6cb90 100644 (file)
@@ -8,9 +8,6 @@ puts ""
 
 pload ALL
 
-set MaxTol1 0.00042926432143107718
-set MaxTol2 0.00042926432143107718
-
 set GoodNbCurv 4
 
 restore [locate_data_file OCC13116_sh1.brep] b1
@@ -23,8 +20,9 @@ set log1 [bopcurves b1_3 b2_1 -2d]
 
 regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log1} full Toler NbCurv
 
-# Before fixing: Tolerance Reached=27.904993728420369
-checkreal ToleranceReached ${Toler} ${MaxTol1} 0.0 0.01
+if { ${Toler} > 0.0005} {
+   puts "Error: bad tolerance of result"
+}
 
 smallview
 don b1_3 b2_1 c_*
@@ -52,8 +50,9 @@ set log2 [bopcurves b1_3 b2_1 -2d]
 
 regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log2} full Toler NbCurv
 
-# Before fixing: Tolerance Reached=40.000000093341022
-checkreal ToleranceReached ${Toler} ${MaxTol2} 0.0 0.01
+if { ${Toler} > 0.0005} {
+   puts "Error: bad tolerance of result"
+}
 
 smallview
 don b1_3 b2_1 c_*
diff --git a/tests/bugs/modalg_7/bug27648 b/tests/bugs/modalg_7/bug27648
new file mode 100644 (file)
index 0000000..b2c892b
--- /dev/null
@@ -0,0 +1,32 @@
+puts "========"
+puts "OCC27648"
+puts "========"
+puts ""
+#################################################
+# Regression vs 6.7.1: General Fuse operation fails to fuse the solids
+#################################################
+
+restore [locate_data_file bug27648_simple.brep] s
+explode s
+bsection r s_1 s_2
+explode s_2 f
+
+# find section edge belonging to the face s_2_3
+foreach e [explode r e] {
+  if {[catch {mk2dcurve c2d $e s_2_3}] == 0} {
+    break
+  }
+}
+
+mkcurve c $e
+
+# in a loop, check that curve has increased Z value along its length
+set delta 0.001
+cvalue c 0 xp yp zp
+for {set p 0} {$p <= 1} {set p [expr $p + $delta]} {
+  cvalue c $p x y z
+  if {[dval z] < [dval zp]} {
+    puts "Error on parameter $p"
+  }
+  copy z zp
+}
\ No newline at end of file
index 07466e1..de3ab70 100755 (executable)
@@ -1,5 +1,3 @@
-puts "TODO OCC28216 ALL: Error : bopcommon is WRONG"
-
 puts "============"
 puts "OCC28216"
 puts "============"
@@ -14,11 +12,11 @@ restore [locate_data_file bug28216_solid.brep] o
 bop s o
 
 bopsection r_section
-checknbshapes r_section -vertex 4 -edge 3 -m "bopsection"
+checknbshapes r_section -vertex 4 -edge 4 -m "bopsection"
 bopcheck r_section
 
 bopcommon r_common
-checknbshapes r_common -vertex 4 -edge 3 -m "bopcommon"
+checknbshapes r_common -vertex 4 -edge 4 -face 1 -m "bopcommon"
 bopcheck r_common
 
 checkview -display r_section -2d -path ${imagedir}/${test_image}-section.png
diff --git a/tests/bugs/modalg_7/bug29511 b/tests/bugs/modalg_7/bug29511
new file mode 100644 (file)
index 0000000..83b1ee6
--- /dev/null
@@ -0,0 +1,20 @@
+puts "============"
+puts "OCC29511"
+puts "============"
+puts ""
+##################################################################
+# Section fails for these two faces
+##################################################################
+
+restore [locate_data_file bug29511_face.brep] face
+restore [locate_data_file bug29511_prism.brep] prism
+
+bsection result face prism -n2d
+
+smallview
+donly result
+fit
+
+checkprops result -l 764.018
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png