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 //=======================================================================
66 //function : getHiStyle
68 //=======================================================================
69 const Handle(Graphic3d_HighlightStyle)& AIS_LocalContext::getHiStyle (const Handle(SelectMgr_SelectableObject)& theObj) const
71 const Handle(Prs3d_Drawer)& aHiDrawer = theObj->HilightAttributes();
72 return !aHiDrawer.IsNull() && aHiDrawer->HasOwnHighlightStyle()
73 ? aHiDrawer->HighlightStyle() : myCTX->HighlightStyle();
76 //=======================================================================
77 //function : getSelStyle
79 //=======================================================================
80 const Handle(Graphic3d_HighlightStyle)& AIS_LocalContext::getSelStyle (const Handle(AIS_InteractiveObject)& theObj) const
82 const Handle(Prs3d_Drawer)& aHiDrawer = theObj->HilightAttributes();
83 return !aHiDrawer.IsNull() && aHiDrawer->HasOwnSelectionStyle()
84 ? aHiDrawer->SelectionStyle() : myCTX->SelectionStyle();
87 //==================================================
90 //==================================================
91 AIS_StatusOfDetection AIS_LocalContext::MoveTo (const Standard_Integer theXpix,
92 const Standard_Integer theYpix,
93 const Handle(V3d_View)& theView,
94 const Standard_Boolean theToRedrawImmediate)
96 // check that ViewerSelector gives
97 if (theView->Viewer() != myCTX->CurrentViewer())
102 myAISCurDetected = 0;
103 myAISDetectedSeq.Clear();
106 myDetectedSeq.Clear();
107 myFilters->SetDisabledObjects (theView->View()->HiddenObjects());
108 myMainVS->Pick (theXpix, theYpix, theView);
110 const Standard_Integer aDetectedNb = myMainVS->NbPicked();
111 for (Standard_Integer aDetIter = 1; aDetIter <= aDetectedNb; ++aDetIter)
113 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (aDetIter);
115 || !myFilters->IsOk (anOwner))
120 myDetectedSeq.Append (aDetIter); // normally they are already arranged in correct order...
121 Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
124 myAISDetectedSeq.Append (anObj);
128 // result of courses..
129 if (aDetectedNb == 0 || myDetectedSeq.IsEmpty())
131 if (mylastindex != 0 && mylastindex <= myMapOfOwner->Extent())
133 myMainPM->ClearImmediateDraw();
134 Unhilight (myMapOfOwner->FindKey (mylastindex), theView);
135 if (theToRedrawImmediate)
137 theView->RedrawImmediate();
142 return aDetectedNb == 0
147 // all owners detected by the selector are passed to the
148 // filters and correct ones are preserved...
150 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
151 manageDetected (anOwner, theView, theToRedrawImmediate);
152 if (myDetectedSeq.Length() == 1)
154 return aDetectedNb == 1
155 ? AIS_SOD_OnlyOneDetected
156 : AIS_SOD_OnlyOneGood;
160 return AIS_SOD_SeveralGood;
164 //=======================================================================
165 //function : AddSelect
167 //=======================================================================
168 AIS_StatusOfPick AIS_LocalContext::AddSelect (const Handle(SelectMgr_EntityOwner)& theObject)
170 mySelection->AddSelect (theObject);
172 Standard_Integer aSelNum = mySelection->Extent();
173 return (aSelNum == 1) ? AIS_SOP_OneSelected
174 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
178 //=======================================================================
181 //=======================================================================
182 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Boolean toUpdateViewer)
186 UnhilightPicked (Standard_False);
189 Standard_Integer aDetIndex = DetectedIndex();
192 ClearSelected (toUpdateViewer);
193 return mySelection->IsEmpty() ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
196 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex);
198 ClearSelected (Standard_False);
200 if (!anOwner->IsSelected()) // anOwner is not selected
202 anOwner->SetSelected (Standard_True);
203 mySelection->Select (anOwner);
208 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
209 for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
211 Unhilight (anOwner, anActiveViewIter.Value());
214 // advanced selection highlighting mechanism
215 if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
217 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
218 UpdateSelected (anIO, Standard_False);
223 myCTX->CurrentViewer()->Update();
227 return (mySelection->Extent() == 1) ? AIS_SOP_OneSelected : AIS_SOP_SeveralSelected;
230 //=======================================================================
233 //=======================================================================
234 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Integer theXPMin,
235 const Standard_Integer theYPMin,
236 const Standard_Integer theXPMax,
237 const Standard_Integer theYPMax,
238 const Handle(V3d_View)& theView,
239 const Standard_Boolean toUpdateViewer)
241 if (theView->Viewer() == myCTX->CurrentViewer())
243 myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
246 UnhilightPicked (Standard_False);
249 Standard_Integer aSelNum = mySelection->Extent();
250 if (myMainVS->NbPicked() == 0)
252 ClearSelected (toUpdateViewer);
254 return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
257 ClearSelected (Standard_False);
259 for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
261 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
262 if (myFilters->IsOk (anOwner))
264 // it can be helpful to classify this owner immediately...
265 if (!anOwner->IsSelected())
267 anOwner->SetSelected (Standard_True);
268 mySelection->Select (anOwner);
275 HilightPicked (toUpdateViewer);
279 Standard_Integer aSelNum = mySelection->Extent();
281 return (aSelNum == 1) ? AIS_SOP_OneSelected
282 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
286 //==================================================
288 // Purpose : Selection by polyline
289 //==================================================
290 AIS_StatusOfPick AIS_LocalContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
291 const Handle(V3d_View)& theView,
292 const Standard_Boolean toUpdateViewer)
294 if (theView->Viewer() == myCTX->CurrentViewer())
296 myMainVS->Pick (thePolyline, theView);
298 Standard_Integer aLastSelNum = mySelection->Extent();
299 if (myMainVS->NbPicked() == 0)
301 // Nothing is selected clear selection.
302 ClearSelected (toUpdateViewer);
305 // Return state to know if something was unselected
306 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
311 UnhilightPicked (Standard_False);
314 // Clear previous selection without update to process this selection
315 ClearSelected (Standard_False);
317 for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
319 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
320 if (myFilters->IsOk (anOwner))
322 // it can be helpful to classify this owner immediately...
323 if (!anOwner->IsSelected())
325 mySelection->AddSelect (anOwner);
326 anOwner->SetSelected (Standard_True);
333 HilightPicked (toUpdateViewer);
337 Standard_Integer aSelNum = mySelection->Extent();
338 return (aSelNum == 1) ? AIS_SOP_OneSelected
339 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
343 //=======================================================================
344 //function : ShiftSelect
346 //=======================================================================
347 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Boolean toUpdateViewer)
349 Standard_Integer aDetIndex = DetectedIndex();
353 Standard_Integer aSelNum = mySelection->Extent();
354 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex);
355 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
356 mySelection->Select (anOwner);
357 anOwner->SetSelected (toSelect);
361 myMainPM->ClearImmediateDraw();
362 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
363 for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
365 Unhilight (anOwner, anActiveViewIter.Value());
368 // advanced selection highlighting mechanism
369 if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
371 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
372 UpdateSelected (anIO, Standard_False);
377 myCTX->CurrentViewer()->Update();
381 Standard_Integer NS = mySelection->Extent();
382 if( NS == 1 ) return AIS_SOP_OneSelected;
383 else if( NS > 1 ) return AIS_SOP_SeveralSelected;
384 return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
386 return AIS_SOP_Error;
389 //=======================================================================
390 //function : ShiftSelect
392 //=======================================================================
393 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Integer theXPMin,
394 const Standard_Integer theYPMin,
395 const Standard_Integer theXPMax,
396 const Standard_Integer theYPMax,
397 const Handle(V3d_View)& theView,
398 const Standard_Boolean toUpdateViewer)
400 myMainPM->ClearImmediateDraw();
402 if (theView->Viewer() == myCTX->CurrentViewer())
404 myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
406 Standard_Integer aLastSelNum = mySelection->Extent();
407 if (myMainVS->NbPicked() == 0)
409 // Nothing is selected clear selection, but don't clear the selection
410 // as it is shift selection and previous selection matters.
411 // Return state to know if something was unselected
412 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
417 UnhilightPicked (Standard_False);
420 for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
422 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
423 if(myFilters->IsOk (anOwner))
425 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
426 mySelection->Select (anOwner);
427 anOwner->SetSelected (toSelect);
433 HilightPicked (toUpdateViewer);
437 Standard_Integer aSelNum = mySelection->Extent();
439 return (aSelNum == 1) ? AIS_SOP_OneSelected
440 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
444 //==================================================
446 // Purpose : Selection by polyline
447 //==================================================
448 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
449 const Handle(V3d_View)& theView,
450 const Standard_Boolean toUpdateViewer)
452 if (theView->Viewer() == myCTX->CurrentViewer())
454 myMainVS->Pick (thePolyline, theView);
456 Standard_Integer aLastSelNum = mySelection->Extent();
457 if (myMainVS->NbPicked() == 0)
459 // Nothing is selected clear selection, but don't clear the selection
460 // as it is shift selection and previous selection matters.
461 // Return state to know if something was unselected
462 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
467 UnhilightPicked (Standard_False);
470 for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
472 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
473 if (myFilters->IsOk (anOwner))
475 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
476 mySelection->Select (anOwner);
477 anOwner->SetSelected (toSelect);
482 HilightPicked (toUpdateViewer);
486 Standard_Integer aSelNum = mySelection->Extent();
488 return (aSelNum == 1) ? AIS_SOP_OneSelected
489 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
493 //==================================================
496 //==================================================
497 void AIS_LocalContext::Hilight (const Handle(SelectMgr_EntityOwner)& theOwner,
498 const Handle(V3d_View)& theView)
500 if (theView.IsNull())
505 const Standard_Integer aHilightMode = GetHiMod (Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable()));
506 myMainPM->BeginImmediateDraw();
507 theOwner->HilightWithColor (myMainPM, getHiStyle (theOwner->Selectable()), aHilightMode);
508 myMainPM->EndImmediateDraw (theView->Viewer());
511 //==================================================
512 // Function: Unhilight
514 //==================================================
515 void AIS_LocalContext::Unhilight (const Handle(SelectMgr_EntityOwner)& theOwner,
516 const Handle(V3d_View)& theView)
518 if (theView.IsNull())
523 const Handle(AIS_InteractiveObject)& anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
524 const Standard_Integer aHilightMode = GetHiMod (anObj);
525 if (IsSelected (theOwner))
527 if (theOwner->IsAutoHilight())
529 theOwner->HilightWithColor (myMainPM, getSelStyle (anObj), aHilightMode);
534 theOwner->Unhilight (myMainPM, aHilightMode);
538 //=======================================================================
539 //function : HilightPicked
541 //=======================================================================
542 void AIS_LocalContext::HilightPicked (const Standard_Boolean theToUpdateviewer)
544 if (mySelection.IsNull())
549 typedef NCollection_Shared<SelectMgr_SequenceOfOwner> SelectMgr_HSequenceOfOwner;
550 typedef NCollection_DataMap <Handle(SelectMgr_SelectableObject), Handle(SelectMgr_HSequenceOfOwner) > SelectMgr_DataMapOfObjectOwners;
551 SelectMgr_DataMapOfObjectOwners aMap;
553 // to avoid problems when there is a loop searching for selected objects...
554 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
556 const Handle(SelectMgr_EntityOwner)& anOwner = aSelIter.Value();
557 Handle(SelectMgr_SelectableObject) aSelObj = anOwner->Selectable();
558 if (anOwner->IsAutoHilight())
560 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(aSelObj);
561 const Standard_Integer aHighMode = GetHiMod (anIO);
562 anOwner->HilightWithColor (myMainPM, getSelStyle (anIO), aHighMode);
566 Handle(SelectMgr_HSequenceOfOwner) aSeq;
567 if (aMap.Find (aSelObj, aSeq))
569 aSeq->Append (anOwner);
573 aSeq = new SelectMgr_HSequenceOfOwner();
574 aSeq->Append (anOwner);
575 aMap.Bind (aSelObj, aSeq);
579 for (SelectMgr_DataMapOfObjectOwners::Iterator aMapIter (aMap); aMapIter.More(); aMapIter.Next())
581 aMapIter.Key()->HilightSelected (myMainPM, *aMapIter.Value());
584 if (theToUpdateviewer)
586 myCTX->CurrentViewer()->Update();
590 //==================================================
591 // Function: UnhilightPicked
593 //==================================================
594 void AIS_LocalContext::UnhilightPicked (const Standard_Boolean theToUpdateViewer)
596 myMainPM->ClearImmediateDraw();
597 if (mySelection.IsNull())
602 NCollection_Map<Handle(SelectMgr_SelectableObject)> anObjMap;
603 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
605 const Handle(SelectMgr_EntityOwner)& anOwner = aSelIter.Value();
606 Handle(SelectMgr_SelectableObject) aSelObj = anOwner->Selectable();
607 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (aSelObj);
608 anObjMap.Add (aSelObj);
609 Standard_Integer aHighMode = GetHiMod (anIO);
610 anOwner->Unhilight (myMainPM, aHighMode);
613 for (NCollection_Map<Handle(SelectMgr_SelectableObject)>::Iterator aMapIter (anObjMap);
614 aMapIter.More(); aMapIter.Next())
616 if (!aMapIter.Key()->IsAutoHilight())
618 aMapIter.Key()->ClearSelected();
622 if (theToUpdateViewer)
624 myCTX->CurrentViewer()->Update();
628 //=======================================================================
629 //function : IsSelected
631 //=======================================================================
632 Standard_Boolean AIS_LocalContext::IsSelected(const Handle(AIS_InteractiveObject)& anIObj) const
634 return (!FindSelectedOwnerFromIO(anIObj).IsNull());
637 //=======================================================================
638 //function : IsSelected
640 //=======================================================================
642 Standard_Boolean AIS_LocalContext::IsSelected (const Handle(SelectMgr_EntityOwner)& theOwner) const
644 return !theOwner.IsNull() && theOwner->IsSelected();
647 //==================================================
650 //==================================================
651 void AIS_LocalContext::
657 //==================================================
660 //==================================================
661 Standard_Boolean AIS_LocalContext::
664 return mySelection->More();
667 //==================================================
670 //==================================================
671 void AIS_LocalContext::
677 //==================================================
678 // Function: HasShape
680 //==================================================
681 Standard_Boolean AIS_LocalContext::HasShape() const
683 if (!mySelection->More())
685 return Standard_False;
688 Handle(StdSelect_BRepOwner) aBROwner = Handle(StdSelect_BRepOwner)::DownCast(mySelection->Value());
689 return !aBROwner.IsNull()
690 && aBROwner->HasShape()
691 && aBROwner->ComesFromDecomposition();
694 //================================================================
695 // Function : HasSelectedShape
696 // Purpose : Checks if there is a selected shape regardless of its decomposition status
697 //================================================================
698 Standard_Boolean AIS_LocalContext::HasSelectedShape() const
700 if (!mySelection->More())
702 return Standard_False;
705 Handle(StdSelect_BRepOwner) aBrepOwner = Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value());
706 return !aBrepOwner.IsNull()
707 && aBrepOwner->HasShape();
710 //==================================================
711 // Function: SelectedShape
713 //==================================================
714 TopoDS_Shape AIS_LocalContext::SelectedShape() const
716 if (!mySelection->More())
718 return TopoDS_Shape();
721 Handle(StdSelect_BRepOwner) aBRO = Handle(StdSelect_BRepOwner)::DownCast(mySelection->Value());
724 return TopoDS_Shape();
727 return aBRO->Shape().Located (aBRO->Location() * aBRO->Shape().Location());
730 //==================================================
731 // Function: SelectedInteractive
733 //==================================================
734 Handle(AIS_InteractiveObject) AIS_LocalContext::SelectedInteractive() const
736 return !mySelection->More()
737 ? Handle(AIS_InteractiveObject)()
738 : Handle(AIS_InteractiveObject)::DownCast (mySelection->Value()->Selectable());
741 //==================================================
742 // Function: SelectedOwner
744 //==================================================
745 Handle(SelectMgr_EntityOwner) AIS_LocalContext::SelectedOwner() const
747 return !mySelection->More()
748 ? Handle(SelectMgr_EntityOwner)()
749 : mySelection->Value();
752 //==================================================
755 //==================================================
756 Standard_Boolean AIS_LocalContext::HasApplicative() const
758 Handle(AIS_InteractiveObject) anIO = SelectedInteractive();
759 return !anIO.IsNull()
763 //==================================================
766 //==================================================
767 const Handle(Standard_Transient)& AIS_LocalContext::
768 SelectedApplicative() const
770 return SelectedInteractive()->GetOwner();
775 //=======================================================================
776 //function : UpdateSelection
777 //purpose : should disappear...
778 //=======================================================================
779 void AIS_LocalContext::UpdateSelected(const Standard_Boolean updateviewer)
781 UnhilightPicked(Standard_False);
782 HilightPicked(updateviewer);
785 //================================================================
786 // Function : UpdateSelected
787 // Purpose : Part of advanced selection mechanism.
788 // Highlightes or clears selection presentation for the given IO
789 //================================================================
790 void AIS_LocalContext::UpdateSelected(const Handle(AIS_InteractiveObject)& anobj,
791 const Standard_Boolean updateviewer)
793 if (anobj.IsNull() || anobj->IsAutoHilight())
796 SelectMgr_SequenceOfOwner aSeq;
797 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
799 if (aSelIter.Value()->IsSameSelectable (anobj))
801 aSeq.Append (aSelIter.Value());
806 anobj->HilightSelected( myMainPM, aSeq );
808 anobj->ClearSelected();
811 myCTX->CurrentViewer()->Update();
815 //==================================================
816 // Function: ClearSelected
818 //==================================================
819 void AIS_LocalContext::ClearSelected (const Standard_Boolean updateviewer)
821 UnhilightPicked(updateviewer);
822 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
824 aSelIter.Value()->SetSelected (Standard_False);
826 mySelection->Clear();
830 //==================================================
831 // Function: ClearOutdatedSelection
833 //==================================================
834 void AIS_LocalContext::ClearOutdatedSelection (const Handle(AIS_InteractiveObject)& theIO,
835 const Standard_Boolean toClearDeactivated)
837 // 1. Collect selectable entities
838 SelectMgr_IndexedMapOfOwner aValidOwners;
840 const TColStd_ListOfInteger& aModes = SelectionModes (theIO);
842 TColStd_ListIteratorOfListOfInteger aModeIter (aModes);
843 for (; aModeIter.More(); aModeIter.Next())
845 int aMode = aModeIter.Value();
846 if (!theIO->HasSelection(aMode))
851 if (toClearDeactivated && !mySM->IsActivated(theIO, aMode, myMainVS))
856 Handle(SelectMgr_Selection) aSelection = theIO->Selection(aMode);
857 for (aSelection->Init(); aSelection->More(); aSelection->Next())
859 Handle(SelectBasics_SensitiveEntity) anEntity = aSelection->Sensitive()->BaseSensitive();
860 if (anEntity.IsNull())
865 Handle(SelectMgr_EntityOwner) anOwner =
866 Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId());
868 if (anOwner.IsNull())
873 aValidOwners.Add(anOwner);
877 // 2. Refresh context's detection and selection and keep only active owners.
878 // Keep last detected object for lastindex initialization.
879 Handle(SelectMgr_EntityOwner) aLastPicked;
880 if (IsValidIndex (mylastindex))
882 aLastPicked = myMapOfOwner->FindKey (mylastindex);
885 // Remove entity owners from detected sequences
886 for (Standard_Integer anIdx = 1; anIdx <= myDetectedSeq.Length(); ++anIdx)
888 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (anIdx));
889 if (anOwner.IsNull() || !anOwner->IsSameSelectable (theIO) || aValidOwners.Contains (anOwner))
894 myDetectedSeq.Remove (anIdx--);
896 if (anIdx < myCurDetected)
901 myCurDetected = Max (myCurDetected, 1);
903 Standard_Boolean isAISRemainsDetected = Standard_False;
905 // 3. AIS_Selection : remove entity owners from AIS_Selection
906 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
907 NCollection_List<Handle(SelectMgr_EntityOwner)> aRemoveEntites;
908 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
910 Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
911 if (!anOwner->IsSameSelectable (theIO))
916 if (aValidOwners.Contains (anOwner))
918 isAISRemainsDetected = Standard_True;
922 aRemoveEntites.Append (anOwner);
923 anOwner->SetSelected (Standard_False);
924 for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
926 Unhilight (anOwner, anActiveViewIter.Value());
931 for (NCollection_List<Handle(SelectMgr_EntityOwner)>::Iterator anIterRemove (aRemoveEntites);
932 anIterRemove.More(); anIterRemove.Next())
934 mySelection->Select (anIterRemove.Value());
937 // 4. AIS_LocalContext - myMapOfOwner : remove entity owners from myMapOfOwner
938 SelectMgr_IndexedMapOfOwner anOwnersToKeep;
939 for (Standard_Integer anIdx = 1; anIdx <= myMapOfOwner->Extent(); anIdx++)
941 Handle(SelectMgr_EntityOwner) anOwner = myMapOfOwner->FindKey (anIdx);
942 if (anOwner.IsNull())
947 if (!anOwner->IsSameSelectable (theIO) || aValidOwners.Contains (anOwner))
949 anOwnersToKeep.Add (anOwner);
953 for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
955 Unhilight (anOwner, anActiveViewIter.Value());
959 myMapOfOwner->Clear();
960 myMapOfOwner->Assign (anOwnersToKeep);
962 if (myDetectedSeq.IsEmpty() && !aLastPicked.IsNull())
964 myMainPM->ClearImmediateDraw();
967 else if (!aLastPicked.IsNull())
969 // For a case when the last detected owner was unhilighted and removed as outdated we
970 // need to check if there were other detected owners with less priority. If yes then
971 // one from the remaining should be treated.
972 Standard_Integer anIndex = 1, aDetectedSeqLength = myDetectedSeq.Length();
973 for (; anIndex <= aDetectedSeqLength; anIndex++)
975 if (aLastPicked == myMainVS->Picked (myDetectedSeq.Value(anIndex)))
977 break; // detected owner was not removed
980 if (anIndex <= aDetectedSeqLength)
982 // Last detected owner was not removed, update mylastindex variable
983 mylastindex = myMapOfOwner->FindIndex (aLastPicked);
987 // Last detected owner was removed. First object from sequence become detected.
988 // Pass any active view because in current implementation the highlighting is
989 // synchronized in all view.
990 manageDetected (myMainVS->Picked (myDetectedSeq.First()),
991 aViewer->ActiveViewIterator().Value(),
996 // Renew iterator of ::DetectedCurrentObject()
997 if (!isAISRemainsDetected)
999 // Remove the interactive object from detected sequences
1000 for (Standard_Integer anIdx = 1; anIdx <= myAISDetectedSeq.Length(); ++anIdx)
1002 Handle(AIS_InteractiveObject) aDetectedIO = myAISDetectedSeq.Value (anIdx);
1003 if (aDetectedIO.IsNull() || aDetectedIO != theIO)
1008 myAISDetectedSeq.Remove (anIdx--);
1010 if (anIdx < myAISCurDetected)
1015 myAISCurDetected = Max (myAISCurDetected, 1);
1019 //=======================================================================
1020 //function : SetSelected
1022 //=======================================================================
1023 void AIS_LocalContext::SetSelected(const Handle(AIS_InteractiveObject)& anIObj,
1024 const Standard_Boolean updateviewer)
1026 if(!IsValidForSelection(anIObj)) return;
1027 UnhilightPicked(Standard_False);
1029 //1st case, owner already <anIObj> as owner
1030 // and not separated is found...
1032 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromIO(anIObj);
1034 //check if in selection number 0 there is an owner that can be triturated...
1035 if(anIObj->HasSelection(0)){
1036 const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0);
1039 Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->BaseSensitive()->OwnerId();
1040 EO = Handle(SelectMgr_EntityOwner)::DownCast (BO);
1044 EO = new SelectMgr_EntityOwner((const Handle(SelectMgr_SelectableObject)&)anIObj);
1047 ClearSelected(Standard_False);
1049 mySelection->Select(EO);
1050 EO->SetSelected (Standard_True);
1052 HilightPicked(updateviewer);
1055 //=======================================================================
1056 //function : AddOrRemoveSelected
1058 //=======================================================================
1060 void AIS_LocalContext::AddOrRemoveSelected(const Handle(AIS_InteractiveObject)& anIObj,
1061 const Standard_Boolean updateviewer)
1063 if(!IsValidForSelection(anIObj)) return;
1064 UnhilightPicked(Standard_False);
1065 // first check if it is selected...
1066 Handle(SelectMgr_EntityOwner) EO;
1068 EO = FindSelectedOwnerFromIO(anIObj);
1072 if(anIObj->HasSelection(0))
1074 const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0);
1077 Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->BaseSensitive()->OwnerId();
1078 EO = Handle(SelectMgr_EntityOwner)::DownCast (BO);
1083 EO = new SelectMgr_EntityOwner((const Handle(SelectMgr_SelectableObject)&)anIObj);
1087 if (!mySelection.IsNull())
1089 AIS_SelectStatus aStatus = mySelection->Select(EO);
1090 EO->SetSelected (aStatus == AIS_SS_Added);
1093 HilightPicked(updateviewer);
1096 //=======================================================================
1097 //function : AddOrRemoveSelected
1098 //purpose : To check...
1099 //=======================================================================
1100 void AIS_LocalContext::AddOrRemoveSelected(const TopoDS_Shape& Sh,
1101 const Standard_Boolean updateviewer)
1103 UnhilightPicked (Standard_False);
1104 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromShape(Sh);
1107 mySelection->Select(EO);
1108 EO->SetSelected (Standard_True);
1110 HilightPicked (updateviewer);
1113 void AIS_LocalContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
1114 const Standard_Boolean toUpdateViewer)
1118 UnhilightPicked (Standard_False);
1121 Standard_Boolean toSelect = theOwner->IsSelected() ? Standard_False : Standard_True;
1123 mySelection->Select(theOwner);
1124 theOwner->SetSelected (toSelect);
1128 HilightPicked (toUpdateViewer);
1132 //==================================================
1133 // Function: manageDetected
1135 //==================================================
1136 void AIS_LocalContext::manageDetected (const Handle(SelectMgr_EntityOwner)& thePickOwner,
1137 const Handle(V3d_View)& theView,
1138 const Standard_Boolean theToRedrawImmediate)
1140 if (thePickOwner.IsNull())
1142 myMainPM->ClearImmediateDraw();
1143 if (theToRedrawImmediate)
1145 theView->RedrawImmediate();
1150 if (!myFilters->IsOk (thePickOwner))
1152 if (mylastindex != 0)
1154 mylastgood = mylastindex;
1156 if (theToRedrawImmediate)
1158 theView->RedrawImmediate();
1163 //=======================================================================================================
1164 // 2 cases : a- object is in the map of picks:
1165 // 1. this is the same index as the last detected: -> Do nothing
1167 // - if lastindex = 0 (no object was detected at the last step)
1168 // the object presentation is highlighted and lastindex = index(objet)
1170 // the presentation of the object corresponding to lastindex is "unhighlighted"
1171 // it is removed if the object is not visualized but only active
1172 // then the presentation of the detected object is highlighted and lastindex = index(objet)
1173 // b- the object is not in the map of picked objects
1174 // - if lastindex != 0 (object detected at the last step) it is unhighlighted ...
1175 // if the object was decomposed, presentation is created for the detected shape and the couple
1176 // (Proprietaire,Prs)is added in the map.
1177 // otherwise the couple(proprietaire, NullPrs) is placed in the map and the interactive object
1178 // itself is highlighted.
1180 //=======================================================================================================
1182 const Standard_Integer aNewIndex = myMapOfOwner->Contains (thePickOwner)
1183 ? myMapOfOwner->FindIndex (thePickOwner)
1184 : myMapOfOwner->Add (thePickOwner);
1186 // For the advanced mesh selection mode the owner indices comparison
1187 // is not effective because in that case only one owner manage the
1188 // selection in current selection mode. It is necessary to check the current detected
1189 // entity and hilight it only if the detected entity is not the same as
1190 // previous detected (IsForcedHilight call)
1191 if (aNewIndex != mylastindex
1192 || thePickOwner->IsForcedHilight())
1194 myMainPM->ClearImmediateDraw();
1195 if (mylastindex != 0
1196 && mylastindex <= myMapOfOwner->Extent())
1198 const Handle(SelectMgr_EntityOwner)& aLastOwner = myMapOfOwner->FindKey (mylastindex);
1199 Unhilight (aLastOwner, theView);
1204 if (!thePickOwner->IsSelected() || myCTX->ToHilightSelected())
1206 Hilight (thePickOwner, theView);
1208 if (theToRedrawImmediate)
1210 theView->RedrawImmediate();
1214 mylastindex = aNewIndex;
1217 if (mylastindex != 0)
1219 mylastgood = mylastindex;
1223 //=======================================================================
1224 //function : HasDetectedShape
1226 //=======================================================================
1228 Standard_Boolean AIS_LocalContext::HasDetectedShape() const
1230 if(mylastindex==0) return Standard_False;
1231 return IsShape(mylastindex);
1234 //=======================================================================
1235 //function : DetectedShape
1237 //=======================================================================
1240 AIS_LocalContext::DetectedShape() const
1242 if(mylastindex != 0)
1244 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner->FindKey (mylastindex));
1245 if(BROwnr.IsNull()) return AIS_myDummyShape;
1246 return BROwnr->Shape();
1248 return AIS_myDummyShape;
1251 //=======================================================================
1252 //function : DetectedInteractive
1254 //=======================================================================
1256 Handle(AIS_InteractiveObject)
1257 AIS_LocalContext::DetectedInteractive() const
1259 Handle(AIS_InteractiveObject) Iobj;
1260 if(IsValidIndex(mylastindex)){
1261 Handle(SelectMgr_SelectableObject) SO = myMapOfOwner->FindKey(mylastindex)->Selectable();
1262 Iobj = Handle(AIS_InteractiveObject)::DownCast (SO);
1266 //=======================================================================
1267 //function : DetectedInteractive
1269 //=======================================================================
1270 Handle(SelectMgr_EntityOwner) AIS_LocalContext::DetectedOwner() const
1272 Handle(SelectMgr_EntityOwner) bid;
1273 if(!IsValidIndex(mylastindex)) return bid;
1274 return myMapOfOwner->FindKey(mylastindex);
1278 //=======================================================================
1279 //function : ComesFromDecomposition
1281 //=======================================================================
1283 Standard_Boolean AIS_LocalContext::ComesFromDecomposition(const Standard_Integer PickedIndex) const
1285 const Handle(SelectMgr_EntityOwner)& OWN = myMapOfOwner->FindKey(PickedIndex);
1286 Handle(SelectMgr_SelectableObject) aSel = OWN->Selectable();
1287 if (myActiveObjects.IsBound (aSel)) { // debug of jmi
1288 const Handle(AIS_LocalStatus)& Stat = myActiveObjects(aSel);
1289 return Stat->Decomposed();
1291 return Standard_False;
1294 //=======================================================================
1295 //function : DisplaySensitive
1297 //=======================================================================
1299 void AIS_LocalContext::DisplaySensitive(const Handle(V3d_View)& aviou)
1301 myMainVS->DisplaySensitive(aviou);
1304 //=======================================================================
1305 //function : ClearSensitive
1307 //=======================================================================
1309 void AIS_LocalContext::ClearSensitive(const Handle(V3d_View)& aviou)
1311 myMainVS->ClearSensitive(aviou);
1315 //=======================================================================
1316 //function : IsShape
1318 //=======================================================================
1319 Standard_Boolean AIS_LocalContext::IsShape(const Standard_Integer Index) const
1321 Handle(SelectMgr_EntityOwner) aEO (myMapOfOwner->FindKey(Index));
1322 if (aEO.IsNull() || ! aEO->IsKind(STANDARD_TYPE(StdSelect_BRepOwner)))
1323 return Standard_False;
1325 ComesFromDecomposition(Index);
1328 Standard_Boolean AIS_LocalContext::IsValidForSelection(const Handle(AIS_InteractiveObject)& anIObj) const
1330 const Handle(SelectMgr_SelectableObject)& aSelObj = anIObj; // to avoid ambiguity
1331 // Shape was not transfered from AIS_Shape to EntityOwner
1332 Handle(AIS_Shape) shape = Handle(AIS_Shape)::DownCast(anIObj);
1333 if( !shape.IsNull() )
1334 return myFilters->IsOk(new StdSelect_BRepOwner(shape->Shape(), aSelObj));
1335 return myFilters->IsOk(new SelectMgr_EntityOwner(aSelObj));
1339 //=======================================================================
1340 //function : HilightNextDetected
1342 //=======================================================================
1343 Standard_Integer AIS_LocalContext::HilightNextDetected (const Handle(V3d_View)& theView,
1344 const Standard_Boolean theToRedrawImmediate)
1346 // go to the next owner
1347 if (myDetectedSeq.IsEmpty())
1352 const Standard_Integer aLen = myDetectedSeq.Length();
1353 if (++myCurDetected > aLen)
1357 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1358 if (anOwner.IsNull())
1362 manageDetected (anOwner, theView, theToRedrawImmediate);
1363 return myCurDetected;
1366 //=======================================================================
1367 //function : HilightPreviousDetected
1369 //=======================================================================
1370 Standard_Integer AIS_LocalContext::HilightPreviousDetected (const Handle(V3d_View)& theView,
1371 const Standard_Boolean theToRedrawImmediate)
1373 if (myDetectedSeq.IsEmpty())
1378 const Standard_Integer aLen = myDetectedSeq.Length();
1379 if (--myCurDetected < 1)
1381 myCurDetected = aLen;
1383 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1384 if (anOwner.IsNull())
1389 manageDetected (anOwner, theView, theToRedrawImmediate);
1390 return myCurDetected;
1393 //=======================================================================
1394 //function : UnhilightLastDetected
1396 //=======================================================================
1397 Standard_Boolean AIS_LocalContext::UnhilightLastDetected (const Handle(V3d_View)& theView)
1399 if (!IsValidIndex (mylastindex))
1401 return Standard_False;
1404 myMainPM->BeginImmediateDraw();
1405 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (mylastindex);
1406 const Standard_Integer aHilightMode = anOwner->HasSelectable()
1407 ? GetHiMod (Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable()))
1410 myMapOfOwner->FindKey (mylastindex)->Unhilight (myMainPM, aHilightMode);
1411 myMainPM->EndImmediateDraw (theView->Viewer());
1413 return Standard_True;
1416 //=======================================================================
1417 //function : FindSelectedOwnerFromIO
1418 //purpose : it is checked if one of the selected owners really presents IObj
1419 //=======================================================================
1420 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromIO (const Handle(AIS_InteractiveObject)& theObj) const
1422 Handle(SelectMgr_EntityOwner) EO,bid;
1424 || mySelection.IsNull())
1426 return Handle(SelectMgr_EntityOwner)();
1429 for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
1431 if (!aSelIter.Value()->IsSameSelectable (theObj))
1436 Handle(StdSelect_BRepOwner) aBROwner = Handle(StdSelect_BRepOwner)::DownCast(aSelIter.Value());
1437 if (aBROwner.IsNull()
1438 || !aBROwner->ComesFromDecomposition())
1440 return aSelIter.Value();
1443 return Handle(SelectMgr_EntityOwner)();
1446 //=======================================================================
1447 //function : FindSelectedOwnerFromShape
1448 //purpose : it is checked if one of the selected owners really presents IObj
1449 //=======================================================================
1450 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromShape(const TopoDS_Shape& sh) const
1452 Handle(SelectMgr_EntityOwner) EO, bid;
1453 if (sh.IsNull()) return EO;
1455 if(mySelection.IsNull()) {
1459 Standard_Boolean found(Standard_False);
1462 NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
1463 myMainVS->ActiveOwners (anActiveOwners);
1464 for (NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (anActiveOwners); anOwnersIt.More(); anOwnersIt.Next())
1466 EO = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value());
1467 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1468 if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) {
1469 found = Standard_True;
1475 if(found) return EO;
1479 //=======================================================================
1480 //function : AIS_LocalContext::InitDetected
1482 //=======================================================================
1483 void AIS_LocalContext::InitDetected()
1485 myAISCurDetected = myAISDetectedSeq.Length()? 1 : 0;
1488 //=======================================================================
1489 //function : AIS_LocalContext::MoreDetected
1491 //=======================================================================
1492 Standard_Boolean AIS_LocalContext::MoreDetected() const
1494 return (myAISCurDetected > 0 && myAISCurDetected <= myAISDetectedSeq.Length());
1497 //=======================================================================
1498 //function : AIS_LocalContext::NextDetected
1500 //=======================================================================
1501 void AIS_LocalContext::NextDetected()
1506 //=======================================================================
1507 //function : DetectedCurrentShape
1509 //=======================================================================
1510 const TopoDS_Shape& AIS_LocalContext::DetectedCurrentShape() const
1512 Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
1514 if (aCurrentShape.IsNull())
1516 return AIS_myDummyShape;
1519 return aCurrentShape->Shape();
1521 //=======================================================================
1522 //function : DetectedCurrentObject
1524 //=======================================================================
1525 Handle(AIS_InteractiveObject) AIS_LocalContext::DetectedCurrentObject() const
1527 return MoreDetected() ? myAISDetectedSeq(myAISCurDetected) : NULL;
1530 //=======================================================================
1531 //function : RestoreActivatedModes
1533 //=======================================================================
1534 void AIS_LocalContext::RestoreActivatedModes() const
1536 for (AIS_DataMapOfSelStat::Iterator anIter (myActiveObjects); anIter.More(); anIter.Next())
1538 const TColStd_ListOfInteger& anActivatedModes = anIter.Value()->SelectionModes();
1539 for (TColStd_ListIteratorOfListOfInteger aModesIter (anActivatedModes); aModesIter.More(); aModesIter.Next())
1541 mySM->Activate (anIter.Key(), aModesIter.Value(), myMainVS);