]> OCCT Git - occt-copy.git/commitdiff
0024694: Wrong processing of two surfaces (implicit and parametric) having tangential... CR24694
authorjgv <jgv@opencascade.com>
Thu, 6 Mar 2014 13:58:44 +0000 (17:58 +0400)
committerjgv <jgv@opencascade.com>
Thu, 6 Mar 2014 13:58:44 +0000 (17:58 +0400)
24 files changed:
src/Contap/Contap_ContourGen_2.gxx
src/Contap/Contap_SurfFunction.cdl
src/Contap/Contap_SurfFunction.lxx
src/IntImp/IntImp_ISurfaceTool.cdl
src/IntImp/IntImp_ZerImpFunc.cdl
src/IntImp/IntImp_ZerImpFunc.gxx
src/IntImp/IntImp_ZerImpFunc.lxx
src/IntPatch/IntPatch_ImpPrmIntersection.cxx
src/IntStart/IntStart_SearchInside.cdl
src/IntStart/IntStart_SearchInside.gxx
src/IntStart/IntStart_SearchInside.lxx
src/IntSurf/IntSurf_PntOn2S.cdl
src/IntSurf/IntSurf_PntOn2S.cxx
src/IntSurf/IntSurf_QuadricTool.cdl
src/IntSurf/IntSurf_QuadricTool.cxx
src/IntSurf/IntSurf_QuadricTool.lxx
src/IntWalk/IntWalk.cdl
src/IntWalk/IntWalk_IWalking.cdl
src/IntWalk/IntWalk_IWalking_1.gxx
src/IntWalk/IntWalk_IWalking_2.gxx
src/IntWalk/IntWalk_IWalking_3.gxx
src/IntWalk/IntWalk_IWalking_4.gxx
src/IntWalk/IntWalk_IWalking_5.gxx
src/IntWalk/IntWalk_IWalking_6.gxx

index 1168dc42f3308281a82a77425aadb32a67c53a78..741633a257bd6ec4c74c89bc499954958ee00411 100644 (file)
@@ -5,8 +5,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
@@ -1338,7 +1338,8 @@ void Contap_ContourGen::Perform
   if (seqpdep.Length() != 0 || seqpins.Length() != 0) {
 
     Contap_TheIWalking iwalk(Preci,Fleche,Pas);
-    iwalk.Perform(seqpdep,seqpins,mySFunc ,Surf);
+    IntSurf_SequenceOfInteriorPoint seqptang; //dummy
+    iwalk.Perform(seqpdep,seqpins,seqptang,mySFunc ,Surf);
     if(!iwalk.IsDone()) {
       return;
     }
index bf8a8e7ec5ef00979d0dd4ed8e2b7adff14fae1a..d771abc5f8ad9a6f66c877414dfb6fa7367b3067 100644 (file)
@@ -5,8 +5,8 @@
 --
 -- This file is part of Open CASCADE Technology software library.
 --
--- This library is free software; you can redistribute it and/or modify it under
--- the terms of the GNU Lesser General Public License version 2.1 as published
+-- This library is free software; you can redistribute it and / or modify it
+-- under the terms of the GNU Lesser General Public version 2.1 as published
 -- by the Free Software Foundation, with special exception defined in the file
 -- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 -- distribution for complete text of the license and disclaimer of any warranty.
@@ -152,6 +152,12 @@ is
        returns Boolean from Standard 
        is static;
     
+    IsTangentSmooth(me : in out)
+
+       returns Boolean from Standard 
+       ---C++: inline
+       is static;
+    
 
     Direction3d(me: in out)
 
@@ -171,6 +177,49 @@ is
        is static;
 
 
+    Projection1(me: in out)
+       returns Real from Standard
+       ---C++: inline
+       is static;
+    
+    Projection2(me: in out)
+       returns Real from Standard
+       ---C++: inline
+       is static;
+    
+    Projection3(me: in out)
+       returns Real from Standard
+       ---C++: inline
+       is static;
+    
+    Projection4(me: in out)
+       returns Real from Standard
+       ---C++: inline
+       is static;
+
+    DerivativesAndNormalOnPSurf(me: in out; D1U :    out Vec from gp;
+                                   D1V :    out Vec from gp;
+                                   Normal : out Dir from gp;
+                                   D2U :    out Vec from gp;
+                                   D2V :    out Vec from gp;
+                                   D2UV :   out Vec from gp)
+       ---C++: inline
+       is static;
+    
+    DerivativesAndNormalOnISurf(me; D1U :    out Vec from gp;
+                                   D1V :    out Vec from gp;
+                                   Normal : out Dir from gp;
+                                   D2U :    out Vec from gp;
+                                   D2V :    out Vec from gp;
+                                   D2UV :   out Vec from gp)
+       ---C++: inline
+       is static;
+    
+    SquareTangentError(me)
+       returns Real from Standard
+       ---C++: inline
+       is static;
+
     FunctionType(me)
     
        returns TFunction from Contap
index 9f2e61a726060cd88efc349e3b23e84a3a5a8b0c..59549b6f680c3a1b34fc3992484fbf231a439d84 100644 (file)
@@ -5,8 +5,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
@@ -100,6 +100,54 @@ inline Standard_Real Contap_SurfFunction::Angle () const
   return myAng;
 }
 
+inline Standard_Boolean Contap_SurfFunction::IsTangentSmooth()
+{
+  return Standard_False;
+}
+
+inline Standard_Real Contap_SurfFunction::Projection1()
+{
+  return 1.;
+}
+
+inline Standard_Real Contap_SurfFunction::Projection2()
+{
+  return 1.;
+}
+
+inline Standard_Real Contap_SurfFunction::Projection3()
+{
+  return 1.;
+}
+
+inline Standard_Real Contap_SurfFunction::Projection4()
+{
+  return 1.;
+}
+
+inline void Contap_SurfFunction::DerivativesAndNormalOnPSurf(gp_Vec&,
+                                                             gp_Vec&,
+                                                             gp_Dir&,
+                                                             gp_Vec&,
+                                                             gp_Vec&,
+                                                             gp_Vec&)
+{
+}
+
+inline void Contap_SurfFunction::DerivativesAndNormalOnISurf(gp_Vec&,
+                                                             gp_Vec&,
+                                                             gp_Dir&,
+                                                             gp_Vec&,
+                                                             gp_Vec&,
+                                                             gp_Vec&) const
+{
+}
+
+inline Standard_Real Contap_SurfFunction::SquareTangentError() const
+{
+  return 0.;
+}
+
 inline Contap_TFunction Contap_SurfFunction::FunctionType () const
 {
   return myType;
index cb704050cdf62c4f1618473c5efb9c734e16b10b..22f57de89829153ac9db5bb75e69266d7fffba9f 100644 (file)
@@ -5,8 +5,8 @@
 --
 -- This file is part of Open CASCADE Technology software library.
 --
--- This library is free software; you can redistribute it and/or modify it under
--- the terms of the GNU Lesser General Public License version 2.1 as published
+-- This library is free software; you can redistribute it and / or modify it
+-- under the terms of the GNU Lesser General Public version 2.1 as published
 -- by the Free Software Foundation, with special exception defined in the file
 -- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 -- distribution for complete text of the license and disclaimer of any warranty.
@@ -21,7 +21,9 @@ deferred generic class ISurfaceTool from IntImp
        --          implicit surface.
 
 
-uses Vec from gp
+uses
+    Vec from gp,
+    Pnt from gp
 
 
 is
@@ -43,11 +45,14 @@ is
 
     ValueAndGradient(myclass; Is: ImplicitSurface; 
                      X, Y, Z: Real from Standard;
-                     Val: out Real from Standard; Grad: out Vec from gp);
+                     Val: out Real from Standard;
+                    Grad: out Vec from gp;
+                    D1U_ISurf, D1V_ISurf: out Vec from gp);
                     
        ---Purpose: Returns the value and the gradient.
 
 
+
     Tolerance(myclass; Is: ImplicitSurface )
     
        ---Purpose: returns the tolerance of the zero of the implicit function
index 5f6d3d093980dead2692b03179553117dee5560a..97978b08c090adb5f9c78b7b2bf57c85d50d6e70 100644 (file)
@@ -5,8 +5,8 @@
 --
 -- This file is part of Open CASCADE Technology software library.
 --
--- This library is free software; you can redistribute it and/or modify it under
--- the terms of the GNU Lesser General Public License version 2.1 as published
+-- This library is free software; you can redistribute it and / or modify it
+-- under the terms of the GNU Lesser General Public version 2.1 as published
 -- by the Free Software Foundation, with special exception defined in the file
 -- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 -- distribution for complete text of the license and disclaimer of any warranty.
@@ -31,6 +31,7 @@ uses Vector  from math,
      Matrix  from math,
      Pnt     from gp,
      Vec     from gp,
+     Dir     from gp,
      Dir2d   from gp
 
 raises UndefinedDerivative from StdFail
@@ -141,6 +142,12 @@ is
 
        is static;
     
+    IsTangentSmooth(me : in out)
+
+       returns Boolean from Standard 
+
+       is static;
+    
 
     Direction3d(me: in out)
 
@@ -161,6 +168,43 @@ is
        raises UndefinedDerivative from StdFail
        is static;
     
+    Projection1(me: in out)
+       returns Real from Standard
+       is static;
+    
+    Projection2(me: in out)
+       returns Real from Standard
+       is static;
+    
+    Projection3(me: in out)
+       returns Real from Standard
+       is static;
+    
+    Projection4(me: in out)
+       returns Real from Standard
+       is static;
+    
+    DerivativesAndNormalOnPSurf(me: in out; D1U :    out Vec from gp;
+                                   D1V :    out Vec from gp;
+                                   Normal : out Dir from gp;
+                                   D2U :    out Vec from gp;
+                                   D2V :    out Vec from gp;
+                                   D2UV :   out Vec from gp)
+       is static;
+    
+    DerivativesAndNormalOnISurf(me; D1U :    out Vec from gp;
+                                   D1V :    out Vec from gp;
+                                   Normal : out Dir from gp;
+                                   D2U :    out Vec from gp;
+                                   D2V :    out Vec from gp;
+                                   D2UV :   out Vec from gp)
+       is static;
+    
+    SquareTangentError(me)
+       returns Real from Standard
+       ---C++: inline
+
+       is static;
 
     PSurface(me)
 
@@ -170,7 +214,6 @@ is
 
        is static;
     
-
     ISurface(me)
 
        returns TheISurface
@@ -195,11 +238,17 @@ fields
   tgdu        : Real    from Standard;
   tgdv        : Real    from Standard;
   gradient    : Vec     from gp;
+  d1u_isurf   : Vec     from gp;
+  d1v_isurf   : Vec     from gp;
   derived     : Boolean from Standard;
   d1u         : Vec     from gp;
   d1v         : Vec     from gp;
   d3d         : Vec     from gp;
   d2d         : Dir2d   from gp;
+  Proj1       : Real    from Standard;
+  Proj2       : Real    from Standard;
+  Proj3       : Real    from Standard;
+  Proj4       : Real    from Standard;
 
 end ZerImpFunc;
 
index d805625a0b68fb86c4cbd957cacb0f9bf1dd9753..e719b429622792015994c8c51f28d6b4cc46ed21 100644 (file)
@@ -3,8 +3,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
@@ -92,7 +92,7 @@ Standard_Boolean IntImp_ZerImpFunc::Values(const math_Vector& X,
   v = X(2);
   ThePSurfaceTool::D1(SURF, u, v, pntsol, d1u, d1v);
   TheISurfaceTool::ValueAndGradient(FUNC, pntsol.X(), pntsol.Y(), pntsol.Z(), 
-                                    valf, gradient);
+                                    valf, gradient, d1u_isurf, d1v_isurf);
   F(1) = valf;
   D(1,1) = d1u.Dot(gradient);
   D(1,2) = d1v.Dot(gradient);
@@ -118,17 +118,233 @@ Standard_Boolean IntImp_ZerImpFunc::IsTangent()
     Standard_Real N2d1v  = d1v.SquareMagnitude();
     tangent =(tgdu * tgdu <= N2grad_EpsAng2 * N2d1v) && 
              (tgdv * tgdv <= N2grad_EpsAng2 * N2d1u);
