]> OCCT Git - occt-copy.git/commitdiff
0027135: Incorrect result of the normal projection algorithm
authoraml <aml@opencascade.com>
Thu, 11 Feb 2016 11:42:04 +0000 (14:42 +0300)
committeraml <aml@opencascade.com>
Fri, 12 Feb 2016 06:43:00 +0000 (09:43 +0300)
New check for possible local traps was added to build correct projection cache.
test case added.

src/ProjLib/ProjLib_CompProjectedCurve.cdl
src/ProjLib/ProjLib_CompProjectedCurve.cxx
tests/bugs/moddata_3/bug27135 [new file with mode: 0644]

index f6e77cf33d19819d515e4e1b91ef5cfc5df7005c..d06da45be9572f3b731730677786c35ba3115265 100644 (file)
@@ -192,6 +192,9 @@ is
     raises
        OutOfRange from Standard 
     is private;
+    
+    UpdateTripleByTrapCriteria(me;  thePoint : out Pnt from gp)
+    is private;
  
     MaxDistance(me;  Index:  Integer)   
         ---Purpose:  returns  the  maximum  distance  between   
index 6b2535eaed7ad3cc8ba815db6fa14677d9836b4b..2105dd09c2bc8588aa5ff679a2c4abf6ac119e5d 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <ProjLib_CompProjectedCurve.ixx>
-#include <ProjLib_HCompProjectedCurve.hxx>
-#include <gp_XY.hxx>
-#include <gp_Mat2d.hxx>
-#include <Extrema_ExtPS.hxx>
-#include <Precision.hxx>
+
+#include <Adaptor2d_HCurve2d.hxx>
+#include <Adaptor3d_HCurve.hxx>
+#include <Adaptor3d_HSurface.hxx>
 #include <Extrema_ExtCS.hxx>
-#include <TColgp_HSequenceOfPnt.hxx>
+#include <Extrema_ExtPS.hxx>
 #include <Extrema_GenLocateExtPS.hxx>
-#include <Extrema_POnSurf.hxx>
 #include <Extrema_POnCurv.hxx>
-#include <ProjLib_PrjResolve.hxx>
+#include <Extrema_POnSurf.hxx>
 #include <GeomAbs_CurveType.hxx>
 #include <GeomLib.hxx>
+#include <gp_Mat2d.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Vec2d.hxx>
+#include <gp_XY.hxx>
+#include <Precision.hxx>
+#include <ProjLib_CompProjectedCurve.hxx>
+#include <ProjLib_HCompProjectedCurve.hxx>
+#include <ProjLib_PrjResolve.hxx>
+#include <Standard_DomainError.hxx>
+#include <Standard_NoSuchObject.hxx>
+#include <Standard_NotImplemented.hxx>
+#include <Standard_OutOfRange.hxx>
+#include <TColgp_HSequenceOfPnt.hxx>
+#include <ProjLib_HSequenceOfHSequenceOfPnt.hxx>
+#include <TColStd_HArray1OfReal.hxx>
+#include <TColStd_HArray1OfBoolean.hxx>
 
 #define FuncTol 1.e-10
 
