Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:04:54

0001 // Created on: 1998-03-26
0002 // Created by: Robert COUBLANC
0003 // Copyright (c) 1998-1999 Matra Datavision
0004 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0005 //
0006 // This file is part of Open CASCADE Technology software library.
0007 //
0008 // This library is free software; you can redistribute it and/or modify it under
0009 // the terms of the GNU Lesser General Public License version 2.1 as published
0010 // by the Free Software Foundation, with special exception defined in the file
0011 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0012 // distribution for complete text of the license and disclaimer of any warranty.
0013 //
0014 // Alternatively, this file may be used under the terms of Open CASCADE
0015 // commercial license or contractual agreement.
0016 
0017 #ifndef _SelectMgr_SortCriterion_HeaderFile
0018 #define _SelectMgr_SortCriterion_HeaderFile
0019 
0020 #include <Graphic3d_Vec3.hxx>
0021 #include <Precision.hxx>
0022 #include <Select3D_SensitiveEntity.hxx>
0023 
0024 //! This class provides data and criterion for sorting candidate
0025 //! entities in the process of interactive selection by mouse click
0026 class SelectMgr_SortCriterion 
0027 {
0028 public:
0029 
0030   Handle(Select3D_SensitiveEntity) Entity; //!< detected entity
0031   gp_Pnt             Point;           //!< 3D point
0032   Graphic3d_Vec3     Normal;          //!< surface normal or 0 vector if undefined
0033   Standard_Real      Depth;           //!< distance from the view plane to the entity
0034   Standard_Real      MinDist;         //!< distance from the clicked point to the entity on the view plane
0035   Standard_Real      Tolerance;       //!< tolerance used for selecting candidates
0036   Standard_Integer   Priority;        //!< selection priority
0037   Standard_Integer   ZLayerPosition;  //!< ZLayer rendering order index, stronger than a depth
0038   Standard_Integer   NbOwnerMatches;  //!< overall number of entities collected for the same owner
0039 
0040 public:
0041   DEFINE_STANDARD_ALLOC
0042 
0043   //! Empty constructor.
0044   SelectMgr_SortCriterion()
0045   : Depth    (0.0),
0046     MinDist  (0.0),
0047     Tolerance(0.0),
0048     Priority (0),
0049     ZLayerPosition (0),
0050     NbOwnerMatches (0) {}
0051 
0052   //! Compare with another item by depth, priority and minDist.
0053   bool IsCloserDepth (const SelectMgr_SortCriterion& theOther) const
0054   {
0055     // the object within different ZLayer groups can not be compared by depth
0056     if (ZLayerPosition != theOther.ZLayerPosition)
0057     {
0058       return ZLayerPosition > theOther.ZLayerPosition;
0059     }
0060 
0061     // closest object is selected if their depths are not equal within tolerance
0062     if (Abs (Depth - theOther.Depth) > Tolerance + theOther.Tolerance)
0063     {
0064       return Depth < theOther.Depth;
0065     }
0066 
0067     Standard_Real aCos = 1.0;
0068     if (Normal.Modulus() > 0 && theOther.Normal.Modulus() > 0)
0069     {
0070       gp_Dir aNormal (Normal.x(), Normal.y(), Normal.z());
0071       gp_Dir anOtherNormal (theOther.Normal.x(), theOther.Normal.y(), theOther.Normal.z());
0072       aCos = Abs (Cos (aNormal.Angle (anOtherNormal)));
0073     }
0074 
0075     Standard_Real aDepth = Depth - Tolerance;
0076     Standard_Real anOtherDepth = theOther.Depth - theOther.Tolerance;
0077     // Comparison depths taking into account tolerances occurs when the surfaces are parallel
0078     // or have the same sensitivity and the angle between them is less than 60 degrees.
0079     if (Abs (aDepth - anOtherDepth) > Precision::Confusion())
0080     {
0081       if ((aCos > 0.5 && Abs (Tolerance - theOther.Tolerance) < Precision::Confusion())
0082        || Abs (aCos - 1.0) < Precision::Confusion())
0083       {
0084         return aDepth < anOtherDepth;
0085       }
0086     }
0087 
0088     // if two objects have similar depth, select the one with higher priority
0089     if (Priority > theOther.Priority)
0090     {
0091       return true;
0092     }
0093 
0094     // if priorities are equal, one closest to the mouse
0095     return Priority == theOther.Priority
0096         && MinDist  <  theOther.MinDist;
0097   }
0098 
0099   //! Compare with another item using old logic (OCCT version <= 6.3.1) with priority considered preceding depth.
0100   bool IsHigherPriority (const SelectMgr_SortCriterion& theOther) const
0101   {
0102     // the object within different ZLayer groups can not be compared by depth
0103     if (ZLayerPosition != theOther.ZLayerPosition)
0104     {
0105       return ZLayerPosition > theOther.ZLayerPosition;
0106     }
0107 
0108     if (Priority > theOther.Priority)
0109     {
0110       return true;
0111     }
0112     else if (Priority != theOther.Priority)
0113     {
0114       return false;
0115     }
0116 
0117     //if (Abs (Depth - theOther.Depth) <= (Tolerance + theOther.Tolerance))
0118     if (Abs (Depth - theOther.Depth) <= Precision::Confusion())
0119     {
0120       return MinDist < theOther.MinDist;
0121     }
0122 
0123     return Depth < theOther.Depth;
0124   }
0125 
0126 };
0127 
0128 #endif // _SelectMgr_SortCriterion_HeaderFile