+
+    if (tangent)
+    {
+#ifdef DRAW
+      Standard_Real SumSquare = tgdu * tgdu + tgdv * tgdv;
+#endif
+      gp_Vec NormSURF = d1u ^ d1v;
+      Proj1 = gradient * d1u;
+      Proj2 = gradient * d1v;
+      Proj3 = NormSURF * d1u_isurf;
+      Proj4 = NormSURF * d1v_isurf;
+#ifdef DRAW
+      cout<<"Tangent !!!"<<endl;
+      cout<<"SumSquare = "<<SumSquare<<endl;
+      cout<<"u = "<<u<<", v = "<<v<<endl;
+      cout<<"pnt = "<<pntsol.X()<<" "<<pntsol.Y()<<" "<<pntsol.Z()<<endl;
+      cout<<"Proj1 = "<<Proj1<<endl;
+      cout<<"Proj2 = "<<Proj2<<endl;
+      cout<<"Proj3 = "<<Proj3<<endl;
+      cout<<"Proj4 = "<<Proj4<<endl<<endl;
+#endif
+    }
+    
+    if(!tangent) {
+      d3d.SetLinearForm(tgdu,d1u,tgdv,d1v);
+      d2d = gp_Dir2d(tgdu, tgdv);
+      if (d3d.Magnitude() <= Tolpetit) {    // jag
+       tangent = Standard_True;
+      }
+      
+      gp_Vec NormSURF = d1u ^ d1v;
+      Proj1 = gradient * d1u;
+      Proj2 = gradient * d1v;
+      Proj3 = NormSURF * d1u_isurf;
+      Proj4 = NormSURF * d1v_isurf;
+#ifdef DRAW
+      cout<<"u = "<<u<<", v = "<<v<<endl;
+      cout<<"pnt = "<<pntsol.X()<<" "<<pntsol.Y()<<" "<<pntsol.Z()<<endl;
+      cout<<"d3d = "<<d3d.X()<<" "<<d3d.Y()<<" "<<d3d.Z()<<endl;
+      cout<<"Proj1 = "<<Proj1<<endl;
+      cout<<"Proj2 = "<<Proj2<<endl;
+      cout<<"Proj3 = "<<Proj3<<endl;
+      cout<<"Proj4 = "<<Proj4<<endl<<endl;
+#endif
+    }
+  }
+  return tangent;
+}
+
+Standard_Boolean IntImp_ZerImpFunc::IsTangentSmooth()
+{
+  const Standard_Real TolCrossProd = 1.e-15;
+  
+  if (!computed) {
+    computed = Standard_True;
+    if(!derived) {
+      ThePSurfaceTool::D1(SURF, u, v, pntsol, d1u, d1v);
+      derived = Standard_True;
+    }
+
+    tgdu =  gradient.Dot(d1v);
+    tgdv = -gradient.Dot(d1u);
+    Standard_Real N2grad = gradient.SquareMagnitude();
+    Standard_Real N2grad_EpsAng2 = N2grad * EpsAng2;
+    Standard_Real N2d1u  = d1u.SquareMagnitude();
+    Standard_Real N2d1v  = d1v.SquareMagnitude();
+    tangent =(tgdu * tgdu <= N2grad_EpsAng2 * N2d1v) && 
+             (tgdv * tgdv <= N2grad_EpsAng2 * N2d1u);
+    
+    gp_Vec NormPSurf = d1u ^ d1v;
+    gp_Vec NormISurf = d1u_isurf ^ d1v_isurf;
+    NormPSurf.Normalize();
+    NormISurf.Normalize();
+#ifdef DRAW
+    Standard_Real theAngle = NormPSurf.Angle(NormISurf);
+#endif
+    gp_Vec CrossProd = NormPSurf ^ NormISurf;
+    Standard_Real CrossProdSqMagn = CrossProd.SquareMagnitude();
+    
+#ifdef DRAW
+    cout<<"Angle = "<<theAngle<<endl;
+    cout<<"CrossProdSqMagn = "<<CrossProdSqMagn<<endl;
+#endif
+
+    tangent = (CrossProdSqMagn <= TolCrossProd);
+    
+    if (tangent)
+    {
+#ifdef DRAW
+      Standard_Real SumSquare = tgdu * tgdu + tgdv * tgdv;
+#endif
+      gp_Vec NormSURF = d1u ^ d1v;
+      Proj1 = gradient * d1u;
+      Proj2 = gradient * d1v;
+      Proj3 = NormSURF * d1u_isurf;
+      Proj4 = NormSURF * d1v_isurf;
+#ifdef DRAW
+      cout<<"Tangent !!!"<<endl;
+      cout<<"SumSquare = "<<SumSquare<<endl;
+      cout<<"u = "<<u<<", v = "<<v<<endl;
+      cout<<"pnt = "<<pntsol.X()<<" "<<pntsol.Y()<<" "<<pntsol.Z()<<endl;
+      cout<<"Proj1 = "<<Proj1<<endl;
+      cout<<"Proj2 = "<<Proj2<<endl;
+      cout<<"Proj3 = "<<Proj3<<endl;
+      cout<<"Proj4 = "<<Proj4<<endl<<endl;
+#endif
+    }
+    
     if(!tangent) {
       d3d.SetLinearForm(tgdu,d1u,tgdv,d1v);
       d2d = gp_Dir2d(tgdu, tgdv);
       if (d3d.Magnitude() <= Tolpetit) {    // jag
        tangent = Standard_True;
       }
-    }    
+      gp_Vec NormSURF = d1u ^ d1v;
+      Proj1 = gradient * d1u;
+      Proj2 = gradient * d1v;
+      Proj3 = NormSURF * d1u_isurf;
+      Proj4 = NormSURF * d1v_isurf;
+#ifdef DRAW
+      cout<<"u = "<<u<<", v = "<<v<<endl;
+      cout<<"pnt = "<<pntsol.X()<<" "<<pntsol.Y()<<" "<<pntsol.Z()<<endl;
+      cout<<"d3d = "<<d3d.X()<<" "<<d3d.Y()<<" "<<d3d.Z()<<endl;
+      cout<<"Proj1 = "<<Proj1<<endl;
+      cout<<"Proj2 = "<<Proj2<<endl;
+      cout<<"Proj3 = "<<Proj3<<endl;
+      cout<<"Proj4 = "<<Proj4<<endl<<endl;
+#endif
+    }
   }
   return tangent;
 }
 
+Standard_Real IntImp_ZerImpFunc::Projection1()
+{
+  if (!derived)
+  {
+    ThePSurfaceTool::D1(SURF, u, v, pntsol, d1u, d1v);
+    derived = Standard_True;
+  }
+  if (!computed)
+  {
+    gp_Vec NormSURF = d1u ^ d1v;
+    Proj1 = gradient * d1u;
+    Proj2 = gradient * d1v;
+    Proj3 = NormSURF * d1u_isurf;
+    Proj4 = NormSURF * d1v_isurf;
+  }
+  return Proj1;
+}
+
+Standard_Real IntImp_ZerImpFunc::Projection2()
+{
+  if (!derived)
+  {
+    ThePSurfaceTool::D1(SURF, u, v, pntsol, d1u, d1v);
+    derived = Standard_True;
+  }
+  if (!computed)
+  {
+    gp_Vec NormSURF = d1u ^ d1v;
+    Proj1 = gradient * d1u;
+    Proj2 = gradient * d1v;
+    Proj3 = NormSURF * d1u_isurf;
+    Proj4 = NormSURF * d1v_isurf;
+  }
+  return Proj2;
+}
+
+Standard_Real IntImp_ZerImpFunc::Projection3()
+{
+  if (!derived)
+  {
+    ThePSurfaceTool::D1(SURF, u, v, pntsol, d1u, d1v);
+    derived = Standard_True;
+  }
+  if (!computed)
+  {
+    gp_Vec NormSURF = d1u ^ d1v;
+    Proj1 = gradient * d1u;
+    Proj2 = gradient * d1v;
+    Proj3 = NormSURF * d1u_isurf;
+    Proj4 = NormSURF * d1v_isurf;
+  }
+  return Proj3;
+}
+
+Standard_Real IntImp_ZerImpFunc::Projection4()
+{
+  if (!derived)
+  {
+    ThePSurfaceTool::D1(SURF, u, v, pntsol, d1u, d1v);
+    derived = Standard_True;
+  }
+  if (!computed)
+  {
+    gp_Vec NormSURF = d1u ^ d1v;
+    Proj1 = gradient * d1u;
+    Proj2 = gradient * d1v;
+    Proj3 = NormSURF * d1u_isurf;
+    Proj4 = NormSURF * d1v_isurf;
+  }
+  return Proj4;
+}
+
+void IntImp_ZerImpFunc::DerivativesAndNormalOnPSurf(gp_Vec& D1U,
+                                                    gp_Vec& D1V,
+                                                    gp_Dir& Normal,
+                                                    gp_Vec& D2U,
+                                                    gp_Vec& D2V,
+                                                    gp_Vec& D2UV)
+{
+  ThePSurfaceTool::D2(SURF, u, v, pntsol, D1U, D1V, D2U, D2V, D2UV);
+  Normal = D1U ^ D1V;
+}
+
+void IntImp_ZerImpFunc::DerivativesAndNormalOnISurf(gp_Vec& D1U,
+                                                    gp_Vec& D1V,
+                                                    gp_Dir& Normal,
+                                                    gp_Vec& D2U,
+                                                    gp_Vec& D2V,
+                                                    gp_Vec& D2UV) const
+{
+  TheISurfaceTool::D2(FUNC, pntsol, D1U, D1V, D2U, D2V, D2UV);
+  Normal = D1U ^ D1V;
+}
+
 #undef EpsAng
 #undef EpsAng2
 #undef Tolpetit
index 5c5e0e7b5d1e5003fb6b2a87a785ecc163890bad..75cb7f645f28849950d1c2ee26df4da236f70b0a 100644 (file)
@@ -3,8 +3,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
@@ -56,6 +56,11 @@ inline const gp_Dir2d& IntImp_ZerImpFunc::Direction2d()
   return d2d;
 }
 
+inline Standard_Real IntImp_ZerImpFunc::SquareTangentError() const
+{
+  return (tgdu * tgdu + tgdv * tgdv);
+}
+
 inline const ThePSurface& IntImp_ZerImpFunc::PSurface() const 
 {
   return  (*((ThePSurface *)(surf)));
index 4f25a9dfbffb19eb064dba222d5b80f5f42a28a9..5b618213a1b1ee413e40652b30a870685bc4a583 100644 (file)
@@ -22,6 +22,7 @@
 #include <IntSurf_PntOn2S.hxx>
 #include <IntSurf_LineOn2S.hxx>
 #include <IntSurf.hxx>
+#include <IntSurf_InteriorPoint.hxx>
 
 #include <Adaptor2d_HCurve2d.hxx>
 #include <IntSurf_PathPoint.hxx>
@@ -402,7 +403,7 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
 {
   Standard_Boolean reversed, procf, procl, dofirst, dolast;
   Standard_Integer indfirst = 0, indlast = 0, ind2, i,j,k, NbSegm;
-  Standard_Integer NbPointIns, NbPointRst, Nblines, Nbpts, NbPointDep;
+  Standard_Integer NbPointIns, NbPointsTang, NbPointRst, Nblines, Nbpts, NbPointDep;
   Standard_Real U1,V1,U2,V2,paramf,paraml,currentparam;
 
   IntPatch_TheSegmentOfTheSOnBounds thesegm;
@@ -517,6 +518,7 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
   //
   IntSurf_SequenceOfPathPoint seqpdep;
   IntSurf_SequenceOfInteriorPoint seqpins;
+  IntSurf_SequenceOfInteriorPoint seqptang;
   //
   NbPointRst = solrst.NbPoints();
   TColStd_Array1OfInteger Destination(1,NbPointRst+1); Destination.Init(0);
@@ -529,33 +531,79 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
     }
   }
   //
