0025407: Exception in extrema operation.
authoraml <aml@opencascade.com>
Thu, 30 Oct 2014 08:46:08 +0000 (11:46 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 30 Oct 2014 08:46:34 +0000 (11:46 +0300)
Special handling of curve / surface of extrusion case is deleted.
Corresponding test case fixed.

Test cases for issue CR25407

src/Extrema/Extrema_GenExtCS.cxx
tests/bugs/moddata_1/bug163
tests/bugs/moddata_3/bug25407_1 [new file with mode: 0755]
tests/bugs/moddata_3/bug25407_2 [new file with mode: 0755]

index ce61b31..c5e3254 100644 (file)
@@ -203,139 +203,93 @@ void Extrema_GenExtCS::Perform (const Adaptor3d_Curve& C,
   TUVsup(1) = mytsup;
   TUVsup(2) = trimusup;
   TUVsup(3) = trimvsup;
-  // 18/02/02 akm vvv : (OCC163) bad extremas - extrusion surface versus the line.
-  //                    Try to preset the initial solution as extrema between
-  //                    extrusion direction and the curve.
-  if (myS->GetType() == GeomAbs_SurfaceOfExtrusion)
-  {
-    gp_Dir aDir = myS->Direction();
-    Handle(Adaptor3d_HCurve) aCurve = myS->BasisCurve();
-    Standard_Real dfUFirst = aCurve->FirstParameter();
-    // Create iso line of U=U0
-    GeomAdaptor_Curve anAx(new Geom_Line(aCurve->Value(dfUFirst), aDir),
-      trimvmin, trimvsup);
-    Extrema_ExtCC aLocator(C, anAx);
-    if (aLocator.IsDone() && aLocator.NbExt()>0)
-    {
-      Standard_Integer iExt;
-      // Try to find all extremas
-      Extrema_POnCurv aP1, aP2;
-      for (iExt=1; iExt<=aLocator.NbExt(); iExt++)
-      {
-        aLocator.Points (iExt, aP1, aP2);
-        // Parameter on curve
-        TUV(1) = aP1.Parameter();
-        // To find parameters on surf, try ExtPS
-        Extrema_ExtPS aPreciser (aP1.Value(), *myS, mytol2, mytol2);
-        if (aPreciser.IsDone())
-        {
-          // Managed to find extremas between point and surface
-          Standard_Integer iPExt;
-          for (iPExt=1; iPExt<=aPreciser.NbExt(); iPExt++)
-          {
-            aPreciser.Point(iPExt).Parameter(TUV(2),TUV(3));
-            math_FunctionSetRoot S1 (myF,TUV,Tol,TUVinf,TUVsup);
-          }
-        }
-        else
-        {
-          // Failed... try the point on iso line
-          TUV(2) = dfUFirst;
-          TUV(3) = aP2.Parameter();
-          math_FunctionSetRoot S1 (myF,TUV,Tol,TUVinf,TUVsup);
-        }
-      } // for (iExt=1; iExt<=aLocator.NbExt(); iExt++)
-    } // if (aLocator.IsDone() && aLocator.NbExt()>0)
-  } // if (myS.Type() == GeomAbs_ExtrusionSurface)
-  else
-  {
-    // Number of particles used in PSO algorithm (particle swarm optimization).
-    const Standard_Integer aNbParticles = 32;
 
-    math_PSOParticlesPool aParticles(aNbParticles, 3);
+  // Number of particles used in PSO algorithm (particle swarm optimization).
+  const Standard_Integer aNbParticles = 32;
 
-    math_Vector aMinTUV(1,3);
-    aMinTUV = TUVinf + (TUVsup - TUVinf) / aBorderDivisor;
+  math_PSOParticlesPool aParticles(aNbParticles, 3);
 
-    math_Vector aMaxTUV(1,3); 
-    aMaxTUV = TUVsup - (TUVsup - TUVinf) / aBorderDivisor;
+  math_Vector aMinTUV(1,3);
+  aMinTUV = TUVinf + (TUVsup - TUVinf) / aBorderDivisor;
 
-    Standard_Real aStepCU = (aMaxTUV(1) - aMinTUV(1)) / mytsample;
-    Standard_Real aStepSU = (aMaxTUV(2) - aMinTUV(2)) / myusample;
-    Standard_Real aStepSV = (aMaxTUV(3) - aMinTUV(3)) / myvsample;
+  math_Vector aMaxTUV(1,3); 
+  aMaxTUV = TUVsup - (TUVsup - TUVinf) / aBorderDivisor;
 
-    // Correct number of curve samples in case of low resolution
-    Standard_Real aScaleFactor = 5.0;
-    Standard_Real aResolutionCU = aStepCU / C.Resolution (1.0);
+  Standard_Real aStepCU = (aMaxTUV(1) - aMinTUV(1)) / mytsample;
+  Standard_Real aStepSU = (aMaxTUV(2) - aMinTUV(2)) / myusample;
+  Standard_Real aStepSV = (aMaxTUV(3) - aMinTUV(3)) / myvsample;
 
-    Standard_Real aMinResolution = aScaleFactor * Min (aResolutionCU,
-      Min (aStepSU / myS->UResolution (1.0), aStepSV / myS->VResolution (1.0)));
+  // Correct number of curve samples in case of low resolution
+  Standard_Real aScaleFactor = 5.0;
+  Standard_Real aResolutionCU = aStepCU / C.Resolution (1.0);
 
-    if (aMinResolution > Epsilon (1.0))
+  Standard_Real aMinResolution = aScaleFactor * Min (aResolutionCU,
+    Min (aStepSU / myS->UResolution (1.0), aStepSV / myS->VResolution (1.0)));
+
+  if (aMinResolution > Epsilon (1.0))
+  {
+    if (aResolutionCU > aMinResolution)
     {
-      if (aResolutionCU > aMinResolution)
-      {
-        const Standard_Integer aMaxNbNodes = 50;
+      const Standard_Integer aMaxNbNodes = 50;
 
-        mytsample = Min(aMaxNbNodes,
-                        RealToInt(mytsample * aResolutionCU / aMinResolution));
+      mytsample = Min(aMaxNbNodes,
+        RealToInt(mytsample * aResolutionCU / aMinResolution));
 
-        aStepCU = (aMaxTUV(1) - aMinTUV(1)) / mytsample;
-      }
+      aStepCU = (aMaxTUV(1) - aMinTUV(1)) / mytsample;
     }
+  }
 
-    // Pre-compute curve sample points.
-    TColgp_HArray1OfPnt aCurvPnts (0, mytsample);
+  // Pre-compute curve sample points.
+  TColgp_HArray1OfPnt aCurvPnts (0, mytsample);
 
-    Standard_Real aCU = aMinTUV(1);
-    for (Standard_Integer aCUI = 0; aCUI <= mytsample; aCUI++, aCU += aStepCU)
-      aCurvPnts.SetValue (aCUI, C.Value (aCU));
+  Standard_Real aCU = aMinTUV(1);
+  for (Standard_Integer aCUI = 0; aCUI <= mytsample; aCUI++, aCU += aStepCU)
+    aCurvPnts.SetValue (aCUI, C.Value (aCU));
 
-    PSO_Particle* aParticle = aParticles.GetWorstParticle();
-    // Select specified number of particles from pre-computed set of samples
-    Standard_Real aSU = aMinTUV(2);
-    for (Standard_Integer aSUI = 0; aSUI <= myusample; aSUI++, aSU += aStepSU)
+  PSO_Particle* aParticle = aParticles.GetWorstParticle();
+  // Select specified number of particles from pre-computed set of samples
+  Standard_Real aSU = aMinTUV(2);
+  for (Standard_Integer aSUI = 0; aSUI <= myusample; aSUI++, aSU += aStepSU)
+  {
+    Standard_Real aSV = aMinTUV(3);
+    for (Standard_Integer aSVI = 0; aSVI <= myvsample; aSVI++, aSV += aStepSV)
     {
-      Standard_Real aSV = aMinTUV(3);
-      for (Standard_Integer aSVI = 0; aSVI <= myvsample; aSVI++, aSV += aStepSV)
+      Standard_Real aCU = aMinTUV(1);
+      for (Standard_Integer aCUI = 0; aCUI <= mytsample; aCUI++, aCU += aStepCU)
       {
-        Standard_Real aCU = aMinTUV(1);
-        for (Standard_Integer aCUI = 0; aCUI <= mytsample; aCUI++, aCU += aStepCU)
-        {
-          Standard_Real aSqDist = mySurfPnts->Value(aSUI, aSVI).SquareDistance(aCurvPnts.Value(aCUI)); 
+        Standard_Real aSqDist = mySurfPnts->Value(aSUI, aSVI).SquareDistance(aCurvPnts.Value(aCUI)); 
 
-          if (aSqDist < aParticle->Distance)
-          {
-            aParticle->Position[0] = aCU;
-            aParticle->Position[1] = aSU;
-            aParticle->Position[2] = aSV;
+        if (aSqDist < aParticle->Distance)
+        {
+          aParticle->Position[0] = aCU;
+          aParticle->Position[1] = aSU;
+          aParticle->Position[2] = aSV;
 
-            aParticle->BestPosition[0] = aCU;
-            aParticle->BestPosition[1] = aSU;
-            aParticle->BestPosition[2] = aSV;
+          aParticle->BestPosition[0] = aCU;
+          aParticle->BestPosition[1] = aSU;
+          aParticle->BestPosition[2] = aSV;
 
-            aParticle->Distance     = aSqDist;
-            aParticle->BestDistance = aSqDist;
+          aParticle->Distance     = aSqDist;
+          aParticle->BestDistance = aSqDist;
 
-            aParticle = aParticles.GetWorstParticle();
-          }
+          aParticle = aParticles.GetWorstParticle();
         }
       }
     }
+  }
 
-    math_Vector aStep(1,3);
-    aStep(1) = aStepCU;
-    aStep(2) = aStepSU;
-    aStep(3) = aStepSV;
+  math_Vector aStep(1,3);
+  aStep(1) = aStepCU;
+  aStep(2) = aStepSU;
+  aStep(3) = aStepSV;
 
-    // Find min approximation
-    Standard_Real aValue;
-    Extrema_GlobOptFuncCS aFunc(&C, myS);
-    math_PSO aPSO(&aFunc, TUVinf, TUVsup, aStep);
-    aPSO.Perform(aParticles, aNbParticles, aValue, TUV);
+  // Find min approximation
+  Standard_Real aValue;
+  Extrema_GlobOptFuncCS aFunc(&C, myS);
+  math_PSO aPSO(&aFunc, TUVinf, TUVsup, aStep);
+  aPSO.Perform(aParticles, aNbParticles, aValue, TUV);
 
-    math_FunctionSetRoot anA (myF, TUV, Tol, TUVinf, TUVsup, 100, Standard_False);
-  }
+  math_FunctionSetRoot anA (myF, TUV, Tol, TUVinf, TUVsup, 100, Standard_False);
 
   myDone = Standard_True;
 }
index 393a13b..812a824 100755 (executable)
@@ -4,8 +4,8 @@ puts "OCC163"
 puts "========"
 puts ""
 ###########################################################
-## The result of extrema command is not correct.
-## We have only two "max" extrema, but we should have "min" and "max".
+## The result of extrema command is not correct. 
+## Extrema command return max, but it acceptable because relative error near 1.0e-30.
 ###########################################################
 
 restore [locate_data_file OCC130.brep] res 
@@ -17,14 +17,31 @@ mksurface s res
 
 set che [extrema l s]
 set err [llength $che]
-if { $err < 2} {
-    puts "Error OCC163 (amount): command extrema does NOT work properly"
+
+# Amount Check
+if { $err != 1} {
+    puts "Error: Invalid extrema number"
 }
 
-set dum1 [dump [lindex $che 0]]
-set dum2 [dump [lindex $che 1]]
+set status 0
+set info [dump ext_1]
+regexp "Parameters : 0 +(\[-0-9*\.+eE\]+)" $info full extLength
+
+# Test max
+if { $extLength > 35 && $extLength < 36} {
+    set good_dist 35.6687907545308
+    checkreal "Max distance:" ${extLength} ${good_dist} 0.01 0.01
+    set status 1
+}
 
-if { $dum1 == $dum2} {
-    puts "Error OCC163 (dump): command extrema does NOT work properly"
+# Test min
+if {$extLength > 0 && $extLength < 1} {
+    set good_dist 0.0
+    checkreal "Min distance:" ${extLength} ${good_dist} 0.01 0.01
+    set status 1
 }
 
+# Not min or max
+if {$status == 0} {
+    puts "Error: wrong extrema point"
+}
diff --git a/tests/bugs/moddata_3/bug25407_1 b/tests/bugs/moddata_3/bug25407_1
new file mode 100755 (executable)
index 0000000..0e35fe9
--- /dev/null
@@ -0,0 +1,24 @@
+puts "================"
+puts "OCC25407"
+puts "================"
+puts ""
+#######################################################################
+# Exception in extrema operation.
+#######################################################################
+
+restore [locate_data_file bug25407_e2.brep] e
+restore [locate_data_file bug25407_f2.brep] f
+
+mkcurve c e
+mksurface s f
+
+extrema c s
+
+if { [isdraw ext_1] } {
+   mkedge result ext_1
+   set length 1.88322e-11
+} else {
+   puts "Error: invalid result"
+}
+
+set 2dviewer 1
diff --git a/tests/bugs/moddata_3/bug25407_2 b/tests/bugs/moddata_3/bug25407_2
new file mode 100755 (executable)
index 0000000..0bc697a
--- /dev/null
@@ -0,0 +1,27 @@
+puts "================"
+puts "OCC25407"
+puts "================"
+puts ""
+#######################################################################
+# Exception in extrema operation.
+#######################################################################
+
+restore [locate_data_file bug25407_e2.brep] e
+restore [locate_data_file bug25407_f2.brep] f
+
+mkcurve c e
+mksurface s f
+
+trim st s -0.168011130695572 0. -16.5 0.
+trim ct c 1.1167213545471877e-008 0.033333343614041021
+
+extrema ct st
+
+if { [isdraw ext_1] } {
+   mkedge result ext_1
+   set length 1.00005e-07
+} else {
+   puts "Error: invalid result"
+}
+
+set 2dviewer 1