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_LocalContext_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())
78 myDetectedSeq.Clear();
79 myFilters->SetDisabledObjects (theView->View()->HiddenObjects());
80 myMainVS->Pick (theXpix, theYpix, theView);
82 const Standard_Integer aDetectedNb = myMainVS->NbPicked();
83 for (Standard_Integer aDetIter = 1; aDetIter <= aDetectedNb; ++aDetIter)
85 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (aDetIter);
87 && myFilters->IsOk (anOwner))
89 myDetectedSeq.Append (aDetIter); // normally they are already arranged in correct order...
93 // result of courses..
94 if (aDetectedNb == 0 || myDetectedSeq.IsEmpty())
96 if (mylastindex != 0 && mylastindex <= myMapOfOwner->Extent())
98 myMainPM->ClearImmediateDraw();
99 Unhilight (myMapOfOwner->FindKey (mylastindex), theView);
100 if (theToRedrawImmediate)
102 theView->RedrawImmediate();
107 return aDetectedNb == 0
112 // all owners detected by the selector are passed to the
113 // filters and correct ones are preserved...
115 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
116 manageDetected (anOwner, theView, theToRedrawImmediate);
117 if (myDetectedSeq.Length() == 1)
119 return aDetectedNb == 1
120 ? AIS_SOD_OnlyOneDetected
121 : AIS_SOD_OnlyOneGood;
125 return AIS_SOD_SeveralGood;
129 //=======================================================================
130 //function : AddSelect
132 //=======================================================================
133 AIS_StatusOfPick AIS_LocalContext::AddSelect (const Handle(SelectMgr_EntityOwner)& theObject)
135 mySelection->AddSelect (theObject);
137 Standard_Integer aSelNum = mySelection->Extent();
138 return (aSelNum == 1) ? AIS_SOP_OneSelected
139 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
143 //=======================================================================
146 //=======================================================================
147 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Boolean toUpdateViewer)
151 UnhilightPicked (Standard_False);
154 Standard_Integer aDetIndex = DetectedIndex();
157 ClearSelected (toUpdateViewer);
158 return mySelection->IsEmpty() ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
161 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex);
163 ClearSelected (Standard_False);
165 if (!anOwner->IsSelected()) // anOwner is not selected
167 anOwner->SetSelected (Standard_True);
168 mySelection->Select (anOwner);
173 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
174 for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
176 Unhilight (anOwner, anActiveViewIter.Value());
179 // advanced selection highlighting mechanism
180 if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
182 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
183 UpdateSelected (anIO, Standard_False);
188 myCTX->CurrentViewer()->Update();
192 return (mySelection->Extent() == 1) ? AIS_SOP_OneSelected : AIS_SOP_SeveralSelected;
195 //=======================================================================
198 //=======================================================================
199 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Integer theXPMin,
200 const Standard_Integer theYPMin,
201 const Standard_Integer theXPMax,
202 const Standard_Integer theYPMax,
203 const Handle(V3d_View)& theView,
204 const Standard_Boolean toUpdateViewer)
206 if (theView->Viewer() == myCTX->CurrentViewer())
208 myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
211 UnhilightPicked (Standard_False);
214 Standard_Integer aSelNum = mySelection->Extent();
215 if (myMainVS->NbPicked() == 0)
217 ClearSelected (toUpdateViewer);
219 return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
222 ClearSelected (Standard_False);
224 for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
226 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
227 if (myFilters->IsOk (anOwner))
229 // it can be helpful to classify this owner immediately...
230 if (!anOwner->IsSelected())
232 anOwner->SetSelected (Standard_True);
233 mySelection->Select (anOwner);
240 HilightPicked (toUpdateViewer);
244 Standard_Integer aSelNum = mySelection->Extent();
246 return (aSelNum == 1) ? AIS_SOP_OneSelected
247 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
251 //==================================================
253 // Purpose : Selection by polyline
254 //==================================================
255 AIS_StatusOfPick AIS_LocalContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
256 const Handle(V3d_View)& theView,
257 const Standard_Boolean toUpdateViewer)
259 if (theView->Viewer() == myCTX->CurrentViewer())
261 myMainVS->Pick (thePolyline, theView);
263 Standard_Integer aLastSelNum = mySelection->Extent();
264 if (myMainVS->NbPicked() == 0)
266 // Nothing is selected clear selection.
267 ClearSelected (toUpdateViewer);
270 // Return state to know if something was unselected
271 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
276 UnhilightPicked (Standard_False);
279 // Clear previous selection without update to process this selection
280 ClearSelected (Standard_False);
282 for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
284 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
285 if (myFilters->IsOk (anOwner))
287 // it can be helpful to classify this owner immediately...
288 if (!anOwner->IsSelected())
290 mySelection->AddSelect (anOwner);
291 anOwner->SetSelected (Standard_True);
298 HilightPicked (toUpdateViewer);
302 Standard_Integer aSelNum = mySelection->Extent();
303 return (aSelNum == 1) ? AIS_SOP_OneSelected
304 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
308 //=======================================================================
309 //function : ShiftSelect
311 //=======================================================================
312 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Boolean toUpdateViewer)
314 Standard_Integer aDetIndex = DetectedIndex();
318 Standard_Integer aSelNum = mySelection->Extent();
319 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex);
320 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
321 mySelection->Select (anOwner);
322 anOwner->SetSelected (toSelect);
326 myMainPM->ClearImmediateDraw();
327 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
328 for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
330 Unhilight (anOwner, anActiveViewIter.Value());
333 // advanced selection highlighting mechanism
334 if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
336 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
337 UpdateSelected (anIO, Standard_False);
342 myCTX->CurrentViewer()->Update();
346 Standard_Integer NS = mySelection->Extent();
347 if( NS == 1 ) return AIS_SOP_OneSelected;
348 else if( NS > 1 ) return AIS_SOP_SeveralSelected;
349 return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
351 return AIS_SOP_Error;
354 //=======================================================================
355 //function : ShiftSelect
357 //=======================================================================
358 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Integer theXPMin,
359 const Standard_Integer theYPMin,
360 const Standard_Integer theXPMax,
361 const Standard_Integer theYPMax,
362 const Handle(V3d_View)& theView,
363 const Standard_Boolean toUpdateViewer)
365 myMainPM->ClearImmediateDraw();
367 if (theView->Viewer() == myCTX->CurrentViewer())
369 myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
371 Standard_Integer aLastSelNum = mySelection->Extent();
372 if (myMainVS->NbPicked() == 0)
374 // Nothing is selected clear selection, but don't clear the selection
375 // as it is shift selection and previous selection matters.
376 // Return state to know if something was unselected
377 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
382 UnhilightPicked (Standard_False);
385 for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
387 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
388 if(myFilters->IsOk (anOwner))
390 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
391 mySelection->Select (anOwner);
392 anOwner->SetSelected (toSelect);
398 HilightPicked (toUpdateViewer);
402 Standard_Integer aSelNum = mySelection->Extent();
404 return (aSelNum == 1) ? AIS_SOP_OneSelected
405 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
409 //==================================================
411 // Purpose : Selection by polyline
412 //==================================================
413 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
414 const Handle(V3d_View)& theView,
415 const Standard_Boolean toUpdateViewer)
417 if (theView->Viewer() == myCTX->CurrentViewer())
419 myMainVS->Pick (thePolyline, theView);
421 Standard_Integer aLastSelNum = mySelection->Extent();
422 if (myMainVS->NbPicked() == 0)
424 // Nothing is selected clear selection, but don't clear the selection
425 // as it is shift selection and previous selection matters.
426 // Return state to know if something was unselected
427 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
432 UnhilightPicked (Standard_False);
435 for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
437 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
438 if (myFilters->IsOk (anOwner))
440 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
441 mySelection->Select (anOwner);
442 anOwner->SetSelected (toSelect);
447 HilightPicked (toUpdateViewer);
451 Standard_Integer aSelNum = mySelection->Extent();
453 return (aSelNum == 1) ? AIS_SOP_OneSelected
454 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
458 //==================================================
461 //==================================================
462 void AIS_LocalContext::Hilight (const Handle(SelectMgr_EntityOwner)& theOwner,
463 const Handle(V3d_View)& theView)
465 if (theView.IsNull())
470 const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast(theOwner->Selectable());
471 const Handle(Prs3d_Drawer)& aHiStyle = myCTX->getHiStyle (anObj, theOwner);
472 const Standard_Integer aHiMode = myCTX->getHilightMode (anObj, aHiStyle, -1);
473 myMainPM->BeginImmediateDraw();
474 theOwner->HilightWithColor (myMainPM, aHiStyle, aHiMode);
475 myMainPM->EndImmediateDraw (theView->Viewer());
478 //==================================================
479 // Function: Unhilight
481 //==================================================
482 void AIS_LocalContext::Unhilight (const Handle(SelectMgr_EntityOwner)& theOwner,
483 const Handle(V3d_View)& theView)
485 if (theView.IsNull())
490 const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
491 if (IsSelected (theOwner))
493 if (theOwner->IsAutoHilight())
495 const Handle(Prs3d_Drawer)& aSelStyle = myCTX->getSelStyle (anObj, theOwner);
496 const Standard_Integer aHiMode = myCTX->getHilightMode (anObj, aSelStyle, -1);
497 theOwner->HilightWithColor (myMainPM, aSelStyle, aHiMode);
502 theOwner->Unhilight (myMainPM);
506 //=======================================================================
507 //function : HilightPicked
509 //=======================================================================
510 void AIS_LocalContext::HilightPicked (const Standard_Boolean theToUpdateviewer)
512 if (mySelection.IsNull())
517 typedef NCollection_Shared<SelectMgr_SequenceOfOwner> SelectMgr_HSequenceOfOwner;
518 typedef NCollection_DataMap <Handle(SelectMgr_SelectableObject), Handle(SelectMgr_HSequenceOfOwner) > SelectMgr_DataMapOfObjectOwners;
519 SelectMgr_DataMapOfObjectOwners aMap;
521 // to avoid problems when there is a loop searching for selected objects...
522 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
524 const Handle(SelectMgr_EntityOwner)& anOwner = aSelIter.Value();
525 Handle(SelectMgr_SelectableObject) aSelObj = anOwner->Selectable();
526 if (anOwner->IsAutoHilight())
528 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(aSelObj);
529 const Handle(Prs3d_Drawer)& aSelStyle = myCTX->getSelStyle (anIO, anOwner);
530 const Standard_Integer aHiMode = myCTX->getHilightMode (anIO, aSelStyle, -1);
531 anOwner->HilightWithColor (myMainPM, aSelStyle, aHiMode);
535 Handle(SelectMgr_HSequenceOfOwner) aSeq;
536 if (aMap.Find (aSelObj, aSeq))
538 aSeq->Append (anOwner);
542 aSeq = new SelectMgr_HSequenceOfOwner();
543 aSeq->Append (anOwner);
544 aMap.Bind (aSelObj, aSeq);
548 for (SelectMgr_DataMapOfObjectOwners::Iterator aMapIter (aMap); aMapIter.More(); aMapIter.Next())
550 aMapIter.Key()->HilightSelected (myMainPM, *aMapIter.Value());
553 if (theToUpdateviewer)
555 myCTX->CurrentViewer()->Update();
559 //==================================================
560 // Function: UnhilightPicked
562 //==================================================
563 void AIS_LocalContext::UnhilightPicked (const Standard_Boolean theToUpdateViewer)
565 myMainPM->ClearImmediateDraw();
566 if (mySelection.IsNull())
571 NCollection_Map<Handle(SelectMgr_SelectableObject)> anObjMap;
572 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
574 const Handle(SelectMgr_EntityOwner)& anOwner = aSelIter.Value();
575 Handle(SelectMgr_SelectableObject) aSelObj = anOwner->Selectable();
576 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (aSelObj);
577 anObjMap.Add (aSelObj);
578 anOwner->Unhilight (myMainPM);
581 for (NCollection_Map<Handle(SelectMgr_SelectableObject)>::Iterator aMapIter (anObjMap);
582 aMapIter.More(); aMapIter.Next())
584 if (!aMapIter.Key()->IsAutoHilight())
586 aMapIter.Key()->ClearSelected();
590 if (theToUpdateViewer)
592 myCTX->CurrentViewer()->Update();
596 //=======================================================================
597 //function : IsSelected
599 //=======================================================================
600 Standard_Boolean AIS_LocalContext::IsSelected(const Handle(AIS_InteractiveObject)& anIObj) const
602 return (!FindSelectedOwnerFromIO(anIObj).IsNull());
605 //=======================================================================
606 //function : IsSelected
608 //=======================================================================
610 Standard_Boolean AIS_LocalContext::IsSelected (const Handle(SelectMgr_EntityOwner)& theOwner) const
612 return !theOwner.IsNull() && theOwner->IsSelected();
615 //==================================================
618 //==================================================
619 void AIS_LocalContext::
625 //==================================================
628 //==================================================
629 Standard_Boolean AIS_LocalContext::
632 return mySelection->More();
635 //==================================================
638 //==================================================
639 void AIS_LocalContext::
645 //==================================================
646 // Function: HasShape
648 //==================================================
649 Standard_Boolean AIS_LocalContext::HasShape() const
651 if (!mySelection->More())
653 return Standard_False;
656 Handle(StdSelect_BRepOwner) aBROwner = Handle(StdSelect_BRepOwner)::DownCast(mySelection->Value());
657 return !aBROwner.IsNull()
658 && aBROwner->HasShape()
659 && aBROwner->ComesFromDecomposition();
662 //================================================================
663 // Function : HasSelectedShape
664 // Purpose : Checks if there is a selected shape regardless of its decomposition status
665 //================================================================
666 Standard_Boolean AIS_LocalContext::HasSelectedShape() const
668 if (!mySelection->More())
670 return Standard_False;
673 Handle(StdSelect_BRepOwner) aBrepOwner = Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value());
674 return !aBrepOwner.IsNull()
675 && aBrepOwner->HasShape();
678 //==================================================
679 // Function: SelectedShape
681 //==================================================
682 TopoDS_Shape AIS_LocalContext::SelectedShape() const
684 if (!mySelection->More())
686 return TopoDS_Shape();
689 Handle(StdSelect_BRepOwner) aBRO = Handle(StdSelect_BRepOwner)::DownCast(mySelection->Value());
692 return TopoDS_Shape();
695 return aBRO->Shape().Located (aBRO->Location() * aBRO->Shape().Location());
698 //==================================================
699 // Function: SelectedInteractive
701 //==================================================
702 Handle(AIS_InteractiveObject) AIS_LocalContext::SelectedInteractive() const
704 return !mySelection->More()
705 ? Handle(AIS_InteractiveObject)()
706 : Handle(AIS_InteractiveObject)::DownCast (mySelection->Value()->Selectable());
709 //==================================================
710 // Function: SelectedOwner
712 //==================================================
713 Handle(SelectMgr_EntityOwner) AIS_LocalContext::SelectedOwner() const
715 return !mySelection->More()
716 ? Handle(SelectMgr_EntityOwner)()
717 : mySelection->Value();
720 //==================================================
723 //==================================================
724 Standard_Boolean AIS_LocalContext::HasApplicative() const
726 Handle(AIS_InteractiveObject) anIO = SelectedInteractive();
727 return !anIO.IsNull()
731 //==================================================
734 //==================================================
735 const Handle(Standard_Transient)& AIS_LocalContext::
736 SelectedApplicative() const
738 return SelectedInteractive()->GetOwner();
743 //=======================================================================
744 //function : UpdateSelection
745 //purpose : should disappear...
746 //=======================================================================
747 void AIS_LocalContext::UpdateSelected(const Standard_Boolean updateviewer)
749 UnhilightPicked(Standard_False);
750 HilightPicked(updateviewer);
753 //================================================================
754 // Function : UpdateSelected
755 // Purpose : Part of advanced selection mechanism.
756 // Highlightes or clears selection presentation for the given IO
757 //================================================================
758 void AIS_LocalContext::UpdateSelected(const Handle(AIS_InteractiveObject)& anobj,
759 const Standard_Boolean updateviewer)
761 if (anobj.IsNull() || anobj->IsAutoHilight())
764 SelectMgr_SequenceOfOwner aSeq;
765 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
767 if (aSelIter.Value()->IsSameSelectable (anobj))
769 aSeq.Append (aSelIter.Value());
774 anobj->HilightSelected( myMainPM, aSeq );
776 anobj->ClearSelected();
779 myCTX->CurrentViewer()->Update();
783 //==================================================
784 // Function: ClearSelected
786 //==================================================
787 void AIS_LocalContext::ClearSelected (const Standard_Boolean updateviewer)
789 UnhilightPicked(updateviewer);
790 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
792 aSelIter.Value()->SetSelected (Standard_False);
794 mySelection->Clear();
798 //==================================================
799 // Function: ClearOutdatedSelection
801 //==================================================
802 void AIS_LocalContext::ClearOutdatedSelection (const Handle(AIS_InteractiveObject)& theIO,
803 const Standard_Boolean toClearDeactivated)
805 // 1. Collect selectable entities
806 SelectMgr_IndexedMapOfOwner aValidOwners;
807 const TColStd_ListOfInteger& aModes = SelectionModes (theIO);
808 for (TColStd_ListIteratorOfListOfInteger aModeIter (aModes); aModeIter.More(); aModeIter.Next())
810 const int aMode = aModeIter.Value();
811 if (!theIO->HasSelection(aMode))
816 if (toClearDeactivated && !mySM->IsActivated(theIO, aMode, myMainVS))
821 const Handle(SelectMgr_Selection)& aSelection = theIO->Selection (aMode);
822 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
824 if (Handle(SelectBasics_SensitiveEntity) anEntity = aSelEntIter.Value()->BaseSensitive())
826 if (Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId()))
828 aValidOwners.Add (anOwner);
834 // 2. Refresh context's detection and selection and keep only active owners.
835 // Keep last detected object for lastindex initialization.
836 Handle(SelectMgr_EntityOwner) aLastPicked;
837 if (IsValidIndex (mylastindex))
839 aLastPicked = myMapOfOwner->FindKey (mylastindex);
842 // Remove entity owners from detected sequences
843 for (Standard_Integer anIdx = 1; anIdx <= myDetectedSeq.Length(); ++anIdx)
845 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (anIdx));
846 if (anOwner.IsNull() || !anOwner->IsSameSelectable (theIO) || aValidOwners.Contains (anOwner))
851 myDetectedSeq.Remove (anIdx--);
852 if (myCurDetected > anIdx)
856 if (myAISCurDetected > anIdx)
861 myCurDetected = Max (myCurDetected, 1);
862 myAISCurDetected = Max (myAISCurDetected, 1);
864 // 3. AIS_Selection : remove entity owners from AIS_Selection
865 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
866 NCollection_List<Handle(SelectMgr_EntityOwner)> aRemoveEntites;
867 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
869 Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
870 if (!anOwner->IsSameSelectable (theIO))
875 if (!aValidOwners.Contains (anOwner))
877 aRemoveEntites.Append (anOwner);
878 anOwner->SetSelected (Standard_False);
879 for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
881 Unhilight (anOwner, anActiveViewIter.Value());
886 for (NCollection_List<Handle(SelectMgr_EntityOwner)>::Iterator anIterRemove (aRemoveEntites);
887 anIterRemove.More(); anIterRemove.Next())
889 mySelection->Select (anIterRemove.Value());
892 // 4. AIS_LocalContext - myMapOfOwner : remove entity owners from myMapOfOwner
893 SelectMgr_IndexedMapOfOwner anOwnersToKeep;
894 for (Standard_Integer anIdx = 1; anIdx <= myMapOfOwner->Extent(); anIdx++)
896 Handle(SelectMgr_EntityOwner) anOwner = myMapOfOwner->FindKey (anIdx);
897 if (anOwner.IsNull())
902 if (!anOwner->IsSameSelectable (theIO) || aValidOwners.Contains (anOwner))
904 anOwnersToKeep.Add (anOwner);
908 for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
910 Unhilight (anOwner, anActiveViewIter.Value());
914 myMapOfOwner->Clear();
915 myMapOfOwner->Assign (anOwnersToKeep);
917 if (myDetectedSeq.IsEmpty() && !aLastPicked.IsNull())
919 myMainPM->ClearImmediateDraw();
922 else if (!aLastPicked.IsNull())
924 // For a case when the last detected owner was unhilighted and removed as outdated we
925 // need to check if there were other detected owners with less priority. If yes then
926 // one from the remaining should be treated.
927 Standard_Integer anIndex = 1, aDetectedSeqLength = myDetectedSeq.Length();
928 for (; anIndex <= aDetectedSeqLength; anIndex++)
930 if (aLastPicked == myMainVS->Picked (myDetectedSeq.Value(anIndex)))
932 break; // detected owner was not removed
935 if (anIndex <= aDetectedSeqLength)
937 // Last detected owner was not removed, update mylastindex variable
938 mylastindex = myMapOfOwner->FindIndex (aLastPicked);
942 // Last detected owner was removed. First object from sequence become detected.
943 // Pass any active view because in current implementation the highlighting is
944 // synchronized in all view.
945 manageDetected (myMainVS->Picked (myDetectedSeq.First()),
946 aViewer->ActiveViewIterator().Value(),
952 //=======================================================================
953 //function : SetSelected
955 //=======================================================================
956 void AIS_LocalContext::SetSelected(const Handle(AIS_InteractiveObject)& anIObj,
957 const Standard_Boolean updateviewer)
959 if(!IsValidForSelection(anIObj)) return;
960 UnhilightPicked(Standard_False);
962 //1st case, owner already <anIObj> as owner
963 // and not separated is found...
965 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromIO(anIObj);
967 //check if global selection there is an owner that can be triturated...
968 if (anIObj->HasSelection (anIObj->GlobalSelectionMode()))
970 EO = anIObj->GlobalSelOwner();
973 EO = new SelectMgr_EntityOwner((const Handle(SelectMgr_SelectableObject)&)anIObj);
976 ClearSelected(Standard_False);
978 mySelection->Select(EO);
979 EO->SetSelected (Standard_True);
981 HilightPicked(updateviewer);
984 //=======================================================================
985 //function : AddOrRemoveSelected
987 //=======================================================================
989 void AIS_LocalContext::AddOrRemoveSelected(const Handle(AIS_InteractiveObject)& anIObj,
990 const Standard_Boolean updateviewer)
992 if(!IsValidForSelection(anIObj)) return;
993 UnhilightPicked(Standard_False);
994 // first check if it is selected...
995 Handle(SelectMgr_EntityOwner) EO;
997 EO = FindSelectedOwnerFromIO(anIObj);
1001 if(anIObj->HasSelection (anIObj->GlobalSelectionMode()))
1003 EO = anIObj->GlobalSelOwner();
1007 EO = new SelectMgr_EntityOwner((const Handle(SelectMgr_SelectableObject)&)anIObj);
1011 if (!mySelection.IsNull())
1013 AIS_SelectStatus aStatus = mySelection->Select(EO);
1014 EO->SetSelected (aStatus == AIS_SS_Added);
1017 HilightPicked(updateviewer);
1020 //=======================================================================
1021 //function : AddOrRemoveSelected
1022 //purpose : To check...
1023 //=======================================================================
1024 void AIS_LocalContext::AddOrRemoveSelected(const TopoDS_Shape& Sh,
1025 const Standard_Boolean updateviewer)
1027 UnhilightPicked (Standard_False);
1028 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromShape(Sh);
1031 mySelection->Select(EO);
1032 EO->SetSelected (Standard_True);
1034 HilightPicked (updateviewer);
1037 void AIS_LocalContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
1038 const Standard_Boolean toUpdateViewer)
1042 UnhilightPicked (Standard_False);
1045 Standard_Boolean toSelect = theOwner->IsSelected() ? Standard_False : Standard_True;
1047 mySelection->Select(theOwner);
1048 theOwner->SetSelected (toSelect);
1052 HilightPicked (toUpdateViewer);
1056 //==================================================
1057 // Function: manageDetected
1059 //==================================================
1060 void AIS_LocalContext::manageDetected (const Handle(SelectMgr_EntityOwner)& thePickOwner,
1061 const Handle(V3d_View)& theView,
1062 const Standard_Boolean theToRedrawImmediate)
1064 if (thePickOwner.IsNull())
1066 myMainPM->ClearImmediateDraw();
1067 if (theToRedrawImmediate)
1069 theView->RedrawImmediate();
1074 if (!myFilters->IsOk (thePickOwner))
1076 if (mylastindex != 0)
1078 mylastgood = mylastindex;
1080 if (theToRedrawImmediate)
1082 theView->RedrawImmediate();
1087 //=======================================================================================================
1088 // 2 cases : a- object is in the map of picks:
1089 // 1. this is the same index as the last detected: -> Do nothing
1091 // - if lastindex = 0 (no object was detected at the last step)
1092 // the object presentation is highlighted and lastindex = index(objet)
1094 // the presentation of the object corresponding to lastindex is "unhighlighted"
1095 // it is removed if the object is not visualized but only active
1096 // then the presentation of the detected object is highlighted and lastindex = index(objet)
1097 // b- the object is not in the map of picked objects
1098 // - if lastindex != 0 (object detected at the last step) it is unhighlighted ...
1099 // if the object was decomposed, presentation is created for the detected shape and the couple
1100 // (Proprietaire,Prs)is added in the map.
1101 // otherwise the couple(proprietaire, NullPrs) is placed in the map and the interactive object
1102 // itself is highlighted.
1104 //=======================================================================================================
1106 const Standard_Integer aNewIndex = myMapOfOwner->Contains (thePickOwner)
1107 ? myMapOfOwner->FindIndex (thePickOwner)
1108 : myMapOfOwner->Add (thePickOwner);
1110 // For the advanced mesh selection mode the owner indices comparison
1111 // is not effective because in that case only one owner manage the
1112 // selection in current selection mode. It is necessary to check the current detected
1113 // entity and hilight it only if the detected entity is not the same as
1114 // previous detected (IsForcedHilight call)
1115 if (aNewIndex != mylastindex
1116 || thePickOwner->IsForcedHilight())
1118 myMainPM->ClearImmediateDraw();
1119 if (mylastindex != 0
1120 && mylastindex <= myMapOfOwner->Extent())
1122 const Handle(SelectMgr_EntityOwner)& aLastOwner = myMapOfOwner->FindKey (mylastindex);
1123 Unhilight (aLastOwner, theView);
1128 if (!thePickOwner->IsSelected() || myCTX->ToHilightSelected())
1130 Hilight (thePickOwner, theView);
1132 if (theToRedrawImmediate)
1134 theView->RedrawImmediate();
1138 mylastindex = aNewIndex;
1141 if (mylastindex != 0)
1143 mylastgood = mylastindex;
1147 //=======================================================================
1148 //function : HasDetectedShape
1150 //=======================================================================
1152 Standard_Boolean AIS_LocalContext::HasDetectedShape() const
1154 if(mylastindex==0) return Standard_False;
1155 return IsShape(mylastindex);
1158 //=======================================================================
1159 //function : DetectedShape
1161 //=======================================================================
1164 AIS_LocalContext::DetectedShape() const
1166 if(mylastindex != 0)
1168 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner->FindKey (mylastindex));
1169 if(BROwnr.IsNull()) return AIS_LocalContext_myDummyShape;
1170 return BROwnr->Shape();
1172 return AIS_LocalContext_myDummyShape;
1175 //=======================================================================
1176 //function : DetectedInteractive
1178 //=======================================================================
1180 Handle(AIS_InteractiveObject)
1181 AIS_LocalContext::DetectedInteractive() const
1183 Handle(AIS_InteractiveObject) Iobj;
1184 if(IsValidIndex(mylastindex)){
1185 Handle(SelectMgr_SelectableObject) SO = myMapOfOwner->FindKey(mylastindex)->Selectable();
1186 Iobj = Handle(AIS_InteractiveObject)::DownCast (SO);
1190 //=======================================================================
1191 //function : DetectedInteractive
1193 //=======================================================================
1194 Handle(SelectMgr_EntityOwner) AIS_LocalContext::DetectedOwner() const
1196 Handle(SelectMgr_EntityOwner) bid;
1197 if(!IsValidIndex(mylastindex)) return bid;
1198 return myMapOfOwner->FindKey(mylastindex);
1202 //=======================================================================
1203 //function : ComesFromDecomposition
1205 //=======================================================================
1207 Standard_Boolean AIS_LocalContext::ComesFromDecomposition(const Standard_Integer PickedIndex) const
1209 const Handle(SelectMgr_EntityOwner)& OWN = myMapOfOwner->FindKey(PickedIndex);
1210 Handle(SelectMgr_SelectableObject) aSel = OWN->Selectable();
1211 if (myActiveObjects.IsBound (aSel)) { // debug of jmi
1212 const Handle(AIS_LocalStatus)& Stat = myActiveObjects(aSel);
1213 return Stat->Decomposed();
1215 return Standard_False;
1218 //=======================================================================
1219 //function : DisplaySensitive
1221 //=======================================================================
1223 void AIS_LocalContext::DisplaySensitive(const Handle(V3d_View)& aviou)
1225 myMainVS->DisplaySensitive(aviou);
1228 //=======================================================================
1229 //function : ClearSensitive
1231 //=======================================================================
1233 void AIS_LocalContext::ClearSensitive(const Handle(V3d_View)& aviou)
1235 myMainVS->ClearSensitive(aviou);
1239 //=======================================================================
1240 //function : IsShape
1242 //=======================================================================
1243 Standard_Boolean AIS_LocalContext::IsShape(const Standard_Integer Index) const
1245 Handle(SelectMgr_EntityOwner) aEO (myMapOfOwner->FindKey(Index));
1246 if (aEO.IsNull() || ! aEO->IsKind(STANDARD_TYPE(StdSelect_BRepOwner)))
1247 return Standard_False;
1249 ComesFromDecomposition(Index);
1252 Standard_Boolean AIS_LocalContext::IsValidForSelection(const Handle(AIS_InteractiveObject)& anIObj) const
1254 const Handle(SelectMgr_SelectableObject)& aSelObj = anIObj; // to avoid ambiguity
1255 // Shape was not transfered from AIS_Shape to EntityOwner
1256 Handle(AIS_Shape) shape = Handle(AIS_Shape)::DownCast(anIObj);
1257 if( !shape.IsNull() )
1258 return myFilters->IsOk(new StdSelect_BRepOwner(shape->Shape(), aSelObj));
1259 return myFilters->IsOk(new SelectMgr_EntityOwner(aSelObj));
1263 //=======================================================================
1264 //function : HilightNextDetected
1266 //=======================================================================
1267 Standard_Integer AIS_LocalContext::HilightNextDetected (const Handle(V3d_View)& theView,
1268 const Standard_Boolean theToRedrawImmediate)
1270 // go to the next owner
1271 if (myDetectedSeq.IsEmpty())
1276 const Standard_Integer aLen = myDetectedSeq.Length();
1277 if (++myCurDetected > aLen)
1281 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1282 if (anOwner.IsNull())
1286 manageDetected (anOwner, theView, theToRedrawImmediate);
1287 return myCurDetected;
1290 //=======================================================================
1291 //function : HilightPreviousDetected
1293 //=======================================================================
1294 Standard_Integer AIS_LocalContext::HilightPreviousDetected (const Handle(V3d_View)& theView,
1295 const Standard_Boolean theToRedrawImmediate)
1297 if (myDetectedSeq.IsEmpty())
1302 const Standard_Integer aLen = myDetectedSeq.Length();
1303 if (--myCurDetected < 1)
1305 myCurDetected = aLen;
1307 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1308 if (anOwner.IsNull())
1313 manageDetected (anOwner, theView, theToRedrawImmediate);
1314 return myCurDetected;
1317 //=======================================================================
1318 //function : UnhilightLastDetected
1320 //=======================================================================
1321 Standard_Boolean AIS_LocalContext::UnhilightLastDetected (const Handle(V3d_View)& theView)
1323 return UnhilightLastDetected (theView->Viewer());
1326 //=======================================================================
1327 //function : UnhilightLastDetected
1329 //=======================================================================
1330 Standard_Boolean AIS_LocalContext::UnhilightLastDetected (const Handle(V3d_Viewer)& theViewer)
1332 if (!IsValidIndex (mylastindex))
1334 return Standard_False;
1337 myMainPM->BeginImmediateDraw();
1338 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (mylastindex);
1339 anOwner->Unhilight (myMainPM);
1340 myMainPM->EndImmediateDraw (theViewer);
1342 return Standard_True;
1345 //=======================================================================
1346 //function : FindSelectedOwnerFromIO
1347 //purpose : it is checked if one of the selected owners really presents IObj
1348 //=======================================================================
1349 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromIO (const Handle(AIS_InteractiveObject)& theObj) const
1351 Handle(SelectMgr_EntityOwner) EO,bid;
1353 || mySelection.IsNull())
1355 return Handle(SelectMgr_EntityOwner)();
1358 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
1360 if (!aSelIter.Value()->IsSameSelectable (theObj))
1365 Handle(StdSelect_BRepOwner) aBROwner = Handle(StdSelect_BRepOwner)::DownCast(aSelIter.Value());
1366 if (aBROwner.IsNull()
1367 || !aBROwner->ComesFromDecomposition())
1369 return aSelIter.Value();
1372 return Handle(SelectMgr_EntityOwner)();
1375 //=======================================================================
1376 //function : FindSelectedOwnerFromShape
1377 //purpose : it is checked if one of the selected owners really presents IObj
1378 //=======================================================================
1379 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromShape(const TopoDS_Shape& sh) const
1381 Handle(SelectMgr_EntityOwner) EO, bid;
1382 if (sh.IsNull()) return EO;
1384 if(mySelection.IsNull()) {
1388 Standard_Boolean found(Standard_False);
1391 NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
1392 myMainVS->ActiveOwners (anActiveOwners);
1393 for (NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (anActiveOwners); anOwnersIt.More(); anOwnersIt.Next())
1395 EO = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value());
1396 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1397 if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) {
1398 found = Standard_True;
1404 if(found) return EO;
1408 //=======================================================================
1409 //function : AIS_LocalContext::InitDetected
1411 //=======================================================================
1412 void AIS_LocalContext::InitDetected()
1414 myAISCurDetected = !myDetectedSeq.IsEmpty() ? myDetectedSeq.Lower() : 0;
1417 //=======================================================================
1418 //function : AIS_LocalContext::MoreDetected
1420 //=======================================================================
1421 Standard_Boolean AIS_LocalContext::MoreDetected() const
1423 return myAISCurDetected >= myDetectedSeq.Lower()
1424 && myAISCurDetected <= myDetectedSeq.Upper();
1427 //=======================================================================
1428 //function : AIS_LocalContext::NextDetected
1430 //=======================================================================
1431 void AIS_LocalContext::NextDetected()
1436 //=======================================================================
1437 //function : DetectedCurrentShape
1439 //=======================================================================
1440 const TopoDS_Shape& AIS_LocalContext::DetectedCurrentShape() const
1442 Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
1444 if (aCurrentShape.IsNull())
1446 return AIS_LocalContext_myDummyShape;
1449 return aCurrentShape->Shape();
1452 //=======================================================================
1453 //function : DetectedCurrentOwner
1455 //=======================================================================
1456 Handle(SelectMgr_EntityOwner) AIS_LocalContext::DetectedCurrentOwner() const
1458 return MoreDetected()
1459 ? myMainVS->Picked (myDetectedSeq (myAISCurDetected))
1460 : Handle(SelectMgr_EntityOwner)();
1463 //=======================================================================
1464 //function : DetectedCurrentObject
1466 //=======================================================================
1467 Handle(AIS_InteractiveObject) AIS_LocalContext::DetectedCurrentObject() const
1469 if (!MoreDetected())
1471 return Handle(AIS_InteractiveObject)();
1473 return Handle(AIS_InteractiveObject)::DownCast (myMainVS->Picked (myDetectedSeq (myAISCurDetected))->Selectable());
1476 //=======================================================================
1477 //function : RestoreActivatedModes
1479 //=======================================================================
1480 void AIS_LocalContext::RestoreActivatedModes() const
1482 for (AIS_DataMapOfSelStat::Iterator anIter (myActiveObjects); anIter.More(); anIter.Next())
1484 const TColStd_ListOfInteger& anActivatedModes = anIter.Value()->SelectionModes();
1485 for (TColStd_ListIteratorOfListOfInteger aModesIter (anActivatedModes); aModesIter.More(); aModesIter.Next())
1487 mySM->Activate (anIter.Key(), aModesIter.Value(), myMainVS);