0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / CSLib / CSLib.cxx
old mode 100755 (executable)
new mode 100644 (file)
index e61263e..4217b94
@@ -1,20 +1,31 @@
-// File:       CSLib.cxx
-// Created:    Mon Sep 9 11:19:10 1991
-// Author:     Michel Chauvat
-
+// Created on: 1991-09-09
+// Created by: Michel Chauvat
+// Copyright (c) 1991-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// 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
+// 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 <CSLib.ixx>
 
+#include <CSLib.hxx>
+#include <CSLib_NormalPolyDef.hxx>
 #include <gp.hxx>
+#include <gp_Dir.hxx>
 #include <gp_Vec.hxx>
+#include <math_FunctionRoots.hxx>
 #include <PLib.hxx>
 #include <Precision.hxx>
 #include <TColgp_Array2OfVec.hxx>
-#include <TColStd_Array2OfReal.hxx>
 #include <TColStd_Array1OfReal.hxx>
-#include <math_FunctionRoots.hxx>
-#include <CSLib_NormalPolyDef.hxx>
-
+#include <TColStd_Array2OfReal.hxx>
 
 #define D1uD1vRatioIsNull   CSLib_D1uD1vRatioIsNull 
 #define D1vD1uRatioIsNull   CSLib_D1vD1uRatioIsNull
@@ -39,7 +50,7 @@ void CSLib::Normal (
 const gp_Vec&        D1U, 
 const gp_Vec&        D1V,
 const Standard_Real        SinTol, 
-CSLib_DerivativeStatus& Status, 
+CSLib_DerivativeStatus& theStatus,
 gp_Dir&              Normal
 ) {
 
@@ -50,18 +61,18 @@ gp_Dir&              Normal
   gp_Vec D1UvD1V = D1U.Crossed(D1V);
 
   if (D1UMag <= gp::Resolution() && D1VMag <= gp::Resolution()) {
-     Status = D1IsNull;
+     theStatus = D1IsNull;
   }
-  else if (D1UMag <= gp::Resolution())           Status = D1uIsNull;
-  else if (D1VMag <= gp::Resolution())           Status = D1vIsNull;
-//  else if ((D1VMag / D1UMag) <= RealEpsilon())   Status = D1vD1uRatioIsNull;
-//  else if ((D1UMag / D1VMag) <= RealEpsilon())   Status = D1uD1vRatioIsNull;
+  else if (D1UMag <= gp::Resolution())           theStatus = D1uIsNull;
+  else if (D1VMag <= gp::Resolution())           theStatus = D1vIsNull;
+//  else if ((D1VMag / D1UMag) <= RealEpsilon())   theStatus = D1vD1uRatioIsNull;
+//  else if ((D1UMag / D1VMag) <= RealEpsilon())   theStatus = D1uD1vRatioIsNull;
   else  {
     Standard_Real Sin2 = 
     D1UvD1V.SquareMagnitude() / (D1UMag * D1VMag);
     
-    if (Sin2 < (SinTol * SinTol))  { Status = D1uIsParallelD1v; }
-    else { Normal = gp_Dir (D1UvD1V);   Status = Done; }
+    if (Sin2 < (SinTol * SinTol))  { theStatus = D1uIsParallelD1v; }
+    else { Normal = gp_Dir (D1UvD1V);   theStatus = Done; }
   }
 }
 
@@ -74,7 +85,7 @@ const gp_Vec&    D2V,
 const gp_Vec&    DUV,
 const Standard_Real    SinTol,
 Standard_Boolean&      Done,
