5c833db121fbd0ca80f45e1a059a047f7372a166
[occt.git] / src / Select3D / Select3D_SensitiveGroup.cxx
1 // File:        Select3D_SensitiveGroup.cxx
2 // Created:     Thu Apr 16 16:17:00 1998
3 // Author:      Robert COUBLANC
4 //              <rob@robox.paris1.matra-dtv.fr>
5
6
7 #include <Select3D_SensitiveGroup.ixx>
8 #include <Select3D_ListIteratorOfListOfSensitive.hxx>
9 #include <Precision.hxx>
10
11 Select3D_SensitiveGroup::Select3D_SensitiveGroup(const Handle(SelectBasics_EntityOwner)& OwnerId,
12                                                  const Standard_Boolean MatchAll):
13 Select3D_SensitiveEntity(OwnerId),
14 myMustMatchAll(MatchAll),
15 myLastRank(0),
16 myX(0.),
17 myY(0.)
18 {
19 }
20
21 Select3D_SensitiveGroup::Select3D_SensitiveGroup(const Handle(SelectBasics_EntityOwner)& OwnerId,
22                                                   Select3D_ListOfSensitive& TheList,
23                                                  const Standard_Boolean MatchAll):
24
25 Select3D_SensitiveEntity(OwnerId),
26 myMustMatchAll(MatchAll),
27 myLastRank(0),
28 myX(0.),
29 myY(0.)
30 {
31   myList.Append(TheList);
32 }
33
34 //=======================================================================
35 //function : Add
36 //purpose  : No control of  entities inside 
37 //=======================================================================
38 void Select3D_SensitiveGroup::Add(Select3D_ListOfSensitive& LL) 
39 {myList.Append(LL);}
40
41 //=======================================================================
42 //function : Add
43 //purpose  : 
44 //=======================================================================
45 void Select3D_SensitiveGroup::Add(const Handle(Select3D_SensitiveEntity)& aSensitive) 
46 {
47   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
48     if(It.Value()==aSensitive) return;
49   }
50   myList.Append(aSensitive);
51 }
52
53 //=======================================================================
54 //function : Remove
55 //purpose  : 
56 //=======================================================================
57 void Select3D_SensitiveGroup::Remove(const Handle(Select3D_SensitiveEntity)& aSensitive) 
58 {
59   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
60     if(It.Value()==aSensitive){
61       myList.Remove(It);
62       return;
63     }
64   }
65 }
66
67 //=======================================================================
68 //function : IsIn
69 //purpose  : 
70 //=======================================================================
71 Standard_Boolean Select3D_SensitiveGroup::IsIn(const Handle(Select3D_SensitiveEntity)& aSensitive) const
72 {
73   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
74     if(It.Value()==aSensitive)
75       return Standard_True;
76   }
77   return Standard_False;
78
79 }
80 //=======================================================================
81 //function : Clear
82 //purpose  : 
83 //=======================================================================
84 void Select3D_SensitiveGroup::Clear()
85 {myList.Clear();}
86
87 //=======================================================================
88 //function : Project
89 //purpose  : 
90 //=======================================================================
91
92 void Select3D_SensitiveGroup::Project(const Select3D_Projector& aProjector) 
93 {
94   Select3D_SensitiveEntity::Project(aProjector); // to set the field last proj...
95   
96   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
97     It.Value()->Project(aProjector);
98   }
99 }
100
101 //=======================================================================
102 //function : Areas
103 //purpose  : 
104 //=======================================================================
105
106 void Select3D_SensitiveGroup::Areas(SelectBasics_ListOfBox2d& boxes) 
107 {
108   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
109     It.Value()->Areas(boxes);
110   }
111 }
112
113 //=======================================================================
114 //function : GetConnected
115 //purpose  : 
116 //=======================================================================
117
118 Handle(Select3D_SensitiveEntity) Select3D_SensitiveGroup::GetConnected(const TopLoc_Location& aLocation) 
119 {
120   Handle(Select3D_SensitiveGroup) newgroup = new Select3D_SensitiveGroup(myOwnerId,myMustMatchAll);
121   Select3D_ListOfSensitive LL;
122   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
123     LL.Append(It.Value()->GetConnected(aLocation));
124   }
125   newgroup->Add(LL);
126   return newgroup;
127 }
128
129 //=======================================================================
130 //function : SetLocation
131 //purpose  : 
132 //=======================================================================
133
134 void Select3D_SensitiveGroup::SetLocation(const TopLoc_Location& aLoc) 
135 {
136   if(aLoc.IsIdentity()) return;
137
138   if(HasLocation())
139     if(aLoc == Location()) return;
140   
141   Select3D_SensitiveEntity::SetLocation(aLoc);
142   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
143     if(It.Value()->HasLocation()){
144       if(It.Value()->Location()!=aLoc)
145         It.Value()->SetLocation(It.Value()->Location()*aLoc);
146     }
147     else
148       It.Value()->SetLocation(aLoc);
149     
150   }
151 }
152
153 //=======================================================================
154 //function : ResetLocation
155 //purpose  : 
156 //=======================================================================
157 void Select3D_SensitiveGroup::ResetLocation() 
158 {
159  if(!HasLocation()) return;
160  for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
161    if(It.Value()->HasLocation() && It.Value()->Location()!=Location())
162      It.Value()->SetLocation(It.Value()->Location()*Location().Inverted());
163    else
164      It.Value()->ResetLocation();
165    
166  }
167  Select3D_SensitiveEntity::ResetLocation();
168 }
169
170 //=======================================================================
171 //function : Matches
172 //purpose  : 
173 //=======================================================================
174 Standard_Boolean Select3D_SensitiveGroup::Matches(const Standard_Real X,
175                                                   const Standard_Real Y,
176                                                   const Standard_Real aTol,
177                                                   Standard_Real& DMin) 
178 {
179   myLastRank = 0;
180   myLastTol = aTol;
181   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
182     myLastRank++;
183     if(It.Value()->Matches(X,Y,aTol,DMin)){
184       myX = X;myY = Y;myLastTol = aTol;
185       SetLastDepth( Precision::Infinite() );
186       
187       Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
188       return Standard_True;
189     }
190   }
191   myLastRank =0;
192   SetLastDepth(0.0);
193   return Standard_False;
194 }
195
196 //=======================================================================
197 //function : Matches
198 //purpose  :  si on doit tout matcher, on ne repond oui que si toutes
199 //            les primitives repondent oui
200 //=======================================================================
201 Standard_Boolean Select3D_SensitiveGroup::Matches(const Standard_Real XMin,
202                                                   const Standard_Real YMin,
203                                                   const Standard_Real XMax,
204                                                   const Standard_Real YMax,
205                                                   const Standard_Real aTol) 
206 {
207   Standard_Boolean result(Standard_True);
208   
209   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
210     if(It.Value()->Matches(XMin,YMin,XMax,YMax,aTol)){
211       if(!myMustMatchAll)
212         return Standard_True;
213     }
214     // ca ne matches pas..
215     else {
216       if(myMustMatchAll)
217         return Standard_False;
218       else
219         result = Standard_False;
220     }
221   }
222   return result;
223 }
224
225 //=======================================================================
226 //function : Matches
227 //purpose  : 
228 //=======================================================================
229
230 Standard_Boolean Select3D_SensitiveGroup::
231 Matches (const TColgp_Array1OfPnt2d& aPoly,
232          const Bnd_Box2d& aBox,
233          const Standard_Real aTol)
234
235   Standard_Boolean result(Standard_True);
236   
237   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
238     if(It.Value()->Matches(aPoly, aBox, aTol)){
239       if(!myMustMatchAll)
240         return Standard_True;
241     }
242     else {
243       if(myMustMatchAll)
244         return Standard_False;
245       else
246         result = Standard_False;
247     }
248   }
249   return result;
250 }
251
252
253 //=======================================================================
254 //function : ComputeDepth
255 //purpose  : to optimise, the minimum depth for 
256 //          entities that answer YES to Matches(X,Y,...) is taken
257 //          the test is started from mylastRank...
258 //=======================================================================
259 Standard_Real Select3D_SensitiveGroup::ComputeDepth(const gp_Lin& EyeLine) const
260 {
261   Standard_Integer currank(0);
262   Standard_Real DMin,thedepth(Precision::Infinite());
263   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
264     currank++;
265     if(currank>=myLastRank){
266       if(It.Value()->Matches(myX,myY,myLastTol,DMin)){
267         It.Value()->ComputeDepth(EyeLine);
268         thedepth = Min(Depth(),
269                        It.Value()->Depth());
270       }
271     }
272     
273   }
274   return thedepth;
275 }
276
277 //=======================================================================
278 //function : MaxBoxes
279 //purpose  : 
280 //=======================================================================
281 Standard_Integer Select3D_SensitiveGroup::MaxBoxes() const
282 {
283   Standard_Integer nbboxes(0);
284   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
285     nbboxes+=It.Value()->MaxBoxes();
286   }
287   return nbboxes;
288 }
289
290 void Select3D_SensitiveGroup::SetLastPrj(const Select3D_Projector& Prj)
291 {
292   Select3D_SensitiveEntity::SetLastPrj(Prj);
293   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
294     It.Value()->SetLastPrj(Prj);
295 }