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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Aspect_TypeOfMarker.hxx>
19 #include <Bnd_Box.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>
42 IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_SelectableObject,PrsMgr_PresentableObject)
44 static Standard_Integer Search (const SelectMgr_SequenceOfSelection& seq,
45 const Handle (SelectMgr_Selection)& theSel)
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;}
55 //==================================================
58 //==================================================
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),
68 InitDefaultHilightAttributes (myHilightDrawer);
69 myHilightDrawer->Link (myDrawer);
72 //==================================================
73 // Function: Destructor
74 // Purpose : Clears all selections of the object
75 //==================================================
76 SelectMgr_SelectableObject::~SelectMgr_SelectableObject()
78 for (Standard_Integer aSelIdx = 1; aSelIdx <= myselections.Length(); ++aSelIdx)
80 myselections.Value (aSelIdx)->Clear();
84 //==================================================
85 // Function: HasSelection
87 //==================================================
88 Standard_Boolean SelectMgr_SelectableObject::HasSelection (const Standard_Integer theMode) const
90 for (Standard_Integer aSelIdx = 1; aSelIdx <= myselections.Length(); ++aSelIdx)
92 if (((myselections.Value (aSelIdx))->Mode()) == theMode)
95 return Standard_False;
98 //==================================================
99 // Function: RecomputePrimitives
100 // Purpose : IMPORTANT: Do not use this method to update
101 // selection primitives except implementing custom
102 // selection manager! This method does not take
103 // into account necessary BVH updates, but may
104 // invalidate the pointers it refers to.
105 // TO UPDATE SELECTION properly from outside classes,
106 // use method UpdateSelection.
107 //==================================================
108 void SelectMgr_SelectableObject::RecomputePrimitives()
110 for (Standard_Integer aSelIdx = 1; aSelIdx <= myselections.Length(); aSelIdx++)
112 RecomputePrimitives (myselections.ChangeValue (aSelIdx)->Mode());
116 //==================================================
117 // Function: RecomputePrimitives
118 // Purpose : IMPORTANT: Do not use this method to update
119 // selection primitives except implementing custom
120 // selection manager! This method does not take
121 // into account necessary BVH updates, but may
122 // invalidate the pointers it refers to.
123 // TO UPDATE SELECTION properly from outside classes,
124 // use method UpdateSelection.
125 //==================================================
126 void SelectMgr_SelectableObject::RecomputePrimitives (const Standard_Integer theMode)
128 Handle(PrsMgr_PresentableObject) aPrsParent (Parent());
129 Handle(SelectMgr_SelectableObject) aSelParent = Handle(SelectMgr_SelectableObject)::DownCast (aPrsParent);
131 for (Standard_Integer aSelIdx =1; aSelIdx <= myselections.Length(); aSelIdx++ )
133 if (myselections.Value (aSelIdx)->Mode() == theMode)
135 myselections (aSelIdx)->Clear();
136 ComputeSelection (myselections (aSelIdx), theMode);
137 myselections (aSelIdx)->UpdateStatus (SelectMgr_TOU_Partial);
138 myselections (aSelIdx)->UpdateBVHStatus (SelectMgr_TBU_Renew);
139 if (theMode == 0 && ! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
141 SetAssemblyOwner (aSelParent->GetAssemblyOwner(), theMode);
147 Handle(SelectMgr_Selection) aNewSel = new SelectMgr_Selection (theMode);
148 ComputeSelection (aNewSel, theMode);
150 if (theMode == 0 && ! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
152 SetAssemblyOwner (aSelParent->GetAssemblyOwner(), theMode);
155 aNewSel->UpdateStatus (SelectMgr_TOU_Partial);
156 aNewSel->UpdateBVHStatus (SelectMgr_TBU_Add);
158 myselections.Append (aNewSel);
161 //==================================================
162 // Function: ClearSelections
164 //==================================================
165 void SelectMgr_SelectableObject::ClearSelections(const Standard_Boolean update)
167 for (Standard_Integer i =1; i<= myselections.Length(); i++ ) {
168 myselections.Value(i)->Clear();
169 myselections.Value (i)->UpdateBVHStatus (SelectMgr_TBU_Remove);
172 myselections.Value(i)->UpdateStatus(SelectMgr_TOU_Full);
178 //==================================================
179 // Function: Selection
181 //==================================================
183 const Handle(SelectMgr_Selection)& SelectMgr_SelectableObject
184 ::Selection(const Standard_Integer aMode) const
186 static Handle(SelectMgr_Selection) bidsel;
187 Standard_Boolean Found = Standard_False;
188 Standard_Integer Rank=0;
189 for (Standard_Integer i=1;i<=myselections.Length() && !Found;i++)
191 if((myselections.Value(i))->Mode()==aMode){ Found = Standard_True;
193 return myselections.Value(Rank);
197 //==================================================
198 // Function: AddSelection
200 //==================================================
202 void SelectMgr_SelectableObject
203 ::AddSelection(const Handle(SelectMgr_Selection)& aSel,
204 const Standard_Integer aMode)
206 Standard_Boolean isReplaced = Standard_False;
209 ComputeSelection(aSel, aMode);
210 aSel->UpdateStatus(SelectMgr_TOU_Partial);
211 aSel->UpdateBVHStatus (SelectMgr_TBU_Add);
213 if (HasSelection(aMode))
215 const Handle(SelectMgr_Selection)& temp= Selection(aMode);
216 Standard_Integer I = Search(myselections,temp);
219 myselections.Remove(I);
220 isReplaced = Standard_True;
224 myselections.Append(aSel);
227 myselections.Last()->UpdateBVHStatus (SelectMgr_TBU_Renew);
232 Handle(PrsMgr_PresentableObject) aPrsParent (Parent());
233 Handle(SelectMgr_SelectableObject) aSelParent = Handle(SelectMgr_SelectableObject)::DownCast (aPrsParent);
234 if (! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
236 SetAssemblyOwner (aSelParent->GetAssemblyOwner(), aMode);
243 //=======================================================================
244 //function : ReSetTransformation
246 //=======================================================================
247 void SelectMgr_SelectableObject::ResetTransformation()
249 for (Init(); More(); Next())
251 const Handle(SelectMgr_Selection) & aSel = CurrentSelection();
252 for (aSel->Init(); aSel->More(); aSel->Next())
254 aSel->UpdateStatus(SelectMgr_TOU_Partial);
255 aSel->UpdateBVHStatus (SelectMgr_TBU_None);
259 PrsMgr_PresentableObject::ResetTransformation();
262 //=======================================================================
263 //function : UpdateTransformation
265 //=======================================================================
266 void SelectMgr_SelectableObject::UpdateTransformation()
268 for (Init(); More(); Next())
270 CurrentSelection()->UpdateStatus (SelectMgr_TOU_Partial);
273 PrsMgr_PresentableObject::UpdateTransformation();
276 //=======================================================================
277 //function : UpdateTransformation
279 //=======================================================================
280 void SelectMgr_SelectableObject::UpdateTransformations(const Handle(SelectMgr_Selection)& Sel)
282 TopLoc_Location aSelfLocation (Transformation());
283 Handle(Select3D_SensitiveEntity) SE;
284 if(aSelfLocation.IsIdentity()) return;
285 for(Sel->Init();Sel->More();Sel->Next()){
286 SE = Handle(Select3D_SensitiveEntity)::DownCast (Sel->Sensitive()->BaseSensitive());
288 const Handle(SelectBasics_EntityOwner)& aEOwner = SE->OwnerId();
289 Handle(SelectMgr_EntityOwner) aMgrEO =
290 Handle(SelectMgr_EntityOwner)::DownCast (aEOwner);
291 if (!aMgrEO.IsNull())
292 aMgrEO->SetLocation (aSelfLocation);
297 //=======================================================================
298 //function : HilightSelected
300 //=======================================================================
301 void SelectMgr_SelectableObject::HilightSelected
302 ( const Handle(PrsMgr_PresentationManager3d)&,
303 const SelectMgr_SequenceOfOwner&)
305 Standard_NotImplemented::Raise ("SelectMgr_SelectableObject::HilightSelected");
308 //=======================================================================
309 //function : ClearSelected
311 //=======================================================================
312 void SelectMgr_SelectableObject::ClearSelected ()
314 if( !mySelectionPrs.IsNull() )
315 mySelectionPrs->Clear();
318 //=======================================================================
319 //function : HilightOwnerWithColor
321 //=======================================================================
322 void SelectMgr_SelectableObject::HilightOwnerWithColor
323 ( const Handle(PrsMgr_PresentationManager3d)&,
324 const Quantity_NameOfColor,
325 const Handle(SelectMgr_EntityOwner)&)
327 Standard_NotImplemented::Raise ("SelectMgr_SelectableObject::HilightOwnerWithColor");
330 //=======================================================================
331 //function : MaxFaceNodes
333 //=======================================================================
334 Standard_Boolean SelectMgr_SelectableObject::IsAutoHilight () const
336 return myAutoHilight;
339 //=======================================================================
340 //function : MaxFaceNodes
342 //=======================================================================
343 void SelectMgr_SelectableObject::SetAutoHilight ( const Standard_Boolean newAutoHilight )
345 myAutoHilight = newAutoHilight;
348 //=======================================================================
349 //function : GetHilightPresentation
351 //=======================================================================
352 Handle(Prs3d_Presentation) SelectMgr_SelectableObject::GetHilightPresentation( const Handle(PrsMgr_PresentationManager3d)& TheMgr )
354 if( myHilightPrs.IsNull() && !TheMgr.IsNull() )
356 myHilightPrs = new Prs3d_Presentation( TheMgr->StructureManager() );
357 myHilightPrs->SetTransformPersistence( GetTransformPersistenceMode(),
358 GetTransformPersistencePoint() );
365 //=======================================================================
366 //function : GetSelectPresentation
368 //=======================================================================
369 Handle(Prs3d_Presentation) SelectMgr_SelectableObject::GetSelectPresentation( const Handle(PrsMgr_PresentationManager3d)& TheMgr )
371 if( mySelectionPrs.IsNull() && !TheMgr.IsNull() ) {
372 mySelectionPrs = new Prs3d_Presentation( TheMgr->StructureManager() );
373 mySelectionPrs->SetTransformPersistence( GetTransformPersistenceMode(),
374 GetTransformPersistencePoint() );
376 return mySelectionPrs;
379 //=======================================================================
380 //function : SetZLayer
382 //=======================================================================
383 void SelectMgr_SelectableObject::SetZLayer (const Graphic3d_ZLayerId theLayerId)
385 // update own presentations
386 PrsMgr_PresentableObject::SetZLayer (theLayerId);
388 // update selection presentations
389 if (!mySelectionPrs.IsNull())
390 mySelectionPrs->SetZLayer (theLayerId);
392 if (!myHilightPrs.IsNull())
393 myHilightPrs->SetZLayer (theLayerId);
395 // update all entity owner presentations
396 for (Init (); More () ;Next ())
398 const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
399 for (aSel->Init (); aSel->More (); aSel->Next ())
401 Handle(Select3D_SensitiveEntity) aEntity =
402 Handle(Select3D_SensitiveEntity)::DownCast (aSel->Sensitive()->BaseSensitive());
403 if (!aEntity.IsNull())
405 Handle(SelectMgr_EntityOwner) aOwner =
406 Handle(SelectMgr_EntityOwner)::DownCast (aEntity->OwnerId());
407 if (!aOwner.IsNull())
408 aOwner->SetZLayer (theLayerId);
414 //=======================================================================
415 //function : UpdateSelection
416 //purpose : Sets update status FULL to selections of the object. Must be
417 // used as the only method of UpdateSelection from outer classes
418 // to prevent BVH structures from being outdated.
419 //=======================================================================
420 void SelectMgr_SelectableObject::UpdateSelection (const Standard_Integer theMode)
424 for (Init(); More(); Next())
426 const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
427 aSel->UpdateStatus (SelectMgr_TOU_Full);
433 for (Init(); More(); Next())
435 if (CurrentSelection()->Mode() == theMode)
437 CurrentSelection()->UpdateStatus (SelectMgr_TOU_Full);
443 //=======================================================================
444 //function : SetAttributes
446 //=======================================================================
447 void SelectMgr_SelectableObject::SetAttributes (const Handle(Prs3d_Drawer)& theDrawer)
449 myDrawer = theDrawer;
452 //=======================================================================
453 //function : UnsetAttributes
455 //=======================================================================
456 void SelectMgr_SelectableObject::UnsetAttributes()
458 Handle(Prs3d_Drawer) aDrawer = new Prs3d_Drawer();
459 if (myDrawer->HasLink())
461 aDrawer->Link (myDrawer->Link());
466 //=======================================================================
467 //function : SetHilightAttributes
469 //=======================================================================
470 void SelectMgr_SelectableObject::SetHilightAttributes (const Handle(Prs3d_Drawer)& theDrawer)
472 myHilightDrawer = theDrawer;
475 //=======================================================================
476 //function : UnsetAttributes
478 //=======================================================================
479 void SelectMgr_SelectableObject::UnsetHilightAttributes()
481 Handle(Prs3d_Drawer) aDrawer = new Prs3d_Drawer();
482 InitDefaultHilightAttributes (aDrawer);
483 aDrawer->Link (myDrawer);
484 myHilightDrawer = aDrawer;
487 //=======================================================================
488 //function : InitDefaultHilightAttributes
490 //=======================================================================
491 void SelectMgr_SelectableObject::InitDefaultHilightAttributes (const Handle(Prs3d_Drawer)& theDrawer)
493 if (!theDrawer->HasOwnPointAspect())
495 theDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, Quantity_NOC_BLACK, 1.0));
496 if (theDrawer->HasLink())
498 *theDrawer->PointAspect()->Aspect() = *theDrawer->Link()->PointAspect()->Aspect();
501 if (!theDrawer->HasOwnLineAspect())
503 theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
504 if (theDrawer->HasLink())
506 *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
509 if (!theDrawer->HasOwnWireAspect())
511 theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
512 if (theDrawer->HasLink())
514 *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
517 if (!theDrawer->HasOwnPlaneAspect())
519 theDrawer->SetPlaneAspect (new Prs3d_PlaneAspect());
520 if (theDrawer->HasLink())
522 *theDrawer->PlaneAspect()->EdgesAspect() = *theDrawer->Link()->PlaneAspect()->EdgesAspect();
525 if (!theDrawer->HasOwnFreeBoundaryAspect())
527 theDrawer->SetFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
528 if (theDrawer->HasLink())
530 *theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect();
533 if (!theDrawer->HasOwnUnFreeBoundaryAspect())
535 theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
536 if (theDrawer->HasLink())
538 *theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect();
542 theDrawer->WireAspect()->SetWidth(2.);
543 theDrawer->LineAspect()->SetWidth(2.);
544 theDrawer->PlaneAspect()->EdgesAspect()->SetWidth(2.);
545 theDrawer->FreeBoundaryAspect()->SetWidth(2.);
546 theDrawer->UnFreeBoundaryAspect()->SetWidth(2.);
547 theDrawer->PointAspect()->SetTypeOfMarker(Aspect_TOM_O_POINT);
548 theDrawer->PointAspect()->SetScale(2.);
550 // By default the hilight drawer has absolute type of deflection.
551 // It is supposed that absolute deflection is taken from Link().
552 // It is necessary to use for all sub-shapes identical coefficient
553 // computed in ::Compute() call for whole shape and stored in base drawer.
554 theDrawer->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
557 //=======================================================================
558 //function : SetAssemblyOwner
559 //purpose : Sets common entity owner for assembly sensitive object entities
560 //=======================================================================
561 void SelectMgr_SelectableObject::SetAssemblyOwner (const Handle(SelectMgr_EntityOwner)& theOwner,
562 const Standard_Integer theMode)
566 for (Standard_Integer aModeIter = 1; aModeIter <= myselections.Length(); ++aModeIter)
568 Handle(SelectMgr_Selection)& aSel = myselections.ChangeValue (aModeIter);
569 for (aSel->Init(); aSel->More(); aSel->Next())
571 aSel->Sensitive()->BaseSensitive()->Set (theOwner);
578 if (!HasSelection (theMode))
581 for (Standard_Integer aModeIter = 1; aModeIter <= myselections.Length(); ++aModeIter)
583 if (myselections.Value (aModeIter)->Mode() == theMode)
585 Handle(SelectMgr_Selection)& aSel = myselections.ChangeValue (aModeIter);
586 for (aSel->Init(); aSel->More(); aSel->Next())
588 aSel->Sensitive()->BaseSensitive()->Set (theOwner);
595 //=======================================================================
596 //function : GetAssemblyOwner
597 //purpose : Returns common entity owner if it is an assembly
598 //=======================================================================
599 const Handle(SelectMgr_EntityOwner)& SelectMgr_SelectableObject::GetAssemblyOwner() const
601 return myAssemblyOwner;
604 //=======================================================================
605 //function : BndBoxOfSelected
606 //purpose : Returns a bounding box of sensitive entities with the owners given
607 // if they are a part of activated selection
608 //=======================================================================
609 Bnd_Box SelectMgr_SelectableObject::BndBoxOfSelected (Handle(SelectMgr_IndexedMapOfOwner)& theOwners)
613 if (theOwners->IsEmpty())
616 for (Init(); More(); Next())
618 const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
619 if (aSel->GetSelectionState() != SelectMgr_SOS_Activated)
622 for (aSel->Init(); aSel->More(); aSel->Next())
624 const Handle(SelectMgr_EntityOwner) anOwner =
625 Handle(SelectMgr_EntityOwner)::DownCast (aSel->Sensitive()->BaseSensitive()->OwnerId());
626 if (theOwners->Contains (anOwner))
628 Select3D_BndBox3d aBox = aSel->Sensitive()->BaseSensitive()->BoundingBox();
630 aTmpBnd.Update (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
631 aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
634 Standard_Integer anOwnerIdx = theOwners->FindIndex (anOwner);
635 if (theOwners->Size() != anOwnerIdx)
637 theOwners->Swap (anOwnerIdx, theOwners->Size());
639 theOwners->RemoveLast();
641 if (theOwners->IsEmpty())
650 //=======================================================================
651 //function : GlobalSelOwner
652 //purpose : Returns entity owner corresponding to selection of the object as a whole
653 //=======================================================================
654 Handle(SelectMgr_EntityOwner) SelectMgr_SelectableObject::GlobalSelOwner() const
656 Handle(SelectMgr_EntityOwner) anOwner;
658 if (!HasSelection (myGlobalSelMode))
661 const Handle(SelectMgr_Selection)& aGlobalSel = Selection (myGlobalSelMode);
662 if (aGlobalSel->IsEmpty())
667 Handle(SelectMgr_EntityOwner)::DownCast (aGlobalSel->Sensitive()->BaseSensitive()->OwnerId());