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