0025592: Bad result of Fillet operation
authorjgv <jgv@opencascade.com>
Thu, 25 Dec 2014 13:47:08 +0000 (16:47 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 25 Dec 2014 13:48:05 +0000 (16:48 +0300)
Comments have been added.

Test case for issue CR25592

src/Blend/Blend_Walking.cdl
src/Blend/Blend_Walking_1.gxx
src/Blend/Blend_Walking_4.gxx
src/ChFi3d/ChFi3d_Builder_2.cxx
src/ChFi3d/ChFi3d_Builder_6.cxx
src/ChFiDS/ChFiDS_ElSpine.cdl
src/ChFiDS/ChFiDS_ElSpine.cxx
tests/bugs/modalg_5/bug25592 [new file with mode: 0755]

index eef32e7..c27137b 100644 (file)
@@ -45,6 +45,7 @@ uses Point            from Blend,
      Transition       from IntSurf,
      Function         from Blend,
      FuncInv          from Blend,
+     HElSpine         from ChFiDS,
      State            from TopAbs
 
 
@@ -66,6 +67,7 @@ is
 
     Perform(me: in out; F       : in out Function from Blend;
                         FInv    : in out FuncInv  from Blend;
+                       HGuide  : HElSpine from ChFiDS;
                         Pdep    : Real from Standard;
                         Pmax    : Real from Standard;
                        MaxStep : Real from Standard;
@@ -164,6 +166,7 @@ is
 
     InternalPerform (me: in out;F       : in out Function from Blend;
                                 FInv    : in out FuncInv  from Blend;
+                               HGuide  : HElSpine from ChFiDS;
                                 Bound   : Real from Standard)
                        
     is static private;
index 1a852dd..e1455a0 100644 (file)
@@ -56,6 +56,7 @@ void Blend_Walking::AddSingularPoint(const Blend_Point& P)
 
 void Blend_Walking::Perform(Blend_Function& Func,
                            Blend_FuncInv& FuncInv,
+                            const Handle(ChFiDS_HElSpine)& HGuide,
                            const Standard_Real Pdep,   
                            const Standard_Real Pmax,
                            const Standard_Real MaxStep,
@@ -154,7 +155,7 @@ void Blend_Walking::Perform(Blend_Function& Func,
     }
   }
 
-  InternalPerform(Func,FuncInv,Pmax);
+  InternalPerform(Func,FuncInv,HGuide,Pmax);
 
   done = Standard_True;
 }
@@ -461,7 +462,8 @@ Standard_Boolean Blend_Walking::Continu(Blend_Function& Func,
   previousP.ParametersOnS1(sol(1),sol(2));
   previousP.ParametersOnS2(sol(3),sol(4));
 
-  InternalPerform(Func,FuncInv,P);
+  Handle(ChFiDS_HElSpine) anHGuide;
+  InternalPerform(Func,FuncInv,anHGuide,P);
   return Standard_True;
 }
 
@@ -502,7 +504,8 @@ Standard_Boolean Blend_Walking::Continu(Blend_Function& Func,
   if(OnS1) clasonS1 = Standard_False;
   else clasonS2 = Standard_False;
 
-  InternalPerform(Func,FuncInv,P);
+  Handle(ChFiDS_HElSpine) anHGuide;
+  InternalPerform(Func,FuncInv,anHGuide,P);
 
   clasonS1 = Standard_True;
   clasonS2 = Standard_True;
@@ -548,7 +551,8 @@ Standard_Boolean Blend_Walking::Complete(Blend_Function& Func,
   previousP.ParametersOnS1(sol(1),sol(2));
   previousP.ParametersOnS2(sol(3),sol(4));
 
-  InternalPerform(Func,FuncInv,Pmin);
+  Handle(ChFiDS_HElSpine) anHGuide;
+  InternalPerform(Func,FuncInv,anHGuide,Pmin);
 
   iscomplete = Standard_True;
   return Standard_True;
index c75cda5..26b4a3b 100644 (file)
@@ -12,6 +12,8 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <gce_MakePln.hxx>
+
 static void evalpinit(math_Vector& parinit,
                      const Blend_Point& previousP,
                      const Standard_Real parprec,
@@ -65,6 +67,7 @@ static void evalpinit(math_Vector& parinit,
 
 void Blend_Walking::InternalPerform(Blend_Function& Func,
                                    Blend_FuncInv& FuncInv,
+                                    const Handle(ChFiDS_HElSpine)& HGuide,
                                    const Standard_Real Bound)
 {
 
@@ -251,12 +254,64 @@ void Blend_Walking::InternalPerform(Blend_Function& Func,
          // avec les surfaces periodiques.
          State = Blend_OnRst12;
          param =  (w1+w2)/2;
+          gp_Pnt Pnt1, Pnt2;
          p2d = TheArcTool::Value(recdomain1->Value(),solrst1(1));
          sol(1) = p2d.X();
          sol(2) = p2d.Y();
+          Pnt1 = TheSurfaceTool::Value(surf1,sol(1),sol(2));
          p2d = TheArcTool::Value(recdomain2->Value(),solrst2(1));
          sol(3) = p2d.X();
          sol(4) = p2d.Y();
+          Pnt2 = TheSurfaceTool::Value(surf2,sol(3),sol(4));
+          if (!HGuide.IsNull())
+          {
+            const Standard_Real TolProd = 1.e-5;
+            Standard_Real SavedParams [2];
+            Standard_Boolean SameDirs [2] = {Standard_False, Standard_False};
+            ChFiDS_ElSpine& theElSpine = HGuide->ChangeCurve();
+            SavedParams[0] = theElSpine.GetSavedFirstParameter();
+            SavedParams[1] = theElSpine.GetSavedLastParameter();
+            for (Standard_Integer ind = 0; ind < 2; ind++)
+            {
+              if (!Precision::IsInfinite(SavedParams[ind]))
+              {
+                //Check the original first and last parameters of guide curve
+                //for equality to found parameter <param>:
+                //check equality of tangent to guide curve and
+                //normal to plane built on 3 points:
+                //point on guide curve and points on restrictions of adjacent
+                //surfaces.
+                gp_Pnt Pnt0;
+                gp_Vec Dir0;
+                HGuide->D1(SavedParams[ind], Pnt0, Dir0);
+                Standard_Real Length = Dir0.Magnitude();
+                if (Length <= gp::Resolution())
+                  continue;
+                Dir0 /= Length;
+                gce_MakePln PlaneBuilder(Pnt0, Pnt1, Pnt2);
+                if (!PlaneBuilder.IsDone())
+                  continue;
+                gp_Pln thePlane = PlaneBuilder.Value();
+                gp_Dir DirPlane = thePlane.Axis().Direction();
+                gp_Vec theProd = Dir0 ^ DirPlane;
+                Standard_Real ProdMod = theProd.Magnitude();
+                if (ProdMod <= TolProd)
+                  SameDirs[ind] = Standard_True;
+              }
+            }
+            Standard_Real theParam = Precision::Infinite();
+            //Choose the closest parameter
+            if (SameDirs[0] && SameDirs[1])
+              theParam = (Abs(param - SavedParams[0]) < Abs(param - SavedParams[1]))?
+                SavedParams[0] : SavedParams[1];
+            else if (SameDirs[0])
+              theParam = SavedParams[0];
+            else if (SameDirs[1])
+              theParam = SavedParams[1];
+            
+            if (!Precision::IsInfinite(theParam))
+              param = theParam;
+          }
        }
        else if (recad1) {
          // sol sur 1
index 24a06db..11da929 100644 (file)
@@ -1862,10 +1862,13 @@ void ChFi3d_Builder::PerformSetOfSurfOnElSpine
   Standard_Real wl = Guide.LastParameter();
   Standard_Real locfleche = (wl - wf) * fleche;
   Standard_Real wfsav = wf, wlsav = wl;
-  //Now the ElSpine is artificially extended to help rsnld.
-  Standard_Real prab = 0.01;
-  Guide.FirstParameter(wf-prab*(wl-wf));
-  Guide.LastParameter (wl+prab*(wl-wf));
+  if (!Guide.IsPeriodic())
+  {
+    //Now the ElSpine is artificially extended to help rsnld.
+    Standard_Real prab = 0.01;
+    Guide.FirstParameter(wf-prab*(wl-wf));
+    Guide.LastParameter (wl+prab*(wl-wf));
+  }
   Handle(ChFiDS_Spine)&  Spine = Stripe->ChangeSpine();
   Standard_Integer ii, nbed = Spine->NbEdges();
   Standard_Real lastedlastp = Spine->LastParameter(nbed);
@@ -1920,7 +1923,9 @@ void ChFi3d_Builder::PerformSetOfSurfOnElSpine
     Last = wf;
     if(Guide.IsPeriodic()) {
       Last = First - Guide.Period();
+      Guide.SaveFirstParameter();
       Guide.FirstParameter(Last);
+      Guide.SaveLastParameter();
       Guide.LastParameter (First * 1.1);//Extension to help rsnld.
     }
   }
index c9d406f..78fc8c0 100644 (file)
@@ -1573,7 +1573,7 @@ Standard_Boolean ChFi3d_Builder::ComputeData
       if (5*TolGuide > MS) TolGuide = MS/5;
       if (5*TolEsp > MS) TolEsp = MS/5;
     }
-    TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
+    TheWalk.Perform(Func,FInv,HGuide,NewFirst,Target,MS,TolGuide,
                    ParSol,TolEsp,Fleche,Appro);
     if (!TheWalk.IsDone()) {
 #ifdef OCCT_DEBUG
@@ -2113,7 +2113,7 @@ Standard_Boolean ChFi3d_Builder::SimulData
       if (5*TolEsp > MS) TolEsp = MS/5;
     }
       
-    TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide,
+    TheWalk.Perform(Func,FInv,HGuide,NewFirst,Target,MS,TolGuide,
                    ParSol,TolEsp,Fleche,Appro);
     
     if (!TheWalk.IsDone()) {
index f85b305..6b5483e 100644 (file)
@@ -50,6 +50,10 @@ is
     LastParameter(me) returns Real from Standard
     is redefined;
     
+    GetSavedFirstParameter(me) returns Real from Standard;
+    
+    GetSavedLastParameter(me)  returns Real from Standard;
+    
     Continuity(me) returns Shape from GeomAbs
     is redefined static;
 
@@ -102,6 +106,10 @@ is
 
     LastParameter(me : in out; P : Real from Standard);
 
+    SaveFirstParameter(me : in out);
+
+    SaveLastParameter(me : in out);
+
     SetOrigin(me : in out; O : Real from Standard);
 
     FirstPointAndTgt(me; P : out Pnt from gp; T : out Vec from gp);
@@ -188,5 +196,7 @@ plast     : Real     from Standard;
 period    : Real     from Standard;
 periodic  : Boolean  from Standard; 
 
+pfirstsav : Real     from Standard;
+plastsav  : Real     from Standard;
 
 end ElSpine;
index aa8a8c1..a7d47fa 100644 (file)
@@ -27,6 +27,8 @@
 
 ChFiDS_ElSpine::ChFiDS_ElSpine():periodic(0)
 {
+  pfirstsav = Precision::Infinite();
+  plastsav  = Precision::Infinite();
 }
 
 
@@ -52,6 +54,26 @@ Standard_Real ChFiDS_ElSpine::LastParameter() const
 }
 
 //=======================================================================
+//function : GetSavedFirstParameter
+//purpose  : 
+//=======================================================================
+
+Standard_Real ChFiDS_ElSpine::GetSavedFirstParameter() const
+{
+  return pfirstsav;
+}
+
+//=======================================================================
+//function : GetSavedLastParameter
+//purpose  : 
+//=======================================================================
+
+Standard_Real ChFiDS_ElSpine::GetSavedLastParameter() const
+{
+  return plastsav;
+}
+
+//=======================================================================
 //function : Continuity
 //purpose  : 
 //=======================================================================
@@ -229,6 +251,26 @@ void ChFiDS_ElSpine::LastParameter(const Standard_Real P)
   plast = P;
 }
 
+//=======================================================================
+//function : SaveFirstParameter
+//purpose  : 
+//=======================================================================
+
+void ChFiDS_ElSpine::SaveFirstParameter()
+{
+  pfirstsav = pfirst;
+}
+
+//=======================================================================
+//function : SaveLastParameter
+//purpose  : 
+//=======================================================================
+
+void ChFiDS_ElSpine::SaveLastParameter()
+{
+  plastsav = plast;
+}
+
 
 //=======================================================================
 //function : SetOrigin
diff --git a/tests/bugs/modalg_5/bug25592 b/tests/bugs/modalg_5/bug25592
new file mode 100755 (executable)
index 0000000..d1916d8
--- /dev/null
@@ -0,0 +1,50 @@
+puts "============"
+puts "OCC25592"
+puts "============"
+puts ""
+######################################################
+# Bad result of Fillet operation
+######################################################
+
+restore [locate_data_file bug25592_tshape.brep] t
+explode t e
+shape c c
+add t_4 c
+add t_6 c
+fillet r t 30 c
+explode r f
+
+set info1 [bopargcheck r_2 #f]
+if { [regexp "to be valid for BOP" ${info1}] == 1 } {
+    puts "1. OK : Good result of Fillet operation\n"
+} else {
+    puts "1. Error : Bad result of Fillet operation\n"
+}
+
+set info2 [bopargcheck r_1 #f]
+if { [regexp "to be valid for BOP" ${info2}] == 1 } {
+    puts "2. OK : Good result of Fillet operation\n"
+} else {
+    puts "2. Error : Bad result of Fillet operation\n"
+}
+
+set info3 [bopargcheck r_6 #f]
+if { [regexp "to be valid for BOP" ${info3}] == 1 } {
+    puts "3. OK : Good result of Fillet operation\n"
+} else {
+    puts "3. Error : Bad result of Fillet operation\n"
+}
+
+set info4 [bopargcheck r_7 #f]
+if { [regexp "to be valid for BOP" ${info4}] == 1 } {
+    puts "4. OK : Good result of Fillet operation\n"
+} else {
+    puts "4. Error : Bad result of Fillet operation\n"
+}
+
+set info5 [bopargcheck r_9 #f]
+if { [regexp "to be valid for BOP" ${info5}] == 1 } {
+    puts "5. OK : Good result of Fillet operation\n"
+} else {
+    puts "5. Error : Bad result of Fillet operation\n"
+}