-  // Recherche des points interieurs
-  if (!reversed) {
-    if (myIsStartPnt)
-      solins.Perform(Func,Surf2,myUStart,myVStart);
+  Standard_Boolean SearchIns = Standard_True;
+  if(Quad.TypeQuadric() == GeomAbs_Plane && solrst.NbSegments() > 0)
+  {
+    //For such kind of cases it is possible that whole surface is on one side of plane,
+    //plane only touches surface and does not cross it,
+    //so no inner points exist.
+    SearchIns = Standard_False;
+    Handle(Adaptor3d_TopolTool) T;
+    if(reversed)
+    {
+      T = D1;
+    }
     else
-      solins.Perform(Func,Surf2,D2,TolTang);
+    {
+      T = D2;
+    }
+    Standard_Integer aNbSamples = 0;
+    aNbSamples = T->NbSamples();
+    gp_Pnt2d s2d;
+    gp_Pnt s3d;
+    Standard_Real aValf[1], aUVap[2];
+    math_Vector Valf(aValf,1,1), UVap(aUVap,1,2);
+    T->SamplePoint(1,s2d, s3d);
+    UVap(1)=s2d.X(); 
+    UVap(2)=s2d.Y();
+    Func.Value(UVap,Valf);
+    Standard_Real rvalf = Sign(1.,Valf(1));
+    for(i = 2; i <= aNbSamples; ++i)
+    {
+      D1->SamplePoint(i,s2d, s3d);
+      UVap(1)=s2d.X(); 
+      UVap(2)=s2d.Y();
+      Func.Value(UVap,Valf);
+      if(rvalf * Valf(1) < 0.)
+      {
+        SearchIns = Standard_True;
+        break;
+      }   
+    }
   }
-  else {
-    if (myIsStartPnt)
-      solins.Perform(Func,Surf1,myUStart,myVStart);
-    else
-      solins.Perform(Func,Surf1,D1,TolTang);
+  // Recherche des points interieurs
+  NbPointIns = 0;
+  if(SearchIns) {
+    if (!reversed) {
+      if (myIsStartPnt)
+        solins.Perform(Func,Surf2,myUStart,myVStart);
+      else
+        solins.Perform(Func,Surf2,D2,TolTang);
+    }
+    else {
+      if (myIsStartPnt)
+        solins.Perform(Func,Surf1,myUStart,myVStart);
+      else
+        solins.Perform(Func,Surf1,D1,TolTang);
+    }
+    NbPointIns = solins.NbPoints();
+    for (i=1; i <= NbPointIns; i++) {
+      seqpins.Append(solins.Value(i));
+    }
+    NbPointsTang = solins.NbTangentPoints();
+    for (i = 1; i <= NbPointsTang; i++)
+      seqptang.Append(solins.TangentPoint(i));
   }
   //
-  NbPointIns = solins.NbPoints();
-  for (i=1; i <= NbPointIns; i++) {
-    seqpins.Append(solins.Value(i));
-  }
   NbPointDep=seqpdep.Length();
   //
   if (NbPointDep || NbPointIns) {
     IntPatch_TheIWalking iwalk(TolTang,Fleche,Pas);
     if (!reversed) {
-      iwalk.Perform(seqpdep,seqpins,Func,Surf2);
+      iwalk.Perform(seqpdep,seqpins,seqptang,Func,Surf2);
     }
     else {
-      iwalk.Perform(seqpdep,seqpins,Func,Surf1,Standard_True);
+      iwalk.Perform(seqpdep,seqpins,seqptang,Func,Surf1,Standard_True);
     }
     if(!iwalk.IsDone()) {
       return;
@@ -722,69 +770,71 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
         wline = new IntPatch_WLine(thelin,Standard_False,trans1,trans2);
 
         if (   iwline->HasFirstPoint() 
-          && iwline->IsTangentAtBegining() == Standard_False) {
-            indfirst = iwline->FirstPointIndex();
-            PPoint = seqpdep(indfirst);
-            tgline = PPoint.Direction3d();
-            Standard_Integer themult = PPoint.Multiplicity();
-            for (i=NbPointRst; i>=1; i--) {
-              if (Destination(i) == indfirst) {
-                if (!reversed) { //-- typeS1 = Pln || Cyl || Sph || Cone
-                  Quad.Parameters(PPoint.Value(),U1,V1);
-
-                  if((V1 < Vmin) && (Vmin-V1 < TolV)) V1 = Vmin;
-                  if((V1 > Vmax) && (V1-Vmax < TolV)) V1 = Vmax;
-
-                  PPoint.Parameters(themult,U2,V2);
-                  Surf2->D1(U2,V2,ptbid,d1u,d1v); //-- @@@@
-                }
-                else {  //-- typeS1 != Pln && Cyl && Sph && Cone
-                  Quad.Parameters(PPoint.Value(),U2,V2);
+          && iwline->IsTangentAtBegining() == Standard_False) 
+        {
+          indfirst = iwline->FirstPointIndex();
+          PPoint = seqpdep(indfirst);
+          tgline = PPoint.Direction3d();
+          Standard_Integer themult = PPoint.Multiplicity();
+          for (i=NbPointRst; i>=1; i--) {
+            if (Destination(i) == indfirst) {
+              if (!reversed) { //-- typeS1 = Pln || Cyl || Sph || Cone
+                Quad.Parameters(PPoint.Value(),U1,V1);
+
+                if((V1 < Vmin) && (Vmin-V1 < TolV)) V1 = Vmin;
+                if((V1 > Vmax) && (V1-Vmax < TolV)) V1 = Vmax;
+
+                PPoint.Parameters(themult,U2,V2);
+                Surf2->D1(U2,V2,ptbid,d1u,d1v); //-- @@@@
+              }
+              else {  //-- typeS1 != Pln && Cyl && Sph && Cone
+                Quad.Parameters(PPoint.Value(),U2,V2);
 
-                  if((V2 < Vmin) && (Vmin-V2 < TolV)) V2 = Vmin;
-                  if((V2 > Vmax) && (V2-Vmax < TolV)) V2 = Vmax;
+                if((V2 < Vmin) && (Vmin-V2 < TolV)) V2 = Vmin;
+                if((V2 > Vmax) && (V2-Vmax < TolV)) V2 = Vmax;
 
-                  PPoint.Parameters(themult,U1,V1);
-                  Surf1->D1(U1,V1,ptbid,d1u,d1v); //-- @@@@
-                }
-
-                VecNormale = d1u.Crossed(d1v);                      
-                //-- Modif du 27 Septembre 94 (Recadrage des pts U,V) 
-                ptdeb.SetValue(PPoint.Value(),TolArc,Standard_False);
-                ptdeb.SetParameters(U1,V1,U2,V2);
-                ptdeb.SetParameter(1.);
+                PPoint.Parameters(themult,U1,V1);
+                Surf1->D1(U1,V1,ptbid,d1u,d1v); //-- @@@@
+              }
 
-                Recadre(reversed,typeS1,typeS2,ptdeb,iwline,1,U1,V1,U2,V2);
+              VecNormale = d1u.Crossed(d1v);                      
+              //-- Modif du 27 Septembre 94 (Recadrage des pts U,V) 
+              ptdeb.SetValue(PPoint.Value(),TolArc,Standard_False);
+              ptdeb.SetParameters(U1,V1,U2,V2);
+              ptdeb.SetParameter(1.);
 
-                currentarc = solrst.Point(i).Arc();
-                currentparam = solrst.Point(i).Parameter();
-                currentarc->D1(currentparam,p2d,d2d);
-                tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
+              Recadre(reversed,typeS1,typeS2,ptdeb,iwline,1,U1,V1,U2,V2);
 
-                Standard_Real squaremagnitudeVecNormale = VecNormale.SquareMagnitude();
-                if(squaremagnitudeVecNormale > 1e-13) { 
-                  DirNormale=VecNormale;
-                  IntSurf::MakeTransition(tgline,tgrst,DirNormale,TLine,TArc);
-                }
-                else { 
-                  TLine.SetValue(Standard_True,IntSurf_Undecided);
-                  TArc.SetValue(Standard_True,IntSurf_Undecided);
-                }
+              currentarc = solrst.Point(i).Arc();
+              currentparam = solrst.Point(i).Parameter();
+              currentarc->D1(currentparam,p2d,d2d);
+              tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
 
-                ptdeb.SetArc(reversed,currentarc,currentparam,TLine,TArc);
-                if (!solrst.Point(i).IsNew()) {
-                  ptdeb.SetVertex(reversed,solrst.Point(i).Vertex());
-                }
-                wline->AddVertex(ptdeb);
-                if (themult == 0) {
-                  wline->SetFirstPoint(wline->NbVertex());
-                }
+              Standard_Real squaremagnitudeVecNormale = VecNormale.SquareMagnitude();
+              if(squaremagnitudeVecNormale > 1e-13) { 
+                DirNormale=VecNormale;
+                IntSurf::MakeTransition(tgline,tgrst,DirNormale,TLine,TArc);
+              }
+              else { 
+                TLine.SetValue(Standard_True,IntSurf_Undecided);
+                TArc.SetValue(Standard_True,IntSurf_Undecided);
+              }
 
-                themult--;
+              ptdeb.SetArc(reversed,currentarc,currentparam,TLine,TArc);
+              if (!solrst.Point(i).IsNew()) {
+                ptdeb.SetVertex(reversed,solrst.Point(i).Vertex());
               }
+              wline->AddVertex(ptdeb);
+              if (themult == 0) {
+                wline->SetFirstPoint(wline->NbVertex());
+              }
+
+              themult--;
             }
+          }
         }
-        else if (iwline->IsTangentAtBegining()) {
+        else if (iwline->IsTangentAtBegining()) 
+        {
           gp_Pnt psol = thelin->Value(1).Value();
           thelin->Value(1).ParametersOnS1(U1,V1);
           thelin->Value(1).ParametersOnS2(U2,V2);
@@ -794,7 +844,8 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
           wline->AddVertex(ptdeb);
           wline->SetFirstPoint(wline->NbVertex());
         }
-        else { 
+        else 
+        { 
           gp_Pnt psol = thelin->Value(1).Value();
           thelin->Value(1).ParametersOnS1(U1,V1);
           thelin->Value(1).ParametersOnS2(U2,V2);
@@ -807,71 +858,73 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
 
 
         if (   iwline->HasLastPoint() 
-          && iwline->IsTangentAtEnd() == Standard_False) {
-            indlast = iwline->LastPointIndex();
-            PPoint = seqpdep(indlast);
-            tgline = PPoint.Direction3d().Reversed();
-            Standard_Integer themult = PPoint.Multiplicity();
-            for (i=NbPointRst; i >=1; i--) {
-              if (Destination(i) == indlast) {
-                if (!reversed) {
-                  Quad.Parameters(PPoint.Value(),U1,V1);
-
-                  if((V1 < Vmin) && (Vmin-V1 < TolV)) V1 = Vmin;
-                  if((V1 > Vmax) && (V1-Vmax < TolV)) V1 = Vmax;
-
-                  PPoint.Parameters(themult,U2,V2);
-                  Surf2->D1(U2,V2,ptbid,d1u,d1v); //-- @@@@
-                  VecNormale = d1u.Crossed(d1v);                    //-- @@@@
-                }
-                else {
-                  Quad.Parameters(PPoint.Value(),U2,V2);
-
-                  if((V2 < Vmin) && (Vmin-V2 < TolV)) V2 = Vmin;
-                  if((V2 > Vmax) && (V2-Vmax < TolV)) V2 = Vmax;
+          && iwline->IsTangentAtEnd() == Standard_False) 
+        {
+          indlast = iwline->LastPointIndex();
+          PPoint = seqpdep(indlast);
+          tgline = PPoint.Direction3d().Reversed();
+          Standard_Integer themult = PPoint.Multiplicity();
+          for (i=NbPointRst; i >=1; i--) {
+            if (Destination(i) == indlast) {
+              if (!reversed) {
+                Quad.Parameters(PPoint.Value(),U1,V1);
+
+                if((V1 < Vmin) && (Vmin-V1 < TolV)) V1 = Vmin;
+                if((V1 > Vmax) && (V1-Vmax < TolV)) V1 = Vmax;
+
+                PPoint.Parameters(themult,U2,V2);
+                Surf2->D1(U2,V2,ptbid,d1u,d1v); //-- @@@@
+                VecNormale = d1u.Crossed(d1v);                    //-- @@@@
+              }
+              else {
+                Quad.Parameters(PPoint.Value(),U2,V2);
 
-                  PPoint.Parameters(themult,U1,V1);
-                  Surf1->D1(U1,V1,ptbid,d1u,d1v); //-- @@@@
-                  VecNormale = d1u.Crossed(d1v);                    //-- @@@@
-                }
+                if((V2 < Vmin) && (Vmin-V2 < TolV)) V2 = Vmin;
+                if((V2 > Vmax) && (V2-Vmax < TolV)) V2 = Vmax;
 
-                ptfin.SetValue(PPoint.Value(),TolArc,Standard_False);
-                ptfin.SetParameters(U1,V1,U2,V2);
-                ptfin.SetParameter(Nbpts);
+                PPoint.Parameters(themult,U1,V1);
+                Surf1->D1(U1,V1,ptbid,d1u,d1v); //-- @@@@
+                VecNormale = d1u.Crossed(d1v);                    //-- @@@@
+              }
 
-                Recadre(reversed,typeS1,typeS2,ptfin,iwline,Nbpts-1,U1,V1,U2,V2);
+              ptfin.SetValue(PPoint.Value(),TolArc,Standard_False);
+              ptfin.SetParameters(U1,V1,U2,V2);
+              ptfin.SetParameter(Nbpts);
 
-                currentarc = solrst.Point(i).Arc();
-                currentparam = solrst.Point(i).Parameter();
-                currentarc->D1(currentparam,p2d,d2d);
-                tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
+              Recadre(reversed,typeS1,typeS2,ptfin,iwline,Nbpts-1,U1,V1,U2,V2);
 
+              currentarc = solrst.Point(i).Arc();
+              currentparam = solrst.Point(i).Parameter();
+              currentarc->D1(currentparam,p2d,d2d);
+              tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
 
-                Standard_Real squaremagnitudeVecNormale = VecNormale.SquareMagnitude();
-                if(squaremagnitudeVecNormale > 1e-13) { 
-                  DirNormale=VecNormale;
-                  IntSurf::MakeTransition(tgline,tgrst,DirNormale,TLine,TArc);
-                }
-                else { 
-                  TLine.SetValue(Standard_True,IntSurf_Undecided);
-                  TArc.SetValue(Standard_True,IntSurf_Undecided);
-                }
 
+              Standard_Real squaremagnitudeVecNormale = VecNormale.SquareMagnitude();
+              if(squaremagnitudeVecNormale > 1e-13) { 
+                DirNormale=VecNormale;
+                IntSurf::MakeTransition(tgline,tgrst,DirNormale,TLine,TArc);
+              }
+              else { 
+                TLine.SetValue(Standard_True,IntSurf_Undecided);
+                TArc.SetValue(Standard_True,IntSurf_Undecided);
+              }
 
-                ptfin.SetArc(reversed,currentarc,currentparam,TLine,TArc);
-                if (!solrst.Point(i).IsNew()) {
-                  ptfin.SetVertex(reversed,solrst.Point(i).Vertex());
-                }
-                wline->AddVertex(ptfin);
-                if (themult == 0) {
-                  wline->SetLastPoint(wline->NbVertex());
-                }
 
-                themult--;
+              ptfin.SetArc(reversed,currentarc,currentparam,TLine,TArc);
+              if (!solrst.Point(i).IsNew()) {
+                ptfin.SetVertex(reversed,solrst.Point(i).Vertex());
+              }
+              wline->AddVertex(ptfin);
+              if (themult == 0) {
+                wline->SetLastPoint(wline->NbVertex());
               }
+
+              themult--;
             }
+          }
         }
-        else if (iwline->IsTangentAtEnd()) {
+        else if (iwline->IsTangentAtEnd()) 
+        {
           gp_Pnt psol = thelin->Value(Nbpts).Value();
           thelin->Value(Nbpts).ParametersOnS1(U1,V1);
           thelin->Value(Nbpts).ParametersOnS2(U2,V2);
@@ -881,7 +934,8 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
           wline->AddVertex(ptfin);
           wline->SetLastPoint(wline->NbVertex());
         }
-        else { 
+        else 
+        { 
           gp_Pnt psol = thelin->Value(Nbpts).Value();
           thelin->Value(Nbpts).ParametersOnS1(U1,V1);
           thelin->Value(Nbpts).ParametersOnS2(U2,V2);
@@ -983,6 +1037,38 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
   if (NbSegm) {
     for(i=1; i<=NbSegm; i++) {
       thesegm = solrst.Segment(i);  
+      //Check if segment is degenerated
+      if(thesegm.HasFirstPoint() && thesegm.HasLastPoint())
+      {
+        Standard_Real tol2 = Precision::Confusion();
+        tol2 *= tol2;
+        const gp_Pnt& aPf = thesegm.FirstPoint().Value();
+        const gp_Pnt& aPl = thesegm.LastPoint().Value();
+        if(aPf.SquareDistance(aPl) <= tol2)
+        {
+          //segment can be degenerated - check inner point
+          paramf = thesegm.FirstPoint().Parameter();
+          paraml = thesegm.LastPoint().Parameter();
+          gp_Pnt2d _p2d = 
+            thesegm.Curve()->Value(.57735 * paramf + 0.42265 * paraml);
+          gp_Pnt aPm;
+          if(reversed)
+          {
+            Surf1->D0(_p2d.X(), _p2d.Y(), aPm);
+          }
+          else
+          {
+            Surf2->D0(_p2d.X(), _p2d.Y(), aPm);
+          }
+          if(aPm.SquareDistance(aPf) <= tol2)
+          {
+            //Degenerated
+            continue;
+          }
+        }
+      }
+
+
       //----------------------------------------------------------------------      
       // on cree une ligne d intersection contenant uniquement le segment.
       // VOIR POUR LA TRANSITION DE LA LIGNE
index 416a44ee35341612b88a201db5c74a33c07eab17..3c4d7d6712df746039b1c76435a4daa650d3db50 100644 (file)
@@ -5,8 +5,8 @@
 --
 -- This file is part of Open CASCADE Technology software library.
 --
--- This library is free software; you can redistribute it and/or modify it under
--- the terms of the GNU Lesser General Public License version 2.1 as published
+-- This library is free software; you can redistribute it and / or modify it
+-- under the terms of the GNU Lesser General Public version 2.1 as published
 -- by the Free Software Foundation, with special exception defined in the file
 -- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 -- distribution for complete text of the license and disclaimer of any warranty.
@@ -68,7 +68,20 @@ is
     NbPoints(me)
     
        ---Purpose: Returns the number of points.
-       --          The exception NotDone if raised if IsDone 
+       --          The exception NotDone is raised if IsDone 
+       --          returns False.
+    
+       returns Integer
+       ---C++: inline
+       
+       raises NotDone from StdFail
+       
+       is static;
+
+    NbTangentPoints(me)
+    
+       ---Purpose: Returns the number of tangent points.
+       --          The exception NotDone is raised if IsDone 
        --          returns False.
     
        returns Integer
@@ -96,10 +109,29 @@ is
 
        is static;
 
+    TangentPoint(me; Index: Integer)
+    
+       ---Purpose: Returns the tangent point of range Index.
+       --          
+       --          The exception NotDone is raised if IsDone 
+       --          returns False.
+       --          The exception OutOfRange if raised if
+       --          Index <= 0 or Index > NbTangentPoints.
+
+       returns InteriorPoint from IntSurf
+       ---C++: return const&
+       ---C++: inline
+       
+       raises NotDone from StdFail,
+              OutOfRange from Standard
+
+       is static;
+
 
 fields
 
-    done : Boolean                 from Standard;
-    list : SequenceOfInteriorPoint from IntSurf;
+    done            : Boolean                 from Standard;
+    list            : SequenceOfInteriorPoint from IntSurf;
+    myTangentPoints : SequenceOfInteriorPoint from IntSurf;
 
 end SearchInside;
index 9d071e690578647f9b0a0b00adab9edd70d9f34d..ae90c5b6765e4f835e919f8689bdc1d37903a783 100644 (file)
@@ -3,8 +3,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
 
 #include <TopAbs_State.hxx>
 
+#ifdef DRAW
+#include <DrawTrSurf.hxx>
+#endif
+
+
 IntStart_SearchInside::IntStart_SearchInside (): done(Standard_False)
 {}
 
@@ -49,6 +54,7 @@ void IntStart_SearchInside::Perform (TheFunction& Func,
 
   done = Standard_False;
   list.Clear();
+  myTangentPoints.Clear();
   Standard_Real aBinf[2], aBsup[2], aUVap[2], atoler[2];
   math_Vector Binf(aBinf,1,2), Bsup(aBsup,1,2), UVap(aUVap,1,2), toler(atoler,1,2);
   gp_Pnt psol;
@@ -118,6 +124,13 @@ void IntStart_SearchInside::Perform (TheFunction& Func,
   //--
 
   
+#ifdef DRAW
+  char* name = new char[100];
+#endif
+
+  gp_Vec NullDir(0.,0.,0.);
+  gp_Vec2d NullDir2d(0.,0.);
+  
   for (i=1; i <= Nbsample+12; i++) {
     gp_Pnt2d s2d;
     gp_Pnt s3d;
@@ -176,9 +189,9 @@ void IntStart_SearchInside::Perform (TheFunction& Func,
       Rsnld.Perform(Func,UVap,Binf,Bsup);
       if (Rsnld.IsDone()) {
        if (Abs(Func.Root()) <= Tol) {
+          psol = Func.Point();
+          Rsnld.Root(UVap);
          if (!Func.IsTangent()) {
-           psol = Func.Point();
-           Rsnld.Root(UVap);
            // On regarde si le point trouve est bien un nouveau point.   
            j = 1;
            nbpt = list.Length();
@@ -207,9 +220,54 @@ void IntStart_SearchInside::Perform (TheFunction& Func,
                list.Append(IntSurf_InteriorPoint(psol,UVap(1),UVap(2),
                                                  Func.Direction3d(),
                                                  Func.Direction2d()));
+#ifdef DRAW
+                gp_Pnt2d p2dsol(UVap(1),UVap(2));
+                sprintf(name, "pp%d", list.Length());
+                DrawTrSurf::Set(name, p2dsol);
+                sprintf(name, "p%d", list.Length());
+                DrawTrSurf::Set(name, psol);
+#endif
              }
            }
-         }
+         }//if (!Func.IsTangent())
+          else //tangent point
+          {
+            Standard_Boolean IsNewTangentPoint = Standard_True;
+            for (j = 1; j <= myTangentPoints.Length(); j++)
+            {
+             const IntSurf_InteriorPoint&  IPj = myTangentPoints(j);
+             const gp_Pnt& Pj = IPj.Value();
+             if (   (Abs(Pj.X()-psol.X()) <= Epsilon)
+                 && (Abs(Pj.Y()-psol.Y()) <= Epsilon)
+                 && (Abs(Pj.Z()-psol.Z()) <= Epsilon)
+                 && (Abs(UVap(1)-IPj.UParameter()) <= toler1)
+                 && (Abs(UVap(2)-IPj.VParameter()) <= toler2) )
+              {
+               IsNewTangentPoint = Standard_False;
+                break;
+             }
+            }
+            
+            if (IsNewTangentPoint)
+            {
+             situ = T->Classify(gp_Pnt2d(UVap(1),UVap(2)),
+                                Maxtoler1toler2,Standard_False);   //-- ,Standard_False pour ne pas recadrer on Periodic
+             if (situ == TopAbs_IN) {
+                myTangentPoints.Append(IntSurf_InteriorPoint(psol,UVap(1),UVap(2),
+                                                             NullDir, NullDir2d));
+#ifdef DRAW
+                gp_Pnt2d p2dsol(UVap(1),UVap(2));
+                sprintf(name, "tpp%d", myTangentPoints.Length());
+                //DrawTrSurf::Set(name, p2dsol);
+                sprintf(name, "tp%d", myTangentPoints.Length());
+                //DrawTrSurf::Set(name, psol);
+                cout<<myTangentPoints.Length()<<" tangent point :"<<endl;
+                cout<<"U = "<<UVap(1)<<", V = "<<UVap(2)<<endl;
+                cout<<"Dist = "<<aRootVal<<endl<<endl;
+#endif
+              }
+            }
+          }
        }
       }
     }
@@ -231,6 +289,7 @@ void IntStart_SearchInside::Perform (TheFunction& Func,
 {
   done = Standard_False;
   list.Clear();
+  myTangentPoints.Clear();
   math_Vector Binf(1,2), Bsup(1,2), toler(1,2);
 
   Binf(1) = ThePSurfaceTool::FirstUParameter(PS);
index c4c9408c6c09f8b242ae76525b3909deeefc16df..3d59fb299e742e374d2e949b0c2d1c1ef59293b0 100644 (file)
@@ -3,8 +3,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
@@ -27,6 +27,12 @@ inline Standard_Integer IntStart_SearchInside::NbPoints () const {
   return list.Length();
 }
 
+inline Standard_Integer IntStart_SearchInside::NbTangentPoints () const {
+
+  if (!done) {StdFail_NotDone::Raise();}
+  return myTangentPoints.Length();
+}
+
 
 inline const IntSurf_InteriorPoint& IntStart_SearchInside::Value 
      (const Standard_Integer Index) const
@@ -36,3 +42,10 @@ inline const IntSurf_InteriorPoint& IntStart_SearchInside::Value
   return list.Value(Index);
 }
 
+inline const IntSurf_InteriorPoint& IntStart_SearchInside::TangentPoint
+     (const Standard_Integer Index) const
+
+{
+  if (!done) {StdFail_NotDone::Raise();}
+  return myTangentPoints.Value(Index);
+}
index ca9ed1415cab5e23540fe6a6ca767415810959af..2e8be42aac8eb00a87f35874327d70d3321c61f9 100644 (file)
@@ -5,8 +5,8 @@
 --
 -- This file is part of Open CASCADE Technology software library.
 --
--- This library is free software; you can redistribute it and/or modify it under
--- the terms of the GNU Lesser General Public License version 2.1 as published
+-- This library is free software; you can redistribute it and / or modify it
+-- under the terms of the GNU Lesser General Public version 2.1 as published
 -- by the Free Software Foundation, with special exception defined in the file
 -- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 -- distribution for complete text of the license and disclaimer of any warranty.
@@ -22,7 +22,9 @@ class PntOn2S from IntSurf
        --          parametric coordinates.
 
 
-uses Pnt from gp
+uses
+    Pnt   from gp,
+    Pnt2d from gp
 
 is
 
@@ -91,6 +93,13 @@ is
 
        is static;
 
+    ValueOnSurface(me; OnFirst: Boolean from Standard)
+    
+       ---Purpose: Returns the point in 2d space of one of the surfaces.
+
+       returns Pnt2d from gp
+       is static;
+
 
 
     ParametersOnS1(me; U1,V1: out Real from Standard)
@@ -110,6 +119,13 @@ is
 
        is static;
 
+    ParametersOnSurface(me; OnFirst: Boolean from Standard;
+                           U,V: out Real from Standard)
+    
+       ---Purpose: Returns the parameters of the point in the
+       --          parametric space of one of the surface.
+
+       is static;
 
     Parameters(me; U1,V1,U2,V2: out Real from Standard)
 
index ff0d19f7a6a24f5707183d88302766ab118d1e65..0bfb4d3db53acd49cd225bd61a8a99d9c4232bc2 100644 (file)
@@ -3,8 +3,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
@@ -48,5 +48,26 @@ void IntSurf_PntOn2S::SetValue (const Standard_Boolean OnFirst,
   }
 }
 
+gp_Pnt2d IntSurf_PntOn2S::ValueOnSurface(const Standard_Boolean OnFirst) const
+{
+  gp_Pnt2d PointOnSurf;
+  if (OnFirst)
+    PointOnSurf.SetCoord(u1,v1);
+  else
+    PointOnSurf.SetCoord(u2,v2);
+  return PointOnSurf;
+}
 
-
+void IntSurf_PntOn2S::ParametersOnSurface(const Standard_Boolean OnFirst,
+                                          Standard_Real& U,
+                                          Standard_Real& V) const
+{
+  if (OnFirst) {
+    U = u1;
+    V = v1;
+  }
+  else {
+    U = u2;
+    V = v2;
+  }
+}
index 4dd1e914498c1a5a243dcab1a6aebf3a2fe06cb5..fbbea665330f49a4831a7c040418656ee5e4fc04 100644 (file)
@@ -5,8 +5,8 @@
 --
 -- This file is part of Open CASCADE Technology software library.
 --
--- This library is free software; you can redistribute it and/or modify it under
--- the terms of the GNU Lesser General Public License version 2.1 as published
+-- This library is free software; you can redistribute it and / or modify it
+-- under the terms of the GNU Lesser General Public version 2.1 as published
 -- by the Free Software Foundation, with special exception defined in the file
 -- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 -- distribution for complete text of the license and disclaimer of any warranty.
@@ -22,7 +22,8 @@ class QuadricTool from IntSurf
        --          as implicit surface.
 
 uses Quadric from IntSurf,
-     Vec     from gp
+     Vec     from gp,
+     Pnt     from gp
 
 is
 
@@ -47,11 +48,22 @@ is
 
     ValueAndGradient(myclass; Quad: Quadric from IntSurf;
                      X, Y, Z: Real from Standard;
-                     Val: out Real from Standard; Grad: out Vec from gp);
+                     Val: out Real from Standard;
+                    Grad: out Vec from gp;
+                    D1U_ISurf, D1V_ISurf: out Vec from gp);
                     
        ---Purpose: Returns the value and the gradient.
 
-       ---C++: inline
+    D2(myclass; Quad:  Quadric from IntSurf;
+                Point: Pnt from gp;
+               D1U:   out Vec from gp;
+               D1V:   out Vec from gp;
+               D2U:   out Vec from gp;
+               D2V:   out Vec from gp;
+               D2UV:  out Vec from gp);
+                    
+       ---Purpose: Returns all first and second derivatives.
+    
     
 
     Tolerance(myclass; Quad: Quadric from IntSurf )
index 798436160a67e9930d4be9d73e517f15576a99ea..25186e0caed3bf8872c422a76eb74c5b3f1190e2 100644 (file)
@@ -3,8 +3,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
 #include <gp_Sphere.hxx>
 #include <gp_Cylinder.hxx>
 
+
+void IntSurf_QuadricTool::ValueAndGradient (const IntSurf_Quadric& Quad,
+                                            const Standard_Real X,
+                                            const Standard_Real Y,
+                                            const Standard_Real Z,
+                                            Standard_Real& Val,
+                                            gp_Vec& Grad,
+                                            gp_Vec& D1U,
+                                            gp_Vec& D1V)
+{
+  gp_Pnt thePoint(X,Y,Z);
+  Quad.ValAndGrad(thePoint, Val, Grad);
+  Standard_Real U, V;
+  Quad.Parameters(thePoint, U, V);
+  Quad.D1(U, V, thePoint, D1U, D1V);
+}
+
+void IntSurf_QuadricTool::D2 (const IntSurf_Quadric& Quad,
+                              const gp_Pnt& aPoint,
+                              gp_Vec& D1U,
+                              gp_Vec& D1V,
+                              gp_Vec& D2U,
+                              gp_Vec& D2V,
+                              gp_Vec& D2UV)
+{
+  Standard_Real U, V;
+  Quad.Parameters(aPoint, U, V);
+  gp_Pnt thePoint;
+  Quad.D1(U, V, thePoint, D1U, D1V);
+  D2U = Quad.DN(U, V, 2, 0);
+  D2V = Quad.DN(U, V, 0, 2);
+  D2UV = Quad.DN(U, V, 1, 1);
+}
+
 Standard_Real IntSurf_QuadricTool::Tolerance (const IntSurf_Quadric& Q) {
   switch (Q.TypeQuadric()) {
   case GeomAbs_Sphere:
index 7e7ef2d6e2209ddb60aa6ed3a6fc83469cf19286..60ce1dd86a923e85cc229ce46a9f2c8cf9e9ad51 100644 (file)
@@ -3,8 +3,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
@@ -31,15 +31,3 @@ inline void IntSurf_QuadricTool::Gradient (const IntSurf_Quadric& Quad,
 
   V = Quad.Gradient(gp_Pnt(X,Y,Z));
 }
-
-inline void IntSurf_QuadricTool::ValueAndGradient (const IntSurf_Quadric& Quad,
-                                                  const Standard_Real X,
-                                                  const Standard_Real Y,
-                                                  const Standard_Real Z,
-                                                  Standard_Real& Val,
-                                                  gp_Vec& V) {
-
-  Quad.ValAndGrad(gp_Pnt(X,Y,Z),Val,V);
-}
-
-
index 9a5f379ffdbbb45e80a4af9193263f102e260378..3822cbc5c7191623d331b27539bc6d2ad0d9dc18 100644 (file)
@@ -35,7 +35,7 @@ is
 
     enumeration StatusDeflection is 
                 PasTropGrand, PointConfondu, ArretSurPointPrecedent,
-                ArretSurPoint, OK;
+                ArretSurPoint, OK, OKtangent;
 
 -- StepTooGreat, ConfusedPoint, StopOnPreviousPoint, StopOnPoint, OK
                
index ec8b08e59f957c70aa8489e7d77a6bf599936141..6ac8ef918e6a51fefa3b1e8d3d4b860f6c956a03 100644 (file)
@@ -5,8 +5,8 @@
 --
 -- This file is part of Open CASCADE Technology software library.
 --
--- This library is free software; you can redistribute it and/or modify it under
--- the terms of the GNU Lesser General Public License version 2.1 as published
+-- This library is free software; you can redistribute it and / or modify it
+-- under the terms of the GNU Lesser General Public version 2.1 as published
 -- by the Free Software Foundation, with special exception defined in the file
 -- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 -- distribution for complete text of the license and disclaimer of any warranty.
@@ -38,6 +38,7 @@ generic class IWalking from  IntWalk (
 uses Vector            from math,
      SequenceOfInteger from TColStd,
      SequenceOfReal    from TColStd,
+     SequenceOfBoolean from TColStd,
      StatusDeflection  from IntWalk,
      VectorOfInteger   from IntWalk,
      VectorOfWalkingData from IntWalk,
@@ -88,6 +89,7 @@ is
     Perform(me: in out;
             Pnts1    : ThePOPIterator;
             Pnts2    : ThePOLIterator;
+           Pnts3    : ThePOLIterator;
             Func     : in out TheIWFunction;
            S        : ThePSurface;
             Reversed : Boolean from Standard = Standard_False)
@@ -180,7 +182,6 @@ is
 
         is static;
     
-
 -- -- private
 
     Cadrage(me; BornInf, BornSup, UVap : in out Vector from math;
@@ -206,6 +207,14 @@ is
     returns Boolean from Standard
     is static protected;                     
 
+    TestArretPassageTang (me: in out; Umult  : SequenceOfReal from TColStd;
+                                  Vmult  : SequenceOfReal from TColStd;
+                                  UV     : Vector from math;
+                                  Index  : Integer from Standard;
+                                 Irang  : out Integer from Standard) 
+    returns Boolean from Standard
+    is static protected;                     
+
     TestArretAjout(me: in out; Section: in out TheIWFunction;
                               UV     : in out Vector from math;
                               Irang  : out Integer from Standard; 
@@ -227,9 +236,10 @@ is
                                UV              : Vector from math;
                               StatusPrecedent : StatusDeflection from IntWalk;
                                NbDivision      : in out Integer from Standard;
-                               Step           : in out Real from Standard;
+                               Step            : in out Real from Standard;
 --                               StepV           : in out Real from Standard;
-                               StepSign        : Integer from Standard)
+                               StepSign        : Integer from Standard;
+                              CurNbPoints     : Integer from Standard)
     returns StatusDeflection from IntWalk                  
     is static protected;                     
 
@@ -251,6 +261,7 @@ is
                                   Vmult  : SequenceOfReal from TColStd;
                                   Pnts1  : ThePOPIterator;
                                  Pnts2  : ThePOLIterator;
+                                 Pnts3  : ThePOLIterator;
                                   Section: in out TheIWFunction;
                                   Rajout : in out Boolean from Standard)
     is static protected;       
@@ -267,6 +278,15 @@ is
 
     is static protected;
     
+    FindExactTangentPoint(me : in out ; TolTang : Real from Standard;
+                                       Section : in out TheIWFunction;
+                                       Psol    : in out PntOn2S from IntSurf)
+    is static protected;
+    
+    ComputeDirOfTangentialIntersection(me : in out; Section : in out TheIWFunction;
+                                                   StepSign: in out Integer from Standard)
+    is static protected;
+    
     Clear (me: in out) is static protected;
     ---Purpose: Clears up internal containers
 
@@ -283,6 +303,7 @@ fields
 
     wd1                 : VectorOfWalkingData from IntWalk;
     wd2                 : VectorOfWalkingData from IntWalk;
+    wd3                 : VectorOfWalkingData from IntWalk;
     nbMultiplicities    : VectorOfInteger   from IntWalk;
     Um                  : Real              from Standard; -- Min U de la surf
     UM                  : Real              from Standard; -- Max U de la surf
@@ -292,9 +313,17 @@ fields
     prevtg              : Boolean           from Standard;
     previousd3d         : Vec               from gp;
     previousd2d         : Dir2d             from gp;
+    previousProj1       : Real              from Standard;
+    previousProj2       : Real              from Standard;
+    previousProj3       : Real              from Standard;
+    previousProj4       : Real              from Standard;
+    PointAfterPossibleCuspPoint : PntOn2S   from IntSurf;
+    PossibleCuspPoint   : Boolean           from Standard;
+    IsTangentialIntersection : Boolean      from Standard;
     seqAjout            : SequenceOfInteger from TColStd; 
     lines               : SequenceOfIWLine;
     NbPointsConfondusConsecutifs: Integer   from Standard;
     EpsilonSembleTropGrand      : Integer   from Standard;
+    
 end IWalking;
 
index 8c1b004098a3add44f50865dc9d9fa3fdc366337..340c79851787fda80b87655fe49e4791bccf8e05 100644 (file)
@@ -3,8 +3,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
@@ -31,9 +31,12 @@ IntWalk_IWalking::IntWalk_IWalking (const Standard_Real Epsilon,
       epsilon(Epsilon*Epsilon),
       wd1 (IntWalk_VectorOfWalkingData::allocator_type (new NCollection_IncAllocator)),
       wd2 (wd1.get_allocator()),
+      wd3 (wd2.get_allocator()),
       nbMultiplicities (wd1.get_allocator()),
       NbPointsConfondusConsecutifs(0),
-      EpsilonSembleTropGrand(0)
+      EpsilonSembleTropGrand(0),
+      PossibleCuspPoint(Standard_False),
+      IsTangentialIntersection(Standard_False)
 {
 }
 
@@ -50,11 +53,13 @@ void IntWalk_IWalking::Clear()
 {
   wd1.clear();
   wd2.clear();
+  wd3.clear();
   IntWalk_WalkingData aDummy;
   aDummy.etat = -10;
   aDummy.ustart = aDummy.vstart = 0.;
   wd1.push_back (aDummy);
   wd2.push_back (aDummy);
+  wd3.push_back (aDummy);
   nbMultiplicities.clear();
   nbMultiplicities.push_back (-1);
   
@@ -82,6 +87,7 @@ void IntWalk_IWalking::Clear()
 //
 void IntWalk_IWalking::Perform(const ThePOPIterator& Pnts1,
                               const ThePOLIterator& Pnts2,
+                               const ThePOLIterator& Pnts3,
                               TheIWFunction& Func,
                               const ThePSurface& Caro,
                               const Standard_Boolean Reversed)
@@ -92,6 +98,7 @@ void IntWalk_IWalking::Perform(const ThePOPIterator& Pnts1,
   Standard_Boolean Rajout = Standard_False;
   Standard_Integer nbPnts1 = Pnts1.Length();
   Standard_Integer nbPnts2 = Pnts2.Length();
+  Standard_Integer nbPnts3 = Pnts3.Length();
   Standard_Real U,V;
 
   Clear();
@@ -139,6 +146,14 @@ void IntWalk_IWalking::Perform(const ThePOPIterator& Pnts1,
     wd2.push_back (aWD2);
   }
 
+  wd3.reserve (nbPnts3);
+  for (I = 1; I <= nbPnts3; I++) {
+    IntWalk_WalkingData aWD3;
+    aWD3.etat = 13;
+    ThePointOfLoopTool::Value2d(Pnts3.Value(I), aWD3.ustart, aWD3.vstart);
+    wd3.push_back (aWD3);
+  }
+
   tolerance(1) = ThePSurfaceTool::UResolution(Caro,Precision::Confusion());
   tolerance(2) = ThePSurfaceTool::VResolution(Caro,Precision::Confusion());
 
@@ -161,9 +176,11 @@ void IntWalk_IWalking::Perform(const ThePOPIterator& Pnts1,
   Func.Set(Caro);
 
   // calculation of all open lines   
-  if (nbPnts1 != 0) ComputeOpenLine(Umult,Vmult,Pnts1,Func,Rajout); 
+  if (nbPnts1 != 0)
+    ComputeOpenLine(Umult,Vmult,Pnts1,Func,Rajout);
   // calculation of all closed lines 
-  if (nbPnts2 != 0) ComputeCloseLine(Umult,Vmult,Pnts1,Pnts2,Func,Rajout); 
+  if (nbPnts2 != 0 || nbPnts3 != 0)
+    ComputeCloseLine(Umult,Vmult,Pnts1,Pnts2,Pnts3,Func,Rajout); 
   for (I = 1; I <= nbPnts1; I++) { 
     if (wd1[I].etat >0) seqSingle.Append(Pnts1(I));
   }
index fa8544421e7636f9e46cd39741eb4c53391110de..62749512346665b7fecb50e83ed58056010dcba8 100644 (file)
@@ -251,6 +251,43 @@ Standard_Boolean IntWalk_IWalking::TestArretPassage
       }
     }
   }
+  for (size_t i = 1; i < wd3.size(); i++) { 
+    if (wd3[i].etat > 0) { 
+      // debug jag 05.04.94
+
+//      if ((Up-wd2[i].ustart)*(UV(1)-wd2[i].ustart) +
+//       (Vp-wd2[i].vstart)*(UV(2)-wd2[i].vstart) <= 0)
+      Utest = wd3[i].ustart;
+      Vtest = wd3[i].vstart;
+
+      Du  = UV(1)-Utest;
+      Dv  = UV(2)-Vtest;
+      Dup = Up - Utest;
+      Dvp = Vp - Vtest;
+      
+//-- lbr le 30 oct 97 
+
+      //IFV for OCC20285
+
+      if ((Abs(Du) < tolu2 && Abs(Dv) < tolv2) ||
+         (Abs(Dup) < tolu2 && Abs(Dvp) < tolv2)) { 
+           
+       wd3[i].etat = -wd3[i].etat;
+      }
+      else {
+       Standard_Real DDu = (UV(1)-Up);
+       Standard_Real DDv = (UV(2)-Vp);
+       Standard_Real DDD = DDu*DDu + DDv*DDv;
+       Standard_Real DD1 = Du*Du + Dv*Dv;
+       if(DD1 <= DDD) { 
+         Standard_Real DD2 = Dup*Dup + Dvp*Dvp;
+         if(DD2 <= DDD && ((Du*Dup) + (Dv*Dvp*tolu/tolv) <= 0.)) {     
+           wd3[i].etat = -wd3[i].etat;
+         }
+       }
+      }
+    }
+  }
 
   // stop test on point given at input and not yet processed
 
@@ -473,6 +510,62 @@ Standard_Boolean IntWalk_IWalking::TestArretPassage
       }
     }
   }
+  for (k = 1; k < (int)wd3.size(); k++) { 
+    if (wd3[k].etat > 0) {
+      Utest = wd3[k].ustart;
+      Vtest = wd3[k].vstart;
+      
+      Utest/=deltau;
+      Vtest/=deltav;
+      
+      Standard_Real UV1mUtest=UV1-Utest;
+      Standard_Real UV2mVtest=UV2-Vtest;
+      if(   (UV1mUtest<tolu2 && UV1mUtest>-tolu2)
+        && (UV2mVtest<tolv2 && UV2mVtest>-tolv2)) {
+        
+         wd3[k].etat = -wd3[k].etat; //-- mark the point as a crossing point 
+      }
+      else { 
+       Standard_Real UpmUtest = (Up-Utest);
+       Standard_Real VpmVtest = (Vp-Vtest);
+       Standard_Real dPreviousStart = (UpmUtest)*(UpmUtest)+(VpmVtest)*(VpmVtest);
+       Standard_Real dCurrentStart  = UV1mUtest * UV1mUtest + UV2mVtest * UV2mVtest;
+
+       Scal=(UpmUtest)*(UV1mUtest)+(VpmVtest)*(UV2mVtest);
+       if( (Abs(UpmUtest)<tolu && Abs(VpmVtest)<tolv)) {
+          
+           wd3[k].etat = -wd3[k].etat;
+       }
+       else if(Scal<0 && (dPreviousStart+dCurrentStart < dPreviousCurrent)) {
+          
+           wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+       }
+       else {
+         if(dPreviousStart < dPreviousCurrent*0.25) {
+            
+           wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+           //-- cout<<"**** etat2 : ("<<k<<")"<<endl;
+         }
+         else { 
+           if(dCurrentStart < dPreviousCurrent*0.25) {
+             //-- cout<<"***** etat2 : ("<<k<<")"<<endl;
+             wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+           }
+           else { 
+             Standard_Real UMidUtest = 0.5*(UV1+Up)-Utest;
+             Standard_Real VMidVtest = 0.5*(UV2+Vp)-Vtest;         
+             Standard_Real dMiddleStart =  UMidUtest*UMidUtest + VMidVtest*VMidVtest;
+
+             if(dMiddleStart < dPreviousCurrent*0.5) { 
+               //-- cout<<"*********** etat2 : ("<<k<<")"<<endl;
+               wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+             }
+           }
+         }
+       }
+      }
+    }
+  }
 
   // crossing test on crossing points.
   
@@ -507,6 +600,165 @@ Standard_Boolean IntWalk_IWalking::TestArretPassage
   return Arrive;
 }
 
+Standard_Boolean IntWalk_IWalking::TestArretPassageTang
+  (const TColStd_SequenceOfReal& Umult,
+   const TColStd_SequenceOfReal& Vmult,
+   const math_Vector& UV, 
+   const Standard_Integer Index, 
+   Standard_Integer& Irang)
+{
+// Umult, Vmult : table of stop (or crossing) points on border, here
+//          only crossing points are taken into account.
+// UV     : the current point.
+// Index  : index of the start point in uvstart2 of the current line
+//          (this is an interior point).
+// Irang  : at output : gives the index of the point passing in uvstart1 or 0.
+//          consider that there is risk to cross only one crossing point.
+
+// test of stop for a CLOSED intersection line.
+// 1) test of crossing on all interior points.
+// 2) test of crossing on all crossing points.
+
+  Standard_Real Up, Vp, Scal;
+  Standard_Boolean Arrive = Standard_False;
+  Standard_Integer N, k, i;
+  Standard_Real Utest,Vtest;
+  Standard_Real tolu = tolerance(1);
+  Standard_Real tolv = tolerance(2);
+
+  
+  // tests of stop and of crossing on all interior points.
+
+  if (!reversed) {
+    previousPoint.ParametersOnS2(Up,Vp);
+  }
+  else {
+    previousPoint.ParametersOnS1(Up,Vp);
+  }
+
+  Standard_Real UV1=UV(1);
+  Standard_Real UV2=UV(2);
+
+
+  //-- Put everything in one box 0 1  x 0 1 
+  //-- actually it is necessary to carry out tests in 3D
+
+  Standard_Real deltau=UM-Um;
+  Standard_Real deltav=VM-Vm;
+
+  Up/=deltau; UV1/=deltau; 
+  Vp/=deltav; UV2/=deltav;
+
+  tolu/=deltau;
+  tolv/=deltav;
+
+  Standard_Real tolu2=tolu+tolu;
+  Standard_Real tolv2=tolv+tolv;
+
+  
+  Standard_Real dPreviousCurrent = (Up-UV1)*(Up-UV1)+(Vp-UV2)*(Vp-UV2);
+  for (k = 1; k < (int)wd3.size(); k++) { 
+    if (wd3[k].etat > 0) {
+      Utest = wd3[k].ustart;
+      Vtest = wd3[k].vstart;
+      
+      Utest/=deltau;
+      Vtest/=deltav;
+      
+      Standard_Real UV1mUtest=UV1-Utest;
+      Standard_Real UV2mVtest=UV2-Vtest;
+      if(   (UV1mUtest<tolu2 && UV1mUtest>-tolu2)
+        && (UV2mVtest<tolv2 && UV2mVtest>-tolv2)) { 
+       if(Index!=k) { 
+         //-- cout<<"* etat2 : ("<<k<<")"<<endl;
+         wd3[k].etat = -wd3[k].etat; //-- mark the point as a crossing point 
+       }
+       else {  //-- Index == k
+         //-- cout<<"* Arrive"<<endl;
+         Arrive=Standard_True;
+       }
+      }
+      else { 
+       Standard_Real UpmUtest = (Up-Utest);
+       Standard_Real VpmVtest = (Vp-Vtest);
+       Standard_Real dPreviousStart = (UpmUtest)*(UpmUtest)+(VpmVtest)*(VpmVtest);
+       Standard_Real dCurrentStart  = UV1mUtest * UV1mUtest + UV2mVtest * UV2mVtest;
+
+       Scal=(UpmUtest)*(UV1mUtest)+(VpmVtest)*(UV2mVtest);
+       if( (Abs(UpmUtest)<tolu && Abs(VpmVtest)<tolv)) { 
+         if(Index != k ) { 
+           //-- cout<<"** etat2 : ("<<k<<")"<<endl;
+           wd3[k].etat = -wd3[k].etat;
+         }
+       }
+       else if(Scal<0 && (dPreviousStart+dCurrentStart < dPreviousCurrent)) { 
+         if (Index == k ) { // on a boucle.
+           Arrive = Standard_True;
+           //-- cout<<"** Arrive  : k="<<k<<endl;
+         }
+         else {
+           //-- cout<<"*** etat2 : ("<<k<<")"<<endl;
+           wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+         }
+       }
+       else if(k!=Index) {
+         if(dPreviousStart < dPreviousCurrent*0.25) { 
+           wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+           //-- cout<<"**** etat2 : ("<<k<<")"<<endl;
+         }
+         else { 
+           if(dCurrentStart < dPreviousCurrent*0.25) {
+             //-- cout<<"***** etat2 : ("<<k<<")"<<endl;
+             wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+           }
+           else { 
+             Standard_Real UMidUtest = 0.5*(UV1+Up)-Utest;
+             Standard_Real VMidVtest = 0.5*(UV2+Vp)-Vtest;         
+             Standard_Real dMiddleStart =  UMidUtest*UMidUtest + VMidVtest*VMidVtest;
+
+             if(dMiddleStart < dPreviousCurrent*0.5) { 
+               //-- cout<<"*********** etat2 : ("<<k<<")"<<endl;
+               wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+             }
+           }
+         }
+       }
+      }
+    }
+  }
+
+  // crossing test on crossing points.
+  
+  Irang =0;
+  for (i = 1; i < (int)wd1.size(); i++) {
+    if (wd1[i].etat > 0 && wd1[i].etat < 11) { //test of crossing points 
+      Utest = wd1[i].ustart;
+      Vtest = wd1[i].vstart;
+      Utest/=deltau;
+      Vtest/=deltav;
+      
+      if (((Up-Utest) * (UV1-Utest) + (Vp-Vtest) * (UV2-Vtest) < 0) ||
+         (Abs(UV1-Utest) < tolu &&  Abs(UV2-Vtest) < tolv)) 
+       Irang = i;
+      else if (nbMultiplicities[i] > 0) {
+       N=0;
+       for (k = 1; k < i; k++) N = N + nbMultiplicities[k];
+       for (Standard_Integer j = N + 1; j <= N + nbMultiplicities[i]; j++) {
+         Standard_Real Umultj = Umult(j)/deltau;
+         Standard_Real Vmultj = Vmult(j)/deltav;         
+          if (((Up-Umultj)*(UV1-Umultj) +
+              (Vp-Vmultj)*(UV2-Vmultj) < 0) ||
+             (Abs(UV1-Umultj) < tolu &&
+              Abs(UV2-Vmultj) < tolv)) {
+           Irang=i;
+           break;
+          }
+       }
+      }
+    }    
+  }
+  return Arrive;
+}
 
 Standard_Boolean IntWalk_IWalking::TestArretAjout
   (TheIWFunction& sp,
index bb790e68e9e82d6dd69f8fd0a84886fb5d4ca96f..3008fa838cfce2cdea074493e42bcea6a1fe3f19 100644 (file)
@@ -3,8 +3,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
@@ -14,6 +14,7 @@
 
 #include <NCollection_IncAllocator.hxx>
 #include <NCollection_LocalArray.hxx>
+#include <Bnd_Box2d.hxx>
 
 
 // modified by NIZHNY-MKK  Thu Nov  2 15:07:26 2000.BEGIN
@@ -74,12 +75,15 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
   Handle(IntWalk_TheIWLine)  CurrentLine;    // line under construction
   Standard_Boolean Tgtend;
 
+  Standard_Real TolTang = 5.e-28;
+
   IntWalk_StatusDeflection Status, StatusPrecedent;
   
   Standard_Integer NbDivision; 
   // number of divisions of step for each section
 
   Standard_Integer StepSign;
+  Standard_Integer StepSignTangent;
   
   ThePointOfPath PathPnt;
 
@@ -105,16 +109,26 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
     // modified by NIZHNY-MKK  Fri Oct 27 12:33:37 2000.BEGIN
     if ((wd1[I].etat > 11) || ((wd1[I].etat < -11) && (movementdirectioninfo[I]!=0))) {
     // modified by NIZHNY-MKK  Fri Oct 27 12:33:43 2000.END
-      PathPnt = Pnts1.Value(I);     
+      PathPnt = Pnts1.Value(I);
+#ifdef DRAW
+      cout<<"PathPnt("<<I<<"):"<<endl;
+#endif
       CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
       CurrentLine->SetTangencyAtBegining(Standard_False);
       Tgtend = Standard_False;
       CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt);
+      PossibleCuspPoint = Standard_False;
+      IsTangentialIntersection = Standard_False;
       UVap(1) = wd1[I].ustart;
       UVap(2) = wd1[I].vstart;
       MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint);
       previousd3d = Func.Direction3d();
       previousd2d = Func.Direction2d();
+      //prevtg = Standard_False;
+      previousProj1 = Func.Projection1();
+      previousProj2 = Func.Projection2();
+      previousProj3 = Func.Projection3();
+      previousProj4 = Func.Projection4();
       CurrentLine->AddPoint(previousPoint);
       // modified by NIZHNY-MKK  Fri Oct 27 12:34:32 2000.BEGIN
       if(movementdirectioninfo[I] !=0) {
@@ -238,8 +252,18 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
              }
            }
            Status = TestDeflection(Func, Arrive, UVap, StatusPrecedent,
-                                   NbDivision,PasC,StepSign);
+                                   NbDivision,PasC,StepSign,CurrentLine->NbPoints());
            StatusPrecedent = Status;
+
+            if (Status == IntWalk_ArretSurPoint && !PossibleCuspPoint && Func.IsTangent())
+            {
+              ComputeDirOfTangentialIntersection(Func, StepSignTangent);
+              MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint);
+              previousProj1 = previousProj2 = previousProj3 = previousProj4 = 0.;
+             CurrentLine->AddPoint(previousPoint);
+              Status = IntWalk_OKtangent;
+            }
+            
            if (Status == IntWalk_PasTropGrand) {
              Arrive = Standard_False;
              ArretAjout = Standard_False;
@@ -324,18 +348,28 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
              }
            }
            else if (Status == IntWalk_ArretSurPoint) {
-             Arrive = Standard_True;                   
-             CurrentLine->AddStatusLast(Standard_False);
-             Tgtend = Standard_True;
+              Arrive = Standard_True;
+              CurrentLine->AddStatusLast(Standard_False);
+              Tgtend = Standard_True;
               MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol);
-             CurrentLine->AddPoint(Psol);
-             Rajout = Standard_True;
+              //jgv
+              if (PossibleCuspPoint &&
+                  Func.IsTangent() && Func.SquareTangentError() > TolTang)
+                FindExactTangentPoint(TolTang, Func, Psol);
+              /////
+              CurrentLine->AddPoint(Psol);
+              Rajout = Standard_True;
               seqAjout.Append(lines.Length() + 1);
            }
            else if (Status == IntWalk_OK) { 
               MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint);
              previousd3d = Func.Direction3d();
              previousd2d = Func.Direction2d();
+              //prevtg = Standard_False;
+              previousProj1 = Func.Projection1();
+              previousProj2 = Func.Projection2();
+              previousProj3 = Func.Projection3();
+              previousProj4 = Func.Projection4();
              CurrentLine->AddPoint(previousPoint);
            }                           
          }
@@ -434,6 +468,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
   } //end of all points
 }
 
+
 // modified by NIZHNY-MKK  Thu Nov  2 15:07:53 2000.BEGIN
 static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd,
                                                            const TColStd_SequenceOfReal& Umult,
index 6dfbf6cbb585597a87105853c562ccc83ce6c57f..569c24c85dc8e0f879b3441aba3a337022a7fa05 100644 (file)
@@ -3,8 +3,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
 // commercial license or contractual agreement.
 
 #include <NCollection_IncAllocator.hxx>
+#include <IntSurf_Quadric.hxx>
 
 void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
                                        const TColStd_SequenceOfReal& Vmult,
                                        const ThePOPIterator& Pnts1,
                                        const ThePOLIterator& Pnts2,
+                                       const ThePOLIterator& Pnts3,
                                        TheIWFunction& Func,
                                         Standard_Boolean& Rajout ) 
 // *********** Processing of closed line **********************
@@ -42,7 +44,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
 // ******************************************************************** 
 {
 
-  Standard_Integer I,N = 0;
+  Standard_Integer I, N = 0;
   Standard_Real aBornInf[2], aBornSup[2], aUVap[2];
   math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2);
   math_Vector Uvap(aUVap,1,2);// parameters of current approach
@@ -61,6 +63,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
   Standard_Boolean Tgtbeg,Tgtend;
 
   Standard_Integer StepSign;
+  Standard_Integer StepSignTangent;
   
   IntWalk_StatusDeflection Status,StatusPrecedent;
   Standard_Integer NbDivision ;   // number of divisions of step 
@@ -77,21 +80,33 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
   
   math_FunctionSetRoot Rsnld(Func,tolerance);
   Standard_Integer nbLoop = Pnts2.Length();
-  
+
   for (I = 1;I<=nbLoop;I++) {
     if (wd2[I].etat > 12) { // start point of closed line
       
       LoopPnt = Pnts2.Value(I);
-      previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt),reversed,
+      gp_Pnt thePoint = ThePointOfLoopTool::Value3d(LoopPnt);
+      previousPoint.SetValue(thePoint,reversed,
                             wd2[I].ustart,wd2[I].vstart);
       previousd3d = ThePointOfLoopTool::Direction3d(LoopPnt);
       previousd2d = ThePointOfLoopTool::Direction2d(LoopPnt);
-
+      
+      Standard_Real theU, theV;
+      ThePointOfLoopTool::Value2d(LoopPnt, theU, theV);
+      IntSurf_PntOn2S PrevPointFromFunc;
+      MakeWalkingPoint(11, theU, theV, Func, PrevPointFromFunc);
+      previousProj1 = Func.Projection1();
+      previousProj2 = Func.Projection2();
+      previousProj3 = Func.Projection3();
+      previousProj4 = Func.Projection4();
+      /////
       CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
       CurrentLine->AddPoint(previousPoint);
       CurrentLine->SetTangentVector(previousd3d,1);
       Tgtbeg = Standard_False;
       Tgtend = Standard_False;
+      PossibleCuspPoint = Standard_False;
+      IsTangentialIntersection = Standard_False;
       Uvap(1) = wd2[I].ustart;
       Uvap(2) = wd2[I].vstart;
 
@@ -191,7 +206,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
              }
            }
            Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent,
-                                   NbDivision,PasC,StepSign);
+                                   NbDivision,PasC,StepSign,CurrentLine->NbPoints());
            StatusPrecedent = Status; 
            if (Status == IntWalk_PasTropGrand) {// division of the step
              Arrive = Standard_False;
@@ -273,6 +288,15 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
                 AddPointInCurrentLine(N,PathPnt,CurrentLine);
              }
            }
+            else if (Status == IntWalk_ArretSurPoint &&
+                     !PossibleCuspPoint && Func.IsTangent())
+            {
+              ComputeDirOfTangentialIntersection(Func, StepSignTangent);
+              MakeWalkingPoint(2, Uvap(1), Uvap(2), Func, previousPoint);
+              previousProj1 = previousProj2 = previousProj3 = previousProj4 = 0.;
+             CurrentLine->AddPoint(previousPoint);
+              Status = IntWalk_OKtangent;
+            }
            else if (Status == IntWalk_ArretSurPoint) {
              if (wd2[I].etat >12) { //line should become open
                wd2[I].etat = 12; //declare it open
@@ -310,6 +334,10 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
              previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
              previousd3d = Func.Direction3d();
              previousd2d = Func.Direction2d();
+              previousProj1 = Func.Projection1();
+              previousProj2 = Func.Projection2();
+              previousProj3 = Func.Projection3();
+              previousProj4 = Func.Projection4();
              CurrentLine->AddPoint(previousPoint);
            }
          }
@@ -339,6 +367,288 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
       }
     } //end of processing of start point
   } //end of all start points