@@ -614,8 +627,8 @@ void ProjLib_CompProjectedCurve::Init()
   //Basic loop  
   while(t <= LastU) 
   {
-    //Search for the begining a new continuous part
-    //To avoid infinite computation in some difficult cases
+    // Search for the beginning of a new continuous part
+    // to avoid infinite computation in some difficult cases.
     new_part = Standard_False;
     if(t > FirstU && Abs(t-prevDeb) <= Precision::PConfusion()) SameDeb=Standard_True;
     while(t <= LastU && !new_part && !FromLastU && !SameDeb)
@@ -627,7 +640,7 @@ void ProjLib_CompProjectedCurve::Init()
       gp_Pnt CPoint;
       Standard_Real ParT,ParU,ParV; 
 
-      // Search an initpoint in the list of Extrema Curve-Surface
+      // Search an initial point in the list of Extrema Curve-Surface
       if(Nend != 0 && !CExt.IsParallel()) 
       {
         for (i=1;i<=Nend;i++)
@@ -725,9 +738,9 @@ void ProjLib_CompProjectedCurve::Init()
         {
           //Search for exact boundary point
           Tol = Min(myTolU, myTolV);
-          gp_Vec2d D;
-          d1(Triple.X(), Triple.Y(), Triple.Z(), D, myCurve, mySurface);
-          Tol /= Max(Abs(D.X()), Abs(D.Y()));
+          gp_Vec2d aD;
+          d1(Triple.X(), Triple.Y(), Triple.Z(), aD, myCurve, mySurface);
+          Tol /= Max(Abs(aD.X()), Abs(aD.Y()));
 
           if(!ExactBound(Triple, t - Step, Tol, 
             myTolU, myTolV, myCurve, mySurface)) 
@@ -851,27 +864,13 @@ void ProjLib_CompProjectedCurve::Init()
         prevStep = Step;
         Triple = gp_Pnt(t, aPrjPS.Solution().X(), aPrjPS.Solution().Y());
 
-        if (mySurface->GetType() == GeomAbs_SurfaceOfRevolution &&
-           (Abs (Triple.Z() - mySurface->FirstVParameter()) < Precision::Confusion() ||
-            Abs (Triple.Z() - mySurface->LastVParameter() ) < Precision::Confusion() ))
-        {
-          // Go out from possible attraktor.
-
-          Standard_Real U,V;
-          InitialPoint(myCurve->Value(t), t, myCurve, mySurface, myTolU, myTolV, U, V);
-          if (Abs (Abs(U - Triple.Y()) - mySurface->UPeriod()) < Precision::Confusion())
-          {
-            // Handle period jump.
-            U = Triple.Y();
-          }
-          Triple.SetY(U);
-          Triple.SetZ(V);
-        }
+        // Check local traps.
+        UpdateTripleByTrapCriteria(Triple);
 
         if((Triple.X() - mySequence->Value(myNbCurves)->Value(mySequence->Value(myNbCurves)->Length()).X()) > 1.e-10)
           mySequence->Value(myNbCurves)->Append(Triple);
-        if (t == LastU) {t = LastU + 1; break;}//return;
 
+        if (t == LastU) {t = LastU + 1; break;}//return;
         //Computation of WalkStep
         d2CurvOnSurf(Triple.X(), Triple.Y(), Triple.Z(), D1, D2, myCurve, mySurface);
         MagnD1 = D1.Magnitude();
@@ -889,7 +888,7 @@ void ProjLib_CompProjectedCurve::Init()
       }
     }
   }
-  // Sequence postproceeding
+  // Sequence post-proceeding.
   Standard_Integer j;
 
   // 1. Removing poor parts
