0029947: Visualization - SelectMgr_SelectableObject::GetSelectPresentation() should...
[occt.git] / src / SelectMgr / SelectMgr_SelectableObject.cxx
1 // Created on: 1995-02-20
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_SelectableObject.hxx>
18
19 #include <Aspect_TypeOfMarker.hxx>
20 #include <Bnd_Box.hxx>
21 #include <gp_Pnt.hxx>
22 #include <Graphic3d_AspectLine3d.hxx>
23 #include <Graphic3d_AspectMarker3d.hxx>
24 #include <Prs3d_Drawer.hxx>
25 #include <Prs3d_LineAspect.hxx>
26 #include <Prs3d_PlaneAspect.hxx>
27 #include <Prs3d_PointAspect.hxx>
28 #include <Prs3d_Presentation.hxx>
29 #include <PrsMgr_PresentableObjectPointer.hxx>
30 #include <PrsMgr_PresentationManager3d.hxx>
31 #include <Select3D_SensitiveEntity.hxx>
32 #include <SelectBasics_EntityOwner.hxx>
33 #include <SelectMgr_EntityOwner.hxx>
34 #include <SelectMgr_IndexedMapOfOwner.hxx>
35 #include <SelectMgr_Selection.hxx>
36 #include <SelectMgr_SelectionManager.hxx>
37 #include <Standard_NoSuchObject.hxx>
38 #include <Standard_NotImplemented.hxx>
39 #include <Standard_Type.hxx>
40 #include <TopLoc_Location.hxx>
41
42 IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_SelectableObject,PrsMgr_PresentableObject)
43
44 namespace
45 {
46   Handle(SelectMgr_Selection)   THE_NULL_SELECTION;
47   Handle(SelectMgr_EntityOwner) THE_NULL_ENTITYOWNER;
48 }
49
50 //==================================================
51 // Function: SelectMgr_SelectableObject
52 // Purpose :
53 //==================================================
54
55 SelectMgr_SelectableObject::SelectMgr_SelectableObject (const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d)
56 : PrsMgr_PresentableObject (aTypeOfPresentation3d),
57   myAutoHilight            (Standard_True),
58   mycurrent                (0),
59   myGlobalSelMode          (0)
60 {
61   //
62 }
63
64 //==================================================
65 // Function: Destructor
66 // Purpose : Clears all selections of the object
67 //==================================================
68 SelectMgr_SelectableObject::~SelectMgr_SelectableObject()
69 {
70   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (myselections); aSelIter.More(); aSelIter.Next())
71   {
72     aSelIter.Value()->Clear();
73   }
74 }
75
76 //==================================================
77 // Function: RecomputePrimitives
78 // Purpose : IMPORTANT: Do not use this method to update
79 //           selection primitives except implementing custom
80 //           selection manager! This method does not take
81 //           into account necessary BVH updates, but may
82 //           invalidate the pointers it refers to.
83 //           TO UPDATE SELECTION properly from outside classes,
84 //           use method UpdateSelection.
85 //==================================================
86 void SelectMgr_SelectableObject::RecomputePrimitives()
87 {
88   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (myselections); aSelIter.More(); aSelIter.Next())
89   {
90     RecomputePrimitives (aSelIter.Value()->Mode());
91   }
92 }
93
94 //==================================================
95 // Function: RecomputePrimitives
96 // Purpose : IMPORTANT: Do not use this method to update
97 //           selection primitives except implementing custom
98 //           selection manager! This method does not take
99 //           into account necessary BVH updates, but may
100 //           invalidate the pointers it refers to.
101 //           TO UPDATE SELECTION properly from outside classes,
102 //           use method UpdateSelection.
103 //==================================================
104 void SelectMgr_SelectableObject::RecomputePrimitives (const Standard_Integer theMode)
105 {
106   SelectMgr_SelectableObject* aSelParent = dynamic_cast<SelectMgr_SelectableObject* > (Parent());
107   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (myselections); aSelIter.More(); aSelIter.Next())
108   {
109     const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
110     if (aSel->Mode() == theMode)
111     {
112       aSel->Clear();
113       ComputeSelection (aSel, theMode);
114       aSel->UpdateStatus (SelectMgr_TOU_Partial);
115       aSel->UpdateBVHStatus (SelectMgr_TBU_Renew);
116       if (theMode == 0 && aSelParent != NULL)
117       {
118         if (const Handle(SelectMgr_EntityOwner)& anAsmOwner = aSelParent->GetAssemblyOwner())
119         {
120           SetAssemblyOwner (anAsmOwner, theMode);
121         }
122       }
123       return;
124     }
125   }
126
127   Handle(SelectMgr_Selection) aNewSel = new SelectMgr_Selection (theMode);
128   ComputeSelection (aNewSel, theMode);
129
130   if (theMode == 0 && aSelParent != NULL)
131   {
132     if (const Handle(SelectMgr_EntityOwner)& anAsmOwner = aSelParent->GetAssemblyOwner())
133     {
134       SetAssemblyOwner (anAsmOwner, theMode);
135     }
136   }
137
138   aNewSel->UpdateStatus (SelectMgr_TOU_Partial);
139   aNewSel->UpdateBVHStatus (SelectMgr_TBU_Add);
140
141   myselections.Append (aNewSel);
142 }
143
144 //==================================================
145 // Function: ClearSelections
146 // Purpose :
147 //==================================================
148 void SelectMgr_SelectableObject::ClearSelections (const Standard_Boolean theToUpdate)
149 {
150   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (myselections); aSelIter.More(); aSelIter.Next())
151   {
152     const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
153     aSel->Clear();
154     aSel->UpdateBVHStatus (SelectMgr_TBU_Remove);
155     if (theToUpdate)
156     {
157       aSel->UpdateStatus (SelectMgr_TOU_Full);
158     }
159   }
160 }
161
162
163 //==================================================
164 // Function: Selection
165 // Purpose :
166 //==================================================
167
168 const Handle(SelectMgr_Selection)& SelectMgr_SelectableObject::Selection (const Standard_Integer theMode) const
169 {
170   if (theMode == -1)
171   {
172     return THE_NULL_SELECTION;
173   }
174
175   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (myselections); aSelIter.More(); aSelIter.Next())
176   {
177     const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
178     if (aSel->Mode() == theMode)
179     {
180       return aSel;
181     }
182   }
183   return THE_NULL_SELECTION;
184 }
185
186 //==================================================
187 // Function: AddSelection
188 // Purpose :
189 //==================================================
190
191 void SelectMgr_SelectableObject::AddSelection (const Handle(SelectMgr_Selection)& theSel,
192                                                const Standard_Integer theMode)
193 {
194   if(theSel->IsEmpty())
195   {
196     ComputeSelection(theSel, theMode);
197     theSel->UpdateStatus(SelectMgr_TOU_Partial);
198     theSel->UpdateBVHStatus (SelectMgr_TBU_Add);
199   }
200
201   Standard_Boolean isReplaced = Standard_False;
202   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (myselections); aSelIter.More(); aSelIter.Next())
203   {
204     if (aSelIter.Value()->Mode() == theMode)
205     {
206       isReplaced = Standard_True;
207       myselections.Remove (aSelIter);
208       break;
209     }
210   }
211
212   myselections.Append (theSel);
213   if (isReplaced)
214   {
215     myselections.Last()->UpdateBVHStatus (SelectMgr_TBU_Renew);
216   }
217
218   if (theMode == 0)
219   {
220     SelectMgr_SelectableObject* aSelParent = dynamic_cast<SelectMgr_SelectableObject* > (Parent());
221     if (aSelParent != NULL)
222     {
223       if (const Handle(SelectMgr_EntityOwner)& anAsmOwner = aSelParent->GetAssemblyOwner())
224       {
225         SetAssemblyOwner (anAsmOwner, theMode);
226       }
227     }
228   }
229 }
230
231 //=======================================================================
232 //function : ReSetTransformation
233 //purpose  :
234 //=======================================================================
235 void SelectMgr_SelectableObject::ResetTransformation() 
236 {
237   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (myselections); aSelIter.More(); aSelIter.Next())
238   {
239     const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
240     aSel->UpdateStatus (SelectMgr_TOU_Partial);
241     aSel->UpdateBVHStatus (SelectMgr_TBU_None);
242   }
243
244   PrsMgr_PresentableObject::ResetTransformation();
245 }
246
247 //=======================================================================
248 //function : UpdateTransformation
249 //purpose  :
250 //=======================================================================
251 void SelectMgr_SelectableObject::UpdateTransformation()
252 {
253   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (myselections); aSelIter.More(); aSelIter.Next())
254   {
255     aSelIter.Value()->UpdateStatus (SelectMgr_TOU_Partial);
256   }
257
258   PrsMgr_PresentableObject::UpdateTransformation();
259 }
260
261 //=======================================================================
262 //function : UpdateTransformation
263 //purpose  :
264 //=======================================================================
265 void SelectMgr_SelectableObject::UpdateTransformations (const Handle(SelectMgr_Selection)& theSel)
266 {
267   const TopLoc_Location aSelfLocation (Transformation());
268   for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
269   {
270     if (Handle(Select3D_SensitiveEntity) aSensEntity = Handle(Select3D_SensitiveEntity)::DownCast (aSelEntIter.Value()->BaseSensitive()))
271     {
272       const Handle(SelectBasics_EntityOwner)& aEOwner = aSensEntity->OwnerId();
273       if (Handle(SelectMgr_EntityOwner) aMgrEO = Handle(SelectMgr_EntityOwner)::DownCast (aEOwner))
274       {
275         aMgrEO->SetLocation (aSelfLocation);
276       }
277     }
278   }
279 }
280
281 //=======================================================================
282 //function : HilightSelected
283 //purpose  :
284 //=======================================================================
285 void SelectMgr_SelectableObject::HilightSelected (const Handle(PrsMgr_PresentationManager3d)&,
286                                                   const SelectMgr_SequenceOfOwner&)
287 {
288   throw Standard_NotImplemented("SelectMgr_SelectableObject::HilightSelected");
289 }
290
291 //=======================================================================
292 //function : ClearSelected
293 //purpose  :
294 //=======================================================================
295 void SelectMgr_SelectableObject::ClearSelected()
296 {
297   if(!mySelectionPrs.IsNull())
298   {
299     mySelectionPrs->Clear();
300   }
301 }
302
303 //=======================================================================
304 //function : ClearDynamicHighlight
305 //purpose  :
306 //=======================================================================
307 void SelectMgr_SelectableObject::ClearDynamicHighlight (const Handle(PrsMgr_PresentationManager3d)& theMgr)
308 {
309   theMgr->ClearImmediateDraw();
310 }
311
312 //=======================================================================
313 //function : HilightOwnerWithColor
314 //purpose  :
315 //=======================================================================
316 void SelectMgr_SelectableObject::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)&,
317                                                         const Handle(Prs3d_Drawer)&,
318                                                         const Handle(SelectMgr_EntityOwner)&)
319 {
320   throw Standard_NotImplemented("SelectMgr_SelectableObject::HilightOwnerWithColor");
321 }
322
323 //=======================================================================
324 //function : IsAutoHilight
325 //purpose  :
326 //=======================================================================
327 Standard_Boolean SelectMgr_SelectableObject::IsAutoHilight() const
328 {
329   return myAutoHilight;
330 }
331
332 //=======================================================================
333 //function : SetAutoHilight
334 //purpose  :
335 //=======================================================================
336 void SelectMgr_SelectableObject::SetAutoHilight ( const Standard_Boolean newAutoHilight )
337 {
338   myAutoHilight = newAutoHilight;
339 }
340
341 //=======================================================================
342 //function : GetHilightPresentation
343 //purpose  :
344 //=======================================================================
345 Handle(Prs3d_Presentation) SelectMgr_SelectableObject::GetHilightPresentation (const Handle(PrsMgr_PresentationManager3d)& theMgr)
346 {
347   if (myHilightPrs.IsNull() && !theMgr.IsNull())
348   {
349     myHilightPrs = new Prs3d_Presentation (theMgr->StructureManager());
350     myHilightPrs->SetTransformPersistence (TransformPersistence());
351     myHilightPrs->SetClipPlanes (myClipPlanes);
352   }
353
354   return myHilightPrs;
355 }
356
357
358 //=======================================================================
359 //function : GetSelectPresentation
360 //purpose  :
361 //=======================================================================
362 Handle(Prs3d_Presentation) SelectMgr_SelectableObject::GetSelectPresentation (const Handle(PrsMgr_PresentationManager3d)& theMgr)
363 {
364   if (mySelectionPrs.IsNull() && !theMgr.IsNull())
365   {
366     mySelectionPrs = new Prs3d_Presentation (theMgr->StructureManager());
367     mySelectionPrs->SetTransformPersistence (TransformPersistence());
368     mySelectionPrs->SetClipPlanes (myClipPlanes);
369   }
370
371   return mySelectionPrs;
372 }
373
374 //=======================================================================
375 //function : ErasePresentations
376 //purpose  :
377 //=======================================================================
378 void SelectMgr_SelectableObject::ErasePresentations (Standard_Boolean theToRemove)
379 {
380   if (!mySelectionPrs.IsNull())
381   {
382     mySelectionPrs->Erase();
383     if (theToRemove)
384     {
385       mySelectionPrs->Clear();
386       mySelectionPrs.Nullify();
387     }
388   }
389   if (!myHilightPrs.IsNull())
390   {
391     myHilightPrs->Erase();
392     if (theToRemove)
393     {
394       myHilightPrs->Clear();
395       myHilightPrs.Nullify();
396     }
397   }
398 }
399
400 //=======================================================================
401 //function : SetZLayer
402 //purpose  :
403 //=======================================================================
404 void SelectMgr_SelectableObject::SetZLayer (const Graphic3d_ZLayerId theLayerId)
405 {
406   // update own presentations
407   PrsMgr_PresentableObject::SetZLayer (theLayerId);
408
409   // update selection presentations
410   if (!mySelectionPrs.IsNull())
411     mySelectionPrs->SetZLayer (theLayerId);
412
413   if (!myHilightPrs.IsNull())
414     myHilightPrs->SetZLayer (theLayerId);
415
416   // update all entity owner presentations
417   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (myselections); aSelIter.More(); aSelIter.Next())
418   {
419     const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
420     for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
421     {
422       if (Handle(Select3D_SensitiveEntity) aEntity = Handle(Select3D_SensitiveEntity)::DownCast (aSelEntIter.Value()->BaseSensitive()))
423       {
424         if (Handle(SelectMgr_EntityOwner) aOwner = Handle(SelectMgr_EntityOwner)::DownCast (aEntity->OwnerId()))
425         {
426           aOwner->SetZLayer (theLayerId);
427         }
428       }
429     }
430   }
431 }
432
433 //=======================================================================
434 //function : UpdateClipping
435 //purpose  :
436 //=======================================================================
437 void SelectMgr_SelectableObject::UpdateClipping()
438 {
439   PrsMgr_PresentableObject::UpdateClipping();
440   if (!mySelectionPrs.IsNull())
441   {
442     mySelectionPrs->SetClipPlanes (myClipPlanes);
443   }
444   if (!myHilightPrs.IsNull())
445   {
446     myHilightPrs->SetClipPlanes (myClipPlanes);
447   }
448 }
449
450 //=======================================================================
451 //function : updateSelection
452 //purpose  : Sets update status FULL to selections of the object. Must be
453 //           used as the only method of UpdateSelection from outer classes
454 //           to prevent BVH structures from being outdated.
455 //=======================================================================
456 void SelectMgr_SelectableObject::updateSelection (const Standard_Integer theMode)
457 {
458   if (theMode == -1)
459   {
460     for (SelectMgr_SequenceOfSelection::Iterator aSelIter (myselections); aSelIter.More(); aSelIter.Next())
461     {
462       const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
463       aSel->UpdateStatus (SelectMgr_TOU_Full);
464     }
465     return;
466   }
467
468   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (myselections); aSelIter.More(); aSelIter.Next())
469   {
470     const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
471     if (aSel->Mode() == theMode)
472     {
473       aSel->UpdateStatus (SelectMgr_TOU_Full);
474       return;
475     }
476   }
477 }
478
479 //=======================================================================
480 //function : SetAssemblyOwner
481 //purpose  : Sets common entity owner for assembly sensitive object entities
482 //=======================================================================
483 void SelectMgr_SelectableObject::SetAssemblyOwner (const Handle(SelectMgr_EntityOwner)& theOwner,
484                                                    const Standard_Integer theMode)
485 {
486   if (theMode == -1)
487   {
488     for (SelectMgr_SequenceOfSelection::Iterator aSelIter (myselections); aSelIter.More(); aSelIter.Next())
489     {
490       const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
491       for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
492       {
493         aSelEntIter.Value()->BaseSensitive()->Set (theOwner);
494       }
495     }
496     return;
497   }
498
499   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (myselections); aSelIter.More(); aSelIter.Next())
500   {
501     const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
502     if (aSel->Mode() == theMode)
503     {
504       for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
505       {
506         aSelEntIter.Value()->BaseSensitive()->Set (theOwner);
507       }
508       return;
509     }
510   }
511 }
512
513 //=======================================================================
514 //function : BndBoxOfSelected
515 //purpose  :
516 //=======================================================================
517 Bnd_Box SelectMgr_SelectableObject::BndBoxOfSelected (const Handle(SelectMgr_IndexedMapOfOwner)& theOwners)
518 {
519   if (theOwners->IsEmpty())
520     return Bnd_Box();
521
522   Bnd_Box aBnd;
523   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (myselections); aSelIter.More(); aSelIter.Next())
524   {
525     const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
526     if (aSel->GetSelectionState() != SelectMgr_SOS_Activated)
527       continue;
528
529     for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
530     {
531       const Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aSelEntIter.Value()->BaseSensitive()->OwnerId());
532       if (theOwners->Contains (anOwner))
533       {
534         Select3D_BndBox3d aBox = aSelEntIter.Value()->BaseSensitive()->BoundingBox();
535         aBnd.Update (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
536                      aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
537       }
538     }
539   }
540
541   return aBnd;
542 }
543
544 //=======================================================================
545 //function : GlobalSelOwner
546 //purpose  : Returns entity owner corresponding to selection of the object as a whole
547 //=======================================================================
548 Handle(SelectMgr_EntityOwner) SelectMgr_SelectableObject::GlobalSelOwner() const
549 {
550   const Handle(SelectMgr_Selection)& aGlobalSel = Selection (myGlobalSelMode);
551   if (!aGlobalSel.IsNull()
552    && !aGlobalSel->IsEmpty())
553   {
554     return Handle(SelectMgr_EntityOwner)::DownCast (aGlobalSel->Entities().First()->BaseSensitive()->OwnerId());
555   }
556   return THE_NULL_ENTITYOWNER;
557 }
558
559 //=======================================================================
560 //function : GetAssemblyOwner
561 //purpose  :
562 //=======================================================================
563 const Handle(SelectMgr_EntityOwner)& SelectMgr_SelectableObject::GetAssemblyOwner() const
564 {
565   return THE_NULL_ENTITYOWNER;
566 }