0025003: Selection of a face fails if sensitive triangulation is computed with interi...
[occt.git] / src / Select3D / Select3D_SensitiveTriangulation.cxx
old mode 100755 (executable)
new mode 100644 (file)
index af65579..70f6cd3
@@ -1,7 +1,19 @@
-// File:       Select3D_SensitiveTriangulation.cxx
-// Created:    Thu May 15 17:47:05 1997
-// Author:     Robert COUBLANC
-//             <rob@robox.paris1.matra-dtv.fr>
+// Created on: 1997-05-15
+// Created by: Robert COUBLANC
+// Copyright (c) 1997-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.
+
 //Modified      Thur Apr 09 98 by rob : No more computation of free edges.
 //                                      fix bug on Compute Depth (don't forget
 //                                      Location...)
@@ -11,6 +23,7 @@
 
 #include <Select3D_SensitiveTriangulation.ixx>
 #include <gp_Pnt2d.hxx>
+#include <Poly.hxx>
 #include <Poly_Connect.hxx>
 #include <CSLib_Class2d.hxx>
 #include <TColStd_Array1OfInteger.hxx>
@@ -31,7 +44,7 @@ static Standard_Integer S3D_NumberOfFreeEdges(const Handle(Poly_Triangulation)&
     for (j = 0; j < 3; j++)
       if (t[j] == 0) nFree++;
   }
-  return nFree; 
+  return nFree;
 }
 static Standard_Boolean S3D_STriangul_NearSegment (const gp_XY& p0, const gp_XY& p1, const gp_XY& TheP,
                                                    const Standard_Real aTol, Standard_Real& aDMin)