+
+  //Process inner tangent points
+  IsTangentialIntersection = Standard_True;
+  StepSign = 1;
+  StepSignTangent = 1;
+  Standard_Integer nbTang = Pnts3.Length();
+  for (I = 1; I <= nbTang; I++) {
+    if (wd3[I].etat > 12) { // start point of closed line
+      
+      LoopPnt = Pnts3.Value(I);
+      gp_Pnt thePoint = ThePointOfLoopTool::Value3d(LoopPnt);
+      previousPoint.SetValue(thePoint,reversed,
+                            wd3[I].ustart, wd3[I].vstart);
+      Standard_Real theU, theV;
+      ThePointOfLoopTool::Value2d(LoopPnt, theU, theV);
+      IntSurf_PntOn2S PrevPointFromFunc;
+      MakeWalkingPoint(11, theU, theV, Func, PrevPointFromFunc);
+      /////
+      ComputeDirOfTangentialIntersection(Func, StepSignTangent);
+      //here <previousd3d> and <previousd2d> are defined
+      
+      CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
+      CurrentLine->AddPoint(previousPoint);
+      CurrentLine->SetTangentVector(previousd3d,1);
+      Tgtbeg = Standard_False;
+      Tgtend = Standard_False;
+      PossibleCuspPoint = Standard_False;
+      Uvap(1) = wd3[I].ustart;
+      Uvap(2) = wd3[I].vstart;
+
+      StepSign = 1;
+
+      // first step of advancement
+
+      Standard_Real d2dx = Abs(previousd2d.X()); 
+      Standard_Real d2dy = Abs(previousd2d.Y()); 
+      if (d2dx < tolerance(1)) {
+       PasC = pas * (VM-Vm)/d2dy;
+      }
+      else if (d2dy < tolerance(2)) {
+       PasC = pas * (UM-Um)/d2dx;
+      }
+      else {
+       PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
+      }
+
+      PasSav = PasC;
+
+      Arrive = Standard_False;
+      ArretAjout = Standard_False;
+      NbDivision = 0;
+      StatusPrecedent = IntWalk_OK;
+      while (!Arrive) {  // as no test of stop is passed
+       Cadre=Cadrage(BornInf,BornSup,Uvap,PasC, StepSign);  // border?
+#ifdef CHRONO
+       Chronrsnld.Start();
+#endif
+
+       Rsnld.Perform(Func,Uvap,BornInf,BornSup);
+
+#ifdef CHRONO
+       Chronrsnld.Stop();
+#endif
+
+       if (Cadre) { // update of limits.
+         BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM;
+       }
+       if (Rsnld.IsDone()) {
+         if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance
+           PasC = PasC/2.;
+           PasCu = Abs(PasC*previousd2d.X());
+           PasCv = Abs(PasC*previousd2d.Y());
+
+           if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
+             if (CurrentLine->NbPoints()==1) break;
+             Arrive = Standard_True;
+             CurrentLine->AddStatusFirstLast(Standard_False,
+                                             Standard_False,Standard_False);
+             Rajout = Standard_True;
+              seqAjout.Append(lines.Length()+1);
+             Tgtend = Standard_True;
+           }
+         }
+         else { // there is a solution
+           Rsnld.Root(Uvap);
+           Arrive = TestArretPassageTang(Umult,Vmult,Uvap,I,Ipass);
+           if (Arrive) {//reset proper parameter to test the arrow.
+             Psol = CurrentLine->Value(1);
+             if (!reversed) {
+               Psol.ParametersOnS2(Uvap(1),Uvap(2));
+             }
+             else {
+               Psol.ParametersOnS1(Uvap(1),Uvap(2));
+             }
+              Cadre = Standard_False; 
+             //in case if there is a frame and arrival at the same time
+           }
+           else { // modif jag 940615
+
+             if (Rajout) {    // test on added points
+               ArretAjout = TestArretAjout(Func,Uvap,N,Psol);
+               if (ArretAjout) {
+                 if (N >0) {
+                   Tgtend = lines.Value(N)->IsTangentAtEnd();
+                   N = -N;
+                 }
+                 else {
+                   Tgtend = lines.Value(-N)->IsTangentAtBegining();
+                 }
+                 Arrive = (wd3[I].etat == 12);
+               }
+             }
+
+             if (!ArretAjout&& Cadre) {  // test on already marked points
+               if (CurrentLine->NbPoints() == 1)  break; // cancel the line
+               TestArretCadre(Umult,Vmult,CurrentLine,Func,Uvap,N);
+//             if (N==0) {
+               if (N <= 0) { // jag 941017
+                 MakeWalkingPoint(2,Uvap(1),Uvap(2),Func,Psol);
+                 Tgtend = Func.IsTangent(); // jag 940616
+                 N = -N;
+               }
+               Arrive = (wd3[I].etat == 12); // the line is open
+             }
+           }
+           Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent,
+                                   NbDivision,PasC,StepSign,CurrentLine->NbPoints());
+           StatusPrecedent = Status; 
+           if (Status == IntWalk_PasTropGrand) {// division of the step
+             Arrive = Standard_False;
+             ArretAjout = Standard_False;
+             Tgtend = Standard_False; // jag 940616
+             if (!reversed) {
+               previousPoint.ParametersOnS2(Uvap(1),Uvap(2));
+             }
+             else {
+               previousPoint.ParametersOnS1(Uvap(1),Uvap(2));
+             }
+           }
+           else if (ArretAjout || Cadre) {
+
+             if (Arrive) { // line s is open
+               CurrentLine->AddStatusLast(Standard_False);
+               if (Status != IntWalk_ArretSurPointPrecedent) {
+                 CurrentLine->AddPoint(Psol);                      
+               }
+               if (Cadre && N==0) {
+                 Rajout = Standard_True;
+                 seqAjout.Append(lines.Length()+1);
+               }
+                
+             }
+             else { // open
+               wd3[I].etat = 12; // declare it open
+               Tgtbeg = Tgtend;
+               Tgtend = Standard_False;
+               ArretAjout = Standard_False;
+               StepSign = -1;
+                StatusPrecedent = IntWalk_OK;
+               PasC = PasSav;
+               if (Status == IntWalk_ArretSurPointPrecedent) {
+                 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
+               }
+               else {
+                 OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine);
+               }
+               if (Cadre && N==0) {
+                 Rajout = Standard_True;
+                 seqAjout.Append(-lines.Length()-1);
+               }
+             }
+           }
+
+           else if ( Status == IntWalk_ArretSurPointPrecedent) {
+             if (CurrentLine->NbPoints() == 1) { //cancel the line
+               Arrive = Standard_False;
+               break;
+             }
+             if (wd3[I].etat >12) { //the line should become open
+               wd3[I].etat = 12; //declare it open
+               ArretAjout = Standard_False;
+               OpenLine(0,Psol,Pnts1,Func,CurrentLine);
+               StepSign = -1;
+                StatusPrecedent = IntWalk_OK;
+               Arrive = Standard_False;
+               PasC = PasSav;
+               Rajout = Standard_True;
+                seqAjout.Append(-lines.Length()-1);
+             }
+             else { // line s is open                 
+               Arrive = Standard_True;
+               CurrentLine->AddStatusLast(Standard_False);
+               Rajout = Standard_True;
+                seqAjout.Append(lines.Length()+1);
+             } 
+           }
+           else if (Arrive)  {
+             if (wd3[I].etat > 12) {  //line closed good case
+               CurrentLine->AddStatusFirstLast(Standard_True,
+                                               Standard_False,Standard_False);
+               CurrentLine->AddPoint(CurrentLine->Value(1));              
+             }
+             else if (N >0) { //point of stop given at input 
+               PathPnt = Pnts1.Value(N);
+               CurrentLine->AddStatusLast(Standard_True,N,PathPnt);
+                AddPointInCurrentLine(N,PathPnt,CurrentLine);
+             }
+           }
+            else if (Status == IntWalk_ArretSurPoint &&
+                     !PossibleCuspPoint && Func.IsTangent())
+            {
+              ComputeDirOfTangentialIntersection(Func, StepSignTangent);
+              MakeWalkingPoint(2, Uvap(1), Uvap(2), Func, previousPoint);
+             CurrentLine->AddPoint(previousPoint);
+              Status = IntWalk_OKtangent;
+            }
+           else if (Status == IntWalk_ArretSurPoint) {
+             if (wd3[I].etat >12) { //line should become open
+               wd3[I].etat = 12; //declare it open
+               Tgtbeg = Standard_True;
+               Tgtend = Standard_False;
+                N= -lines.Length()-1;
+                Psol.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
+               OpenLine(N,Psol,Pnts1,Func,CurrentLine);
+               StepSign = -1;
+               Rajout = Standard_True;
+                seqAjout.Append(N);
+                StatusPrecedent = IntWalk_OK;
+               Arrive = Standard_False;
+               PasC = PasSav;  
+             }
+             else { 
+               Arrive = Standard_True;                   
+               if (Ipass!=0) { //point of passage, point of stop
+                 PathPnt = Pnts1.Value(Ipass);
+                 CurrentLine->AddStatusLast(Standard_True,Ipass,PathPnt);
+                  AddPointInCurrentLine(Ipass,PathPnt,CurrentLine);
+               }
+               else {
+                  CurrentLine->AddStatusLast(Standard_False);
+                 IntSurf_PntOn2S newP;
+                 newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
+                  CurrentLine->AddPoint(newP);
+                 Rajout = Standard_True;
+                 seqAjout.Append(lines.Length()+1);
+                }
+             }
+           }
+           else if (Status == IntWalk_OK) { 
+             if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass);
+             previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
+             //previousd3d = Func.Direction3d();
+             //previousd2d = Func.Direction2d();
+             CurrentLine->AddPoint(previousPoint);
+           }
+         }
+       }
+       else { //no numerical solution NotDone
+         PasC = PasC/2.;
+         PasCu = Abs(PasC*previousd2d.X());
+         PasCv = Abs(PasC*previousd2d.Y());
+
+         if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
+            if (CurrentLine->NbPoints() == 1)  break; // cancel the line
+           Arrive = Standard_True;
+           CurrentLine->AddStatusFirstLast(Standard_False,Standard_False,
+                                           Standard_False);
+           Tgtend = Standard_True;
+           Rajout = Standard_True;
+           seqAjout.Append(lines.Length()+1);
+         }  
+       }
+      }// end of started line 
+      if (Arrive) {
+       CurrentLine->SetTangencyAtBegining(Tgtbeg);
+       CurrentLine->SetTangencyAtEnd(Tgtend);
+       
+       lines.Append(CurrentLine);
+       wd3[I].etat = -wd3[I].etat; //mark point as processed
+      }
+    } //end of processing of tangent point
+  } //end of all tangent points
 }
 
 
