0030679: Attached model hangs most of OCCT common functionality
[occt.git] / src / SelectMgr / SelectMgr_SelectionManager.cxx
1 // Created on: 1995-02-13
2 // Created by: Mister rmi
3 // Copyright (c) 1995-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 #include <SelectMgr_SelectionManager.hxx>
18
19 #include <SelectMgr_SelectableObject.hxx>
20 #include <SelectMgr_Selection.hxx>
21 #include <TCollection_AsciiString.hxx>
22
23 IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_SelectionManager,Standard_Transient)
24
25 //==================================================
26 // Function: Create
27 // Purpose :
28 //==================================================
29 SelectMgr_SelectionManager::SelectMgr_SelectionManager (const Handle(SelectMgr_ViewerSelector)& theSelector)
30 : mySelector (theSelector)
31 {
32   //
33 }
34
35 //==================================================
36 // Function: Contains
37 // Purpose :
38 //==================================================
39 Standard_Boolean SelectMgr_SelectionManager::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
40 {
41   return myGlobal.Contains (theObject);
42 }
43
44 //==================================================
45 // Function: Load
46 // Purpose :
47 //==================================================
48 void SelectMgr_SelectionManager::Load (const Handle(SelectMgr_SelectableObject)& theObject,
49                                        const Standard_Integer theMode)
50 {
51   if (myGlobal.Contains(theObject))
52     return;
53
54   for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next())
55   {
56     Load (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theMode);
57   }
58
59   if (!theObject->HasOwnPresentations())
60     return;
61
62   myGlobal.Add(theObject);
63   if (!mySelector->Contains (theObject) && theObject->HasOwnPresentations())
64   {
65     mySelector->AddSelectableObject (theObject);
66   }
67   if (theMode != -1)
68     loadMode (theObject, theMode);
69 }
70
71 //==================================================
72 // Function: Remove
73 // Purpose :
74 //==================================================
75 void SelectMgr_SelectionManager::Remove (const Handle(SelectMgr_SelectableObject)& theObject)
76 {
77   for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next())
78   {
79     Remove (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()));
80   }
81
82   if (!theObject->HasOwnPresentations())
83     return;
84
85   if (myGlobal.Contains (theObject))
86   {
87     if (mySelector->Contains (theObject))
88     {
89       for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObject->Selections()); aSelIter.More(); aSelIter.Next())
90       {
91         mySelector->RemoveSelectionOfObject (theObject, aSelIter.Value());
92         aSelIter.Value()->UpdateBVHStatus (SelectMgr_TBU_Remove);
93         mySelector->Deactivate (aSelIter.Value());
94       }
95       mySelector->RemoveSelectableObject (theObject);
96     }
97     myGlobal.Remove (theObject);
98   }
99
100   theObject->ClearSelections();
101 }
102
103 //==================================================
104 // Function: Activate
105 // Purpose :
106 //==================================================
107 void SelectMgr_SelectionManager::Activate (const Handle(SelectMgr_SelectableObject)& theObject,
108                                            const Standard_Integer theMode)
109 {
110   if (theMode == -1)
111     return;
112
113   for (PrsMgr_ListOfPresentableObjectsIter anChildIter (theObject->Children()); anChildIter.More(); anChildIter.Next())
114   {
115     Activate (Handle(SelectMgr_SelectableObject)::DownCast (anChildIter.Value()), theMode);
116   }
117   if (!theObject->HasOwnPresentations())
118     return;
119
120   Standard_Boolean isComputed = Standard_False;
121   if (const Handle(SelectMgr_Selection)& aSelOld = theObject->Selection (theMode))
122   {
123     isComputed = !aSelOld->IsEmpty();
124   }
125   if (!isComputed)
126   {
127     loadMode (theObject, theMode);
128   }
129
130   const Handle(SelectMgr_Selection)& aSelection = theObject->Selection (theMode);
131   switch (aSelection->UpdateStatus())
132   {
133     case SelectMgr_TOU_Full:
134     {
135       if (theObject->HasSelection (theMode))
136       {
137         mySelector->RemoveSelectionOfObject (theObject, aSelection);
138       }
139       theObject->RecomputePrimitives (theMode);
140       // pass through SelectMgr_TOU_Partial
141     }
142     Standard_FALLTHROUGH
143     case SelectMgr_TOU_Partial:
144     {
145       theObject->UpdateTransformations (aSelection);
146       mySelector->RebuildObjectsTree();
147       break;
148     }
149     default:
150       break;
151   }
152   aSelection->UpdateStatus(SelectMgr_TOU_None);
153
154   switch (aSelection->BVHUpdateStatus())
155   {
156     case SelectMgr_TBU_Add:
157     case SelectMgr_TBU_Renew:
158     {
159       mySelector->AddSelectionToObject (theObject, aSelection);
160       break;
161     }
162     case SelectMgr_TBU_Remove:
163     {
164       if (aSelection->GetSelectionState() == SelectMgr_SOS_Deactivated)
165       {
166         mySelector->AddSelectionToObject (theObject, aSelection);
167       }
168       break;
169     }
170     default:
171       break;
172   }
173   aSelection->UpdateBVHStatus (SelectMgr_TBU_None);
174
175   if (myGlobal.Contains (theObject))
176   {
177     mySelector->Activate (theObject->Selection (theMode));
178   }
179 }
180
181 //==================================================
182 // Function: Deactivate
183 // Purpose :
184 //==================================================
185 void SelectMgr_SelectionManager::Deactivate (const Handle(SelectMgr_SelectableObject)& theObject,
186                                              const Standard_Integer theMode)
187 {
188   for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next())
189   {
190     Deactivate (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theMode);
191   }
192   if (!theObject->HasOwnPresentations())
193   {
194     return;
195   }
196   if (!myGlobal.Contains(theObject))
197   {
198     return;
199   }
200
201   const Handle(SelectMgr_Selection)& aSel = theObject->Selection (theMode);
202   if (theMode == -1)
203   {
204     for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObject->Selections()); aSelIter.More(); aSelIter.Next())
205     {
206       mySelector->Deactivate (aSelIter.Value());
207     }
208   }
209   else if (!aSel.IsNull())
210   {
211     mySelector->Deactivate (aSel);
212   }
213 }
214
215 //=======================================================================
216 //function : IsActivated
217 //purpose  :
218 //=======================================================================
219 Standard_Boolean SelectMgr_SelectionManager::IsActivated (const Handle(SelectMgr_SelectableObject)& theObject,
220                                                           const Standard_Integer theMode) const
221 {
222   for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next())
223   {
224     if (IsActivated (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theMode))
225       return Standard_True;
226   }
227   if (!theObject->HasOwnPresentations())
228   {
229     return Standard_False;
230   }
231   if (!myGlobal.Contains(theObject))
232   {
233     return Standard_False;
234   }
235
236   if (theMode == -1)
237   {
238     for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObject->Selections()); aSelIter.More(); aSelIter.Next())
239     {
240       if (mySelector->Status (aSelIter.Value()) == SelectMgr_SOS_Activated)
241       {
242         return Standard_True;
243       }
244     }
245     return Standard_False;
246   }
247
248   const Handle(SelectMgr_Selection)& aSelection = theObject->Selection (theMode);
249   if (aSelection.IsNull())
250   {
251     return Standard_False;
252   }
253   return !aSelection.IsNull()
254        && mySelector->Status (aSelection) == SelectMgr_SOS_Activated;
255 }
256
257 //=======================================================================
258 //function : ClearSelectionStructures
259 //purpose  : Removes sensitive entities from all viewer selectors
260 //           after method Clear() was called to the selection they belonged to
261 //           or it was recomputed somehow
262 //=======================================================================
263 void SelectMgr_SelectionManager::ClearSelectionStructures (const Handle(SelectMgr_SelectableObject)& theObj,
264                                                            const Standard_Integer theMode)
265 {
266   for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObj->Children()); anChildrenIter.More(); anChildrenIter.Next())
267   {
268     ClearSelectionStructures (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theMode);
269   }
270
271   if (!theObj->HasOwnPresentations())
272   {
273     return;
274   }
275   if (!myGlobal.Contains(theObj))
276   {
277     return;
278   }
279
280   if (theMode != -1)
281   {
282     if (const Handle(SelectMgr_Selection)& aSelection = theObj->Selection (theMode))
283     {
284       mySelector->RemoveSelectionOfObject (theObj, aSelection);
285       aSelection->UpdateBVHStatus (SelectMgr_TBU_Add);
286     }
287   }
288   else
289   {
290     for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObj->Selections()); aSelIter.More(); aSelIter.Next())
291     {
292       const Handle(SelectMgr_Selection)& aSelection = aSelIter.Value();
293       mySelector->RemoveSelectionOfObject (theObj, aSelection);
294       aSelection->UpdateBVHStatus (SelectMgr_TBU_Add);
295     }
296   }
297   mySelector->RebuildObjectsTree();
298 }
299
300 //=======================================================================
301 //function : RestoreSelectionStructuress
302 //purpose  : Re-adds newely calculated sensitive  entities of recomputed selection
303 //           defined by mode theMode to all viewer selectors contained that selection.
304 //=======================================================================
305 void SelectMgr_SelectionManager::RestoreSelectionStructures (const Handle(SelectMgr_SelectableObject)& theObj,
306                                                              const Standard_Integer theMode)
307 {
308   for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObj->Children()); anChildrenIter.More(); anChildrenIter.Next())
309   {
310     RestoreSelectionStructures (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theMode);
311   }
312   if (!theObj->HasOwnPresentations())
313   {
314     return;
315   }
316   if (!myGlobal.Contains(theObj))
317   {
318     return;
319   }
320
321   if (theMode != -1)
322   {
323     if (const Handle(SelectMgr_Selection)& aSelection = theObj->Selection (theMode))
324     {
325       mySelector->AddSelectionToObject (theObj, aSelection);
326       aSelection->UpdateBVHStatus (SelectMgr_TBU_None);
327     }
328   }
329   else
330   {
331     for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObj->Selections()); aSelIter.More(); aSelIter.Next())
332     {
333       const Handle(SelectMgr_Selection)& aSelection = aSelIter.Value();
334       mySelector->AddSelectionToObject (theObj, aSelection);
335       aSelection->UpdateBVHStatus (SelectMgr_TBU_None);
336     }
337   }
338   mySelector->RebuildObjectsTree();
339 }
340
341 //==================================================
342 // Function: recomputeSelectionMode
343 // Purpose :
344 //==================================================
345 void SelectMgr_SelectionManager::recomputeSelectionMode (const Handle(SelectMgr_SelectableObject)& theObject,
346                                                          const Handle(SelectMgr_Selection)& theSelection,
347                                                          const Standard_Integer theMode)
348 {
349   theSelection->UpdateStatus (SelectMgr_TOU_Full);
350
351   ClearSelectionStructures (theObject, theMode);
352   theObject->RecomputePrimitives (theMode);
353   RestoreSelectionStructures (theObject, theMode);
354   theSelection->UpdateStatus (SelectMgr_TOU_None);
355   theSelection->UpdateBVHStatus (SelectMgr_TBU_None);
356 }
357
358 //==================================================
359 // Function: Update
360 // Purpose :
361 //==================================================
362 void SelectMgr_SelectionManager::RecomputeSelection (const Handle(SelectMgr_SelectableObject)& theObject,
363                                                      const Standard_Boolean theIsForce,
364                                                      const Standard_Integer theMode)
365 {
366   if (theIsForce)
367   {
368     if (theMode == -1)
369     {
370       ClearSelectionStructures (theObject);
371       theObject->RecomputePrimitives();
372       theObject->UpdateTransformation();
373       RestoreSelectionStructures (theObject);
374     }
375     else if (theObject->HasSelection (theMode))
376     {
377       ClearSelectionStructures (theObject, theMode);
378       theObject->RecomputePrimitives (theMode);
379       theObject->UpdateTransformation();
380       RestoreSelectionStructures (theObject, theMode);
381     }
382     return;
383   }
384
385   for (PrsMgr_ListOfPresentableObjectsIter anChildrenIter (theObject->Children()); anChildrenIter.More(); anChildrenIter.Next())
386   {
387     RecomputeSelection (Handle(SelectMgr_SelectableObject)::DownCast (anChildrenIter.Value()), theIsForce, theMode);
388   }
389   if (!theObject->HasOwnPresentations())
390   {
391     return;
392   }
393   if (!myGlobal.Contains (theObject))
394   {
395     return;
396   }
397
398   if (theMode == -1)
399   {
400     for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObject->Selections()); aSelIter.More(); aSelIter.Next())
401     {
402       const Handle(SelectMgr_Selection)& aSelection = aSelIter.Value();
403       const Standard_Integer aSelMode = aSelection->Mode();
404       recomputeSelectionMode (theObject, aSelection, aSelMode);
405     }
406   }
407   else
408   {
409     if (const Handle(SelectMgr_Selection)& aSelection = theObject->Selection (theMode))
410     {
411       recomputeSelectionMode (theObject, aSelection, theMode);
412     }
413   }
414 }
415
416 //=======================================================================
417 //function : Update
418 //purpose  : Selections are recalculated if they are flagged
419 //           "TO RECALCULATE" and activated in one of selectors.
420 //           If ForceUpdate = True, and they are "TO RECALCULATE"
421 //           This is done without caring for the state of activation.
422 //=======================================================================
423 void SelectMgr_SelectionManager::Update (const Handle(SelectMgr_SelectableObject)& theObject,
424                                          const Standard_Boolean theIsForce)
425 {
426   for (PrsMgr_ListOfPresentableObjectsIter aChildIter (theObject->Children()); aChildIter.More(); aChildIter.Next())
427   {
428     Update (Handle(SelectMgr_SelectableObject)::DownCast (aChildIter.Value()), theIsForce);
429   }
430   if (!theObject->HasOwnPresentations())
431   {
432     return;
433   }
434
435   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObject->Selections()); aSelIter.More(); aSelIter.Next())
436   {
437     const Handle(SelectMgr_Selection)& aSelection = aSelIter.Value();
438     if (theIsForce || mySelector->Status (aSelection) == SelectMgr_SOS_Activated)
439     {
440       switch (aSelection->UpdateStatus())
441       {
442         case SelectMgr_TOU_Full:
443         {
444           ClearSelectionStructures (theObject, aSelection->Mode());
445           theObject->RecomputePrimitives (aSelection->Mode()); // no break on purpose...
446           RestoreSelectionStructures (theObject, aSelection->Mode());
447           // pass through SelectMgr_TOU_Partial
448         }
449         Standard_FALLTHROUGH
450         case SelectMgr_TOU_Partial:
451         {
452           theObject->UpdateTransformations (aSelection);
453           mySelector->RebuildObjectsTree();
454           break;
455         }
456         default:
457           break;
458       }
459       aSelection->UpdateStatus (SelectMgr_TOU_None);
460       aSelection->UpdateBVHStatus (SelectMgr_TBU_None);
461     }
462   }
463 }
464
465 //==================================================
466 // Function: loadMode
467 // Purpose : Private Method
468 //==================================================
469 void SelectMgr_SelectionManager::loadMode (const Handle(SelectMgr_SelectableObject)& theObject,
470                                            const Standard_Integer theMode)
471 {
472   if (theMode == -1)
473   {
474     return;
475   }
476
477   if (const Handle(SelectMgr_Selection)& aSelOld = theObject->Selection (theMode))
478   {
479     if (aSelOld->IsEmpty())
480     {
481       if (aSelOld->BVHUpdateStatus() == SelectMgr_TBU_Remove)
482       {
483         Handle(SelectMgr_Selection) aNewSel = new SelectMgr_Selection (theMode);
484         theObject->AddSelection (aNewSel, theMode);
485         aNewSel->UpdateBVHStatus (SelectMgr_TBU_Remove);
486         aNewSel->SetSelectionState (SelectMgr_SOS_Deactivated);
487       }
488     }
489     return;
490   }
491
492   Handle(SelectMgr_Selection) aNewSel = new SelectMgr_Selection (theMode);
493   theObject->AddSelection (aNewSel, theMode);
494   if (myGlobal.Contains (theObject))
495   {
496     mySelector->AddSelectionToObject (theObject, aNewSel);
497     aNewSel->UpdateBVHStatus (SelectMgr_TBU_None);
498   }
499 }
500
501 //=======================================================================
502 //function : SetUpdateMode
503 //purpose  :
504 //=======================================================================
505 void SelectMgr_SelectionManager::SetUpdateMode (const Handle(SelectMgr_SelectableObject)& theObject,
506                                                 const SelectMgr_TypeOfUpdate theType)
507 {
508   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theObject->Selections()); aSelIter.More(); aSelIter.Next())
509   {
510     aSelIter.Value()->UpdateStatus (theType);
511   }
512 }
513
514 //=======================================================================
515 //function : SetUpdateMode
516 //purpose  :
517 //=======================================================================
518 void SelectMgr_SelectionManager::SetUpdateMode (const Handle(SelectMgr_SelectableObject)& theObject,
519                                                 const Standard_Integer theMode,
520                                                 const SelectMgr_TypeOfUpdate theType)
521 {
522   if (const Handle(SelectMgr_Selection)& aSel = theObject->Selection (theMode))
523   {
524     aSel->UpdateStatus (theType);
525   }
526 }
527
528 //=======================================================================
529 //function : SetSelectionSensitivity
530 //purpose  : Allows to manage sensitivity of a particular selection of interactive object theObject and
531 //           changes previous sensitivity value of all sensitive entities in selection with theMode
532 //           to the given theNewSensitivity.
533 //=======================================================================
534 void SelectMgr_SelectionManager::SetSelectionSensitivity (const Handle(SelectMgr_SelectableObject)& theObject,
535                                                           const Standard_Integer theMode,
536                                                           const Standard_Integer theNewSens)
537 {
538   Standard_ASSERT_RAISE (theNewSens > 0, "Error! Selection sensitivity have positive value.");
539   if (theObject.IsNull())
540   {
541     return;
542   }
543
544   const Handle(SelectMgr_Selection)& aSel = theObject->Selection (theMode);
545   if (aSel.IsNull())
546   {
547     return;
548   }
549
550   const Standard_Integer aPrevSens = aSel->Sensitivity();
551   aSel->SetSensitivity (theNewSens);
552   if (myGlobal.Contains (theObject)
553    && mySelector->Contains (theObject))
554   {
555     mySelector->myTolerances.Decrement (aPrevSens);
556     mySelector->myTolerances.Add (theNewSens);
557     mySelector->myToUpdateTolerance = Standard_True;
558   }
559 }
560
561 //=======================================================================
562 //function : UpdateSelection
563 //purpose  :
564 //=======================================================================
565 void SelectMgr_SelectionManager::UpdateSelection (const Handle(SelectMgr_SelectableObject)& theObject)
566 {
567   if (myGlobal.Contains (theObject)
568    && mySelector->Contains (theObject))
569   {
570     mySelector->MoveSelectableObject (theObject);
571   }
572 }