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