3fb98b347b9b0a337d77db7e0f43b43a1fc9d36e
[occt.git] / src / SelectMgr / SelectMgr_SortCriterion.hxx
1 // Created on: 1998-03-26
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #ifndef _SelectMgr_SortCriterion_HeaderFile
18 #define _SelectMgr_SortCriterion_HeaderFile
19
20 #include <Graphic3d_ZLayerId.hxx>
21 #include <Precision.hxx>
22 #include <SelectBasics_SensitiveEntity.hxx>
23
24 //! This class provides data and criterion for sorting candidate
25 //! entities in the process of interactive selection by mouse click
26 class SelectMgr_SortCriterion 
27 {
28 public:
29
30   Handle(SelectBasics_SensitiveEntity) Entity; //!< detected entity
31   gp_Pnt             Point;           //!< 3D point
32   Standard_Real      Depth;           //!< distance from the view plane to the entity
33   Standard_Real      MinDist;         //!< distance from the clicked point to the entity on the view plane
34   Standard_Real      Tolerance;       //!< tolerance used for selecting candidates
35   Standard_Integer   Priority;        //!< selection priority
36   Standard_Integer   ZLayerPosition;  //!< ZLayer rendering order index, stronger than a depth
37   Standard_Integer   NbOwnerMatches;  //!< overall number of entities collected for the same owner
38   Standard_Boolean   ToPreferClosest; //!< whether closest object is preferred even if has less priority
39
40 public:
41   DEFINE_STANDARD_ALLOC
42
43   //! Empty constructor.
44   SelectMgr_SortCriterion()
45   : Depth    (0.0),
46     MinDist  (0.0),
47     Tolerance(0.0),
48     Priority (0),
49     ZLayerPosition  (0),
50     NbOwnerMatches  (0),
51     ToPreferClosest (Standard_True) {}
52
53   //! Comparison operator.
54   bool operator> (const SelectMgr_SortCriterion& theOther) const { return IsGreater (theOther); }
55
56   //! Comparison operator.
57   bool operator< (const SelectMgr_SortCriterion& theOther) const { return IsLower   (theOther); }
58
59   //! Compare with another item.
60   bool IsGreater (const SelectMgr_SortCriterion& theOther) const
61   {
62     // the object within different ZLayer groups can not be compared by depth
63     if (ZLayerPosition != theOther.ZLayerPosition)
64     {
65       return ZLayerPosition > theOther.ZLayerPosition;
66     }
67
68     if (ToPreferClosest)
69     {
70       // closest object is selected unless difference is within tolerance
71       if (Abs (Depth - theOther.Depth) > (Tolerance + theOther.Tolerance))
72       {
73         return Depth < theOther.Depth;
74       }
75
76       // if two objects have similar depth, select the one with higher priority
77       if (Priority > theOther.Priority)
78       {
79         return true;
80       }
81
82       // if priorities are equal, one closest to the mouse
83       return Priority == theOther.Priority
84           && MinDist  <  theOther.MinDist;
85     }
86
87     // old logic (OCCT version <= 6.3.1)
88     if (Priority > theOther.Priority)
89     {
90       return true;
91     }
92     else if (Priority != theOther.Priority)
93     {
94       return false;
95     }
96
97     if (Abs (Depth - theOther.Depth) <= Precision::Confusion())
98     {
99       return MinDist < theOther.MinDist;
100     }
101
102     return Depth < theOther.Depth;
103   }
104
105   //! Compare with another item.
106   bool IsLower (const SelectMgr_SortCriterion& theOther) const
107   {
108     // the object within different ZLayer groups can not be compared by depth
109     if (ZLayerPosition != theOther.ZLayerPosition)
110     {
111       return ZLayerPosition < theOther.ZLayerPosition;
112     }
113
114     if (ToPreferClosest)
115     {
116       // closest object is selected unless difference is within tolerance
117       if (ToPreferClosest
118        && Abs (Depth - theOther.Depth) > (Tolerance + theOther.Tolerance))
119       {
120         return Depth > theOther.Depth;
121       }
122
123       // if two objects have similar depth, select the one with higher priority
124       if (Priority < theOther.Priority)
125       {
126         return true;
127       }
128
129       // if priorities are equal, one closest to the mouse
130       return Priority == theOther.Priority
131           && MinDist  >  theOther.MinDist;
132     }
133
134     // old logic (OCCT version <= 6.3.1)
135     if (Priority > theOther.Priority)
136     {
137       return false;
138     }
139     else if (Priority != theOther.Priority)
140     {
141       return true;
142     }
143
144     if (Abs (Depth - theOther.Depth) <= Precision::Confusion())
145     {
146       return MinDist > theOther.MinDist;
147     }
148
149     return Depth > theOther.Depth;
150   }
151
152 };
153
154 #endif // _SelectMgr_SortCriterion_HeaderFile