554afffbe75abb11405f05c42bc24bd31e8f969c
[occt.git] / src / Select3D / Select3D_SensitiveGroup.cxx
1 // Created on: 1998-04-16
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22
23 #include <Select3D_SensitiveGroup.ixx>
24 #include <Select3D_ListIteratorOfListOfSensitive.hxx>
25 #include <Precision.hxx>
26
27 //=======================================================================
28 //function : Creation
29 //purpose  : 
30 //=======================================================================
31 Select3D_SensitiveGroup::Select3D_SensitiveGroup(const Handle(SelectBasics_EntityOwner)& OwnerId,
32                                                  const Standard_Boolean MatchAll):
33 Select3D_SensitiveEntity(OwnerId),
34 myMustMatchAll(MatchAll),
35 myLastRank(0),
36 myX(0.),
37 myY(0.)
38 {
39 }
40
41 //=======================================================================
42 //function : Creation
43 //purpose  : 
44 //=======================================================================
45
46 Select3D_SensitiveGroup::Select3D_SensitiveGroup(const Handle(SelectBasics_EntityOwner)& OwnerId,
47                                                  Select3D_ListOfSensitive& TheList, 
48                                                  const Standard_Boolean MatchAll):
49 Select3D_SensitiveEntity(OwnerId),
50 myMustMatchAll(MatchAll),
51 myLastRank(0),
52 myX(0.),
53 myY(0.)
54 {
55   myList.Append(TheList);
56 }
57
58 //=======================================================================
59 //function : Add
60 //purpose  : No control of  entities inside 
61 //=======================================================================
62
63 void Select3D_SensitiveGroup::Add(Select3D_ListOfSensitive& LL) 
64 {myList.Append(LL);}
65
66 //=======================================================================
67 //function : Add
68 //purpose  : 
69 //=======================================================================
70
71 void Select3D_SensitiveGroup::Add(const Handle(Select3D_SensitiveEntity)& aSensitive) 
72 {
73   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
74   {
75     if(It.Value()==aSensitive) return;
76   }
77   myList.Append(aSensitive);
78 }
79
80 //=======================================================================
81 //function : Remove
82 //purpose  : 
83 //=======================================================================
84
85 void Select3D_SensitiveGroup::Remove(const Handle(Select3D_SensitiveEntity)& aSensitive) 
86 {
87   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
88   {
89     if(It.Value()==aSensitive)
90     {
91       myList.Remove(It);
92       return;
93     }
94   }
95 }
96
97 //=======================================================================
98 //function : IsIn
99 //purpose  : 
100 //=======================================================================
101
102 Standard_Boolean Select3D_SensitiveGroup::IsIn(const Handle(Select3D_SensitiveEntity)& aSensitive) const
103 {
104   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
105   {
106     if(It.Value()==aSensitive)
107       return Standard_True;
108   }
109   return Standard_False;
110 }
111
112 //=======================================================================
113 //function : Clear
114 //purpose  : 
115 //=======================================================================
116
117 void Select3D_SensitiveGroup::Clear()
118 {myList.Clear();}
119
120 //=======================================================================
121 //function : Project
122 //purpose  : 
123 //=======================================================================
124
125 void Select3D_SensitiveGroup::Project(const Handle(Select3D_Projector)& aProjector) 
126 {
127   Select3D_SensitiveEntity::Project(aProjector); // to set the field last proj...
128
129   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) 
130   {
131     It.Value()->Project(aProjector);
132   }
133 }
134
135 //=======================================================================
136 //function : Areas
137 //purpose  : 
138 //=======================================================================
139
140 void Select3D_SensitiveGroup::Areas(SelectBasics_ListOfBox2d& boxes) 
141 {
142   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) 
143   {
144     It.Value()->Areas(boxes);
145   }
146 }
147
148 //=======================================================================
149 //function : GetConnected
150 //purpose  : 
151 //=======================================================================
152
153 Handle(Select3D_SensitiveEntity) Select3D_SensitiveGroup::GetConnected(const TopLoc_Location& aLocation) 
154 {
155   Handle(Select3D_SensitiveGroup) newgroup = new Select3D_SensitiveGroup(myOwnerId,myMustMatchAll);
156   Select3D_ListOfSensitive LL;
157   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) 
158   {
159     LL.Append(It.Value()->GetConnected(aLocation));
160   }
161   newgroup->Add(LL);
162   return newgroup;
163 }
164
165 //=======================================================================
166 //function : SetLocation
167 //purpose  : 
168 //=======================================================================
169
170 void Select3D_SensitiveGroup::SetLocation(const TopLoc_Location& aLoc) 
171 {
172   if(aLoc.IsIdentity()) return;
173
174   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
175   {
176     It.Value()->SetLocation(aLoc);
177   }
178
179   if(HasLocation())
180     if(aLoc == Location()) return;
181   
182   Select3D_SensitiveEntity::SetLocation(aLoc);
183   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) 
184   {
185     if(It.Value()->HasLocation())
186     {
187       if(It.Value()->Location()!=aLoc) 
188         It.Value()->SetLocation(It.Value()->Location()*aLoc);
189     }
190     else
191       It.Value()->SetLocation(aLoc);
192   }
193 }
194
195 //=======================================================================
196 //function : ResetLocation
197 //purpose  : 
198 //=======================================================================
199
200 void Select3D_SensitiveGroup::ResetLocation() 
201 {
202  if(!HasLocation()) return;
203  for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
204  {
205    if(It.Value()->HasLocation() && It.Value()->Location()!=Location())
206      It.Value()->SetLocation(It.Value()->Location()*Location().Inverted());
207    else
208      It.Value()->ResetLocation();
209  }
210  Select3D_SensitiveEntity::ResetLocation();
211 }
212
213 //=======================================================================
214 //function : Matches
215 //purpose  : 
216 //=======================================================================
217
218 Standard_Boolean Select3D_SensitiveGroup::Matches(const Standard_Real X, 
219                                                   const Standard_Real Y, 
220                                                   const Standard_Real aTol, 
221                                                   Standard_Real& DMin) 
222 {
223   myLastRank = 0;
224   myLastTol = (Standard_ShortReal)aTol;
225   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
226     myLastRank++;
227     if (It.Value()->Matches (X, Y, aTol, DMin))
228     {
229       myX = (Standard_ShortReal)X;
230       myY = (Standard_ShortReal)Y;
231       myLastTol = (Standard_ShortReal)aTol;
232       // compute and validate the depth (will call ::ComputeDepth())
233       return Select3D_SensitiveEntity::Matches (X, Y, aTol, DMin);
234     }
235   }
236   // no match
237   myLastRank = 0;
238   SetLastDepth (ShortRealLast());
239   return Standard_False;
240 }
241
242 //=======================================================================
243 //function : Matches
244 //purpose  :  si on doit tout matcher, on ne repond oui que si toutes
245 //            les primitives repondent oui
246 //=======================================================================
247 Standard_Boolean Select3D_SensitiveGroup::Matches(const Standard_Real XMin, 
248                                                   const Standard_Real YMin, 
249                                                   const Standard_Real XMax, 
250                                                   const Standard_Real YMax, 
251                                                   const Standard_Real aTol) 
252 {
253   Standard_Boolean result(Standard_True);
254   
255   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
256   {
257     if(It.Value()->Matches(XMin,YMin,XMax,YMax,aTol))
258     {
259       if(!myMustMatchAll)
260         return Standard_True;
261     }
262     // ca ne matches pas..
263     else 
264     {
265       if(myMustMatchAll) 
266         return Standard_False;
267       else 
268         result = Standard_False;
269     }
270   }
271   return result;
272 }
273
274 //=======================================================================
275 //function : Matches
276 //purpose  : 
277 //=======================================================================
278
279 Standard_Boolean Select3D_SensitiveGroup::
280 Matches (const TColgp_Array1OfPnt2d& aPoly,
281          const Bnd_Box2d& aBox,
282          const Standard_Real aTol)
283
284   Standard_Boolean result(Standard_True);
285   
286   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
287   {
288     if(It.Value()->Matches(aPoly, aBox, aTol))
289     {
290       if(!myMustMatchAll) 
291         return Standard_True;
292     }
293     else 
294     {
295       if(myMustMatchAll) 
296         return Standard_False;
297       else 
298         result = Standard_False;
299     }
300   }
301   return result;
302 }
303
304 //=======================================================================
305 //function : ComputeDepth
306 //purpose  : to optimise, the minimum depth for 
307 //          entities that answer YES to Matches(X,Y,...) is taken
308 //          the test is started from mylastRank...
309 //=======================================================================
310 Standard_Real Select3D_SensitiveGroup::ComputeDepth(const gp_Lin& EyeLine) const
311 {
312   Standard_Integer currank = 0;
313   Standard_Real DMin, thedepth (Precision::Infinite());
314   for (Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
315   {
316     currank++;
317     if (currank >= myLastRank)
318     {
319       // this recomputes and validates the depth for the entity
320       if (It.Value()->Matches (myX, myY, myLastTol, DMin))
321       {
322         It.Value()->ComputeDepth (EyeLine);
323         if (It.Value()->Depth() < thedepth)
324         {
325           // search for topmost entity
326           thedepth = It.Value()->Depth();
327           //myLastRank = currank; // can not do this here...
328         }
329       }
330     }
331   }
332   return thedepth;
333 }
334
335 //=======================================================================
336 //function : MaxBoxes
337 //purpose  : 
338 //=======================================================================
339
340 Standard_Integer Select3D_SensitiveGroup::MaxBoxes() const
341 {
342   Standard_Integer nbboxes(0);
343   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
344     nbboxes+=It.Value()->MaxBoxes();
345   }
346   return nbboxes;
347 }
348
349 //=======================================================================
350 //function : SetLastPrj
351 //purpose  : 
352 //=======================================================================
353
354 void Select3D_SensitiveGroup::SetLastPrj(const Handle(Select3D_Projector)& Prj)
355 {
356   Select3D_SensitiveEntity::SetLastPrj(Prj);
357   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
358     It.Value()->SetLastPrj(Prj);
359 }
360
361 //=======================================================================
362 //function : Set
363 //purpose  : 
364 //=======================================================================
365
366 void Select3D_SensitiveGroup::Set 
367   (const Handle(SelectBasics_EntityOwner)& TheOwnerId)
368
369   Select3D_SensitiveEntity::Set(TheOwnerId);
370   // set TheOwnerId for each element of sensitive group
371   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
372     It.Value()->Set(TheOwnerId);
373 }