Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-27 09:39:08

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 <NCollection_Vec3.hxx>
0021 #include <Standard_TypeDef.hxx>
0022 #include <Precision.hxx>
0023 #include <Select3D_SensitiveEntity.hxx>
0024 
0025 //! This class provides data and criterion for sorting candidate
0026 //! entities in the process of interactive selection by mouse click
0027 class SelectMgr_SortCriterion
0028 {
0029 public:
0030   occ::handle<Select3D_SensitiveEntity> Entity; //!< detected entity
0031   gp_Pnt                                Point;  //!< 3D point
0032   NCollection_Vec3<float>               Normal; //!< surface normal or 0 vector if undefined
0033   double                                Depth;  //!< distance from the view plane to the entity
0034                                                 // clang-format off
0035   double      MinDist;           //!< distance from the clicked point to the entity on the view plane
0036   double      Tolerance;         //!< tolerance used for selecting candidates
0037   int   SelectionPriority; //!< selection priority
0038   int   DisplayPriority;   //!< display priority
0039   int   ZLayerPosition;    //!< ZLayer rendering order index, stronger than a depth
0040   int   NbOwnerMatches;    //!< overall number of entities collected for the same owner
0041                                                 // clang-format on
0042   bool IsPreferPriority; //!< flag to signal comparison to be done over priority
0043 
0044 public:
0045   DEFINE_STANDARD_ALLOC
0046 
0047   //! Empty constructor.
0048   SelectMgr_SortCriterion()
0049       : Depth(0.0),
0050         MinDist(0.0),
0051         Tolerance(0.0),
0052         SelectionPriority(0),
0053         DisplayPriority(0),
0054         ZLayerPosition(0),
0055         NbOwnerMatches(0),
0056         IsPreferPriority(false)
0057   {
0058   }
0059 
0060   //! Compare with another item by depth, priority and minDist.
0061   bool IsCloserDepth(const SelectMgr_SortCriterion& theOther) const
0062   {
0063     // the object within different ZLayer groups can not be compared by depth
0064     if (ZLayerPosition != theOther.ZLayerPosition)
0065     {
0066       return ZLayerPosition > theOther.ZLayerPosition;
0067     }
0068 
0069     // closest object is selected if their depths are not equal within tolerance
0070     if (std::abs(Depth - theOther.Depth) > Tolerance + theOther.Tolerance)
0071     {
0072       return Depth < theOther.Depth;
0073     }
0074 
0075     double aCos = 1.0;
0076     if (Normal.Modulus() > 0 && theOther.Normal.Modulus() > 0)
0077     {
0078       gp_Dir aNormal(Normal.x(), Normal.y(), Normal.z());
0079       gp_Dir anOtherNormal(theOther.Normal.x(), theOther.Normal.y(), theOther.Normal.z());
0080       aCos = std::abs(std::cos(aNormal.Angle(anOtherNormal)));
0081     }
0082 
0083     double aDepth       = Depth - Tolerance;
0084     double anOtherDepth = theOther.Depth - theOther.Tolerance;
0085     // Comparison depths taking into account tolerances occurs when the surfaces are parallel
0086     // or have the same sensitivity and the angle between them is less than 60 degrees.
0087     if (std::abs(aDepth - anOtherDepth) > Precision::Confusion())
0088     {
0089       if ((aCos > 0.5 && std::abs(Tolerance - theOther.Tolerance) < Precision::Confusion())
0090           || std::abs(aCos - 1.0) < Precision::Confusion())
0091       {
0092         return aDepth < anOtherDepth;
0093       }
0094     }
0095 
0096     // if two objects have similar depth, select the one with higher priority
0097     if (SelectionPriority > theOther.SelectionPriority)
0098     {
0099       return true;
0100     }
0101 
0102     if (DisplayPriority > theOther.DisplayPriority)
0103     {
0104       return true;
0105     }
0106 
0107     // if priorities are equal, one closest to the mouse
0108     return SelectionPriority == theOther.SelectionPriority && MinDist < theOther.MinDist;
0109   }
0110 
0111   //! Compare with another item using old logic (OCCT version <= 6.3.1) with priority considered
0112   //! preceding depth.
0113   bool IsHigherPriority(const SelectMgr_SortCriterion& theOther) const
0114   {
0115     // the object within different ZLayer groups can not be compared by depth
0116     if (ZLayerPosition != theOther.ZLayerPosition)
0117     {
0118       return ZLayerPosition > theOther.ZLayerPosition;
0119     }
0120 
0121     if (SelectionPriority != theOther.SelectionPriority)
0122     {
0123       return SelectionPriority > theOther.SelectionPriority;
0124     }
0125 
0126     if (DisplayPriority != theOther.DisplayPriority)
0127     {
0128       return DisplayPriority > theOther.DisplayPriority;
0129     }
0130 
0131     // if (Abs (Depth - theOther.Depth) <= (Tolerance + theOther.Tolerance))
0132     if (std::abs(Depth - theOther.Depth) <= Precision::Confusion())
0133     {
0134       return MinDist < theOther.MinDist;
0135     }
0136 
0137     return Depth < theOther.Depth;
0138   }
0139 };
0140 
0141 #endif // _SelectMgr_SortCriterion_HeaderFile