555b96c1f3225249dc35bec4ad8e0670a4418f6f
[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   Standard_NotImplemented::Raise ("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 : 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   Standard_NotImplemented::Raise ("SelectMgr_SelectableObject::HilightOwnerWithColor");
321 }
322
323 //=======================================================================
324 //function : MaxFaceNodes
325 //purpose  : 
326 //=======================================================================
327 Standard_Boolean SelectMgr_SelectableObject::IsAutoHilight () const
328 {
329   return myAutoHilight;
330 }
331
332 //=======================================================================
333 //function : MaxFaceNodes
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   }
352
353   return myHilightPrs;
354 }
355
356
357 //=======================================================================
358 //function : GetSelectPresentation
359 //purpose  : 
360 //=======================================================================
361 Handle(Prs3d_Presentation) SelectMgr_SelectableObject::GetSelectPresentation (const Handle(PrsMgr_PresentationManager3d)& theMgr)
362 {
363   if (mySelectionPrs.IsNull() && !theMgr.IsNull())
364   {
365     mySelectionPrs = new Prs3d_Presentation (theMgr->StructureManager());
366     mySelectionPrs->SetTransformPersistence (TransformPersistence());
367   }
368
369   return mySelectionPrs;
370 }
371
372 //=======================================================================
373 //function : SetZLayer
374 //purpose  :
375 //=======================================================================
376 void SelectMgr_SelectableObject::SetZLayer (const Graphic3d_ZLayerId theLayerId)
377 {
378   // update own presentations
379   PrsMgr_PresentableObject::SetZLayer (theLayerId);
380
381   // update selection presentations
382   if (!mySelectionPrs.IsNull())
383     mySelectionPrs->SetZLayer (theLayerId);
384
385   if (!myHilightPrs.IsNull())
386     myHilightPrs->SetZLayer (theLayerId);
387
388   // update all entity owner presentations
389   for (Init (); More () ;Next ())
390   {
391     const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
392     for (aSel->Init (); aSel->More (); aSel->Next ())
393     {
394       Handle(Select3D_SensitiveEntity) aEntity = 
395         Handle(Select3D_SensitiveEntity)::DownCast (aSel->Sensitive()->BaseSensitive());
396       if (!aEntity.IsNull())
397       {
398         Handle(SelectMgr_EntityOwner) aOwner = 
399           Handle(SelectMgr_EntityOwner)::DownCast (aEntity->OwnerId());
400         if (!aOwner.IsNull())
401           aOwner->SetZLayer (theLayerId);
402       }
403     }
404   }
405 }
406
407 //=======================================================================
408 //function : updateSelection
409 //purpose  : Sets update status FULL to selections of the object. Must be
410 //           used as the only method of UpdateSelection from outer classes
411 //           to prevent BVH structures from being outdated.
412 //=======================================================================
413 void SelectMgr_SelectableObject::updateSelection (const Standard_Integer theMode)
414 {
415   if (theMode == -1)
416   {
417     for (Init(); More(); Next())
418     {
419       const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
420       aSel->UpdateStatus (SelectMgr_TOU_Full);
421     }
422
423     return;
424   }
425
426   for (Init(); More(); Next())
427   {
428     if (CurrentSelection()->Mode() == theMode)
429     {
430       CurrentSelection()->UpdateStatus (SelectMgr_TOU_Full);
431       return;
432     }
433   }
434 }
435
436 //=======================================================================
437 //function : SetAssemblyOwner
438 //purpose  : Sets common entity owner for assembly sensitive object entities
439 //=======================================================================
440 void SelectMgr_SelectableObject::SetAssemblyOwner (const Handle(SelectMgr_EntityOwner)& theOwner,
441                                                    const Standard_Integer theMode)
442 {
443   if (theMode == -1)
444   {
445     for (Standard_Integer aModeIter = 1; aModeIter <= myselections.Length(); ++aModeIter)
446     {
447       Handle(SelectMgr_Selection)& aSel = myselections.ChangeValue (aModeIter);
448       for (aSel->Init(); aSel->More(); aSel->Next())
449       {
450         aSel->Sensitive()->BaseSensitive()->Set (theOwner);
451       }
452     }
453
454     return;
455   }
456
457   if (!HasSelection (theMode))
458     return;
459
460   for (Standard_Integer aModeIter = 1; aModeIter <= myselections.Length(); ++aModeIter)
461   {
462     if (myselections.Value (aModeIter)->Mode() == theMode)
463     {
464       Handle(SelectMgr_Selection)& aSel = myselections.ChangeValue (aModeIter);
465       for (aSel->Init(); aSel->More(); aSel->Next())
466       {
467         aSel->Sensitive()->BaseSensitive()->Set (theOwner);
468       }
469       return;
470     }
471   }
472 }
473
474 //=======================================================================
475 //function : GetAssemblyOwner
476 //purpose  : Returns common entity owner if it is an assembly
477 //=======================================================================
478 const Handle(SelectMgr_EntityOwner)& SelectMgr_SelectableObject::GetAssemblyOwner() const
479 {
480   return myAssemblyOwner;
481 }
482
483 //=======================================================================
484 //function : BndBoxOfSelected
485 //purpose  :
486 //=======================================================================
487 Bnd_Box SelectMgr_SelectableObject::BndBoxOfSelected (const Handle(SelectMgr_IndexedMapOfOwner)& theOwners)
488 {
489   if (theOwners->IsEmpty())
490     return Bnd_Box();
491
492   Bnd_Box aBnd;
493   for (Init(); More(); Next())
494   {
495     const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
496     if (aSel->GetSelectionState() != SelectMgr_SOS_Activated)
497       continue;
498
499     for (aSel->Init(); aSel->More(); aSel->Next())
500     {
501       const Handle(SelectMgr_EntityOwner) anOwner =
502         Handle(SelectMgr_EntityOwner)::DownCast (aSel->Sensitive()->BaseSensitive()->OwnerId());
503       if (theOwners->Contains (anOwner))
504       {
505         Select3D_BndBox3d aBox = aSel->Sensitive()->BaseSensitive()->BoundingBox();
506         aBnd.Update (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
507                      aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
508       }
509     }
510   }
511
512   return aBnd;
513 }
514
515 //=======================================================================
516 //function : GlobalSelOwner
517 //purpose  : Returns entity owner corresponding to selection of the object as a whole
518 //=======================================================================
519 Handle(SelectMgr_EntityOwner) SelectMgr_SelectableObject::GlobalSelOwner() const
520 {
521    Handle(SelectMgr_EntityOwner) anOwner;
522
523   if (!HasSelection (myGlobalSelMode))
524     return anOwner;
525
526   const Handle(SelectMgr_Selection)& aGlobalSel = Selection (myGlobalSelMode);
527   if (aGlobalSel->IsEmpty())
528     return anOwner;
529
530   aGlobalSel->Init();
531   anOwner =
532     Handle(SelectMgr_EntityOwner)::DownCast (aGlobalSel->Sensitive()->BaseSensitive()->OwnerId());
533
534   return anOwner;
535 }