index fa7e62e888de7a53861a5b8f2d38e5fa2d848a25..cdf7297801a6d3fc09f2b034d77b75020b48f02a 100644 (file)
@@ -3,8 +3,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
@@ -20,6 +20,13 @@ namespace {
                                                    // because the angle is too great in 2d (U4)
 }
 
+static Standard_Real RealSign(const Standard_Real aValue)
+{
+  if (aValue >= 0.)
+    return 1.;
+  else return -1.;
+}
+
 IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection
   (TheIWFunction& sp,
    const Standard_Boolean Finished,
@@ -27,7 +34,8 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection
    const IntWalk_StatusDeflection StatusPrecedent,
    Standard_Integer& NbDivision,
    Standard_Real& Step,
-   const Standard_Integer StepSign)
+   const Standard_Integer StepSign,
+   const Standard_Integer CurNbPoints)
 {
   // Check the step of advancement, AND recalculate this step :
   //
@@ -117,9 +125,16 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection
     return IntWalk_ArretSurPointPrecedent; // leave as step back  
                                            // with confused point
 
-
-  if (sp.IsTangent()) 
-    return IntWalk_ArretSurPoint;       
+  if (IsTangentialIntersection)
+  {
+    if (sp.IsTangentSmooth()) 
+      return IntWalk_ArretSurPoint;       
+  }
+  else
+  {
+    if (sp.IsTangent()) 
+      return IntWalk_ArretSurPoint;
+  }
 
 //if during routing one has subdivided more than  MaxDivision for each
 //previous step, bug on the square; do nothing (experience U4)
@@ -168,6 +183,34 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection
        Status = IntWalk_PasTropGrand;
       return Status;
     }