-CSLib_NormalStatus& Status,
+CSLib_NormalStatus& theStatus,
 gp_Dir&          Normal
 ) {
 
@@ -96,25 +107,25 @@ gp_Dir&          Normal
 
 
   if (LD1Nu <= RealEpsilon() && LD1Nv <= RealEpsilon())  { 
-      Status = D1NIsNull;
+      theStatus = D1NIsNull;
       Done = Standard_False;
   }
   else if (LD1Nu < RealEpsilon()) {
-      Status = D1NuIsNull;
+      theStatus = D1NuIsNull;
       Done = Standard_True;
       Normal = gp_Dir (D1Nv);
   }
   else if (LD1Nv < RealEpsilon()) {
-      Status = D1NvIsNull;
+      theStatus = D1NvIsNull;
       Done = Standard_True;
       Normal = gp_Dir (D1Nu);
   }
   else if ((LD1Nv / LD1Nu) <= RealEpsilon()) { 
-      Status = D1NvNuRatioIsNull;
+      theStatus = D1NvNuRatioIsNull;
       Done = Standard_False;
   }
   else if ((LD1Nu / LD1Nv) <= RealEpsilon()) { 
-      Status = D1NuNvRatioIsNull; 
+      theStatus = D1NuNvRatioIsNull;
       Done = Standard_False;
   }
   else {
@@ -122,12 +133,12 @@ gp_Dir&          Normal
     Standard_Real Sin2 = D1NCross.SquareMagnitude() / (LD1Nu * LD1Nv);
 
     if (Sin2 < (SinTol * SinTol))  { 
-      Status = D1NuIsParallelD1Nv;
+      theStatus = D1NuIsParallelD1Nv;
       Done = Standard_True;
       Normal = gp_Dir (D1Nu);
     }    
     else { 
-      Status = InfinityOfSolutions;
+      theStatus = InfinityOfSolutions;
       Done = Standard_False;
     }
   }
@@ -138,7 +149,7 @@ void CSLib::Normal (
 const gp_Vec&        D1U, 
 const gp_Vec&        D1V,
 const Standard_Real        MagTol, 
-CSLib_NormalStatus& Status, 
+CSLib_NormalStatus& theStatus,
 gp_Dir&              Normal
 ) {
 // Function: Calculate the normal from tangents by u and by v.
@@ -150,11 +161,17 @@ gp_Dir&              Normal
 
   if (NMag <= MagTol || D1UMag <= MagTol || D1VMag <= MagTol ) {
 
-     Status = Singular;
+     theStatus = Singular;
 //     if (D1UMag <= MagTol || D1VMag <= MagTol && NMag > MagTol) MagTol = 2* NMag;
 }
   else
-     { Normal = gp_Dir (D1UvD1V);   Status = Defined; }
+  {
+    // Firstly normalize tangent vectors D1U and D1V (this method is more stable)
+    gp_Dir aD1U(D1U);
+    gp_Dir aD1V(D1V);
+    Normal = gp_Dir(aD1U.Crossed(aD1V));
+    theStatus = Defined;
+  }
   
 
 }
@@ -169,7 +186,7 @@ void CSLib::Normal(const Standard_Integer MaxOrder,
                    const Standard_Real Umax,
                    const Standard_Real Vmin,
                    const Standard_Real Vmax,
-                   CSLib_NormalStatus& Status,
+                   CSLib_NormalStatus& theStatus,
                    gp_Dir& Normal, 
                    Standard_Integer& OrderU, 
                    Standard_Integer& OrderV)
@@ -177,7 +194,7 @@ void CSLib::Normal(const Standard_Integer MaxOrder,
 //  Standard_Integer i,l,Order=-1;
   Standard_Integer i=0,Order=-1;
   Standard_Boolean Trouve=Standard_False;
-//  Status = Singular;
+//  theStatus = Singular;
   Standard_Real Norme;
   gp_Vec D;
   //Find k0 such that all derivatives N=dS/du ^ dS/dv are null
@@ -202,7 +219,7 @@ void CSLib::Normal(const Standard_Integer MaxOrder,
   {
      if(Order == 0) 
      {
-         Status = Defined;
+         theStatus = Defined;
          Normal=D.Normalized();
      }
      else
@@ -286,7 +303,7 @@ void CSLib::Normal(const Standard_Integer MaxOrder,
            sup = M_PI;
         }
         Standard_Boolean CS=0;
-        Standard_Real Vprec=0,Vsuiv;
+        Standard_Real Vprec = 0., Vsuiv = 0.;
         //Creation of the polynom
         CSLib_NormalPolyDef  Poly(Order,Ratio);
         //Find zeros of SAPS
@@ -294,9 +311,7 @@ void CSLib::Normal(const Standard_Integer MaxOrder,
                                   Precision::Confusion(),
                                    Precision::Confusion());
         //If there are zeros
-        if(FindRoots.IsDone())
-        {
-           if(FindRoots.NbSolutions()>0)
+        if (FindRoots.IsDone() && FindRoots.NbSolutions() > 0)
            {
                //ranking by increasing order of roots of SAPS in Sol0
 
@@ -306,13 +321,13 @@ void CSLib::Normal(const Standard_Integer MaxOrder,
                while(n<=FindRoots.NbSolutions())
                {
                  Standard_Real ASOL=FindRoots.Value(n);
-                 Standard_Integer i=n-1;
-                 while((i>=1) && (Sol0(i)> ASOL))
+                 Standard_Integer j=n-1;
+                 while((j>=1) && (Sol0(j)> ASOL))
                   {
-                    Sol0(i+1)=Sol0(i);
-                    i--;
+                    Sol0(j+1)=Sol0(j);
+                    j--;
                  }
-                 Sol0(i+1)=ASOL;
+                 Sol0(j+1)=ASOL;
                  n++;
                }//end while(n
                //Add limits of the domains 
@@ -340,14 +355,14 @@ void CSLib::Normal(const Standard_Integer MaxOrder,
                    }
                }
             }
-            else
+         else
             {
                //SAPS has no root, so forcedly do not change the sign
                CS=Standard_False;
                Poly.Value(inf,Vsuiv);
             }
-            //fin if(MFR.NbSolutions()>0)
-         }//fin if(MFR>IsDone())
+         //fin if(MFR.IsDone() && MFR.NbSolutions()>0)
+
          if(CS)
          //Polynom changes the sign
             SP=0;
@@ -358,16 +373,16 @@ void CSLib::Normal(const Standard_Integer MaxOrder,
                  //Polynom is always negative
                  SP=-1;
          if(SP==0)
-             Status = InfinityOfSolutions;
+             theStatus = InfinityOfSolutions;
          else
          {
-            Status = Defined;
+            theStatus = Defined;
             Normal=SP*Vk0.Normalized();
          }
        }
        else 
        {
-         Status = Defined;
+         theStatus = Defined;
          Normal=D.Normalized();
        }
     }