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