@@ -921,11 +920,11 @@ void ProjLib_CompProjectedCurve::Init()
   for(i = 1; i <= myNbCurves; i++)
     for(j = 1; j <= mySequence->Value(i)->Length(); j++) 
     {
-      gp_Pnt POnC, POnS, Triple;
+      gp_Pnt POnC, POnS, aTriple;
       Standard_Real Distance;
-      Triple = mySequence->Value(i)->Value(j);
-      myCurve->D0(Triple.X(), POnC);
-      mySurface->D0(Triple.Y(), Triple.Z(), POnS);
+      aTriple = mySequence->Value(i)->Value(j);
+      myCurve->D0(aTriple.X(), POnC);
+      mySurface->D0(aTriple.Y(), aTriple.Z(), POnS);
       Distance = POnC.Distance(POnS);
       if (myMaxDistance->Value(i) < Distance)
         myMaxDistance->ChangeValue(i) = Distance;
@@ -1235,12 +1234,12 @@ void ProjLib_CompProjectedCurve::D0(const Standard_Real U,gp_Pnt2d& P) const
     Extrema_ExtPS aExtPS(thePoint, mySurface->Surface(), myTolU, myTolV);
     if (aExtPS.IsDone() && aExtPS.NbExt()) 
     {
-      Standard_Integer i, Nend, imin = 1;
+      Standard_Integer k, Nend, imin = 1;
       // Search for the nearest solution which is also a normal projection
       Nend = aExtPS.NbExt();
-      for(i = 2; i <= Nend; i++)
-        if (aExtPS.SquareDistance(i) < aExtPS.SquareDistance(imin))
-          imin = i;
+      for(k = 2; k <= Nend; k++)
+        if (aExtPS.SquareDistance(k) < aExtPS.SquareDistance(imin))
+          imin = k;
       const Extrema_POnSurf& POnS = aExtPS.Point(imin);
       Standard_Real ParU,ParV;
       POnS.Parameter(ParU, ParV);
@@ -1612,3 +1611,51 @@ GeomAbs_CurveType ProjLib_CompProjectedCurve::GetType() const
 {
   return GeomAbs_OtherCurve;
 }
+
+//=======================================================================
+//function : UpdateTripleByTrapCriteria
+//purpose  :
+//=======================================================================
+void ProjLib_CompProjectedCurve::UpdateTripleByTrapCriteria(gp_Pnt &thePoint) const
+{
+  Standard_Boolean isProblemsPossible = Standard_False;
+  // Check possible traps cases:
+
+  // 25892 bug.
+  if (mySurface->GetType() == GeomAbs_SurfaceOfRevolution &&
+     (Abs (thePoint.Z() - mySurface->FirstVParameter()) < Precision::PConfusion() ||
+      Abs (thePoint.Z() - mySurface->LastVParameter() ) < Precision::PConfusion() ))
+  {
+    isProblemsPossible = Standard_True;
+  }
+
+  // 27135 bug. Trap on degenerated edge.
+  if (mySurface->GetType() == GeomAbs_Sphere &&
+     (Abs (thePoint.Z() - mySurface->FirstVParameter()) < Precision::PConfusion() ||
+      Abs (thePoint.Z() - mySurface->LastVParameter() ) < Precision::PConfusion() ||
+      Abs (thePoint.Y() - mySurface->FirstUParameter()) < Precision::PConfusion() ||
+      Abs (thePoint.Y() - mySurface->LastUParameter() ) < Precision::PConfusion() ))
+  {
+    isProblemsPossible = Standard_True;
+  }
+
+  if (!isProblemsPossible)
+    return;
+
+  Standard_Real U,V;
+  InitialPoint(myCurve->Value(thePoint.X()), thePoint.X(), myCurve, mySurface, myTolU, myTolV, U, V);
+
+  // Restore original position in case of period jump.
+  if (mySurface->IsUPeriodic() &&
+      Abs (Abs(U - thePoint.Y()) - mySurface->UPeriod()) < Precision::PConfusion())
+  {
+    U = thePoint.Y();
+  }
+  if (mySurface->IsVPeriodic() &&
+      Abs (Abs(V - thePoint.Z()) - mySurface->VPeriod()) < Precision::PConfusion())
+  {
+    V = thePoint.Z();
+  }
+  thePoint.SetY(U);
+  thePoint.SetZ(V);
+}
diff --git a/tests/bugs/moddata_3/bug27135 b/tests/bugs/moddata_3/bug27135
new file mode 100644 (file)
index 0000000..0376155
--- /dev/null
@@ -0,0 +1,23 @@
+puts "================"
+puts "0027135"
+puts "================"
+puts ""
+##############################################################
+# Incorrect result of the normal projection algorithm
+# Degenerated edge in result
+##############################################################
+
+restore [locate_data_file bug27135.brep] aShape
+explode aShape
+
+nproject result aShape_1 aShape_2
+
+# Result length check.
+checkprops result -l 5.74501
+
+# Visual check.
+donly result
+smallview
+fit
+display aShape_2
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png