+    //jgv: detect possible cusp points
+    //point is suspicious to be a cusp point
+    //if there are 2 or more changes of sign
+    if (!IsTangentialIntersection && CurNbPoints > 1)
+    {
+      Standard_Real ChangeSign [5];
+      ChangeSign[1] = RealSign(previousProj1) * RealSign(sp.Projection1());
+      ChangeSign[2] = RealSign(previousProj2) * RealSign(sp.Projection2());
+      ChangeSign[3] = RealSign(previousProj3) * RealSign(sp.Projection3());
+      ChangeSign[4] = RealSign(previousProj4) * RealSign(sp.Projection4());
+      Standard_Real SumChange = ChangeSign[1]+ChangeSign[2]+ChangeSign[3]+ChangeSign[4];
+      if (SumChange <= 0 || //at least 2 changes of sign
+          (StatusPrecedent == IntWalk_PasTropGrand && SumChange <= 2)) //1 change of sign
+      {
+        PossibleCuspPoint = Standard_True;
+        if (SumChange <= 0)
+          MakeWalkingPoint(1, UV(1), UV(2), sp, PointAfterPossibleCuspPoint);
+        Step  = Step / 2.;
+        StepU = Abs(Step*previousd2d.X());
+        StepV = Abs(Step*previousd2d.Y());
+        if (StepU < tolerance(1) && StepV < tolerance(2))
+          Status = IntWalk_ArretSurPointPrecedent;
+        else 
+          Status = IntWalk_PasTropGrand;
+        return Status;
+      }
+    }
+    //////////////////////////////////
   }
 
   if (!Finished) {
index cbf903ac24f8af57c7e96ef7f9a7cc590fb413b6..a9647766aa68cc0ac3d65f54197ee67d8693608d 100644 (file)
@@ -3,8 +3,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <Geom2d_Line.hxx>
+#include <GCE2d_MakeLine.hxx>
+
+
 #ifndef DEB
 #define No_Standard_RangeError
 #define No_Standard_OutOfRange
@@ -39,7 +43,6 @@ void IntWalk_IWalking::MakeWalkingPoint
          IntSurf_PntOn2S& Psol )
 
 {
-
 // Case == 1      : make a WalkinkPoint.
 // Case == 2      : make a WalkinkPoint.
 //                  The computation of the tangency on is done  
@@ -65,11 +68,201 @@ void IntWalk_IWalking::MakeWalkingPoint
   else {
     Standard_ConstructionError::Raise();
   }
+}
+
+void IntWalk_IWalking::ComputeDirOfTangentialIntersection(TheIWFunction& sp,
+                                                          Standard_Integer& StepSignTangent)
+{
+  gp_Vec Pu, Pv, Puu, Puv, Pvv;
+  gp_Vec Iu, Iv, Iuu, Iuv, Ivv;
+  gp_Dir NormalP, NormalI;
+
+  sp.DerivativesAndNormalOnPSurf(Pu, Pv, NormalP, Puu, Pvv, Puv);
+  sp.DerivativesAndNormalOnISurf(Iu, Iv, NormalI, Iuu, Ivv, Iuv);
+
+  Standard_Real Lp, Mp, Np, Li, Mi, Ni; //second fundamental form coefficients
+  Lp = Puu * NormalP;
+  Mp = Puv * NormalP;
+  Np = Pvv * NormalP;
+  Li = Iuu * NormalI;
+  Mi = Iuv * NormalI;
+  Ni = Ivv * NormalI;
+
+  gp_Vec Normal;
+  if (NormalP * NormalI < 0.)
+    NormalI.Reverse();
+  Normal.SetXYZ(0.5*(NormalP.XYZ() + NormalI.XYZ()));
+  Normal.Normalize();
+
+  Standard_Real A11, A12, A21, A22;
+  Standard_Real NormIdotNorm = (Iu ^ Iv) * Normal;
+  A11 = ((Pu ^ Iv) * Normal) / NormIdotNorm;
+  A12 = ((Pv ^ Iv) * Normal) / NormIdotNorm;
+  A21 = ((Iu ^ Pu) * Normal) / NormIdotNorm;
+  A22 = ((Iu ^ Pv) * Normal) / NormIdotNorm;
 
+  Standard_Real B11, B12, B22;
+  B11 = A11*A11*Li + 2*A11*A21*Mi + A21*A21*Ni - Lp;
+  B12 = A11*A12*Li + (A11*A22 + A21*A12)*Mi + A21*A22*Ni - Mp;
+  B22 = A12*A12*Li + 2*A12*A22*Mi + A22*A22*Ni - Np;
 
+  Standard_Real Discriminant = B12*B12 - B11*B22;
+#ifdef DRAW
+  cout<<"Discriminant = "<<Discriminant<<endl<<endl;
+#endif
+
+  const Standard_Real TolDiscr = 1.e-8;
+  const Standard_Real TolB = 1.e-5;
+  if (Abs(Discriminant) < TolDiscr)
+  {
+    if (Abs(B11) <= TolB && Abs(B22) <= TolB)
+    {
+#ifdef DRAW
+      cout<<"Possible branching"<<endl<<endl;
+#endif
+    }
+    else
+    {
+      gp_Vec NewPreviousD3d;
+      gp_Dir2d NewPreviousD2d;
+      if (Abs(B11) > TolB)
+      {
+        Standard_Real CoefPu = -B12/B11;
+        NewPreviousD3d = CoefPu*Pu + Pv;
+        NewPreviousD3d.Normalize();
+        NewPreviousD2d = gp_Dir2d(CoefPu, 1.);
+      }
+      else
+      {
+        Standard_Real CoefPv = -B12/B22;
+        NewPreviousD3d = Pu + CoefPv*Pv;
+        NewPreviousD3d.Normalize();
+        NewPreviousD2d = gp_Dir2d(1., CoefPv);
+      }
+      
+      if (!IsTangentialIntersection)
+      {
+        IsTangentialIntersection = Standard_True;
+        if (NewPreviousD3d * previousd3d < 0)
+          StepSignTangent = -1;
+        else
+          StepSignTangent = 1;
+      }
+      previousd3d = StepSignTangent * NewPreviousD3d;
+      previousd2d = StepSignTangent * NewPreviousD2d;
+    }
+  }
 }
 
