0027285: Visualization - selection of AIS_MultipleConnectedInteractive is broken
[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
18 #include <Aspect_TypeOfMarker.hxx>
19 #include <Bnd_Box.hxx>
20 #include <gp_Pnt.hxx>
21 #include <Graphic3d_AspectLine3d.hxx>
22 #include <Graphic3d_AspectMarker3d.hxx>
23 #include <Prs3d_Drawer.hxx>
24 #include <Prs3d_LineAspect.hxx>
25 #include <Prs3d_PlaneAspect.hxx>
26 #include <Prs3d_PointAspect.hxx>
27 #include <Prs3d_Presentation.hxx>
28 #include <PrsMgr_PresentableObjectPointer.hxx>
29 #include <PrsMgr_PresentationManager3d.hxx>
30 #include <Select3D_SensitiveEntity.hxx>
31 #include <SelectBasics_EntityOwner.hxx>
32 #include <SelectMgr_EntityOwner.hxx>
33 #include <SelectMgr_IndexedMapOfOwner.hxx>
34 #include <SelectMgr_SelectableObject.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 static Standard_Integer Search (const SelectMgr_SequenceOfSelection& seq,
45                                 const Handle (SelectMgr_Selection)& theSel)
46 {
47   Standard_Integer ifound=0;
48   for (Standard_Integer i=1;i<=seq.Length()&& ifound==0;i++)
49     {if(theSel == seq.Value(i)) ifound=i;}
50   return ifound;
51
52
53
54
55 //==================================================
56 // Function: 
57 // Purpose :
58 //==================================================
59
60 SelectMgr_SelectableObject::SelectMgr_SelectableObject (const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d)
61 : PrsMgr_PresentableObject (aTypeOfPresentation3d),
62   myDrawer                 (new Prs3d_Drawer()),
63   myHilightDrawer          (new Prs3d_Drawer()),
64   myAssemblyOwner          (NULL),
65   myAutoHilight            (Standard_True),
66   myGlobalSelMode          (0)
67 {
68   InitDefaultHilightAttributes (myHilightDrawer);
69   myHilightDrawer->Link (myDrawer);
70 }
71
72
73 //==================================================
74 // Function: HasSelection
75 // Purpose :
76 //==================================================
77 Standard_Boolean SelectMgr_SelectableObject::HasSelection (const Standard_Integer theMode) const
78 {
79   for (Standard_Integer aSelIdx = 1; aSelIdx <= myselections.Length(); ++aSelIdx)
80   {
81     if (((myselections.Value (aSelIdx))->Mode()) == theMode)
82       return Standard_True;
83   }
84   return Standard_False;
85 }
86
87 //==================================================
88 // Function: RecomputePrimitives
89 // Purpose : IMPORTANT: Do not use this method to update
90 //           selection primitives except implementing custom
91 //           selection manager! This method does not take
92 //           into account necessary BVH updates, but may
93 //           invalidate the pointers it refers to.
94 //           TO UPDATE SELECTION properly from outside classes,
95 //           use method UpdateSelection.
96 //==================================================
97 void SelectMgr_SelectableObject::RecomputePrimitives()
98 {
99   for (Standard_Integer aSelIdx = 1; aSelIdx <= myselections.Length(); aSelIdx++)
100     {
101       RecomputePrimitives (myselections.ChangeValue (aSelIdx)->Mode());
102     }
103 }
104
105 //==================================================
106 // Function: RecomputePrimitives
107 // Purpose : IMPORTANT: Do not use this method to update
108 //           selection primitives except implementing custom
109 //           selection manager! This method does not take
110 //           into account necessary BVH updates, but may
111 //           invalidate the pointers it refers to.
112 //           TO UPDATE SELECTION properly from outside classes,
113 //           use method UpdateSelection.
114 //==================================================
115 void SelectMgr_SelectableObject::RecomputePrimitives (const Standard_Integer theMode)
116 {
117   Handle(PrsMgr_PresentableObject) aPrsParent (Parent());
118   Handle(SelectMgr_SelectableObject) aSelParent = Handle(SelectMgr_SelectableObject)::DownCast (aPrsParent);
119
120   for (Standard_Integer aSelIdx =1; aSelIdx <= myselections.Length(); aSelIdx++ )
121   {
122     if (myselections.Value (aSelIdx)->Mode() == theMode)
123     {
124       myselections (aSelIdx)->Clear();
125       ComputeSelection (myselections (aSelIdx), theMode);
126       myselections (aSelIdx)->UpdateStatus (SelectMgr_TOU_Partial);
127       myselections (aSelIdx)->UpdateBVHStatus (SelectMgr_TBU_Renew);
128       if (theMode == 0 && ! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
129       {
130         SetAssemblyOwner (aSelParent->GetAssemblyOwner(), theMode);
131       }
132       return;
133     }
134   }
135
136   Handle(SelectMgr_Selection) aNewSel = new SelectMgr_Selection (theMode);
137   ComputeSelection (aNewSel, theMode);
138
139   if (theMode == 0 && ! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
140   {
141     SetAssemblyOwner (aSelParent->GetAssemblyOwner(), theMode);
142   }
143
144   aNewSel->UpdateStatus (SelectMgr_TOU_Partial);
145   aNewSel->UpdateBVHStatus (SelectMgr_TBU_Add);
146
147   myselections.Append (aNewSel);
148 }
149
150 //==================================================
151 // Function: ClearSelections
152 // Purpose :
153 //==================================================
154 void SelectMgr_SelectableObject::ClearSelections(const Standard_Boolean update)
155 {
156   for (Standard_Integer i =1; i<= myselections.Length(); i++ ) {
157     myselections.Value(i)->Clear();
158     myselections.Value (i)->UpdateBVHStatus (SelectMgr_TBU_Remove);
159     if(update)
160     {
161       myselections.Value(i)->UpdateStatus(SelectMgr_TOU_Full);
162     }
163   }
164 }
165
166
167 //==================================================
168 // Function: Selection
169 // Purpose :
170 //==================================================
171
172 const Handle(SelectMgr_Selection)& SelectMgr_SelectableObject
173 ::Selection(const Standard_Integer aMode) const
174 {
175   static Handle(SelectMgr_Selection) bidsel;
176   Standard_Boolean Found = Standard_False;
177   Standard_Integer Rank=0;
178   for (Standard_Integer i=1;i<=myselections.Length() && !Found;i++)
179     {
180       if((myselections.Value(i))->Mode()==aMode){ Found = Standard_True;
181                                                   Rank=i;}}
182   return myselections.Value(Rank);
183 }
184
185
186 //==================================================
187 // Function: AddSelection
188 // Purpose :
189 //==================================================
190
191 void SelectMgr_SelectableObject
192 ::AddSelection(const Handle(SelectMgr_Selection)& aSel,
193                const Standard_Integer aMode)
194 {
195   Standard_Boolean isReplaced = Standard_False;
196   if(aSel->IsEmpty())
197   {
198     ComputeSelection(aSel, aMode);
199     aSel->UpdateStatus(SelectMgr_TOU_Partial);
200     aSel->UpdateBVHStatus (SelectMgr_TBU_Add);
201   }
202   if (HasSelection(aMode))
203   {
204     const Handle(SelectMgr_Selection)& temp= Selection(aMode);
205     Standard_Integer I = Search(myselections,temp);
206     if(I!=0)
207     {
208       myselections.Remove(I);
209       isReplaced = Standard_True;
210     }
211   }
212
213   myselections.Append(aSel);
214   if (isReplaced)
215   {
216     myselections.Last()->UpdateBVHStatus (SelectMgr_TBU_Renew);
217   }
218
219   if (aMode == 0)
220   {
221     Handle(PrsMgr_PresentableObject) aPrsParent (Parent());
222     Handle(SelectMgr_SelectableObject) aSelParent = Handle(SelectMgr_SelectableObject)::DownCast (aPrsParent);
223     if (! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
224     {
225       SetAssemblyOwner (aSelParent->GetAssemblyOwner(), aMode);
226     }
227   }
228 }
229
230
231
232 //=======================================================================
233 //function : ReSetTransformation
234 //purpose  : 
235 //=======================================================================
236 void SelectMgr_SelectableObject::ResetTransformation() 
237 {
238   for (Init(); More(); Next())
239   {
240     const Handle(SelectMgr_Selection) & aSel = CurrentSelection();
241     for (aSel->Init(); aSel->More(); aSel->Next())
242     {
243       aSel->UpdateStatus(SelectMgr_TOU_Partial);
244       aSel->UpdateBVHStatus (SelectMgr_TBU_None);
245     }
246   }
247
248   PrsMgr_PresentableObject::ResetTransformation();
249 }
250
251 //=======================================================================
252 //function : UpdateTransformation
253 //purpose  : 
254 //=======================================================================
255 void SelectMgr_SelectableObject::UpdateTransformation()
256 {
257   for (Init(); More(); Next())
258   {
259     CurrentSelection()->UpdateStatus (SelectMgr_TOU_Partial);
260   }
261
262   PrsMgr_PresentableObject::UpdateTransformation();
263 }
264
265 //=======================================================================
266 //function : UpdateTransformation
267 //purpose  : 
268 //=======================================================================
269 void SelectMgr_SelectableObject::UpdateTransformations(const Handle(SelectMgr_Selection)& Sel)
270 {
271   TopLoc_Location aSelfLocation (Transformation());
272   Handle(Select3D_SensitiveEntity) SE;
273   if(aSelfLocation.IsIdentity()) return;
274   for(Sel->Init();Sel->More();Sel->Next()){
275     SE =  Handle(Select3D_SensitiveEntity)::DownCast (Sel->Sensitive()->BaseSensitive());
276     if(!SE.IsNull()){
277       const Handle(SelectBasics_EntityOwner)& aEOwner = SE->OwnerId();
278       Handle(SelectMgr_EntityOwner) aMgrEO =
279                               Handle(SelectMgr_EntityOwner)::DownCast (aEOwner);
280       if (!aMgrEO.IsNull())
281         aMgrEO->SetLocation (aSelfLocation);
282     }
283   }
284 }
285
286 //=======================================================================
287 //function : HilightSelected
288 //purpose  : 
289 //=======================================================================
290 void SelectMgr_SelectableObject::HilightSelected 
291   ( const Handle(PrsMgr_PresentationManager3d)&,
292     const SelectMgr_SequenceOfOwner&)
293 {
294   Standard_NotImplemented::Raise ("SelectMgr_SelectableObject::HilightSelected");
295 }
296
297 //=======================================================================
298 //function : ClearSelected
299 //purpose  : 
300 //=======================================================================
301 void SelectMgr_SelectableObject::ClearSelected ()
302 {
303   if( !mySelectionPrs.IsNull() )
304     mySelectionPrs->Clear();
305 }
306
307 //=======================================================================
308 //function : HilightOwnerWithColor
309 //purpose  : 
310 //=======================================================================
311 void SelectMgr_SelectableObject::HilightOwnerWithColor 
312   ( const Handle(PrsMgr_PresentationManager3d)&,
313     const Quantity_NameOfColor,
314     const Handle(SelectMgr_EntityOwner)&)
315 {
316   Standard_NotImplemented::Raise ("SelectMgr_SelectableObject::HilightOwnerWithColor");
317 }
318
319 //=======================================================================
320 //function : MaxFaceNodes
321 //purpose  : 
322 //=======================================================================
323 Standard_Boolean SelectMgr_SelectableObject::IsAutoHilight () const
324 {
325   return myAutoHilight;
326 }
327
328 //=======================================================================
329 //function : MaxFaceNodes
330 //purpose  : 
331 //=======================================================================
332 void SelectMgr_SelectableObject::SetAutoHilight ( const Standard_Boolean newAutoHilight )
333 {
334   myAutoHilight = newAutoHilight;
335 }
336
337 //=======================================================================
338 //function : GetHilightPresentation
339 //purpose  : 
340 //=======================================================================
341 Handle(Prs3d_Presentation) SelectMgr_SelectableObject::GetHilightPresentation( const Handle(PrsMgr_PresentationManager3d)& TheMgr )
342 {
343   if( myHilightPrs.IsNull() && !TheMgr.IsNull() )
344     {
345       myHilightPrs = new Prs3d_Presentation( TheMgr->StructureManager() );
346       myHilightPrs->SetTransformPersistence( GetTransformPersistenceMode(), 
347                                          GetTransformPersistencePoint() );
348     }
349
350   return myHilightPrs;
351 }
352
353
354 //=======================================================================
355 //function : GetSelectPresentation
356 //purpose  : 
357 //=======================================================================
358 Handle(Prs3d_Presentation) SelectMgr_SelectableObject::GetSelectPresentation( const Handle(PrsMgr_PresentationManager3d)& TheMgr )
359 {
360   if( mySelectionPrs.IsNull() && !TheMgr.IsNull() ) {
361     mySelectionPrs = new Prs3d_Presentation( TheMgr->StructureManager() );
362     mySelectionPrs->SetTransformPersistence( GetTransformPersistenceMode(), 
363                                              GetTransformPersistencePoint() );
364   }
365   return mySelectionPrs;
366 }
367
368 //=======================================================================
369 //function : SetZLayer
370 //purpose  :
371 //=======================================================================
372 void SelectMgr_SelectableObject::SetZLayer (const Graphic3d_ZLayerId theLayerId)
373 {
374   // update own presentations
375   PrsMgr_PresentableObject::SetZLayer (theLayerId);
376
377   // update selection presentations
378   if (!mySelectionPrs.IsNull())
379     mySelectionPrs->SetZLayer (theLayerId);
380
381   if (!myHilightPrs.IsNull())
382     myHilightPrs->SetZLayer (theLayerId);
383
384   // update all entity owner presentations
385   for (Init (); More () ;Next ())
386   {
387     const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
388     for (aSel->Init (); aSel->More (); aSel->Next ())
389     {
390       Handle(Select3D_SensitiveEntity) aEntity = 
391         Handle(Select3D_SensitiveEntity)::DownCast (aSel->Sensitive()->BaseSensitive());
392       if (!aEntity.IsNull())
393       {
394         Handle(SelectMgr_EntityOwner) aOwner = 
395           Handle(SelectMgr_EntityOwner)::DownCast (aEntity->OwnerId());
396         if (!aOwner.IsNull())
397           aOwner->SetZLayer (theLayerId);
398       }
399     }
400   }
401 }
402
403 //=======================================================================
404 //function : UpdateSelection
405 //purpose  : Sets update status FULL to selections of the object. Must be
406 //           used as the only method of UpdateSelection from outer classes
407 //           to prevent BVH structures from being outdated.
408 //=======================================================================
409 void SelectMgr_SelectableObject::UpdateSelection (const Standard_Integer theMode)
410 {
411   if (theMode == -1)
412   {
413     for (Init(); More(); Next())
414     {
415       const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
416       aSel->UpdateStatus (SelectMgr_TOU_Full);
417     }
418
419     return;
420   }
421
422   for (Init(); More(); Next())
423   {
424     if (CurrentSelection()->Mode() == theMode)
425     {
426       CurrentSelection()->UpdateStatus (SelectMgr_TOU_Full);
427       return;
428     }
429   }
430 }
431
432 //=======================================================================
433 //function : SetAttributes
434 //purpose  : 
435 //=======================================================================
436 void SelectMgr_SelectableObject::SetAttributes (const Handle(Prs3d_Drawer)& theDrawer)
437 {
438   myDrawer = theDrawer;
439 }
440
441 //=======================================================================
442 //function : UnsetAttributes
443 //purpose  : 
444 //=======================================================================
445 void SelectMgr_SelectableObject::UnsetAttributes()
446 {
447   Handle(Prs3d_Drawer) aDrawer = new Prs3d_Drawer();
448   if (myDrawer->HasLink())
449   {
450     aDrawer->Link (myDrawer->Link());
451   }
452   myDrawer = aDrawer;
453 }
454
455 //=======================================================================
456 //function : SetHilightAttributes
457 //purpose  :
458 //=======================================================================
459 void SelectMgr_SelectableObject::SetHilightAttributes (const Handle(Prs3d_Drawer)& theDrawer)
460 {
461   myHilightDrawer = theDrawer;
462 }
463
464 //=======================================================================
465 //function : UnsetAttributes
466 //purpose  :
467 //=======================================================================
468 void SelectMgr_SelectableObject::UnsetHilightAttributes()
469 {
470   Handle(Prs3d_Drawer) aDrawer = new Prs3d_Drawer();
471   InitDefaultHilightAttributes (aDrawer);
472   aDrawer->Link (myDrawer);
473   myHilightDrawer = aDrawer;
474 }
475
476 //=======================================================================
477 //function : InitDefaultHilightAttributes
478 //purpose  :
479 //=======================================================================
480 void SelectMgr_SelectableObject::InitDefaultHilightAttributes (const Handle(Prs3d_Drawer)& theDrawer)
481 {
482   if (!theDrawer->HasOwnPointAspect())
483   {
484     theDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, Quantity_NOC_BLACK, 1.0));
485     if (theDrawer->HasLink())
486     {
487       *theDrawer->PointAspect()->Aspect() = *theDrawer->Link()->PointAspect()->Aspect();
488     }
489   }
490   if (!theDrawer->HasOwnLineAspect())
491   {
492     theDrawer->SetLineAspect  (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
493     if (theDrawer->HasLink())
494     {
495       *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
496     }
497   }
498   if (!theDrawer->HasOwnWireAspect())
499   {
500     theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
501     if (theDrawer->HasLink())
502     {
503       *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
504     }
505   }
506   if (!theDrawer->HasOwnPlaneAspect())
507   {
508     theDrawer->SetPlaneAspect (new Prs3d_PlaneAspect());
509     if (theDrawer->HasLink())
510     {
511       *theDrawer->PlaneAspect()->EdgesAspect() = *theDrawer->Link()->PlaneAspect()->EdgesAspect();
512     }
513   }
514   if (!theDrawer->HasOwnFreeBoundaryAspect())
515   {
516     theDrawer->SetFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
517     if (theDrawer->HasLink())
518     {
519       *theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect();
520     }
521   }
522   if (!theDrawer->HasOwnUnFreeBoundaryAspect())
523   {
524     theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
525     if (theDrawer->HasLink())
526     {
527       *theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect();
528     }
529   }
530
531   theDrawer->WireAspect()->SetWidth(2.);
532   theDrawer->LineAspect()->SetWidth(2.);
533   theDrawer->PlaneAspect()->EdgesAspect()->SetWidth(2.);
534   theDrawer->FreeBoundaryAspect()->SetWidth(2.);
535   theDrawer->UnFreeBoundaryAspect()->SetWidth(2.);
536   theDrawer->PointAspect()->SetTypeOfMarker(Aspect_TOM_O_POINT);
537   theDrawer->PointAspect()->SetScale(2.);
538
539   // By default the hilight drawer has absolute type of deflection.
540   // It is supposed that absolute deflection is taken from Link().
541   // It is necessary to use for all sub-shapes identical coefficient
542   // computed in ::Compute() call for whole shape and stored in base drawer.
543   theDrawer->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
544 }
545
546 //=======================================================================
547 //function : SetAssemblyOwner
548 //purpose  : Sets common entity owner for assembly sensitive object entities
549 //=======================================================================
550 void SelectMgr_SelectableObject::SetAssemblyOwner (const Handle(SelectMgr_EntityOwner)& theOwner,
551                                                    const Standard_Integer theMode)
552 {
553   if (theMode == -1)
554   {
555     for (Standard_Integer aModeIter = 1; aModeIter <= myselections.Length(); ++aModeIter)
556     {
557       Handle(SelectMgr_Selection)& aSel = myselections.ChangeValue (aModeIter);
558       for (aSel->Init(); aSel->More(); aSel->Next())
559       {
560         aSel->Sensitive()->BaseSensitive()->Set (theOwner);
561       }
562     }
563
564     return;
565   }
566
567   if (!HasSelection (theMode))
568     return;
569
570   for (Standard_Integer aModeIter = 1; aModeIter <= myselections.Length(); ++aModeIter)
571   {
572     if (myselections.Value (aModeIter)->Mode() == theMode)
573     {
574       Handle(SelectMgr_Selection)& aSel = myselections.ChangeValue (aModeIter);
575       for (aSel->Init(); aSel->More(); aSel->Next())
576       {
577         aSel->Sensitive()->BaseSensitive()->Set (theOwner);
578       }
579       return;
580     }
581   }
582 }
583
584 //=======================================================================
585 //function : GetAssemblyOwner
586 //purpose  : Returns common entity owner if it is an assembly
587 //=======================================================================
588 const Handle(SelectMgr_EntityOwner)& SelectMgr_SelectableObject::GetAssemblyOwner() const
589 {
590   return myAssemblyOwner;
591 }
592
593 //=======================================================================
594 //function : BndBoxOfSelected
595 //purpose  : Returns a bounding box of sensitive entities with the owners given
596 //           if they are a part of activated selection
597 //=======================================================================
598 Bnd_Box SelectMgr_SelectableObject::BndBoxOfSelected (Handle(SelectMgr_IndexedMapOfOwner)& theOwners)
599 {
600   Bnd_Box aBnd;
601
602   if (theOwners->IsEmpty())
603     return aBnd;
604
605   for (Init(); More(); Next())
606   {
607     const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
608     if (aSel->GetSelectionState() != SelectMgr_SOS_Activated)
609       continue;
610
611     for (aSel->Init(); aSel->More(); aSel->Next())
612     {
613       const Handle(SelectMgr_EntityOwner) anOwner =
614         Handle(SelectMgr_EntityOwner)::DownCast (aSel->Sensitive()->BaseSensitive()->OwnerId());
615       if (theOwners->Contains (anOwner))
616       {
617         Select3D_BndBox3d aBox = aSel->Sensitive()->BaseSensitive()->BoundingBox();
618         Bnd_Box aTmpBnd;
619         aTmpBnd.Update (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
620                         aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
621         aBnd.Add (aTmpBnd);
622
623         Standard_Integer anOwnerIdx = theOwners->FindIndex (anOwner);
624         if (theOwners->Size() != anOwnerIdx)
625         {
626           theOwners->Swap (anOwnerIdx, theOwners->Size());
627         }
628         theOwners->RemoveLast();
629
630         if (theOwners->IsEmpty())
631           return aBnd;
632       }
633     }
634   }
635
636   return aBnd;
637 }
638
639 //=======================================================================
640 //function : GlobalSelOwner
641 //purpose  : Returns entity owner corresponding to selection of the object as a whole
642 //=======================================================================
643 Handle(SelectMgr_EntityOwner) SelectMgr_SelectableObject::GlobalSelOwner() const
644 {
645    Handle(SelectMgr_EntityOwner) anOwner;
646
647   if (!HasSelection (myGlobalSelMode))
648     return anOwner;
649
650   const Handle(SelectMgr_Selection)& aGlobalSel = Selection (myGlobalSelMode);
651   if (aGlobalSel->IsEmpty())
652     return anOwner;
653
654   aGlobalSel->Init();
655   anOwner =
656     Handle(SelectMgr_EntityOwner)::DownCast (aGlobalSel->Sensitive()->BaseSensitive()->OwnerId());
657
658   return anOwner;
659 }