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 //==================================================
63 //==================================================
64 AIS_StatusOfDetection AIS_LocalContext::MoveTo (const Standard_Integer theXpix,
65 const Standard_Integer theYpix,
66 const Handle(V3d_View)& theView,
67 const Standard_Boolean theToRedrawImmediate)
69 // check that ViewerSelector gives
70 if (theView->Viewer() != myCTX->CurrentViewer())
76 myAISDetectedSeq.Clear();
79 myDetectedSeq.Clear();
80 myFilters->SetDisabledObjects (theView->View()->HiddenObjects());
81 myMainVS->Pick (theXpix, theYpix, theView);
83 const Standard_Integer aDetectedNb = myMainVS->NbPicked();
84 for (Standard_Integer aDetIter = 1; aDetIter <= aDetectedNb; ++aDetIter)
86 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (aDetIter);
88 || !myFilters->IsOk (anOwner))
93 myDetectedSeq.Append (aDetIter); // normally they are already arranged in correct order...
94 Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
97 myAISDetectedSeq.Append (anObj);
101 // result of courses..
102 if (aDetectedNb == 0 || myDetectedSeq.IsEmpty())
104 if (mylastindex != 0 && mylastindex <= myMapOfOwner->Extent())
106 myMainPM->ClearImmediateDraw();
107 Unhilight (myMapOfOwner->FindKey (mylastindex), theView);
108 if (theToRedrawImmediate)
110 theView->RedrawImmediate();
115 return aDetectedNb == 0
120 // all owners detected by the selector are passed to the
121 // filters and correct ones are preserved...
123 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
124 manageDetected (anOwner, theView, theToRedrawImmediate);
125 if (myDetectedSeq.Length() == 1)
127 return aDetectedNb == 1
128 ? AIS_SOD_OnlyOneDetected
129 : AIS_SOD_OnlyOneGood;
133 return AIS_SOD_SeveralGood;
137 //=======================================================================
138 //function : AddSelect
140 //=======================================================================
141 AIS_StatusOfPick AIS_LocalContext::AddSelect (const Handle(SelectMgr_EntityOwner)& theObject)
143 mySelection->AddSelect (theObject);
145 Standard_Integer aSelNum = mySelection->Extent();
146 return (aSelNum == 1) ? AIS_SOP_OneSelected
147 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
151 //=======================================================================
154 //=======================================================================
155 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Boolean toUpdateViewer)
159 UnhilightPicked (Standard_False);
162 Standard_Integer aDetIndex = DetectedIndex();
165 ClearSelected (toUpdateViewer);
166 return mySelection->IsEmpty() ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
169 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex);
171 ClearSelected (Standard_False);
173 if (!anOwner->IsSelected()) // anOwner is not selected
175 anOwner->SetSelected (Standard_True);
176 mySelection->Select (anOwner);
181 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
182 for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
184 Unhilight (anOwner, anActiveViewIter.Value());
187 // advanced selection highlighting mechanism
188 if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
190 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
191 UpdateSelected (anIO, Standard_False);
196 myCTX->CurrentViewer()->Update();
200 return (mySelection->Extent() == 1) ? AIS_SOP_OneSelected : AIS_SOP_SeveralSelected;
203 //=======================================================================
206 //=======================================================================
207 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Integer theXPMin,
208 const Standard_Integer theYPMin,
209 const Standard_Integer theXPMax,
210 const Standard_Integer theYPMax,
211 const Handle(V3d_View)& theView,
212 const Standard_Boolean toUpdateViewer)
214 if (theView->Viewer() == myCTX->CurrentViewer())
216 myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
219 UnhilightPicked (Standard_False);
222 Standard_Integer aSelNum = mySelection->Extent();
223 if (myMainVS->NbPicked() == 0)
225 ClearSelected (toUpdateViewer);
227 return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
230 ClearSelected (Standard_False);
232 for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
234 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
235 if (myFilters->IsOk (anOwner))
237 // it can be helpful to classify this owner immediately...
238 if (!anOwner->IsSelected())
240 anOwner->SetSelected (Standard_True);
241 mySelection->Select (anOwner);
248 HilightPicked (toUpdateViewer);
252 Standard_Integer aSelNum = mySelection->Extent();
254 return (aSelNum == 1) ? AIS_SOP_OneSelected
255 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
259 //==================================================
261 // Purpose : Selection by polyline
262 //==================================================
263 AIS_StatusOfPick AIS_LocalContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
264 const Handle(V3d_View)& theView,
265 const Standard_Boolean toUpdateViewer)
267 if (theView->Viewer() == myCTX->CurrentViewer())
269 myMainVS->Pick (thePolyline, theView);
271 Standard_Integer aLastSelNum = mySelection->Extent();
272 if (myMainVS->NbPicked() == 0)
274 // Nothing is selected clear selection.
275 ClearSelected (toUpdateViewer);
278 // Return state to know if something was unselected
279 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
284 UnhilightPicked (Standard_False);
287 // Clear previous selection without update to process this selection
288 ClearSelected (Standard_False);
290 for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
292 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
293 if (myFilters->IsOk (anOwner))
295 // it can be helpful to classify this owner immediately...
296 if (!anOwner->IsSelected())
298 mySelection->AddSelect (anOwner);
299 anOwner->SetSelected (Standard_True);
306 HilightPicked (toUpdateViewer);
310 Standard_Integer aSelNum = mySelection->Extent();
311 return (aSelNum == 1) ? AIS_SOP_OneSelected
312 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
316 //=======================================================================
317 //function : ShiftSelect
319 //=======================================================================
320 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Boolean toUpdateViewer)
322 Standard_Integer aDetIndex = DetectedIndex();
326 Standard_Integer aSelNum = mySelection->Extent();
327 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex);
328 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
329 mySelection->Select (anOwner);
330 anOwner->SetSelected (toSelect);
334 myMainPM->ClearImmediateDraw();
335 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
336 for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
338 Unhilight (anOwner, anActiveViewIter.Value());
341 // advanced selection highlighting mechanism
342 if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
344 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
345 UpdateSelected (anIO, Standard_False);
350 myCTX->CurrentViewer()->Update();
354 Standard_Integer NS = mySelection->Extent();
355 if( NS == 1 ) return AIS_SOP_OneSelected;
356 else if( NS > 1 ) return AIS_SOP_SeveralSelected;
357 return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
359 return AIS_SOP_Error;
362 //=======================================================================
363 //function : ShiftSelect
365 //=======================================================================
366 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Integer theXPMin,
367 const Standard_Integer theYPMin,
368 const Standard_Integer theXPMax,
369 const Standard_Integer theYPMax,
370 const Handle(V3d_View)& theView,
371 const Standard_Boolean toUpdateViewer)
373 myMainPM->ClearImmediateDraw();
375 if (theView->Viewer() == myCTX->CurrentViewer())
377 myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
379 Standard_Integer aLastSelNum = mySelection->Extent();
380 if (myMainVS->NbPicked() == 0)
382 // Nothing is selected clear selection, but don't clear the selection
383 // as it is shift selection and previous selection matters.
384 // Return state to know if something was unselected
385 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
390 UnhilightPicked (Standard_False);
393 for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
395 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
396 if(myFilters->IsOk (anOwner))
398 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
399 mySelection->Select (anOwner);
400 anOwner->SetSelected (toSelect);
406 HilightPicked (toUpdateViewer);
410 Standard_Integer aSelNum = mySelection->Extent();
412 return (aSelNum == 1) ? AIS_SOP_OneSelected
413 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
417 //==================================================
419 // Purpose : Selection by polyline
420 //==================================================
421 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
422 const Handle(V3d_View)& theView,
423 const Standard_Boolean toUpdateViewer)
425 if (theView->Viewer() == myCTX->CurrentViewer())
427 myMainVS->Pick (thePolyline, theView);
429 Standard_Integer aLastSelNum = mySelection->Extent();
430 if (myMainVS->NbPicked() == 0)
432 // Nothing is selected clear selection, but don't clear the selection
433 // as it is shift selection and previous selection matters.
434 // Return state to know if something was unselected
435 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
440 UnhilightPicked (Standard_False);
443 for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
445 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
446 if (myFilters->IsOk (anOwner))
448 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
449 mySelection->Select (anOwner);
450 anOwner->SetSelected (toSelect);
455 HilightPicked (toUpdateViewer);
459 Standard_Integer aSelNum = mySelection->Extent();
461 return (aSelNum == 1) ? AIS_SOP_OneSelected
462 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
466 //==================================================
469 //==================================================
470 void AIS_LocalContext::Hilight (const Handle(SelectMgr_EntityOwner)& theOwner,
471 const Handle(V3d_View)& theView)
473 if (theView.IsNull())
478 const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast(theOwner->Selectable());
479 const Handle(Prs3d_Drawer)& aHiStyle = myCTX->getHiStyle (anObj, theOwner);
480 const Standard_Integer aHiMode = myCTX->getHilightMode (anObj, aHiStyle, -1);
481 myMainPM->BeginImmediateDraw();
482 theOwner->HilightWithColor (myMainPM, aHiStyle, aHiMode);
483 myMainPM->EndImmediateDraw (theView->Viewer());
486 //==================================================
487 // Function: Unhilight
489 //==================================================
490 void AIS_LocalContext::Unhilight (const Handle(SelectMgr_EntityOwner)& theOwner,
491 const Handle(V3d_View)& theView)
493 if (theView.IsNull())
498 const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
499 if (IsSelected (theOwner))
501 if (theOwner->IsAutoHilight())
503 const Handle(Prs3d_Drawer)& aSelStyle = myCTX->getSelStyle (anObj, theOwner);
504 const Standard_Integer aHiMode = myCTX->getHilightMode (anObj, aSelStyle, -1);
505 theOwner->HilightWithColor (myMainPM, aSelStyle, aHiMode);
510 theOwner->Unhilight (myMainPM);
514 //=======================================================================
515 //function : HilightPicked
517 //=======================================================================
518 void AIS_LocalContext::HilightPicked (const Standard_Boolean theToUpdateviewer)
520 if (mySelection.IsNull())
525 typedef NCollection_Shared<SelectMgr_SequenceOfOwner> SelectMgr_HSequenceOfOwner;
526 typedef NCollection_DataMap <Handle(SelectMgr_SelectableObject), Handle(SelectMgr_HSequenceOfOwner) > SelectMgr_DataMapOfObjectOwners;
527 SelectMgr_DataMapOfObjectOwners aMap;
529 // to avoid problems when there is a loop searching for selected objects...
530 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
532 const Handle(SelectMgr_EntityOwner)& anOwner = aSelIter.Value();
533 Handle(SelectMgr_SelectableObject) aSelObj = anOwner->Selectable();
534 if (anOwner->IsAutoHilight())
536 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(aSelObj);
537 const Handle(Prs3d_Drawer)& aSelStyle = myCTX->getSelStyle (anIO, anOwner);
538 const Standard_Integer aHiMode = myCTX->getHilightMode (anIO, aSelStyle, -1);
539 anOwner->HilightWithColor (myMainPM, aSelStyle, aHiMode);
543 Handle(SelectMgr_HSequenceOfOwner) aSeq;
544 if (aMap.Find (aSelObj, aSeq))
546 aSeq->Append (anOwner);
550 aSeq = new SelectMgr_HSequenceOfOwner();
551 aSeq->Append (anOwner);
552 aMap.Bind (aSelObj, aSeq);
556 for (SelectMgr_DataMapOfObjectOwners::Iterator aMapIter (aMap); aMapIter.More(); aMapIter.Next())
558 aMapIter.Key()->HilightSelected (myMainPM, *aMapIter.Value());
561 if (theToUpdateviewer)
563 myCTX->CurrentViewer()->Update();
567 //==================================================
568 // Function: UnhilightPicked
570 //==================================================
571 void AIS_LocalContext::UnhilightPicked (const Standard_Boolean theToUpdateViewer)
573 myMainPM->ClearImmediateDraw();
574 if (mySelection.IsNull())
579 NCollection_Map<Handle(SelectMgr_SelectableObject)> anObjMap;
580 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
582 const Handle(SelectMgr_EntityOwner)& anOwner = aSelIter.Value();
583 Handle(SelectMgr_SelectableObject) aSelObj = anOwner->Selectable();
584 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (aSelObj);
585 anObjMap.Add (aSelObj);
586 anOwner->Unhilight (myMainPM);
589 for (NCollection_Map<Handle(SelectMgr_SelectableObject)>::Iterator aMapIter (anObjMap);
590 aMapIter.More(); aMapIter.Next())
592 if (!aMapIter.Key()->IsAutoHilight())
594 aMapIter.Key()->ClearSelected();
598 if (theToUpdateViewer)
600 myCTX->CurrentViewer()->Update();
604 //=======================================================================
605 //function : IsSelected
607 //=======================================================================
608 Standard_Boolean AIS_LocalContext::IsSelected(const Handle(AIS_InteractiveObject)& anIObj) const
610 return (!FindSelectedOwnerFromIO(anIObj).IsNull());
613 //=======================================================================
614 //function : IsSelected
616 //=======================================================================
618 Standard_Boolean AIS_LocalContext::IsSelected (const Handle(SelectMgr_EntityOwner)& theOwner) const
620 return !theOwner.IsNull() && theOwner->IsSelected();
623 //==================================================
626 //==================================================
627 void AIS_LocalContext::
633 //==================================================
636 //==================================================
637 Standard_Boolean AIS_LocalContext::
640 return mySelection->More();
643 //==================================================
646 //==================================================
647 void AIS_LocalContext::
653 //==================================================
654 // Function: HasShape
656 //==================================================
657 Standard_Boolean AIS_LocalContext::HasShape() const
659 if (!mySelection->More())
661 return Standard_False;
664 Handle(StdSelect_BRepOwner) aBROwner = Handle(StdSelect_BRepOwner)::DownCast(mySelection->Value());
665 return !aBROwner.IsNull()
666 && aBROwner->HasShape()
667 && aBROwner->ComesFromDecomposition();
670 //================================================================
671 // Function : HasSelectedShape
672 // Purpose : Checks if there is a selected shape regardless of its decomposition status
673 //================================================================
674 Standard_Boolean AIS_LocalContext::HasSelectedShape() const
676 if (!mySelection->More())
678 return Standard_False;
681 Handle(StdSelect_BRepOwner) aBrepOwner = Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value());
682 return !aBrepOwner.IsNull()
683 && aBrepOwner->HasShape();
686 //==================================================
687 // Function: SelectedShape
689 //==================================================
690 TopoDS_Shape AIS_LocalContext::SelectedShape() const
692 if (!mySelection->More())
694 return TopoDS_Shape();
697 Handle(StdSelect_BRepOwner) aBRO = Handle(StdSelect_BRepOwner)::DownCast(mySelection->Value());
700 return TopoDS_Shape();
703 return aBRO->Shape().Located (aBRO->Location() * aBRO->Shape().Location());
706 //==================================================
707 // Function: SelectedInteractive
709 //==================================================
710 Handle(AIS_InteractiveObject) AIS_LocalContext::SelectedInteractive() const
712 return !mySelection->More()
713 ? Handle(AIS_InteractiveObject)()
714 : Handle(AIS_InteractiveObject)::DownCast (mySelection->Value()->Selectable());
717 //==================================================
718 // Function: SelectedOwner
720 //==================================================
721 Handle(SelectMgr_EntityOwner) AIS_LocalContext::SelectedOwner() const
723 return !mySelection->More()
724 ? Handle(SelectMgr_EntityOwner)()
725 : mySelection->Value();
728 //==================================================
731 //==================================================
732 Standard_Boolean AIS_LocalContext::HasApplicative() const
734 Handle(AIS_InteractiveObject) anIO = SelectedInteractive();
735 return !anIO.IsNull()
739 //==================================================
742 //==================================================
743 const Handle(Standard_Transient)& AIS_LocalContext::
744 SelectedApplicative() const
746 return SelectedInteractive()->GetOwner();
751 //=======================================================================
752 //function : UpdateSelection
753 //purpose : should disappear...
754 //=======================================================================
755 void AIS_LocalContext::UpdateSelected(const Standard_Boolean updateviewer)
757 UnhilightPicked(Standard_False);
758 HilightPicked(updateviewer);
761 //================================================================
762 // Function : UpdateSelected
763 // Purpose : Part of advanced selection mechanism.
764 // Highlightes or clears selection presentation for the given IO
765 //================================================================
766 void AIS_LocalContext::UpdateSelected(const Handle(AIS_InteractiveObject)& anobj,
767 const Standard_Boolean updateviewer)
769 if (anobj.IsNull() || anobj->IsAutoHilight())
772 SelectMgr_SequenceOfOwner aSeq;
773 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
775 if (aSelIter.Value()->IsSameSelectable (anobj))
777 aSeq.Append (aSelIter.Value());
782 anobj->HilightSelected( myMainPM, aSeq );
784 anobj->ClearSelected();
787 myCTX->CurrentViewer()->Update();
791 //==================================================
792 // Function: ClearSelected
794 //==================================================
795 void AIS_LocalContext::ClearSelected (const Standard_Boolean updateviewer)
797 UnhilightPicked(updateviewer);
798 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
800 aSelIter.Value()->SetSelected (Standard_False);
802 mySelection->Clear();
806 //==================================================
807 // Function: ClearOutdatedSelection
809 //==================================================
810 void AIS_LocalContext::ClearOutdatedSelection (const Handle(AIS_InteractiveObject)& theIO,
811 const Standard_Boolean toClearDeactivated)
813 // 1. Collect selectable entities
814 SelectMgr_IndexedMapOfOwner aValidOwners;
816 const TColStd_ListOfInteger& aModes = SelectionModes (theIO);
818 TColStd_ListIteratorOfListOfInteger aModeIter (aModes);
819 for (; aModeIter.More(); aModeIter.Next())
821 int aMode = aModeIter.Value();
822 if (!theIO->HasSelection(aMode))
827 if (toClearDeactivated && !mySM->IsActivated(theIO, aMode, myMainVS))
832 Handle(SelectMgr_Selection) aSelection = theIO->Selection(aMode);
833 for (aSelection->Init(); aSelection->More(); aSelection->Next())
835 Handle(SelectBasics_SensitiveEntity) anEntity = aSelection->Sensitive()->BaseSensitive();
836 if (anEntity.IsNull())
841 Handle(SelectMgr_EntityOwner) anOwner =
842 Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId());
844 if (anOwner.IsNull())
849 aValidOwners.Add(anOwner);
853 // 2. Refresh context's detection and selection and keep only active owners.
854 // Keep last detected object for lastindex initialization.
855 Handle(SelectMgr_EntityOwner) aLastPicked;
856 if (IsValidIndex (mylastindex))
858 aLastPicked = myMapOfOwner->FindKey (mylastindex);
861 // Remove entity owners from detected sequences
862 for (Standard_Integer anIdx = 1; anIdx <= myDetectedSeq.Length(); ++anIdx)
864 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (anIdx));
865 if (anOwner.IsNull() || !anOwner->IsSameSelectable (theIO) || aValidOwners.Contains (anOwner))
870 myDetectedSeq.Remove (anIdx--);
872 if (anIdx < myCurDetected)
877 myCurDetected = Max (myCurDetected, 1);
879 Standard_Boolean isAISRemainsDetected = Standard_False;
881 // 3. AIS_Selection : remove entity owners from AIS_Selection
882 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
883 NCollection_List<Handle(SelectMgr_EntityOwner)> aRemoveEntites;
884 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
886 Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
887 if (!anOwner->IsSameSelectable (theIO))
892 if (aValidOwners.Contains (anOwner))
894 isAISRemainsDetected = Standard_True;
898 aRemoveEntites.Append (anOwner);
899 anOwner->SetSelected (Standard_False);
900 for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
902 Unhilight (anOwner, anActiveViewIter.Value());
907 for (NCollection_List<Handle(SelectMgr_EntityOwner)>::Iterator anIterRemove (aRemoveEntites);
908 anIterRemove.More(); anIterRemove.Next())
910 mySelection->Select (anIterRemove.Value());
913 // 4. AIS_LocalContext - myMapOfOwner : remove entity owners from myMapOfOwner
914 SelectMgr_IndexedMapOfOwner anOwnersToKeep;
915 for (Standard_Integer anIdx = 1; anIdx <= myMapOfOwner->Extent(); anIdx++)
917 Handle(SelectMgr_EntityOwner) anOwner = myMapOfOwner->FindKey (anIdx);
918 if (anOwner.IsNull())
923 if (!anOwner->IsSameSelectable (theIO) || aValidOwners.Contains (anOwner))
925 anOwnersToKeep.Add (anOwner);
929 for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
931 Unhilight (anOwner, anActiveViewIter.Value());
935 myMapOfOwner->Clear();
936 myMapOfOwner->Assign (anOwnersToKeep);
938 if (myDetectedSeq.IsEmpty() && !aLastPicked.IsNull())
940 myMainPM->ClearImmediateDraw();
943 else if (!aLastPicked.IsNull())
945 // For a case when the last detected owner was unhilighted and removed as outdated we
946 // need to check if there were other detected owners with less priority. If yes then
947 // one from the remaining should be treated.
948 Standard_Integer anIndex = 1, aDetectedSeqLength = myDetectedSeq.Length();
949 for (; anIndex <= aDetectedSeqLength; anIndex++)
951 if (aLastPicked == myMainVS->Picked (myDetectedSeq.Value(anIndex)))
953 break; // detected owner was not removed
956 if (anIndex <= aDetectedSeqLength)
958 // Last detected owner was not removed, update mylastindex variable
959 mylastindex = myMapOfOwner->FindIndex (aLastPicked);
963 // Last detected owner was removed. First object from sequence become detected.
964 // Pass any active view because in current implementation the highlighting is
965 // synchronized in all view.
966 manageDetected (myMainVS->Picked (myDetectedSeq.First()),
967 aViewer->ActiveViewIterator().Value(),
972 // Renew iterator of ::DetectedCurrentObject()
973 if (!isAISRemainsDetected)
975 // Remove the interactive object from detected sequences
976 for (Standard_Integer anIdx = 1; anIdx <= myAISDetectedSeq.Length(); ++anIdx)
978 Handle(AIS_InteractiveObject) aDetectedIO = myAISDetectedSeq.Value (anIdx);
979 if (aDetectedIO.IsNull() || aDetectedIO != theIO)
984 myAISDetectedSeq.Remove (anIdx--);
986 if (anIdx < myAISCurDetected)
991 myAISCurDetected = Max (myAISCurDetected, 1);
995 //=======================================================================
996 //function : SetSelected
998 //=======================================================================
999 void AIS_LocalContext::SetSelected(const Handle(AIS_InteractiveObject)& anIObj,
1000 const Standard_Boolean updateviewer)
1002 if(!IsValidForSelection(anIObj)) return;
1003 UnhilightPicked(Standard_False);
1005 //1st case, owner already <anIObj> as owner
1006 // and not separated is found...
1008 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromIO(anIObj);
1010 //check if global selection there is an owner that can be triturated...
1011 if (anIObj->HasSelection (anIObj->GlobalSelectionMode()))
1013 EO = anIObj->GlobalSelOwner();
1016 EO = new SelectMgr_EntityOwner((const Handle(SelectMgr_SelectableObject)&)anIObj);
1019 ClearSelected(Standard_False);
1021 mySelection->Select(EO);
1022 EO->SetSelected (Standard_True);
1024 HilightPicked(updateviewer);
1027 //=======================================================================
1028 //function : AddOrRemoveSelected
1030 //=======================================================================
1032 void AIS_LocalContext::AddOrRemoveSelected(const Handle(AIS_InteractiveObject)& anIObj,
1033 const Standard_Boolean updateviewer)
1035 if(!IsValidForSelection(anIObj)) return;
1036 UnhilightPicked(Standard_False);
1037 // first check if it is selected...
1038 Handle(SelectMgr_EntityOwner) EO;
1040 EO = FindSelectedOwnerFromIO(anIObj);
1044 if(anIObj->HasSelection (anIObj->GlobalSelectionMode()))
1046 EO = anIObj->GlobalSelOwner();
1050 EO = new SelectMgr_EntityOwner((const Handle(SelectMgr_SelectableObject)&)anIObj);
1054 if (!mySelection.IsNull())
1056 AIS_SelectStatus aStatus = mySelection->Select(EO);
1057 EO->SetSelected (aStatus == AIS_SS_Added);
1060 HilightPicked(updateviewer);
1063 //=======================================================================
1064 //function : AddOrRemoveSelected
1065 //purpose : To check...
1066 //=======================================================================
1067 void AIS_LocalContext::AddOrRemoveSelected(const TopoDS_Shape& Sh,
1068 const Standard_Boolean updateviewer)
1070 UnhilightPicked (Standard_False);
1071 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromShape(Sh);
1074 mySelection->Select(EO);
1075 EO->SetSelected (Standard_True);
1077 HilightPicked (updateviewer);
1080 void AIS_LocalContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
1081 const Standard_Boolean toUpdateViewer)
1085 UnhilightPicked (Standard_False);
1088 Standard_Boolean toSelect = theOwner->IsSelected() ? Standard_False : Standard_True;
1090 mySelection->Select(theOwner);
1091 theOwner->SetSelected (toSelect);
1095 HilightPicked (toUpdateViewer);
1099 //==================================================
1100 // Function: manageDetected
1102 //==================================================
1103 void AIS_LocalContext::manageDetected (const Handle(SelectMgr_EntityOwner)& thePickOwner,
1104 const Handle(V3d_View)& theView,
1105 const Standard_Boolean theToRedrawImmediate)
1107 if (thePickOwner.IsNull())
1109 myMainPM->ClearImmediateDraw();
1110 if (theToRedrawImmediate)
1112 theView->RedrawImmediate();
1117 if (!myFilters->IsOk (thePickOwner))
1119 if (mylastindex != 0)
1121 mylastgood = mylastindex;
1123 if (theToRedrawImmediate)
1125 theView->RedrawImmediate();
1130 //=======================================================================================================
1131 // 2 cases : a- object is in the map of picks:
1132 // 1. this is the same index as the last detected: -> Do nothing
1134 // - if lastindex = 0 (no object was detected at the last step)
1135 // the object presentation is highlighted and lastindex = index(objet)
1137 // the presentation of the object corresponding to lastindex is "unhighlighted"
1138 // it is removed if the object is not visualized but only active
1139 // then the presentation of the detected object is highlighted and lastindex = index(objet)
1140 // b- the object is not in the map of picked objects
1141 // - if lastindex != 0 (object detected at the last step) it is unhighlighted ...
1142 // if the object was decomposed, presentation is created for the detected shape and the couple
1143 // (Proprietaire,Prs)is added in the map.
1144 // otherwise the couple(proprietaire, NullPrs) is placed in the map and the interactive object
1145 // itself is highlighted.
1147 //=======================================================================================================
1149 const Standard_Integer aNewIndex = myMapOfOwner->Contains (thePickOwner)
1150 ? myMapOfOwner->FindIndex (thePickOwner)
1151 : myMapOfOwner->Add (thePickOwner);
1153 // For the advanced mesh selection mode the owner indices comparison
1154 // is not effective because in that case only one owner manage the
1155 // selection in current selection mode. It is necessary to check the current detected
1156 // entity and hilight it only if the detected entity is not the same as
1157 // previous detected (IsForcedHilight call)
1158 if (aNewIndex != mylastindex
1159 || thePickOwner->IsForcedHilight())
1161 myMainPM->ClearImmediateDraw();
1162 if (mylastindex != 0
1163 && mylastindex <= myMapOfOwner->Extent())
1165 const Handle(SelectMgr_EntityOwner)& aLastOwner = myMapOfOwner->FindKey (mylastindex);
1166 Unhilight (aLastOwner, theView);
1171 if (!thePickOwner->IsSelected() || myCTX->ToHilightSelected())
1173 Hilight (thePickOwner, theView);
1175 if (theToRedrawImmediate)
1177 theView->RedrawImmediate();
1181 mylastindex = aNewIndex;
1184 if (mylastindex != 0)
1186 mylastgood = mylastindex;
1190 //=======================================================================
1191 //function : HasDetectedShape
1193 //=======================================================================
1195 Standard_Boolean AIS_LocalContext::HasDetectedShape() const
1197 if(mylastindex==0) return Standard_False;
1198 return IsShape(mylastindex);
1201 //=======================================================================
1202 //function : DetectedShape
1204 //=======================================================================
1207 AIS_LocalContext::DetectedShape() const
1209 if(mylastindex != 0)
1211 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner->FindKey (mylastindex));
1212 if(BROwnr.IsNull()) return AIS_myDummyShape;
1213 return BROwnr->Shape();
1215 return AIS_myDummyShape;
1218 //=======================================================================
1219 //function : DetectedInteractive
1221 //=======================================================================
1223 Handle(AIS_InteractiveObject)
1224 AIS_LocalContext::DetectedInteractive() const
1226 Handle(AIS_InteractiveObject) Iobj;
1227 if(IsValidIndex(mylastindex)){
1228 Handle(SelectMgr_SelectableObject) SO = myMapOfOwner->FindKey(mylastindex)->Selectable();
1229 Iobj = Handle(AIS_InteractiveObject)::DownCast (SO);
1233 //=======================================================================
1234 //function : DetectedInteractive
1236 //=======================================================================
1237 Handle(SelectMgr_EntityOwner) AIS_LocalContext::DetectedOwner() const
1239 Handle(SelectMgr_EntityOwner) bid;
1240 if(!IsValidIndex(mylastindex)) return bid;
1241 return myMapOfOwner->FindKey(mylastindex);
1245 //=======================================================================
1246 //function : ComesFromDecomposition
1248 //=======================================================================
1250 Standard_Boolean AIS_LocalContext::ComesFromDecomposition(const Standard_Integer PickedIndex) const
1252 const Handle(SelectMgr_EntityOwner)& OWN = myMapOfOwner->FindKey(PickedIndex);
1253 Handle(SelectMgr_SelectableObject) aSel = OWN->Selectable();
1254 if (myActiveObjects.IsBound (aSel)) { // debug of jmi
1255 const Handle(AIS_LocalStatus)& Stat = myActiveObjects(aSel);
1256 return Stat->Decomposed();
1258 return Standard_False;
1261 //=======================================================================
1262 //function : DisplaySensitive
1264 //=======================================================================
1266 void AIS_LocalContext::DisplaySensitive(const Handle(V3d_View)& aviou)
1268 myMainVS->DisplaySensitive(aviou);
1271 //=======================================================================
1272 //function : ClearSensitive
1274 //=======================================================================
1276 void AIS_LocalContext::ClearSensitive(const Handle(V3d_View)& aviou)
1278 myMainVS->ClearSensitive(aviou);
1282 //=======================================================================
1283 //function : IsShape
1285 //=======================================================================
1286 Standard_Boolean AIS_LocalContext::IsShape(const Standard_Integer Index) const
1288 Handle(SelectMgr_EntityOwner) aEO (myMapOfOwner->FindKey(Index));
1289 if (aEO.IsNull() || ! aEO->IsKind(STANDARD_TYPE(StdSelect_BRepOwner)))
1290 return Standard_False;
1292 ComesFromDecomposition(Index);
1295 Standard_Boolean AIS_LocalContext::IsValidForSelection(const Handle(AIS_InteractiveObject)& anIObj) const
1297 const Handle(SelectMgr_SelectableObject)& aSelObj = anIObj; // to avoid ambiguity
1298 // Shape was not transfered from AIS_Shape to EntityOwner
1299 Handle(AIS_Shape) shape = Handle(AIS_Shape)::DownCast(anIObj);
1300 if( !shape.IsNull() )
1301 return myFilters->IsOk(new StdSelect_BRepOwner(shape->Shape(), aSelObj));
1302 return myFilters->IsOk(new SelectMgr_EntityOwner(aSelObj));
1306 //=======================================================================
1307 //function : HilightNextDetected
1309 //=======================================================================
1310 Standard_Integer AIS_LocalContext::HilightNextDetected (const Handle(V3d_View)& theView,
1311 const Standard_Boolean theToRedrawImmediate)
1313 // go to the next owner
1314 if (myDetectedSeq.IsEmpty())
1319 const Standard_Integer aLen = myDetectedSeq.Length();
1320 if (++myCurDetected > aLen)
1324 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1325 if (anOwner.IsNull())
1329 manageDetected (anOwner, theView, theToRedrawImmediate);
1330 return myCurDetected;
1333 //=======================================================================
1334 //function : HilightPreviousDetected
1336 //=======================================================================
1337 Standard_Integer AIS_LocalContext::HilightPreviousDetected (const Handle(V3d_View)& theView,
1338 const Standard_Boolean theToRedrawImmediate)
1340 if (myDetectedSeq.IsEmpty())
1345 const Standard_Integer aLen = myDetectedSeq.Length();
1346 if (--myCurDetected < 1)
1348 myCurDetected = aLen;
1350 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1351 if (anOwner.IsNull())
1356 manageDetected (anOwner, theView, theToRedrawImmediate);
1357 return myCurDetected;
1360 //=======================================================================
1361 //function : UnhilightLastDetected
1363 //=======================================================================
1364 Standard_Boolean AIS_LocalContext::UnhilightLastDetected (const Handle(V3d_View)& theView)
1366 if (!IsValidIndex (mylastindex))
1368 return Standard_False;
1371 myMainPM->BeginImmediateDraw();
1372 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (mylastindex);
1373 anOwner->Unhilight (myMainPM);
1374 myMainPM->EndImmediateDraw (theView->Viewer());
1376 return Standard_True;
1379 //=======================================================================
1380 //function : FindSelectedOwnerFromIO
1381 //purpose : it is checked if one of the selected owners really presents IObj
1382 //=======================================================================
1383 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromIO (const Handle(AIS_InteractiveObject)& theObj) const
1385 Handle(SelectMgr_EntityOwner) EO,bid;
1387 || mySelection.IsNull())
1389 return Handle(SelectMgr_EntityOwner)();
1392 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
1394 if (!aSelIter.Value()->IsSameSelectable (theObj))
1399 Handle(StdSelect_BRepOwner) aBROwner = Handle(StdSelect_BRepOwner)::DownCast(aSelIter.Value());
1400 if (aBROwner.IsNull()
1401 || !aBROwner->ComesFromDecomposition())
1403 return aSelIter.Value();
1406 return Handle(SelectMgr_EntityOwner)();
1409 //=======================================================================
1410 //function : FindSelectedOwnerFromShape
1411 //purpose : it is checked if one of the selected owners really presents IObj
1412 //=======================================================================
1413 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromShape(const TopoDS_Shape& sh) const
1415 Handle(SelectMgr_EntityOwner) EO, bid;
1416 if (sh.IsNull()) return EO;
1418 if(mySelection.IsNull()) {
1422 Standard_Boolean found(Standard_False);
1425 NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
1426 myMainVS->ActiveOwners (anActiveOwners);
1427 for (NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (anActiveOwners); anOwnersIt.More(); anOwnersIt.Next())
1429 EO = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value());
1430 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1431 if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) {
1432 found = Standard_True;
1438 if(found) return EO;
1442 //=======================================================================
1443 //function : AIS_LocalContext::InitDetected
1445 //=======================================================================
1446 void AIS_LocalContext::InitDetected()
1448 myAISCurDetected = myAISDetectedSeq.Length()? 1 : 0;
1451 //=======================================================================
1452 //function : AIS_LocalContext::MoreDetected
1454 //=======================================================================
1455 Standard_Boolean AIS_LocalContext::MoreDetected() const
1457 return (myAISCurDetected > 0 && myAISCurDetected <= myAISDetectedSeq.Length());
1460 //=======================================================================
1461 //function : AIS_LocalContext::NextDetected
1463 //=======================================================================
1464 void AIS_LocalContext::NextDetected()
1469 //=======================================================================
1470 //function : DetectedCurrentShape
1472 //=======================================================================
1473 const TopoDS_Shape& AIS_LocalContext::DetectedCurrentShape() const
1475 Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
1477 if (aCurrentShape.IsNull())
1479 return AIS_myDummyShape;
1482 return aCurrentShape->Shape();
1484 //=======================================================================
1485 //function : DetectedCurrentObject
1487 //=======================================================================
1488 Handle(AIS_InteractiveObject) AIS_LocalContext::DetectedCurrentObject() const
1490 return MoreDetected() ? myAISDetectedSeq(myAISCurDetected) : NULL;
1493 //=======================================================================
1494 //function : RestoreActivatedModes
1496 //=======================================================================
1497 void AIS_LocalContext::RestoreActivatedModes() const
1499 for (AIS_DataMapOfSelStat::Iterator anIter (myActiveObjects); anIter.More(); anIter.Next())
1501 const TColStd_ListOfInteger& anActivatedModes = anIter.Value()->SelectionModes();
1502 for (TColStd_ListIteratorOfListOfInteger aModesIter (anActivatedModes); aModesIter.More(); aModesIter.Next())
1504 mySM->Activate (anIter.Key(), aModesIter.Value(), myMainVS);