+void IntWalk_IWalking::FindExactTangentPoint(const Standard_Real TolTang,
+                                             TheIWFunction& sp,
+                                             IntSurf_PntOn2S& Psol)
+                                             
+{
+  IntSurf_PntOn2S TangentPoint = Psol;
+
+  IntSurf_PntOn2S Pfirst, Plast;
+
+  Standard_Real newU, newV;
+  IntSurf_PntOn2S newPoint;
+
+  Standard_Real MinOffset = Sqrt(tolerance(1)*tolerance(1) + tolerance(2)*tolerance(2));
+
+  gp_Pnt2d prevP2d = previousPoint.ValueOnSurface(reversed);
+  gp_Pnt2d TangP2d = TangentPoint.ValueOnSurface(reversed);
+  gp_Pnt2d EndP2d = PointAfterPossibleCuspPoint.ValueOnSurface(reversed);
+  Handle(Geom2d_Line) Line1 = GCE2d_MakeLine(TangP2d, prevP2d);
+  Handle(Geom2d_Line) Line2 = GCE2d_MakeLine(TangP2d, EndP2d);
 
+  Standard_Real Dist1 = prevP2d.Distance(TangP2d);
+  Standard_Real Dist2 = TangP2d.Distance(EndP2d);
+  Standard_Real Dist = (Dist1 < Dist2)? Dist1 : Dist2;
+  Standard_Real Offset = 0.01*Dist;
+  if (Offset < MinOffset)
+    Offset = MinOffset;
+
+  Standard_Real TangentError = sp.SquareTangentError();
+
+  gp_Pnt2d DeltaUV1 = Line1->Value(Offset);
+  gp_Pnt2d DeltaUV2 = Line2->Value(Offset);
+  IntSurf_PntOn2S DeltaPnt1, DeltaPnt2;
+
+  MakeWalkingPoint(11, DeltaUV1.X(), DeltaUV1.Y(), sp, DeltaPnt1);
+  Standard_Boolean IsTangentPoint = sp.IsTangent();
+  Standard_Real DeltaError1 = sp.SquareTangentError();
+  MakeWalkingPoint(11, DeltaUV2.X(), DeltaUV2.Y(), sp, DeltaPnt2);
+  IsTangentPoint = sp.IsTangent();
+  Standard_Real DeltaError2 = sp.SquareTangentError();
+
+  if (DeltaError1 <= TangentError && TangentError <= DeltaError2)
+  {
+    Pfirst = previousPoint;
+    Plast  = TangentPoint;
+    Dist = Dist1;
+  }
+  else if (DeltaError1 >= TangentError && TangentError >= DeltaError2)
+  {
+    Pfirst = TangentPoint;
+    Plast  = PointAfterPossibleCuspPoint;
+    Dist = Dist2;
+  }
+  else
+  {
+    Pfirst = DeltaPnt1;
+    Plast  = DeltaPnt2;
+    Dist = DeltaUV1.Distance(DeltaUV2);
+  }
+
+  Standard_Real newError;
+  for (;;)
+  {
+    Standard_Real Ufirst, Vfirst, Ulast, Vlast;
+    Pfirst.ParametersOnSurface(reversed, Ufirst, Vfirst);
+    Plast.ParametersOnSurface(reversed, Ulast, Vlast);
+    
+    newU = 0.5*(Ufirst + Ulast);
+    newV = 0.5*(Vfirst + Vlast);
+
+    if (Abs(newU - Ufirst) < tolerance(1) &&
+        Abs(newV - Vfirst) < tolerance(2))
+      break;
+    
+    MakeWalkingPoint(11, newU, newV, sp, newPoint);
+    
+    IsTangentPoint = sp.IsTangent();
+    newError = sp.SquareTangentError();
+    if (newError <= TolTang)
+      break;
+
+    gp_Pnt2d newP2d(newU, newV);
+    Handle(Geom2d_Line) newLine = GCE2d_MakeLine(newP2d, Plast.ValueOnSurface(reversed));
+    Dist *= 0.5;
+    Offset = 0.01*Dist;
+
+    DeltaUV1 = newLine->Value(-Offset);
+    DeltaUV2 = newLine->Value(Offset);
+
+    MakeWalkingPoint(11, DeltaUV1.X(), DeltaUV1.Y(), sp, DeltaPnt1);
+    IsTangentPoint = sp.IsTangent();
+    DeltaError1 = sp.SquareTangentError();
+    MakeWalkingPoint(11, DeltaUV2.X(), DeltaUV2.Y(), sp, DeltaPnt2);
+    IsTangentPoint = sp.IsTangent();
+    DeltaError2 = sp.SquareTangentError();
+
+    if (DeltaError1 <= newError && newError <= DeltaError2)
+      Plast = newPoint;
+    else if (DeltaError1 >= newError && newError >= DeltaError2)
+      Pfirst = newPoint;
+    else
+    {
+      Pfirst = DeltaPnt1;
+      Plast  = DeltaPnt2;
+      Dist = DeltaUV1.Distance(DeltaUV2);
+    }
+  }
+
+  Psol = newPoint;
+}
 
 void IntWalk_IWalking::OpenLine(const Standard_Integer N,
                                 const IntSurf_PntOn2S& Psol,
@@ -94,8 +287,16 @@ void IntWalk_IWalking::OpenLine(const Standard_Integer N,
     previousPoint.ParametersOnS1(UV(1),UV(2));
   }
   sp.Values(UV, FF, DD);
-  previousd3d = sp.Direction3d();
-  previousd2d = sp.Direction2d();
+  if (sp.IsTangent())
+  {
+    Standard_Integer theSign = 1;
+    ComputeDirOfTangentialIntersection(sp, theSign);
+  }
+  else
+  {
+    previousd3d = sp.Direction3d();
+    previousd2d = sp.Direction2d();
+  }
 
   if (N>0) { //departure point given at input
     PathPnt = Pnts1.Value(N);