@@ -45,7 +58,10 @@ static Standard_Boolean S3D_STriangul_NearSegment (const gp_XY& p0, const gp_XY&
 
   gp_XY V01(p1);V01-=p0;
   gp_XY Vec(TheP);Vec -= p0;
-  
+
+  if (V01.SquareModulus() < Precision::SquareConfusion())
+    return Standard_False;
+
   Standard_Real u = Vec*V01.Normalized();
   if(u<-aTol) return Standard_False;
   Standard_Real u1 = u-aTol;
@@ -68,19 +84,19 @@ static Standard_Boolean S3D_STriangul_NearSegment (const gp_XY& p0, const gp_XY&
 //   VEdg-= PEdg2.XY();
 //   VCur-=PCur.XY();
 //   Standard_Real long1 = VEdg.SquareModulus();
-  
+
 //   if(long1<=TolTol)
 //     return VCur.SquareModulus();
 //   Standard_Real Val = VEdg^VCur;
 //   return Val*Val/long1;
-  
+
 // }
 
 static Standard_Boolean S3D_IsEdgeIn(const Standard_Integer e1,
-                                    const Standard_Integer e2,
-                                    const Standard_Integer N1,
-                                    const Standard_Integer N2,
-                                    const Standard_Integer N3)
+                                     const Standard_Integer e2,
+                                     const Standard_Integer N1,
+                                     const Standard_Integer N2,
+                                     const Standard_Integer N3)
 {
   Standard_Integer bid1  = (e1 == N1) ? N1 : ((e1 == N2) ? N2 : ( e1==N3 ? N3 : 0));
   if(bid1==0) return Standard_False;
@@ -90,19 +106,17 @@ static Standard_Boolean S3D_IsEdgeIn(const Standard_Integer e1,
   return Standard_True;
 }
 
-
-
 //=======================================================================
 //function : Select3D_SensitiveTriangulation
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 Select3D_SensitiveTriangulation::
 Select3D_SensitiveTriangulation(const Handle(SelectBasics_EntityOwner)& OwnerId,
-                               const Handle(Poly_Triangulation)& Trg,
-                               const TopLoc_Location& Loc,
-                               const Standard_Boolean InteriorFlag):
-                               Select3D_SensitiveEntity(OwnerId),
+                                const Handle(Poly_Triangulation)& Trg,
+                                const TopLoc_Location& Loc,
+                                const Standard_Boolean InteriorFlag):
+Select3D_SensitiveEntity(OwnerId),
 myTriangul(Trg),
 myiniloc(Loc),
 myIntFlag(InteriorFlag),
@@ -114,43 +128,47 @@ myDetectedTr(-1)
 
   Standard_Integer fr = 1;
   const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
-  const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();  
+  const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
   Standard_Integer nbTriangles (myTriangul->NbTriangles());
   gp_XYZ cdg(0,0,0);
   Standard_Integer n[3];
-  
+
   // to find connections in case when the border is not concerned...
-  if(!myIntFlag){
+  if(!myIntFlag)
+  {
     myFreeEdges = new TColStd_HArray1OfInteger(1,2*S3D_NumberOfFreeEdges(Trg));
     TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1();
     Poly_Connect pc(myTriangul);
     Standard_Integer t[3];
     Standard_Integer i,j;
-    for ( i = 1; i <= nbTriangles; i++) {
+    for ( i = 1; i <= nbTriangles; i++)
+    {
       pc.Triangles(i,t[0],t[1],t[2]);
       triangles(i).Get(n[0],n[1],n[2]);
       cdg += (Nodes(n[0]).XYZ() + Nodes(n[1]).XYZ()+ Nodes(n[2]).XYZ())/3.;
-      for (j = 0; j < 3; j++) {
-       Standard_Integer k = (j+1) % 3;
-       if (t[j] == 0) {
-         FreeE(fr)  = n[j];
-         FreeE(fr+1)= n[k];
-         fr += 2;
-       }
+      for (j = 0; j < 3; j++)
+      {
+        Standard_Integer k = (j+1) % 3;
+        if (t[j] == 0)
+        {
+          FreeE(fr)  = n[j];
+          FreeE(fr+1)= n[k];
+          fr += 2;
+        }
       }
     }
   }
   else{
-    for (Standard_Integer i = 1; i <= nbTriangles; i++) {
+    for (Standard_Integer i = 1; i <= nbTriangles; i++)
+    {
       triangles(i).Get(n[0],n[1],n[2]);
       cdg += (Nodes(n[0]).XYZ() + Nodes(n[1]).XYZ()+ Nodes(n[2]).XYZ())/3.;
     }
   }
 
-  
   if(nbTriangles!=0) cdg /= nbTriangles;
   myCDG3D = gp_Pnt(cdg);
-  
+
   ComputeTotalTrsf();
 
   if(myTrsf.Form()!=gp_Identity)
@@ -160,15 +178,16 @@ myDetectedTr(-1)
 
 //=======================================================================
 //function : Select3D_SensitiveTriangulation
-//purpose  : 
+//purpose  :
 //=======================================================================
+
 Select3D_SensitiveTriangulation::
 Select3D_SensitiveTriangulation(const Handle(SelectBasics_EntityOwner)& OwnerId,
-                               const Handle(Poly_Triangulation)& Trg,
-                               const TopLoc_Location& Loc,
-                               const Handle(TColStd_HArray1OfInteger)& FreeEdges,
-                               const gp_Pnt& TheCDG,
-                               const Standard_Boolean InteriorFlag):
+                                const Handle(Poly_Triangulation)& Trg,
+                                const TopLoc_Location& Loc,
+                                const Handle(TColStd_HArray1OfInteger)& FreeEdges,
+                                const gp_Pnt& TheCDG,
+                                const Standard_Boolean InteriorFlag):
 Select3D_SensitiveEntity(OwnerId),
 myTriangul(Trg),
 myiniloc(Loc),
@@ -179,123 +198,68 @@ myNodes2d(1,Trg->NbNodes()),
 myDetectedTr(-1)
 {
 }
+
 //=======================================================================
 //function : Project
-//purpose  : 
+//purpose  :
 //=======================================================================
 
-void Select3D_SensitiveTriangulation::Project(const Select3D_Projector& aPrj) 
+void Select3D_SensitiveTriangulation::Project(const Handle(Select3D_Projector)& aPrj)
 {
-  Select3D_SensitiveEntity::Project(aPrj); // to set the field last proj...
-  
   mybox2d.SetVoid();
-  const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();  
-  
+  const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
+
   gp_Pnt2d ProjPT;
-  
+
   for(Standard_Integer I=1;I<=myTriangul->NbNodes();I++){
     if(myTrsf.Form()!=gp_Identity)
-      aPrj.Project(Nodes(I).Transformed(myTrsf),ProjPT);
+      aPrj->Project(Nodes(I).Transformed(myTrsf),ProjPT);
     else
-      aPrj.Project(Nodes(I),ProjPT);
-    
+      aPrj->Project(Nodes(I),ProjPT);
+
     myNodes2d.SetValue(I,ProjPT);
     mybox2d.Add(ProjPT);
   }
-  
-  aPrj.Project(myCDG3D,myCDG2D);
+
+  aPrj->Project(myCDG3D,myCDG2D);
 }
 
 //=======================================================================
 //function : Areas
-//purpose  : 
+//purpose  :
 //=======================================================================
 
-void Select3D_SensitiveTriangulation::Areas(SelectBasics_ListOfBox2d& boxes) 
+void Select3D_SensitiveTriangulation::Areas(SelectBasics_ListOfBox2d& boxes)
 {
   boxes.Append(mybox2d);
 }
 
-//=======================================================================
-//function : getUV
-//purpose  : compute parameters of the picked point on triangle in 2d
-//     Note: parameters of point P on triangle (P1, P2, P3) are defined 
-//           as U and V such that P = P1 + U * (P2 - P1) + V * (P3 - P1);
-//    Range: U >= 0, V >= 0, U + V <= 1
-//=======================================================================
-
-static gp_XY getUV (const gp_XY& aP2d1, const gp_XY& aP2d2, const gp_XY& aP2d3,
-                    const gp_XY& aPick)
-{
-  gp_XY aDU = aP2d2 - aP2d1;
-  gp_XY aDV = aP2d3 - aP2d1;
-  Standard_Real aDet = aDU ^ aDV;
-
-  // case of non-degenerated triangle
-  gp_XY aDP = aPick - aP2d1;
-  if ( Abs (aDet) > gp::Resolution() )
-  {
-    Standard_Real aU =  (aDP ^ aDV) / aDet;
-    Standard_Real aV = -(aDP ^ aDU) / aDet;
-    if ( aU < 0. ) aU = 0.;
-    if ( aV < 0. ) aV = 0.;
-    if ( aU + aV > 1. ) { Standard_Real aD = aU + aV; aU /= aD; aV /= aD; }
-    return gp_XY (aU, aV);
-  }
-
-  // degenerated case (in 2d projection)
-  Standard_Real aL2U = aDU.SquareModulus();
-  Standard_Real aL2V = aDV.SquareModulus();
-  if ( aL2U < gp::Resolution() ) // side 1-2 is degenerated 
-  {
-    if ( aL2V < gp::Resolution() ) // whole triangle is degenerated to point
-      return gp_XY (0., 0.);
-    else
-      return gp_XY (0., (aDP * aDV) / aL2V);
-  }
-  else if ( aL2V < gp::Resolution() ) // side 1-3 is degenerated
-    return gp_XY ((aDP * aDU) / aL2U, 0.);
-  else // sides 1-2 and 1-3 are collinear
-  {
-    // select parameter on one of sides so as to have points closer to picked
-    Standard_Real aU = Min (1., Max (0., (aDP * aDU) / aL2U));
-    Standard_Real aV = Min (1., Max (0., (aDP * aDV) / aL2V));
-    gp_XY aP2dU = aP2d1 + aU * aDU;
-    gp_XY aP2dV = aP2d1 + aV * aDV;
-    if ( (aPick - aP2dU).SquareModulus() < (aPick - aP2dV).SquareModulus() )
-      return gp_XY ((aDP * aDU) / aL2U, 0.);
-    else
-      return gp_XY (0., (aDP * aDV) / aL2V);
-  }
-}
-
 //=======================================================================
 //function : Matches
-//purpose  : 
+//purpose  :
 //=======================================================================
-Standard_Boolean Select3D_SensitiveTriangulation::Matches(const Standard_Real X,
-                                                         const Standard_Real Y,
-                                                         const Standard_Real aTol,
-                                                         Standard_Real& DMin) 
-{
-  // get view direction (necessary for calculation of depth) from field mylastprj of the base class
-  if ( ! mylastprj )
-    return Standard_False;
 
-  DMin = Precision::Infinite();
-  gp_XY BidPoint(X,Y);
+Standard_Boolean Select3D_SensitiveTriangulation::Matches (const SelectBasics_PickArgs& thePickArgs,
+                                                           Standard_Real& theMatchDMin,
+                                                           Standard_Real& theMatchDepth)
+{
+  theMatchDMin = Precision::Infinite();
+  gp_XY BidPoint (thePickArgs.X(), thePickArgs.Y());
   myDetectedTr = -1;
   const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
 
   // it is checked if we are inside the triangle 2d.
   if(myIntFlag)
   {
-    gp_Lin EyeLine = (*((Select3D_Projector*)mylastprj)).Shoot(X,Y);
-    if ( myTrsf.Form()!=gp_Identity )
-      EyeLine.Transform (myTrsf.Inverted());
+    gp_Lin aPickingLine = thePickArgs.PickLine();
+
+    if (myTrsf.Form() != gp_Identity)
+    {
+      aPickingLine.Transform (myTrsf.Inverted());
+    }
 
     Standard_Real aMinDepth = Precision::Infinite();
-    const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();  
+    const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
     for (Standard_Integer itr=1; itr<=myTriangul->NbTriangles(); itr++)
     {
       Standard_Integer n1,n2,n3;
@@ -303,30 +267,30 @@ Standard_Boolean Select3D_SensitiveTriangulation::Matches(const Standard_Real X,
       const gp_XY& aPnt2d1 = myNodes2d(n1).XY();
       const gp_XY& aPnt2d2 = myNodes2d(n2).XY();
       const gp_XY& aPnt2d3 = myNodes2d(n3).XY();
-      Standard_Real DD = 0.;
-      if (Status (BidPoint, aPnt2d1, aPnt2d2, aPnt2d3, aTol, DD) == 2)
+      gp_XY aUV;
+      Standard_Real aDistSquare = Poly::PointOnTriangle (aPnt2d1, aPnt2d2, aPnt2d3, BidPoint, aUV);
+      if (aDistSquare > thePickArgs.Tolerance() * thePickArgs.Tolerance())
         continue;
 
-      // compute depth on this triangle
-      gp_XY aUV = getUV (aPnt2d1, aPnt2d2, aPnt2d3, BidPoint);
-      Standard_Real aDepth1 = ElCLib::Parameter (EyeLine, Nodes(n1));
-      Standard_Real aDepth2 = ElCLib::Parameter (EyeLine, Nodes(n2));
-      Standard_Real aDepth3 = ElCLib::Parameter (EyeLine, Nodes(n3));
-      Standard_Real aDepth = aDepth1 + aUV.X() * (aDepth2 - aDepth1) + 
+      // get interpolated depth of the triangle nodes
+      Standard_Real aDepth1 = ElCLib::Parameter (aPickingLine, Nodes(n1));
+      Standard_Real aDepth2 = ElCLib::Parameter (aPickingLine, Nodes(n2));
+      Standard_Real aDepth3 = ElCLib::Parameter (aPickingLine, Nodes(n3));
+      Standard_Real aDepth = aDepth1 + aUV.X() * (aDepth2 - aDepth1) +
                                        aUV.Y() * (aDepth3 - aDepth1);
 
-      // take triangle with lowest depth
-      if ( aDepth < aMinDepth )
+      // accept triangle with lowest depth and within defined depth interval
+      if (aDepth < aMinDepth && !thePickArgs.IsClipped(aDepth))
       {
         aMinDepth = aDepth;
         myDetectedTr = itr;
-        DMin = DD;
+        theMatchDMin = Sqrt (aDistSquare);
       }
     }
   }
-  
+
   //    Case only Test on Border of the triangulation...
-  //   
+  //
   else
   {
     //Standard_Integer ifirst;
@@ -334,156 +298,176 @@ Standard_Boolean Select3D_SensitiveTriangulation::Matches(const Standard_Real X,
     Standard_Integer nn = FreeE.Length(), Node1,Node2;
     //Standard_Real LEdg;
     //Standard_Real DMinDMin,TolTol = aTol*aTol;
-    
+
     for (Standard_Integer ifri =1; ifri <= nn && myDetectedTr < 0; ifri+=2)
     {
       Node1 = FreeE(ifri);
       Node2 = FreeE(ifri+1);
       if (S3D_STriangul_NearSegment (myNodes2d(Node1).XY(),
                                      myNodes2d(Node2).XY(),
-                                     BidPoint, aTol, DMin) )
+                                     BidPoint, thePickArgs.Tolerance(), theMatchDMin))
       {
-       for(Standard_Integer itr=1; itr <= myTriangul->NbTriangles(); itr++)
+        for(Standard_Integer itr=1; itr <= myTriangul->NbTriangles(); itr++)
         {
           Standard_Integer n1,n2,n3;
-         triangles(itr).Get(n1,n2,n3);
-         if(S3D_IsEdgeIn(Node1,Node2,n1,n2,n3))
+          triangles(itr).Get(n1,n2,n3);
+          if(S3D_IsEdgeIn(Node1,Node2,n1,n2,n3))
           {
-           myDetectedTr = itr;
+            myDetectedTr = itr;
             break; // return first found; selection of closest is not implemented yet
           }
-       }
+        }
       }
     }
-  } 
+  }
   if ( myDetectedTr <= 0 )
     return Standard_False;
-  Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
-  return Standard_True;
-}
 
+  // get precise depth for the detected triangle
+  theMatchDepth = ComputeDepth (thePickArgs.PickLine(), myDetectedTr);
+
+  // this test should not fail if the topmost triangle is taken from the
+  // first if-case block (for other cases this test make sense?)
+  return !thePickArgs.IsClipped (theMatchDepth);
+}
 
 //=======================================================================
 //function : Matches
-//purpose  : 
+//purpose  :
 //=======================================================================
 
-Standard_Boolean Select3D_SensitiveTriangulation::Matches(const Standard_Real XMin,
-                                                         const Standard_Real YMin,
-                                                         const Standard_Real XMax,
-                                                         const Standard_Real YMax,
-                                                         const Standard_Real aTol) 
+Standard_Boolean Select3D_SensitiveTriangulation::
+Matches(const Standard_Real XMin,
+        const Standard_Real YMin,
+        const Standard_Real XMax,
+        const Standard_Real YMax,
+        const Standard_Real aTol)
 {
   Bnd_Box2d B;
   B.Update(Min(XMin,XMax)-aTol,
-          Min(YMin,YMax)-aTol,
-          Max(XMin,XMax)+aTol,
-          Max(YMin,YMax)+aTol);
-  
-  for(Standard_Integer i=myNodes2d.Lower();i<=myNodes2d.Upper();i++){
+           Min(YMin,YMax)-aTol,
+           Max(XMin,XMax)+aTol,
+           Max(YMin,YMax)+aTol);
+
+  for(Standard_Integer i=myNodes2d.Lower();i<=myNodes2d.Upper();i++)
+  {
     if(B.IsOut(myNodes2d(i)))
       return Standard_False;
   }
   return Standard_True;
 }
 
-
 //=======================================================================
 //function : Matches
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 Standard_Boolean Select3D_SensitiveTriangulation::
 Matches (const TColgp_Array1OfPnt2d& aPoly,
-        const Bnd_Box2d& aBox,
-        const Standard_Real aTol)
-{ 
+         const Bnd_Box2d& aBox,
+         const Standard_Real aTol)
+{
   Standard_Real Umin,Vmin,Umax,Vmax;
   aBox.Get(Umin,Vmin,Umax,Vmax);
-  Standard_Real Tolu,Tolv;
-  Tolu = 1e-7;
-  Tolv = 1e-7;
   CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
 
-  for(Standard_Integer j=1;j<=myNodes2d.Length();j++){
+  for(Standard_Integer j=1;j<=myNodes2d.Length();j++)
+  {
     Standard_Integer RES = aClassifier2d.SiDans(myNodes2d(j));
     if(RES!=1) return Standard_False;
   }
   return Standard_True;
 }
 
+//=======================================================================
+//function : Status
+//purpose  :
+//=======================================================================
 
-
-Standard_Integer Select3D_SensitiveTriangulation::Status (const gp_XY& TheP,
-                                                         const gp_XY& Proj0,
-                                                         const gp_XY& Proj1,
-                                                         const gp_XY& Proj2,
-                                                         const Standard_Real aTol,
-                                                         Standard_Real& DD) const
+Standard_Integer Select3D_SensitiveTriangulation::
+Status (const gp_XY& TheP,
+        const gp_XY& Proj0,
+        const gp_XY& Proj1,
+        const gp_XY& Proj2,
+        const Standard_Real aTol,
+        Standard_Real& DD) const
 {
   return Select3D_SensitiveTriangle::Status(Proj0,Proj1,Proj2,TheP,aTol,DD);
 }
 
 //=======================================================================
 //function : IsFree
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 Standard_Boolean Select3D_SensitiveTriangulation::IsFree(const Standard_Integer IndexOfTriangle,
-                                                        Standard_Integer& FoundIndex) const
+                                                         Standard_Integer& FoundIndex) const
 {
-
   FoundIndex=-1;
   Standard_Integer n[3];
   const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
   triangles(IndexOfTriangle).Get(n[0],n[1],n[2]);
-    TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1();
+  TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1();
 
-  for(Standard_Integer I=1;I<=FreeE.Length() && FoundIndex==-1;I+=2){
-    
-    if(FreeE(I) == n[0]){
-      
-      if(FreeE(I+1)== n[1] || FreeE(I+1)== n[2]) FoundIndex=I;}
-    else if(FreeE(I) == n[1]){
-      if(FreeE(I+1)== n[0] || FreeE(I+1)== n[2]) FoundIndex=I;}
-    else if(FreeE(I) == n[2]){
-      if(FreeE(I+1)== n[0] || FreeE(I+1)== n[1]) FoundIndex=I;}
+  for(Standard_Integer I=1;I<=FreeE.Length() && FoundIndex==-1;I+=2)
+  {
+    if(FreeE(I) == n[0])
+    {
+      if(FreeE(I+1)== n[1] || FreeE(I+1)== n[2])
+        FoundIndex=I;
+    }
+    else if(FreeE(I) == n[1])
+    {
+      if(FreeE(I+1)== n[0] || FreeE(I+1)== n[2])
+        FoundIndex=I;
+    }
+    else if(FreeE(I) == n[2])
+    {
+      if(FreeE(I+1)== n[0] || FreeE(I+1)== n[1])
+        FoundIndex=I;
+    }
   }
-  
+
   return FoundIndex!=-1;
 }
 
 
 //=======================================================================
 //function : GetConnected
-//purpose  : 
+//purpose  :
 //=======================================================================
+
 Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangulation::
 GetConnected(const TopLoc_Location& aLoc)
 {
-  
-  Handle(Select3D_SensitiveTriangulation) NiouEnt = 
+  Handle(Select3D_SensitiveTriangulation) NiouEnt =
     new Select3D_SensitiveTriangulation(myOwnerId,myTriangul,myiniloc,myFreeEdges,myCDG3D,myIntFlag);
-  
-  if(HasLocation()) NiouEnt->SetLocation(Location());
+
+  if(HasLocation())
+    NiouEnt->SetLocation(Location());
 //  TopLoc_Location TheLocToApply = HasLocation() ?  Location()*aLoc : aLoc;
 //  if(!TheLocToApply.IsIdentity())
   NiouEnt->UpdateLocation(aLoc);
-    
 
   return NiouEnt;
 }
 
-
 //=======================================================================
 //function : ResetLocation
-//purpose  : 
+//purpose  :
 //=======================================================================
-void Select3D_SensitiveTriangulation::ResetLocation() 
+
+void Select3D_SensitiveTriangulation::ResetLocation()
 {
   Select3D_SensitiveEntity::ResetLocation();
   ComputeTotalTrsf();
 }
+
+//=======================================================================
+//function : SetLocation
+//purpose  :
+//=======================================================================
+
 void Select3D_SensitiveTriangulation::SetLocation(const TopLoc_Location& aLoc)
 {
   Select3D_SensitiveEntity::SetLocation(aLoc);
@@ -493,9 +477,9 @@ void Select3D_SensitiveTriangulation::SetLocation(const TopLoc_Location& aLoc)
 
 //=======================================================================
 //function : Dump
-//purpose  : 
+//purpose  :
 //=======================================================================
-void Select3D_SensitiveTriangulation::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const 
+void Select3D_SensitiveTriangulation::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
 {
   S<<"\tSensitiveTriangulation 3D :"<<endl;
   if(myiniloc.IsIdentity())
@@ -504,12 +488,13 @@ void Select3D_SensitiveTriangulation::Dump(Standard_OStream& S,const Standard_Bo
     S<<"\t\tExisting Initial Location"<<endl;
   if(HasLocation())
     S<<"\t\tExisting Location"<<endl;
-  
+
   S<<"\t\tNb Triangles : "<<myTriangul->NbTriangles()<<endl;
   S<<"\t\tNb Nodes     : "<<myTriangul->NbNodes()<<endl;
   S<<"\t\tNb Free Edges: "<<myFreeEdges->Length()/2<<endl;
 
-  if(FullDump){
+  if(FullDump)
+  {
 //    S<<"\t\t\tOwner:"<<myOwnerId<<endl;
     Select3D_SensitiveEntity::DumpBox(S,mybox2d);
   }
@@ -517,131 +502,173 @@ void Select3D_SensitiveTriangulation::Dump(Standard_OStream& S,const Standard_Bo
 
 //=======================================================================
 //function : ComputeDepth
-//purpose  :  
+//purpose  :
 //=======================================================================
-Standard_Real Select3D_SensitiveTriangulation::ComputeDepth(const gp_Lin& EyeLine) const
+
+Standard_Real Select3D_SensitiveTriangulation::ComputeDepth(const gp_Lin& thePickLine,
+                                                            const Standard_Integer theTriangle) const
 {
-  if(myDetectedTr==-1) return Precision::Infinite(); // currently not implemented...
+  if (theTriangle == -1)
+  {
+    return Precision::Infinite(); // currently not implemented...
+  }
+
   const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
-  const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();  
-  
+  const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
+
   Standard_Integer n1,n2,n3;
-  triangles(myDetectedTr).Get(n1,n2,n3);
+  triangles (theTriangle).Get (n1,n2,n3);
   gp_Pnt P[3]={Nodes(n1),Nodes(n2),Nodes(n3)};
 
-  if(myTrsf.Form()!=gp_Identity){
-    for(Standard_Integer i =0;i<=2;i++){
-      P[i].Transform(myTrsf);
+  if (myTrsf.Form() != gp_Identity)
+  {
+    for (Standard_Integer i =0; i<=2; i++)
+    {
+      P[i].Transform (myTrsf);
     }
   }
-  
+
   // formula calculate the parameter of the point on the intersection
   // t = (P1P2 ^P1P3)* OP1  / ((P1P2^P1P3)*Dir)
-  Standard_Real prof(Precision::Infinite());
-  gp_Pnt Oye  = EyeLine.Location(); // origin of the target line eye/point...
-  gp_Dir Dir  = EyeLine.Direction();
+  Standard_Real prof (Precision::Infinite());
+  gp_Pnt Oye  = thePickLine.Location(); // origin of the target line eye/point...
+  gp_Dir Dir  = thePickLine.Direction();
+
+  gp_Vec Vtr[3];
+  for (Standard_Integer i=0; i<=2; i++)
+  {
+    Vtr[i] = gp_Vec (P[i%3], P[(i+1)%3]);
+  }
 
-  gp_Vec Vtr[3]; 
-  for(Standard_Integer i=0;i<=2;i++)
-    Vtr[i] = gp_Vec(P[i%3],P[(i+1)%3]);
   Vtr[2] = -Vtr[2];
-  
+
   // remove singular cases immediately...
-  Standard_Integer SingularCase(-1);
-  if(Vtr[0].SquareMagnitude()<= Precision::Confusion())
+  Standard_Integer SingularCase (-1);
+  if (Vtr[0].SquareMagnitude() <= Precision::Confusion())
+  {
     SingularCase = 0;
-  if(Vtr[1].SquareMagnitude()<= Precision::Confusion())
+  }
+
+  if (Vtr[1].SquareMagnitude() <= Precision::Confusion())
+  {
     SingularCase = (SingularCase == -1) ? 1 : 2;
+  }
+
 #ifdef BUC60858
-  if(Vtr[2].SquareMagnitude()<= Precision::Confusion())
+  if (Vtr[2].SquareMagnitude() <= Precision::Confusion())
+  {
     if( SingularCase < 0 ) SingularCase = 1;
+  }
 #endif
-  
+
   // 3 pts mixed...
-  if(SingularCase ==2){
-    prof= ElCLib::Parameter(EyeLine,P[0]);
+  if (SingularCase ==2)
+  {
+    prof = ElCLib::Parameter (thePickLine, P[0]);
     return prof;
   }
-  
-  if(SingularCase!=0)
+
+  if (SingularCase!=0)
+  {
     Vtr[0].Normalize();
-  if(SingularCase!=1 &&
-     SingularCase!=2)
+  }
+
+  if (SingularCase!=1 && SingularCase!=2)
+  {
     Vtr[2].Normalize();
-  gp_Vec OPo(Oye,P[0]);
+  }
+
+  gp_Vec OPo (Oye, P[0]);
+
   // 2 points mixed... the intersection between the segment and the target line eye/point.
-  // 
-  if(SingularCase!=-1){
+  if (SingularCase!=-1)
+  {
     gp_Vec V = SingularCase==0 ? Vtr[2] : Vtr[0];
     gp_Vec Det = Dir^V;
     gp_Vec VSM = OPo^V;
-    if(Det.X()> Precision::Confusion())
-      prof = VSM.X()/Det.X();
-    else if (Det.Y()> Precision::Confusion())
-      prof = VSM.Y()/Det.Y();
-    else if(Det.Z()> Precision::Confusion())
-      prof = VSM.Z()/Det.Z();
+
+    if (Det.X() > Precision::Confusion())
+    {
+      prof = VSM.X() / Det.X();
+    }
+    else if (Det.Y() > Precision::Confusion())
+    {
+      prof = VSM.Y() / Det.Y();
+    }
+    else if (Det.Z() > Precision::Confusion())
+    {
+      prof = VSM.Z() / Det.Z();
+    }
   }
-  else{
-    
-    Standard_Real val1 = OPo.DotCross(Vtr[0],Vtr[2]);
-    Standard_Real val2 = Dir.DotCross(Vtr[0],Vtr[2]);
-    
-    if(Abs(val2)>Precision::Confusion())
-      prof =val1/val2;
-  } 
-  if (prof==Precision::Infinite()){
-    prof= ElCLib::Parameter(EyeLine,P[0]);
-    prof = Min (prof, ElCLib::Parameter(EyeLine,P[1]));
-    prof = Min (prof, ElCLib::Parameter(EyeLine,P[2]));
+  else
+  {
+    Standard_Real val1 = OPo.DotCross (Vtr[0], Vtr[2]);
+    Standard_Real val2 = Dir.DotCross (Vtr[0], Vtr[2]);
+
+    if (Abs (val2) > Precision::Confusion())
+    {
+      prof = val1 / val2;
+    }
   }
-  
+
+  if (prof == Precision::Infinite())
+  {
+    prof= ElCLib::Parameter (thePickLine, P[0]);
+    prof = Min (prof, ElCLib::Parameter (thePickLine, P[1]));
+    prof = Min (prof, ElCLib::Parameter (thePickLine, P[2]));
+  }
+
   return prof;
 }
 
 //=======================================================================
 //function : DetectedTriangle
-//purpose  : 
+//purpose  :
 //=======================================================================
-Standard_Boolean Select3D_SensitiveTriangulation::DetectedTriangle(gp_Pnt& P1,
-                                                                  gp_Pnt& P2,
-                                                                  gp_Pnt& P3) const
+
+Standard_Boolean Select3D_SensitiveTriangulation::
+DetectedTriangle(gp_Pnt& P1,
+                 gp_Pnt& P2,
+                 gp_Pnt& P3) const
 {
   if(myDetectedTr==-1) return Standard_False; // currently not implemented...
   const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
-  const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();  
+  const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
   Standard_Integer n1,n2,n3;
   triangles(myDetectedTr).Get(n1,n2,n3);
-  
+
   P1 = Nodes(n1);
   P2 = Nodes(n2);
   P3 = Nodes(n3);
-  if(myTrsf.Form()!=gp_Identity){
+  if(myTrsf.Form()!=gp_Identity)
+  {
     P1.Transform(myTrsf);
     P2.Transform(myTrsf);
     P3.Transform(myTrsf);
   }
-  
+
   return Standard_True;
 }
 
 //=============================================================================
 // Function : DetectedTriangle2d
-// Purpose  : 
+// Purpose  :
 //=============================================================================
-Standard_Boolean Select3D_SensitiveTriangulation::DetectedTriangle2d( 
-  gp_Pnt2d& P1, gp_Pnt2d& P2, gp_Pnt2d& P3) const
+
+Standard_Boolean Select3D_SensitiveTriangulation::
+DetectedTriangle2d(gp_Pnt2d& P1,
+                   gp_Pnt2d& P2,
+                   gp_Pnt2d& P3) const
 {
-  if(myDetectedTr==-1) 
+  if(myDetectedTr==-1)
     return Standard_False; //  currently not implemented...
   const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
-  const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();  
   Standard_Integer n1,n2,n3;
   triangles( myDetectedTr ).Get(n1,n2,n3);
 
   int aLower = myNodes2d.Lower();
   int anUpper = myNodes2d.Upper();
-  if ( n1 >= aLower && n1 <= anUpper && 
+  if ( n1 >= aLower && n1 <= anUpper &&
        n2 >= aLower && n2 <= anUpper &&
        n3 >= aLower && n3 <= anUpper )
   {
@@ -650,25 +677,32 @@ Standard_Boolean Select3D_SensitiveTriangulation::DetectedTriangle2d(
     P3 = myNodes2d.Value( n3 );
     return Standard_True;
   }
-  else 
+  else
     return Standard_False;
-  
 }
 
-void Select3D_SensitiveTriangulation::ComputeTotalTrsf() 
+//=============================================================================
+// Function : ComputeTotalTrsf
+// Purpose  :
+//=============================================================================
+
+void Select3D_SensitiveTriangulation::ComputeTotalTrsf()
 {
   Standard_Boolean hasloc = (HasLocation() || !myiniloc.IsIdentity());
-  
-  if(hasloc){
+
+  if(hasloc)
+  {
     if(myiniloc.IsIdentity())
       myTrsf = Location().Transformation();
-    else if(HasLocation()){
+    else if(HasLocation())
+    {
       myTrsf = (Location()*myiniloc).Transformation();
     }
     else
       myTrsf = myiniloc.Transformation();
   }
-  else{
+  else
+  {
     gp_Trsf TheId;
     myTrsf = TheId;
   }