1 // Created on: 1996-10-30
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1996-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.
17 // Modified by rob Thu Apr 02 1998
18 // - use of optimisation in SelectMgr_ViewerSelector
19 // -> Best management in detected entities...
21 #include <AIS_InteractiveContext.hxx>
22 #include <AIS_InteractiveObject.hxx>
23 #include <AIS_LocalContext.hxx>
24 #include <AIS_LocalStatus.hxx>
25 #include <AIS_Selection.hxx>
26 #include <AIS_Shape.hxx>
27 #include <Aspect_Grid.hxx>
28 #include <Geom_Transformation.hxx>
29 #include <Graphic3d_ArrayOfTriangles.hxx>
30 #include <Graphic3d_Group.hxx>
31 #include <NCollection_Map.hxx>
32 #include <OSD_Environment.hxx>
33 #include <Prs3d_Drawer.hxx>
34 #include <Prs3d_Presentation.hxx>
35 #include <Prs3d_ShadingAspect.hxx>
36 #include <Select3D_SensitiveTriangulation.hxx>
37 #include <SelectBasics_SensitiveEntity.hxx>
38 #include <SelectMgr_EntityOwner.hxx>
39 #include <SelectMgr_Filter.hxx>
40 #include <SelectMgr_OrFilter.hxx>
41 #include <SelectMgr_SelectableObject.hxx>
42 #include <SelectMgr_Selection.hxx>
43 #include <SelectMgr_SelectionManager.hxx>
44 #include <SelectMgr_SequenceOfOwner.hxx>
45 #include <Standard_Transient.hxx>
46 #include <StdSelect_BRepOwner.hxx>
47 #include <StdSelect_ViewerSelector3d.hxx>
48 #include <TCollection_AsciiString.hxx>
49 #include <TColStd_ListIteratorOfListOfInteger.hxx>
50 #include <TColStd_ListOfInteger.hxx>
51 #include <TColStd_MapIteratorOfMapOfTransient.hxx>
52 #include <TColStd_MapOfTransient.hxx>
53 #include <V3d_View.hxx>
57 TopoDS_Shape AIS_myDummyShape;
60 static Standard_Integer GetHiMod(const Handle(AIS_InteractiveObject)& IO)
62 return IO->HasHilightMode() ? IO->HilightMode():0;
65 //==================================================
68 //==================================================
69 AIS_StatusOfDetection AIS_LocalContext::MoveTo (const Standard_Integer theXpix,
70 const Standard_Integer theYpix,
71 const Handle(V3d_View)& theView,
72 const Standard_Boolean theToRedrawImmediate)
74 // check that ViewerSelector gives
75 if (theView->Viewer() != myCTX->CurrentViewer())
81 myAISDetectedSeq.Clear();
84 myDetectedSeq.Clear();
85 myFilters->SetDisabledObjects (theView->View()->HiddenObjects());
86 myMainVS->Pick (theXpix, theYpix, theView);
88 const Standard_Integer aDetectedNb = myMainVS->NbPicked();
89 for (Standard_Integer aDetIter = 1; aDetIter <= aDetectedNb; ++aDetIter)
91 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (aDetIter);
93 || !myFilters->IsOk (anOwner))
98 myDetectedSeq.Append (aDetIter); // normally they are already arranged in correct order...
99 Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
102 myAISDetectedSeq.Append (anObj);
106 // result of courses..
107 if (aDetectedNb == 0 || myDetectedSeq.IsEmpty())
109 if (mylastindex != 0 && mylastindex <= myMapOfOwner->Extent())
111 myMainPM->ClearImmediateDraw();
112 Unhilight (myMapOfOwner->FindKey (mylastindex), theView);
113 if (theToRedrawImmediate)
115 theView->RedrawImmediate();
120 return aDetectedNb == 0
125 // all owners detected by the selector are passed to the
126 // filters and correct ones are preserved...
128 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
129 manageDetected (anOwner, theView, theToRedrawImmediate);
130 if (myDetectedSeq.Length() == 1)
132 return aDetectedNb == 1
133 ? AIS_SOD_OnlyOneDetected
134 : AIS_SOD_OnlyOneGood;
138 return AIS_SOD_SeveralGood;
142 //=======================================================================
143 //function : AddSelect
145 //=======================================================================
146 AIS_StatusOfPick AIS_LocalContext::AddSelect (const Handle(Standard_Transient)& theObject)
148 mySelection->AddSelect (theObject);
150 Standard_Integer aSelNum = mySelection->Extent();
151 return (aSelNum == 1) ? AIS_SOP_OneSelected
152 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
156 //=======================================================================
159 //=======================================================================
160 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Boolean toUpdateViewer)
164 UnhilightPicked (Standard_False);
167 Standard_Integer aDetIndex = DetectedIndex();
170 ClearSelected (toUpdateViewer);
171 return (mySelection->Extent() == 0) ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
174 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex);
176 ClearSelected (Standard_False);
178 if (!anOwner->IsSelected()) // anOwner is not selected
180 anOwner->SetSelected (Standard_True);
181 mySelection->Select (anOwner);
186 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
187 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
189 Unhilight (anOwner, aViewer->ActiveView());
192 // advanced selection highlighting mechanism
193 if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
195 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
196 UpdateSelected (anIO, Standard_False);
201 myCTX->CurrentViewer()->Update();
205 return (mySelection->Extent() == 1) ? AIS_SOP_OneSelected : AIS_SOP_SeveralSelected;
208 //=======================================================================
211 //=======================================================================
212 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Integer theXPMin,
213 const Standard_Integer theYPMin,
214 const Standard_Integer theXPMax,
215 const Standard_Integer theYPMax,
216 const Handle(V3d_View)& theView,
217 const Standard_Boolean toUpdateViewer)
219 if (theView->Viewer() == myCTX->CurrentViewer())
221 myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
224 UnhilightPicked (Standard_False);
227 Standard_Integer aSelNum = mySelection->Extent();
230 if (!myMainVS->More())
232 ClearSelected (toUpdateViewer);
234 return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
237 ClearSelected (Standard_False);
239 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
241 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
242 if (myFilters->IsOk (anOwner))
244 // it can be helpful to classify this owner immediately...
245 if (!anOwner->IsSelected())
247 anOwner->SetSelected (Standard_True);
248 mySelection->Select (anOwner);
255 HilightPicked (toUpdateViewer);
259 Standard_Integer aSelNum = mySelection->Extent();
261 return (aSelNum == 1) ? AIS_SOP_OneSelected
262 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
266 //==================================================
268 // Purpose : Selection by polyline
269 //==================================================
270 AIS_StatusOfPick AIS_LocalContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
271 const Handle(V3d_View)& theView,
272 const Standard_Boolean toUpdateViewer)
274 if (theView->Viewer() == myCTX->CurrentViewer())
276 myMainVS->Pick (thePolyline, theView);
278 Standard_Integer aLastSelNum = mySelection->Extent();
280 if (!myMainVS->More())
282 // Nothing is selected clear selection.
283 ClearSelected (toUpdateViewer);
286 // Return state to know if something was unselected
287 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
292 UnhilightPicked (Standard_False);
295 // Clear previous selection without update to process this selection
296 ClearSelected (Standard_False);
298 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
300 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
301 if (myFilters->IsOk (anOwner))
303 // it can be helpful to classify this owner immediately...
304 if (!anOwner->IsSelected())
306 mySelection->AddSelect (anOwner);
307 anOwner->SetSelected (Standard_True);
314 HilightPicked (toUpdateViewer);
318 Standard_Integer aSelNum = mySelection->Extent();
319 return (aSelNum == 1) ? AIS_SOP_OneSelected
320 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
324 //=======================================================================
325 //function : ShiftSelect
327 //=======================================================================
328 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Boolean toUpdateViewer)
330 Standard_Integer aDetIndex = DetectedIndex();
334 Standard_Integer aSelNum = mySelection->Extent();
335 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex);
336 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
337 mySelection->Select (anOwner);
338 anOwner->SetSelected (toSelect);
342 myMainPM->ClearImmediateDraw();
343 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
344 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
346 Unhilight (anOwner, aViewer->ActiveView());
349 // advanced selection highlighting mechanism
350 if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
352 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
353 UpdateSelected (anIO, Standard_False);
358 myCTX->CurrentViewer()->Update();
362 Standard_Integer NS = mySelection->Extent();
363 if( NS == 1 ) return AIS_SOP_OneSelected;
364 else if( NS > 1 ) return AIS_SOP_SeveralSelected;
365 return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
367 return AIS_SOP_Error;
370 //=======================================================================
371 //function : ShiftSelect
373 //=======================================================================
374 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Integer theXPMin,
375 const Standard_Integer theYPMin,
376 const Standard_Integer theXPMax,
377 const Standard_Integer theYPMax,
378 const Handle(V3d_View)& theView,
379 const Standard_Boolean toUpdateViewer)
381 myMainPM->ClearImmediateDraw();
383 if (theView->Viewer() == myCTX->CurrentViewer())
385 myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
387 Standard_Integer aLastSelNum = mySelection->Extent();
390 if (!myMainVS->More())
392 // Nothing is selected clear selection, but don't clear the selection
393 // as it is shift selection and previous selection matters.
394 // Return state to know if something was unselected
395 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
400 UnhilightPicked (Standard_False);
403 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
405 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
406 if(myFilters->IsOk (anOwner))
408 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
409 mySelection->Select (anOwner);
410 anOwner->SetSelected (toSelect);
416 HilightPicked (toUpdateViewer);
420 Standard_Integer aSelNum = mySelection->Extent();
422 return (aSelNum == 1) ? AIS_SOP_OneSelected
423 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
427 //==================================================
429 // Purpose : Selection by polyline
430 //==================================================
431 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
432 const Handle(V3d_View)& theView,
433 const Standard_Boolean toUpdateViewer)
435 if (theView->Viewer() == myCTX->CurrentViewer())
437 myMainVS->Pick (thePolyline, theView);
439 Standard_Integer aLastSelNum = mySelection->Extent();
441 if(!myMainVS->More())
443 // Nothing is selected clear selection, but don't clear the selection
444 // as it is shift selection and previous selection matters.
445 // Return state to know if something was unselected
446 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
451 UnhilightPicked (Standard_False);
454 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
456 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
457 if (myFilters->IsOk (anOwner))
459 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
460 mySelection->Select (anOwner);
461 anOwner->SetSelected (toSelect);
466 HilightPicked (toUpdateViewer);
470 Standard_Integer aSelNum = mySelection->Extent();
472 return (aSelNum == 1) ? AIS_SOP_OneSelected
473 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
477 //==================================================
480 //==================================================
481 void AIS_LocalContext::Hilight (const Handle(SelectMgr_EntityOwner)& theOwner,
482 const Handle(V3d_View)& theView)
484 if (theView.IsNull())
489 const Standard_Integer aHilightMode = GetHiMod (Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable()));
490 myMainPM->BeginImmediateDraw();
491 theOwner->HilightWithColor (myMainPM, myCTX->HilightColor(), aHilightMode);
492 myMainPM->EndImmediateDraw (theView->Viewer());
495 //==================================================
496 // Function: Unhilight
498 //==================================================
499 void AIS_LocalContext::Unhilight (const Handle(SelectMgr_EntityOwner)& theOwner,
500 const Handle(V3d_View)& theView)
502 if (theView.IsNull())
507 const Standard_Integer aHilightMode = GetHiMod (Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable()));
508 if (IsSelected (theOwner))
510 if (theOwner->IsAutoHilight())
512 theOwner->HilightWithColor (myMainPM, myCTX->SelectionColor(), aHilightMode);
517 theOwner->Unhilight (myMainPM, aHilightMode);
521 //=======================================================================
522 //function : HilightPicked
524 //=======================================================================
525 void AIS_LocalContext::HilightPicked(const Standard_Boolean updateviewer)
527 if( mySelection.IsNull() ) return;
529 typedef NCollection_DataMap <Handle(SelectMgr_SelectableObject), NCollection_Handle<SelectMgr_SequenceOfOwner> > SelectMgr_DataMapOfObjectOwners;
530 SelectMgr_DataMapOfObjectOwners aMap;
532 Handle (PrsMgr_PresentationManager3d) PM = myMainPM;
534 // to avoid problems when there is a loop searching for selected objects...
535 const AIS_NListTransient& Obj = mySelection->Objects();
536 AIS_NListTransient::Iterator anIter( Obj );
537 for(; anIter.More(); anIter.Next())
539 const Handle(Standard_Transient)& Tr = anIter.Value();
541 const Handle(SelectMgr_EntityOwner)& Ownr =
542 *((const Handle(SelectMgr_EntityOwner)*) &Tr);
543 Handle(AIS_InteractiveObject) IO;
544 if(Ownr->HasSelectable()){
545 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(Ownr);
546 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
547 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
548 IO = Handle(AIS_InteractiveObject)::DownCast (SO);
551 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
552 Standard_Integer HM = GetHiMod(Handle(AIS_InteractiveObject)::DownCast (SO));
553 if ( Ownr->IsAutoHilight() )
554 Ownr->HilightWithColor(PM,myCTX->SelectionColor(),HM);
555 else if ( aMap.IsBound (SO) )
556 aMap(SO)->Append ( Ownr );
558 NCollection_Handle<SelectMgr_SequenceOfOwner> aSeq = new SelectMgr_SequenceOfOwner;
559 aSeq->Append ( Ownr );
560 aMap.Bind ( SO, aSeq );
565 for ( SelectMgr_DataMapOfObjectOwners::Iterator aMapIter(aMap);
566 aMapIter.More(); aMapIter.Next() )
568 aMapIter.Key()->HilightSelected (myMainPM, *aMapIter.Value());
573 myCTX->CurrentViewer()->Update();
577 //==================================================
580 //==================================================
581 void AIS_LocalContext::UnhilightPicked (const Standard_Boolean updateviewer)
583 myMainPM->ClearImmediateDraw();
585 if( mySelection.IsNull() ) return;
586 Handle (PrsMgr_PresentationManager3d) PM = myMainPM;
587 NCollection_Map<Handle(SelectMgr_SelectableObject)> anObjMap;
589 const AIS_NListTransient& Obj = mySelection->Objects();
590 AIS_NListTransient::Iterator anIter( Obj );
591 for(; anIter.More(); anIter.Next()){
592 const Handle(Standard_Transient)& Tr = anIter.Value();
594 const Handle(SelectMgr_EntityOwner)& Ownr =
595 *((const Handle(SelectMgr_EntityOwner)*) &Tr);
596 Standard_Integer HM(0);
597 if(Ownr->HasSelectable()){
598 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
599 Handle(AIS_InteractiveObject) IO = Handle(AIS_InteractiveObject)::DownCast (SO);
603 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(Ownr);
604 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
607 Ownr->Unhilight(PM,HM);
611 for (NCollection_Map<Handle(SelectMgr_SelectableObject)>::Iterator anIter1 ( anObjMap );
612 anIter1.More(); anIter1.Next() )
614 if ( !anIter1.Key()->IsAutoHilight() )
615 anIter1.Key()->ClearSelected();
619 myCTX->CurrentViewer()->Update();
622 //=======================================================================
623 //function : IsSelected
625 //=======================================================================
626 Standard_Boolean AIS_LocalContext::IsSelected(const Handle(AIS_InteractiveObject)& anIObj) const
628 return (!FindSelectedOwnerFromIO(anIObj).IsNull());
631 //=======================================================================
632 //function : IsSelected
634 //=======================================================================
636 Standard_Boolean AIS_LocalContext::IsSelected (const Handle(SelectMgr_EntityOwner)& theOwner) const
638 return !theOwner.IsNull() && theOwner->IsSelected();
641 //==================================================
644 //==================================================
645 void AIS_LocalContext::
651 //==================================================
654 //==================================================
655 Standard_Boolean AIS_LocalContext::
658 return mySelection->More();
661 //==================================================
664 //==================================================
665 void AIS_LocalContext::
671 //==================================================
674 //==================================================
675 Standard_Boolean AIS_LocalContext::
678 Handle(Standard_Transient) Tr = mySelection->Value();
679 if( Tr.IsNull() ) return Standard_False;
680 Handle(SelectMgr_EntityOwner) EO = Handle(SelectMgr_EntityOwner)::DownCast (Tr);
681 Handle(StdSelect_BRepOwner) BRO = Handle(StdSelect_BRepOwner)::DownCast(EO);
682 if(BRO.IsNull()) return Standard_False;
683 Standard_Boolean hasshape = BRO->HasShape();
684 Standard_Boolean comes = BRO->ComesFromDecomposition();
685 return (hasshape&&comes);
688 //================================================================
689 // Function : HasSelectedShape
690 // Purpose : Checks if there is a selected shape regardless of its decomposition status
691 //================================================================
692 Standard_Boolean AIS_LocalContext::HasSelectedShape() const
694 if (mySelection->Extent() == 0)
695 return Standard_False;
697 Handle(Standard_Transient) aCurSelection = mySelection->Value();
698 if (aCurSelection.IsNull())
699 return Standard_False;
701 Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aCurSelection);
702 Handle(StdSelect_BRepOwner) aBrepOwner = Handle(StdSelect_BRepOwner)::DownCast (anOwner);
703 if (aBrepOwner.IsNull())
705 return Standard_False;
707 return aBrepOwner->HasShape();
710 //==================================================
713 //==================================================
714 TopoDS_Shape AIS_LocalContext::SelectedShape() const
716 Handle(Standard_Transient) aTr = mySelection->Value();
717 Handle(SelectMgr_EntityOwner) anEO = Handle(SelectMgr_EntityOwner)::DownCast (aTr);
718 Handle(StdSelect_BRepOwner) aBRO = Handle(StdSelect_BRepOwner)::DownCast(anEO);
721 return TopoDS_Shape();
724 return aBRO->Shape().Located (aBRO->Location() * aBRO->Shape().Location());
727 //==================================================
730 //==================================================
731 Handle(AIS_InteractiveObject) AIS_LocalContext::
732 SelectedInteractive() const
734 Handle(AIS_InteractiveObject) IO;
735 Handle(Standard_Transient) Tr = mySelection->Value();
737 Handle(SelectMgr_EntityOwner) EO = Handle(SelectMgr_EntityOwner)::DownCast (Tr);
738 Handle(SelectMgr_SelectableObject) SO;
739 if(EO->HasSelectable()){
740 SO = EO->Selectable();
741 IO = Handle(AIS_InteractiveObject)::DownCast (SO);
746 //==================================================
749 //==================================================
750 Handle(SelectMgr_EntityOwner) AIS_LocalContext::
751 SelectedOwner() const
753 Handle(SelectMgr_EntityOwner) EO;
754 Handle(Standard_Transient) Tr = mySelection->Value();
756 EO = Handle(SelectMgr_EntityOwner)::DownCast (Tr);
760 //==================================================
763 //==================================================
764 Standard_Boolean AIS_LocalContext::
765 HasApplicative() const
767 Handle(AIS_InteractiveObject) IO = SelectedInteractive();
768 if( IO.IsNull() ) return Standard_False;
769 return IO->HasOwner();
772 //==================================================
775 //==================================================
776 const Handle(Standard_Transient)& AIS_LocalContext::
777 SelectedApplicative() const
779 return SelectedInteractive()->GetOwner();
784 //=======================================================================
785 //function : UpdateSelection
786 //purpose : should disappear...
787 //=======================================================================
788 void AIS_LocalContext::UpdateSelected(const Standard_Boolean updateviewer)
790 UnhilightPicked(Standard_False);
791 HilightPicked(updateviewer);
794 //================================================================
795 // Function : UpdateSelected
796 // Purpose : Part of advanced selection mechanism.
797 // Highlightes or clears selection presentation for the given IO
798 //================================================================
799 void AIS_LocalContext::UpdateSelected(const Handle(AIS_InteractiveObject)& anobj,
800 const Standard_Boolean updateviewer)
802 if (anobj.IsNull() || anobj->IsAutoHilight())
805 SelectMgr_SequenceOfOwner aSeq;
806 for (mySelection->Init(); mySelection->More(); mySelection->Next() ){
807 Handle(SelectMgr_EntityOwner) aOwner = Handle(SelectMgr_EntityOwner)::DownCast(mySelection->Value());
809 if ( !aOwner.IsNull() && aOwner->HasSelectable() && aOwner->Selectable() == anobj )
810 aSeq.Append( aOwner );
814 anobj->HilightSelected( myMainPM, aSeq );
816 anobj->ClearSelected();
819 myCTX->CurrentViewer()->Update();
823 //==================================================
824 // Function: ClearSelected
826 //==================================================
827 void AIS_LocalContext::ClearSelected (const Standard_Boolean updateviewer)
829 UnhilightPicked(updateviewer);
831 const AIS_NListTransient& Obj = mySelection->Objects();
832 AIS_NListTransient::Iterator anIter( Obj );
833 for(; anIter.More(); anIter.Next()){
834 const Handle(Standard_Transient)& Tr = anIter.Value();
837 (*((const Handle(SelectMgr_EntityOwner)*)&Tr))->SetSelected (Standard_False);
840 mySelection->Select();
844 //==================================================
845 // Function: ClearOutdatedSelection
847 //==================================================
848 void AIS_LocalContext::ClearOutdatedSelection (const Handle(AIS_InteractiveObject)& theIO,
849 const Standard_Boolean toClearDeactivated)
851 // 1. Collect selectable entities
852 SelectMgr_IndexedMapOfOwner aValidOwners;
854 const TColStd_ListOfInteger& aModes = SelectionModes (theIO);
856 TColStd_ListIteratorOfListOfInteger aModeIter (aModes);
857 for (; aModeIter.More(); aModeIter.Next())
859 int aMode = aModeIter.Value();
860 if (!theIO->HasSelection(aMode))
865 if (toClearDeactivated && !mySM->IsActivated(theIO, aMode, myMainVS))
870 Handle(SelectMgr_Selection) aSelection = theIO->Selection(aMode);
871 for (aSelection->Init(); aSelection->More(); aSelection->Next())
873 Handle(SelectBasics_SensitiveEntity) anEntity = aSelection->Sensitive()->BaseSensitive();
874 if (anEntity.IsNull())
879 Handle(SelectMgr_EntityOwner) anOwner =
880 Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId());
882 if (anOwner.IsNull())
887 aValidOwners.Add(anOwner);
891 // 2. Refresh context's detection and selection and keep only active owners.
892 // Keep last detected object for lastindex initialization.
893 Handle(SelectMgr_EntityOwner) aLastPicked;
894 if (IsValidIndex (mylastindex))
896 aLastPicked = myMapOfOwner->FindKey (mylastindex);
899 // Remove entity owners from detected sequences
900 for (Standard_Integer anIdx = 1; anIdx <= myDetectedSeq.Length(); ++anIdx)
902 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (anIdx));
903 if (anOwner.IsNull() || anOwner->Selectable() != theIO || aValidOwners.Contains (anOwner))
908 myDetectedSeq.Remove (anIdx--);
910 if (anIdx < myCurDetected)
915 myCurDetected = Max (myCurDetected, 1);
917 Standard_Boolean isAISRemainsDetected = Standard_False;
919 // 3. AIS_Selection : remove entity owners from AIS_Selection
920 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
921 AIS_NListTransient::Iterator anIter (mySelection->Objects());
922 AIS_NListTransient aRemoveEntites;
923 for (; anIter.More(); anIter.Next())
925 Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anIter.Value());
926 if (anOwner.IsNull() || anOwner->Selectable() != theIO)
931 if (aValidOwners.Contains (anOwner))
933 isAISRemainsDetected = Standard_True;
937 aRemoveEntites.Append (anOwner);
938 anOwner->SetSelected (Standard_False);
939 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
941 Unhilight (anOwner, aViewer->ActiveView());
945 AIS_NListTransient::Iterator anIterRemove (aRemoveEntites);
946 for (; anIterRemove.More(); anIterRemove.Next())
948 mySelection->Select (anIterRemove.Value());
951 // 4. AIS_LocalContext - myMapOfOwner : remove entity owners from myMapOfOwner
952 SelectMgr_IndexedMapOfOwner anOwnersToKeep;
953 for (Standard_Integer anIdx = 1; anIdx <= myMapOfOwner->Extent(); anIdx++)
955 Handle(SelectMgr_EntityOwner) anOwner = myMapOfOwner->FindKey (anIdx);
956 if (anOwner.IsNull())
961 if (anOwner->Selectable() != theIO || aValidOwners.Contains (anOwner))
963 anOwnersToKeep.Add (anOwner);
967 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
969 Unhilight (anOwner, aViewer->ActiveView());
973 myMapOfOwner->Clear();
974 myMapOfOwner->Assign (anOwnersToKeep);
976 if (myDetectedSeq.IsEmpty() && !aLastPicked.IsNull())
978 myMainPM->ClearImmediateDraw();
981 else if (!aLastPicked.IsNull())
983 // For a case when the last detected owner was unhilighted and removed as outdated we
984 // need to check if there were other detected owners with less priority. If yes then
985 // one from the remaining should be treated.
986 Standard_Integer anIndex = 1, aDetectedSeqLength = myDetectedSeq.Length();
987 for (; anIndex <= aDetectedSeqLength; anIndex++)
989 if (aLastPicked == myMainVS->Picked (myDetectedSeq.Value(anIndex)))
991 break; // detected owner was not removed
994 if (anIndex <= aDetectedSeqLength)
996 // Last detected owner was not removed, update mylastindex variable
997 mylastindex = myMapOfOwner->FindIndex (aLastPicked);
1001 // Last detected owner was removed. First object from sequence become detected.
1002 // Pass any active view because in current implementation the highlighting is
1003 // synchronized in all view.
1004 aViewer->InitActiveViews();
1005 manageDetected (myMainVS->Picked (myDetectedSeq.First()),
1006 aViewer->ActiveView(),
1011 // Renew iterator of ::DetectedCurrentObject()
1012 if (!isAISRemainsDetected)
1014 // Remove the interactive object from detected sequences
1015 for (Standard_Integer anIdx = 1; anIdx <= myAISDetectedSeq.Length(); ++anIdx)
1017 Handle(AIS_InteractiveObject) aDetectedIO = myAISDetectedSeq.Value (anIdx);
1018 if (aDetectedIO.IsNull() || aDetectedIO != theIO)
1023 myAISDetectedSeq.Remove (anIdx--);
1025 if (anIdx < myAISCurDetected)
1030 myAISCurDetected = Max (myAISCurDetected, 1);
1034 //=======================================================================
1035 //function : SetSelected
1037 //=======================================================================
1038 void AIS_LocalContext::SetSelected(const Handle(AIS_InteractiveObject)& anIObj,
1039 const Standard_Boolean updateviewer)
1041 if(!IsValidForSelection(anIObj)) return;
1042 UnhilightPicked(Standard_False);
1044 //1st case, owner already <anIObj> as owner
1045 // and not separated is found...
1047 Handle(Standard_Transient) Tr;
1048 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromIO(anIObj);
1050 //check if in selection number 0 there is an owner that can be triturated...
1051 if(anIObj->HasSelection(0)){
1052 const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0);
1055 Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->BaseSensitive()->OwnerId();
1056 EO = Handle(SelectMgr_EntityOwner)::DownCast (BO);
1060 EO = new SelectMgr_EntityOwner((const Handle(SelectMgr_SelectableObject)&)anIObj);
1063 ClearSelected(Standard_False);
1065 mySelection->Select(EO);
1066 EO->SetSelected (Standard_True);
1068 HilightPicked(updateviewer);
1071 //=======================================================================
1072 //function : AddOrRemoveSelected
1074 //=======================================================================
1076 void AIS_LocalContext::AddOrRemoveSelected(const Handle(AIS_InteractiveObject)& anIObj,
1077 const Standard_Boolean updateviewer)
1079 if(!IsValidForSelection(anIObj)) return;
1080 UnhilightPicked(Standard_False);
1081 // first check if it is selected...
1082 Handle(SelectMgr_EntityOwner) EO;
1084 EO = FindSelectedOwnerFromIO(anIObj);
1088 if(anIObj->HasSelection(0))
1090 const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0);
1093 Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->BaseSensitive()->OwnerId();
1094 EO = Handle(SelectMgr_EntityOwner)::DownCast (BO);
1099 EO = new SelectMgr_EntityOwner((const Handle(SelectMgr_SelectableObject)&)anIObj);
1103 if (!mySelection.IsNull())
1105 AIS_SelectStatus aStatus = mySelection->Select(EO);
1106 EO->SetSelected (aStatus == AIS_SS_Added);
1109 HilightPicked(updateviewer);
1112 //=======================================================================
1113 //function : AddOrRemoveSelected
1114 //purpose : To check...
1115 //=======================================================================
1116 void AIS_LocalContext::AddOrRemoveSelected(const TopoDS_Shape& Sh,
1117 const Standard_Boolean updateviewer)
1119 UnhilightPicked (Standard_False);
1120 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromShape(Sh);
1123 mySelection->Select(EO);
1124 EO->SetSelected (Standard_True);
1126 HilightPicked (updateviewer);
1129 void AIS_LocalContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
1130 const Standard_Boolean toUpdateViewer)
1134 UnhilightPicked (Standard_False);
1137 Standard_Boolean toSelect = theOwner->IsSelected() ? Standard_False : Standard_True;
1139 mySelection->Select(theOwner);
1140 theOwner->SetSelected (toSelect);
1144 HilightPicked (toUpdateViewer);
1148 //==================================================
1149 // Function: manageDetected
1151 //==================================================
1152 void AIS_LocalContext::manageDetected (const Handle(SelectMgr_EntityOwner)& thePickOwner,
1153 const Handle(V3d_View)& theView,
1154 const Standard_Boolean theToRedrawImmediate)
1156 if (thePickOwner.IsNull())
1158 myMainPM->ClearImmediateDraw();
1159 if (theToRedrawImmediate)
1161 theView->RedrawImmediate();
1166 if (!myFilters->IsOk (thePickOwner))
1168 if (mylastindex != 0)
1170 mylastgood = mylastindex;
1172 if (theToRedrawImmediate)
1174 theView->RedrawImmediate();
1179 //=======================================================================================================
1180 // 2 cases : a- object is in the map of picks:
1181 // 1. this is the same index as the last detected: -> Do nothing
1183 // - if lastindex = 0 (no object was detected at the last step)
1184 // the object presentation is highlighted and lastindex = index(objet)
1186 // the presentation of the object corresponding to lastindex is "unhighlighted"
1187 // it is removed if the object is not visualized but only active
1188 // then the presentation of the detected object is highlighted and lastindex = index(objet)
1189 // b- the object is not in the map of picked objects
1190 // - if lastindex != 0 (object detected at the last step) it is unhighlighted ...
1191 // if the object was decomposed, presentation is created for the detected shape and the couple
1192 // (Proprietaire,Prs)is added in the map.
1193 // otherwise the couple(proprietaire, NullPrs) is placed in the map and the interactive object
1194 // itself is highlighted.
1196 //=======================================================================================================
1198 const Standard_Integer aNewIndex = myMapOfOwner->Contains (thePickOwner)
1199 ? myMapOfOwner->FindIndex (thePickOwner)
1200 : myMapOfOwner->Add (thePickOwner);
1202 // For the advanced mesh selection mode the owner indices comparison
1203 // is not effective because in that case only one owner manage the
1204 // selection in current selection mode. It is necessary to check the current detected
1205 // entity and hilight it only if the detected entity is not the same as
1206 // previous detected (IsForcedHilight call)
1207 if (aNewIndex != mylastindex
1208 || thePickOwner->IsForcedHilight())
1210 myMainPM->ClearImmediateDraw();
1211 if (mylastindex != 0
1212 && mylastindex <= myMapOfOwner->Extent())
1214 const Handle(SelectMgr_EntityOwner)& aLastOwner = myMapOfOwner->FindKey (mylastindex);
1215 Unhilight (aLastOwner, theView);
1220 if (!thePickOwner->IsSelected() || myCTX->ToHilightSelected())
1222 Hilight (thePickOwner, theView);
1224 if (theToRedrawImmediate)
1226 theView->RedrawImmediate();
1230 mylastindex = aNewIndex;
1233 if (mylastindex != 0)
1235 mylastgood = mylastindex;
1239 //=======================================================================
1240 //function : HasDetectedShape
1242 //=======================================================================
1244 Standard_Boolean AIS_LocalContext::HasDetectedShape() const
1246 if(mylastindex==0) return Standard_False;
1247 return IsShape(mylastindex);
1250 //=======================================================================
1251 //function : DetectedShape
1253 //=======================================================================
1256 AIS_LocalContext::DetectedShape() const
1258 if(mylastindex != 0)
1260 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner->FindKey (mylastindex));
1261 if(BROwnr.IsNull()) return AIS_myDummyShape;
1262 return BROwnr->Shape();
1264 return AIS_myDummyShape;
1267 //=======================================================================
1268 //function : DetectedInteractive
1270 //=======================================================================
1272 Handle(AIS_InteractiveObject)
1273 AIS_LocalContext::DetectedInteractive() const
1275 Handle(AIS_InteractiveObject) Iobj;
1276 if(IsValidIndex(mylastindex)){
1277 Handle(SelectMgr_SelectableObject) SO = myMapOfOwner->FindKey(mylastindex)->Selectable();
1278 Iobj = Handle(AIS_InteractiveObject)::DownCast (SO);
1282 //=======================================================================
1283 //function : DetectedInteractive
1285 //=======================================================================
1286 Handle(SelectMgr_EntityOwner) AIS_LocalContext::DetectedOwner() const
1288 Handle(SelectMgr_EntityOwner) bid;
1289 if(!IsValidIndex(mylastindex)) return bid;
1290 return myMapOfOwner->FindKey(mylastindex);
1294 //=======================================================================
1295 //function : ComesFromDecomposition
1297 //=======================================================================
1299 Standard_Boolean AIS_LocalContext::ComesFromDecomposition(const Standard_Integer PickedIndex) const
1301 const Handle(SelectMgr_EntityOwner)& OWN = myMapOfOwner->FindKey(PickedIndex);
1302 Handle(SelectMgr_SelectableObject) aSel = OWN->Selectable();
1303 if (myActiveObjects.IsBound (aSel)) { // debug of jmi
1304 const Handle(AIS_LocalStatus)& Stat = myActiveObjects(aSel);
1305 return Stat->Decomposed();
1307 return Standard_False;
1310 //=======================================================================
1311 //function : DisplaySensitive
1313 //=======================================================================
1315 void AIS_LocalContext::DisplaySensitive(const Handle(V3d_View)& aviou)
1317 myMainVS->DisplaySensitive(aviou);
1320 //=======================================================================
1321 //function : ClearSensitive
1323 //=======================================================================
1325 void AIS_LocalContext::ClearSensitive(const Handle(V3d_View)& aviou)
1327 myMainVS->ClearSensitive(aviou);
1331 //=======================================================================
1332 //function : IsShape
1334 //=======================================================================
1335 Standard_Boolean AIS_LocalContext::IsShape(const Standard_Integer Index) const
1337 Handle(SelectMgr_EntityOwner) aEO (myMapOfOwner->FindKey(Index));
1338 if (aEO.IsNull() || ! aEO->IsKind(STANDARD_TYPE(StdSelect_BRepOwner)))
1339 return Standard_False;
1341 ComesFromDecomposition(Index);
1344 Standard_Boolean AIS_LocalContext::IsValidForSelection(const Handle(AIS_InteractiveObject)& anIObj) const
1346 const Handle(SelectMgr_SelectableObject)& aSelObj = anIObj; // to avoid ambiguity
1347 // Shape was not transfered from AIS_Shape to EntityOwner
1348 Handle(AIS_Shape) shape = Handle(AIS_Shape)::DownCast(anIObj);
1349 if( !shape.IsNull() )
1350 return myFilters->IsOk(new StdSelect_BRepOwner(shape->Shape(), aSelObj));
1351 return myFilters->IsOk(new SelectMgr_EntityOwner(aSelObj));
1355 //=======================================================================
1356 //function : HilightNextDetected
1358 //=======================================================================
1359 Standard_Integer AIS_LocalContext::HilightNextDetected (const Handle(V3d_View)& theView,
1360 const Standard_Boolean theToRedrawImmediate)
1362 // go to the next owner
1363 if (myDetectedSeq.IsEmpty())
1368 const Standard_Integer aLen = myDetectedSeq.Length();
1369 if (++myCurDetected > aLen)
1373 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1374 if (anOwner.IsNull())
1378 manageDetected (anOwner, theView, theToRedrawImmediate);
1379 return myCurDetected;
1382 //=======================================================================
1383 //function : HilightPreviousDetected
1385 //=======================================================================
1386 Standard_Integer AIS_LocalContext::HilightPreviousDetected (const Handle(V3d_View)& theView,
1387 const Standard_Boolean theToRedrawImmediate)
1389 if (myDetectedSeq.IsEmpty())
1394 const Standard_Integer aLen = myDetectedSeq.Length();
1395 if (--myCurDetected < 1)
1397 myCurDetected = aLen;
1399 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1400 if (anOwner.IsNull())
1405 manageDetected (anOwner, theView, theToRedrawImmediate);
1406 return myCurDetected;
1409 //=======================================================================
1410 //function : UnhilightLastDetected
1412 //=======================================================================
1413 Standard_Boolean AIS_LocalContext::UnhilightLastDetected (const Handle(V3d_View)& theView)
1415 if (!IsValidIndex (mylastindex))
1417 return Standard_False;
1420 myMainPM->BeginImmediateDraw();
1421 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (mylastindex);
1422 const Standard_Integer aHilightMode = anOwner->HasSelectable()
1423 ? GetHiMod (Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable()))
1426 myMapOfOwner->FindKey (mylastindex)->Unhilight (myMainPM, aHilightMode);
1427 myMainPM->EndImmediateDraw (theView->Viewer());
1429 return Standard_True;
1432 //=======================================================================
1433 //function : FindSelectedOwnerFromIO
1434 //purpose : it is checked if one of the selected owners really presents IObj
1435 //=======================================================================
1436 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromIO
1437 (const Handle(AIS_InteractiveObject)& anIObj) const
1439 Handle(SelectMgr_EntityOwner) EO,bid;
1440 if (anIObj.IsNull()) return EO;
1442 if(mySelection.IsNull()) {
1444 cout<<"\t\tAIS_LocalCOntext::FindSelectedOwnerFromShape : Selection "
1445 <<mySelName<<" Nulle "<<endl;
1449 Standard_Boolean found(Standard_False);
1450 const AIS_NListTransient& Obj = mySelection->Objects();
1451 AIS_NListTransient::Iterator anIter( Obj );
1452 for(; anIter.More(); anIter.Next()){
1453 const Handle(Standard_Transient)& Tr = anIter.Value();
1455 EO = Handle(SelectMgr_EntityOwner)::DownCast (Tr);
1456 if(EO->HasSelectable()){
1457 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1458 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
1459 if (anIObj == EO->Selectable()){
1460 found =Standard_True;
1467 if(found) return EO;
1471 //=======================================================================
1472 //function : FindSelectedOwnerFromShape
1473 //purpose : it is checked if one of the selected owners really presents IObj
1474 //=======================================================================
1475 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromShape(const TopoDS_Shape& sh) const
1477 Handle(SelectMgr_EntityOwner) EO, bid;
1478 if (sh.IsNull()) return EO;
1480 if(mySelection.IsNull()) {
1482 cout<<"\t\tAIS_LocalCOntext::FindSelectedOwnerFromShape : Selection "<<mySelName<<" Nulle "<<endl;
1487 Standard_Boolean found(Standard_False);
1490 NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
1491 myMainVS->ActiveOwners (anActiveOwners);
1492 for (NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (anActiveOwners); anOwnersIt.More(); anOwnersIt.Next())
1494 EO = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value());
1495 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1496 if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) {
1497 found = Standard_True;
1503 if(found) return EO;
1507 //=======================================================================
1508 //function : AIS_LocalContext::InitDetected
1510 //=======================================================================
1511 void AIS_LocalContext::InitDetected()
1513 myAISCurDetected = myAISDetectedSeq.Length()? 1 : 0;
1516 //=======================================================================
1517 //function : AIS_LocalContext::MoreDetected
1519 //=======================================================================
1520 Standard_Boolean AIS_LocalContext::MoreDetected() const
1522 return (myAISCurDetected > 0 && myAISCurDetected <= myAISDetectedSeq.Length());
1525 //=======================================================================
1526 //function : AIS_LocalContext::NextDetected
1528 //=======================================================================
1529 void AIS_LocalContext::NextDetected()
1534 //=======================================================================
1535 //function : DetectedCurrentShape
1537 //=======================================================================
1538 const TopoDS_Shape& AIS_LocalContext::DetectedCurrentShape() const
1540 Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
1542 if (aCurrentShape.IsNull())
1544 return AIS_myDummyShape;
1547 return aCurrentShape->Shape();
1549 //=======================================================================
1550 //function : DetectedCurrentObject
1552 //=======================================================================
1553 Handle(AIS_InteractiveObject) AIS_LocalContext::DetectedCurrentObject() const
1555 return MoreDetected() ? myAISDetectedSeq(myAISCurDetected) : NULL;
1558 //=======================================================================
1559 //function : RestoreActivatedModes
1561 //=======================================================================
1562 void AIS_LocalContext::RestoreActivatedModes() const
1564 for (AIS_DataMapOfSelStat::Iterator anIter (myActiveObjects); anIter.More(); anIter.Next())
1566 const TColStd_ListOfInteger& anActivatedModes = anIter.Value()->SelectionModes();
1567 for (TColStd_ListIteratorOfListOfInteger aModesIter (anActivatedModes); aModesIter.More(); aModesIter.Next())
1569 mySM->Activate (anIter.Key(), aModesIter.Value(), myMainVS);