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 Standard_Boolean Found = Standard_False;
187 Standard_Integer Rank=0;
188 for (Standard_Integer i=1;i<=myselections.Length() && !Found;i++)
190 if((myselections.Value(i))->Mode()==aMode){ Found = Standard_True;
192 return myselections.Value(Rank);
196 //==================================================
197 // Function: AddSelection
199 //==================================================
201 void SelectMgr_SelectableObject
202 ::AddSelection(const Handle(SelectMgr_Selection)& aSel,
203 const Standard_Integer aMode)
205 Standard_Boolean isReplaced = Standard_False;
208 ComputeSelection(aSel, aMode);
209 aSel->UpdateStatus(SelectMgr_TOU_Partial);
210 aSel->UpdateBVHStatus (SelectMgr_TBU_Add);
212 if (HasSelection(aMode))
214 const Handle(SelectMgr_Selection)& temp= Selection(aMode);
215 Standard_Integer I = Search(myselections,temp);
218 myselections.Remove(I);
219 isReplaced = Standard_True;
223 myselections.Append(aSel);
226 myselections.Last()->UpdateBVHStatus (SelectMgr_TBU_Renew);
231 Handle(PrsMgr_PresentableObject) aPrsParent (Parent());
232 Handle(SelectMgr_SelectableObject) aSelParent = Handle(SelectMgr_SelectableObject)::DownCast (aPrsParent);
233 if (! aSelParent.IsNull() && ! aSelParent->GetAssemblyOwner().IsNull())
235 SetAssemblyOwner (aSelParent->GetAssemblyOwner(), aMode);
242 //=======================================================================
243 //function : ReSetTransformation
245 //=======================================================================
246 void SelectMgr_SelectableObject::ResetTransformation()
248 for (Init(); More(); Next())
250 const Handle(SelectMgr_Selection) & aSel = CurrentSelection();
251 for (aSel->Init(); aSel->More(); aSel->Next())
253 aSel->UpdateStatus(SelectMgr_TOU_Partial);
254 aSel->UpdateBVHStatus (SelectMgr_TBU_None);
258 PrsMgr_PresentableObject::ResetTransformation();
261 //=======================================================================
262 //function : UpdateTransformation
264 //=======================================================================
265 void SelectMgr_SelectableObject::UpdateTransformation()
267 for (Init(); More(); Next())
269 CurrentSelection()->UpdateStatus (SelectMgr_TOU_Partial);
272 PrsMgr_PresentableObject::UpdateTransformation();
275 //=======================================================================
276 //function : UpdateTransformation
278 //=======================================================================
279 void SelectMgr_SelectableObject::UpdateTransformations(const Handle(SelectMgr_Selection)& Sel)
281 TopLoc_Location aSelfLocation (Transformation());
282 Handle(Select3D_SensitiveEntity) SE;
283 if(aSelfLocation.IsIdentity()) return;
284 for(Sel->Init();Sel->More();Sel->Next()){
285 SE = Handle(Select3D_SensitiveEntity)::DownCast (Sel->Sensitive()->BaseSensitive());
287 const Handle(SelectBasics_EntityOwner)& aEOwner = SE->OwnerId();
288 Handle(SelectMgr_EntityOwner) aMgrEO =
289 Handle(SelectMgr_EntityOwner)::DownCast (aEOwner);
290 if (!aMgrEO.IsNull())
291 aMgrEO->SetLocation (aSelfLocation);
296 //=======================================================================
297 //function : HilightSelected
299 //=======================================================================
300 void SelectMgr_SelectableObject::HilightSelected
301 ( const Handle(PrsMgr_PresentationManager3d)&,
302 const SelectMgr_SequenceOfOwner&)
304 Standard_NotImplemented::Raise ("SelectMgr_SelectableObject::HilightSelected");
307 //=======================================================================
308 //function : ClearSelected
310 //=======================================================================
311 void SelectMgr_SelectableObject::ClearSelected ()
313 if( !mySelectionPrs.IsNull() )
314 mySelectionPrs->Clear();
317 //=======================================================================
318 //function : HilightOwnerWithColor
320 //=======================================================================
321 void SelectMgr_SelectableObject::HilightOwnerWithColor
322 ( const Handle(PrsMgr_PresentationManager3d)&,
323 const Quantity_NameOfColor,
324 const Handle(SelectMgr_EntityOwner)&)
326 Standard_NotImplemented::Raise ("SelectMgr_SelectableObject::HilightOwnerWithColor");
329 //=======================================================================
330 //function : MaxFaceNodes
332 //=======================================================================
333 Standard_Boolean SelectMgr_SelectableObject::IsAutoHilight () const
335 return myAutoHilight;
338 //=======================================================================
339 //function : MaxFaceNodes
341 //=======================================================================
342 void SelectMgr_SelectableObject::SetAutoHilight ( const Standard_Boolean newAutoHilight )
344 myAutoHilight = newAutoHilight;
347 //=======================================================================
348 //function : GetHilightPresentation
350 //=======================================================================
351 Handle(Prs3d_Presentation) SelectMgr_SelectableObject::GetHilightPresentation( const Handle(PrsMgr_PresentationManager3d)& TheMgr )
353 if( myHilightPrs.IsNull() && !TheMgr.IsNull() )
355 myHilightPrs = new Prs3d_Presentation( TheMgr->StructureManager() );
356 myHilightPrs->SetTransformPersistence( GetTransformPersistenceMode(),
357 GetTransformPersistencePoint() );
364 //=======================================================================
365 //function : GetSelectPresentation
367 //=======================================================================
368 Handle(Prs3d_Presentation) SelectMgr_SelectableObject::GetSelectPresentation( const Handle(PrsMgr_PresentationManager3d)& TheMgr )
370 if( mySelectionPrs.IsNull() && !TheMgr.IsNull() ) {
371 mySelectionPrs = new Prs3d_Presentation( TheMgr->StructureManager() );
372 mySelectionPrs->SetTransformPersistence( GetTransformPersistenceMode(),
373 GetTransformPersistencePoint() );
375 return mySelectionPrs;
378 //=======================================================================
379 //function : SetZLayer
381 //=======================================================================
382 void SelectMgr_SelectableObject::SetZLayer (const Graphic3d_ZLayerId theLayerId)
384 // update own presentations
385 PrsMgr_PresentableObject::SetZLayer (theLayerId);
387 // update selection presentations
388 if (!mySelectionPrs.IsNull())
389 mySelectionPrs->SetZLayer (theLayerId);
391 if (!myHilightPrs.IsNull())
392 myHilightPrs->SetZLayer (theLayerId);
394 // update all entity owner presentations
395 for (Init (); More () ;Next ())
397 const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
398 for (aSel->Init (); aSel->More (); aSel->Next ())
400 Handle(Select3D_SensitiveEntity) aEntity =
401 Handle(Select3D_SensitiveEntity)::DownCast (aSel->Sensitive()->BaseSensitive());
402 if (!aEntity.IsNull())
404 Handle(SelectMgr_EntityOwner) aOwner =
405 Handle(SelectMgr_EntityOwner)::DownCast (aEntity->OwnerId());
406 if (!aOwner.IsNull())
407 aOwner->SetZLayer (theLayerId);
413 //=======================================================================
414 //function : UpdateSelection
415 //purpose : Sets update status FULL to selections of the object. Must be
416 // used as the only method of UpdateSelection from outer classes
417 // to prevent BVH structures from being outdated.
418 //=======================================================================
419 void SelectMgr_SelectableObject::UpdateSelection (const Standard_Integer theMode)
423 for (Init(); More(); Next())
425 const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
426 aSel->UpdateStatus (SelectMgr_TOU_Full);
432 for (Init(); More(); Next())
434 if (CurrentSelection()->Mode() == theMode)
436 CurrentSelection()->UpdateStatus (SelectMgr_TOU_Full);
442 //=======================================================================
443 //function : SetAttributes
445 //=======================================================================
446 void SelectMgr_SelectableObject::SetAttributes (const Handle(Prs3d_Drawer)& theDrawer)
448 myDrawer = theDrawer;
451 //=======================================================================
452 //function : UnsetAttributes
454 //=======================================================================
455 void SelectMgr_SelectableObject::UnsetAttributes()
457 Handle(Prs3d_Drawer) aDrawer = new Prs3d_Drawer();
458 if (myDrawer->HasLink())
460 aDrawer->Link (myDrawer->Link());
465 //=======================================================================
466 //function : SetHilightAttributes
468 //=======================================================================
469 void SelectMgr_SelectableObject::SetHilightAttributes (const Handle(Prs3d_Drawer)& theDrawer)
471 myHilightDrawer = theDrawer;
474 //=======================================================================
475 //function : UnsetAttributes
477 //=======================================================================
478 void SelectMgr_SelectableObject::UnsetHilightAttributes()
480 Handle(Prs3d_Drawer) aDrawer = new Prs3d_Drawer();
481 InitDefaultHilightAttributes (aDrawer);
482 aDrawer->Link (myDrawer);
483 myHilightDrawer = aDrawer;
486 //=======================================================================
487 //function : InitDefaultHilightAttributes
489 //=======================================================================
490 void SelectMgr_SelectableObject::InitDefaultHilightAttributes (const Handle(Prs3d_Drawer)& theDrawer)
492 if (!theDrawer->HasOwnPointAspect())
494 theDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, Quantity_NOC_BLACK, 1.0));
495 if (theDrawer->HasLink())
497 *theDrawer->PointAspect()->Aspect() = *theDrawer->Link()->PointAspect()->Aspect();
500 if (!theDrawer->HasOwnLineAspect())
502 theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
503 if (theDrawer->HasLink())
505 *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
508 if (!theDrawer->HasOwnWireAspect())
510 theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
511 if (theDrawer->HasLink())
513 *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
516 if (!theDrawer->HasOwnPlaneAspect())
518 theDrawer->SetPlaneAspect (new Prs3d_PlaneAspect());
519 if (theDrawer->HasLink())
521 *theDrawer->PlaneAspect()->EdgesAspect() = *theDrawer->Link()->PlaneAspect()->EdgesAspect();
524 if (!theDrawer->HasOwnFreeBoundaryAspect())
526 theDrawer->SetFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
527 if (theDrawer->HasLink())
529 *theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect();
532 if (!theDrawer->HasOwnUnFreeBoundaryAspect())
534 theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
535 if (theDrawer->HasLink())
537 *theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect();
541 theDrawer->WireAspect()->SetWidth(2.);
542 theDrawer->LineAspect()->SetWidth(2.);
543 theDrawer->PlaneAspect()->EdgesAspect()->SetWidth(2.);
544 theDrawer->FreeBoundaryAspect()->SetWidth(2.);
545 theDrawer->UnFreeBoundaryAspect()->SetWidth(2.);
546 theDrawer->PointAspect()->SetTypeOfMarker(Aspect_TOM_O_POINT);
547 theDrawer->PointAspect()->SetScale(2.);
549 // By default the hilight drawer has absolute type of deflection.
550 // It is supposed that absolute deflection is taken from Link().
551 // It is necessary to use for all sub-shapes identical coefficient
552 // computed in ::Compute() call for whole shape and stored in base drawer.
553 theDrawer->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
556 //=======================================================================
557 //function : SetAssemblyOwner
558 //purpose : Sets common entity owner for assembly sensitive object entities
559 //=======================================================================
560 void SelectMgr_SelectableObject::SetAssemblyOwner (const Handle(SelectMgr_EntityOwner)& theOwner,
561 const Standard_Integer theMode)
565 for (Standard_Integer aModeIter = 1; aModeIter <= myselections.Length(); ++aModeIter)
567 Handle(SelectMgr_Selection)& aSel = myselections.ChangeValue (aModeIter);
568 for (aSel->Init(); aSel->More(); aSel->Next())
570 aSel->Sensitive()->BaseSensitive()->Set (theOwner);
577 if (!HasSelection (theMode))
580 for (Standard_Integer aModeIter = 1; aModeIter <= myselections.Length(); ++aModeIter)
582 if (myselections.Value (aModeIter)->Mode() == theMode)
584 Handle(SelectMgr_Selection)& aSel = myselections.ChangeValue (aModeIter);
585 for (aSel->Init(); aSel->More(); aSel->Next())
587 aSel->Sensitive()->BaseSensitive()->Set (theOwner);
594 //=======================================================================
595 //function : GetAssemblyOwner
596 //purpose : Returns common entity owner if it is an assembly
597 //=======================================================================
598 const Handle(SelectMgr_EntityOwner)& SelectMgr_SelectableObject::GetAssemblyOwner() const
600 return myAssemblyOwner;
603 //=======================================================================
604 //function : BndBoxOfSelected
605 //purpose : Returns a bounding box of sensitive entities with the owners given
606 // if they are a part of activated selection
607 //=======================================================================
608 Bnd_Box SelectMgr_SelectableObject::BndBoxOfSelected (Handle(SelectMgr_IndexedMapOfOwner)& theOwners)
612 if (theOwners->IsEmpty())
615 for (Init(); More(); Next())
617 const Handle(SelectMgr_Selection)& aSel = CurrentSelection();
618 if (aSel->GetSelectionState() != SelectMgr_SOS_Activated)
621 for (aSel->Init(); aSel->More(); aSel->Next())
623 const Handle(SelectMgr_EntityOwner) anOwner =
624 Handle(SelectMgr_EntityOwner)::DownCast (aSel->Sensitive()->BaseSensitive()->OwnerId());
625 if (theOwners->Contains (anOwner))
627 Select3D_BndBox3d aBox = aSel->Sensitive()->BaseSensitive()->BoundingBox();
629 aTmpBnd.Update (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
630 aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
633 Standard_Integer anOwnerIdx = theOwners->FindIndex (anOwner);
634 if (theOwners->Size() != anOwnerIdx)
636 theOwners->Swap (anOwnerIdx, theOwners->Size());
638 theOwners->RemoveLast();
640 if (theOwners->IsEmpty())
649 //=======================================================================
650 //function : GlobalSelOwner
651 //purpose : Returns entity owner corresponding to selection of the object as a whole
652 //=======================================================================
653 Handle(SelectMgr_EntityOwner) SelectMgr_SelectableObject::GlobalSelOwner() const
655 Handle(SelectMgr_EntityOwner) anOwner;
657 if (!HasSelection (myGlobalSelMode))
660 const Handle(SelectMgr_Selection)& aGlobalSel = Selection (myGlobalSelMode);
661 if (aGlobalSel->IsEmpty())
666 Handle(SelectMgr_EntityOwner)::DownCast (aGlobalSel->Sensitive()->BaseSensitive()->OwnerId());