Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-29 09:16:15

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