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_LocalContext.jxx>
22 #include <StdSelect_BRepOwner.hxx>
23 #include <TColStd_ListOfInteger.hxx>
24 #include <TColStd_ListIteratorOfListOfInteger.hxx>
25 #include <TColStd_MapOfTransient.hxx>
26 #include <TColStd_MapIteratorOfMapOfTransient.hxx>
27 #include <Prs3d_Presentation.hxx>
28 #include <Prs3d_Drawer.hxx>
29 #include <Prs3d_ShadingAspect.hxx>
30 #include <AIS_LocalStatus.hxx>
31 #include <Graphic3d_ArrayOfTriangles.hxx>
32 #include <Graphic3d_Group.hxx>
33 #include <Select3D_SensitiveTriangulation.hxx>
34 #include <StdSelect_ViewerSelector3d.hxx>
35 #include <SelectBasics_SensitiveEntity.hxx>
36 #include <TCollection_AsciiString.hxx>
37 #include <NCollection_Map.hxx>
38 #include <Visual3d_View.hxx>
40 #include <SelectMgr_Selection.hxx>
41 #include <SelectMgr_SequenceOfOwner.hxx>
42 #include <OSD_Environment.hxx>
44 #include <Geom_Transformation.hxx>
45 #include <AIS_Selection.hxx>
46 #include <Aspect_Grid.hxx>
47 #include <AIS_Shape.hxx>
48 #include <AIS_InteractiveObject.hxx>
49 #include <SelectMgr_EntityOwner.hxx>
51 static Standard_Integer GetHiMod(const Handle(AIS_InteractiveObject)& IO)
53 return IO->HasHilightMode() ? IO->HilightMode():0;
56 //==================================================
59 //==================================================
60 AIS_StatusOfDetection AIS_LocalContext::MoveTo (const Standard_Integer theXpix,
61 const Standard_Integer theYpix,
62 const Handle(V3d_View)& theView,
63 const Standard_Boolean theToRedrawImmediate)
65 // check that ViewerSelector gives
66 if (theView->Viewer() != myCTX->CurrentViewer())
72 myAISDetectedSeq.Clear();
75 myDetectedSeq.Clear();
76 myFilters->SetDisabledObjects (theView->View()->HiddenObjects());
77 myMainVS->Pick (theXpix, theYpix, theView);
79 const Standard_Integer aDetectedNb = myMainVS->NbPicked();
80 for (Standard_Integer aDetIter = 1; aDetIter <= aDetectedNb; ++aDetIter)
82 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (aDetIter);
84 || !myFilters->IsOk (anOwner))
89 myDetectedSeq.Append (aDetIter); // normally they are already arranged in correct order...
90 Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
93 myAISDetectedSeq.Append (anObj);
97 // result of courses..
98 if (aDetectedNb == 0 || myDetectedSeq.IsEmpty())
100 if (mylastindex != 0 && mylastindex <= myMapOfOwner->Extent())
102 myMainPM->ClearImmediateDraw();
103 Unhilight (myMapOfOwner->FindKey (mylastindex), theView);
104 if (theToRedrawImmediate)
106 theView->RedrawImmediate();
111 return aDetectedNb == 0
116 // all owners detected by the selector are passed to the
117 // filters and correct ones are preserved...
119 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
120 manageDetected (anOwner, theView, theToRedrawImmediate);
121 if (myDetectedSeq.Length() == 1)
123 return aDetectedNb == 1
124 ? AIS_SOD_OnlyOneDetected
125 : AIS_SOD_OnlyOneGood;
129 return AIS_SOD_SeveralGood;
133 //=======================================================================
136 //=======================================================================
137 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Boolean toUpdateViewer)
141 UnhilightPicked (Standard_False);
144 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
146 Standard_Integer aDetIndex = DetectedIndex();
149 ClearSelected (toUpdateViewer);
150 return (AIS_Selection::Extent() == 0) ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
153 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex);
155 ClearSelected (Standard_False);
157 if (!anOwner->IsSelected()) // anOwner is not selected
159 anOwner->SetSelected (Standard_True);
160 AIS_Selection::Select (anOwner);
165 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
166 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
168 Unhilight (anOwner, aViewer->ActiveView());
171 // advanced selection highlighting mechanism
172 if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
174 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
175 UpdateSelected (anIO, Standard_False);
180 myCTX->CurrentViewer()->Update();
184 return (AIS_Selection::Extent() == 1) ? AIS_SOP_OneSelected : AIS_SOP_SeveralSelected;
187 //=======================================================================
190 //=======================================================================
191 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Integer theXPMin,
192 const Standard_Integer theYPMin,
193 const Standard_Integer theXPMax,
194 const Standard_Integer theYPMax,
195 const Handle(V3d_View)& theView,
196 const Standard_Boolean toUpdateViewer)
198 if (theView->Viewer() == myCTX->CurrentViewer())
200 myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
203 UnhilightPicked (Standard_False);
206 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
207 Standard_Integer aSelNum = AIS_Selection::Extent();
210 if (!myMainVS->More())
212 ClearSelected (toUpdateViewer);
214 return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
217 ClearSelected (Standard_False);
219 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
221 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
222 if (myFilters->IsOk (anOwner))
224 // it can be helpful to classify this owner immediately...
225 if (!anOwner->IsSelected())
227 anOwner->SetSelected (Standard_True);
228 AIS_Selection::Select (anOwner);
235 HilightPicked (toUpdateViewer);
239 Standard_Integer aSelNum = AIS_Selection::Extent();
241 return (aSelNum == 1) ? AIS_SOP_OneSelected
242 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
246 //==================================================
248 // Purpose : Selection by polyline
249 //==================================================
250 AIS_StatusOfPick AIS_LocalContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
251 const Handle(V3d_View)& theView,
252 const Standard_Boolean toUpdateViewer)
254 if (theView->Viewer() == myCTX->CurrentViewer())
256 myMainVS->Pick (thePolyline, theView);
258 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
260 Standard_Integer aLastSelNum = AIS_Selection::Extent();
262 if (!myMainVS->More())
264 // Nothing is selected clear selection.
265 ClearSelected (toUpdateViewer);
268 // Return state to know if something was unselected
269 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
274 UnhilightPicked (Standard_False);
277 // Clear previous selection without update to process this selection
278 ClearSelected (Standard_False);
280 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
282 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
283 if (myFilters->IsOk (anOwner))
285 // it can be helpful to classify this owner immediately...
286 if (!anOwner->IsSelected())
288 AIS_Selection::AddSelect (anOwner);
289 anOwner->SetSelected (Standard_True);
296 HilightPicked (toUpdateViewer);
300 Standard_Integer aSelNum = AIS_Selection::Extent();
301 return (aSelNum == 1) ? AIS_SOP_OneSelected
302 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
306 //=======================================================================
307 //function : ShiftSelect
309 //=======================================================================
310 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Boolean toUpdateViewer)
312 Standard_Integer aDetIndex = DetectedIndex();
313 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
317 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
318 Standard_Integer aSelNum = AIS_Selection::Extent();
319 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex);
320 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
321 AIS_Selection::Select (anOwner);
322 anOwner->SetSelected (toSelect);
326 myMainPM->ClearImmediateDraw();
327 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
328 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
330 Unhilight (anOwner, aViewer->ActiveView());
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 = AIS_Selection::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 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
372 Standard_Integer aLastSelNum = AIS_Selection::Extent();
375 if (!myMainVS->More())
377 // Nothing is selected clear selection, but don't clear the selection
378 // as it is shift selection and previous selection matters.
379 // Return state to know if something was unselected
380 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
385 UnhilightPicked (Standard_False);
388 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
390 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
391 if(myFilters->IsOk (anOwner))
393 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
394 AIS_Selection::Select (anOwner);
395 anOwner->SetSelected (toSelect);
401 HilightPicked (toUpdateViewer);
405 Standard_Integer aSelNum = AIS_Selection::Extent();
407 return (aSelNum == 1) ? AIS_SOP_OneSelected
408 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
412 //==================================================
414 // Purpose : Selection by polyline
415 //==================================================
416 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
417 const Handle(V3d_View)& theView,
418 const Standard_Boolean toUpdateViewer)
420 if (theView->Viewer() == myCTX->CurrentViewer())
422 myMainVS->Pick (thePolyline, theView);
424 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
426 Standard_Integer aLastSelNum = AIS_Selection::Extent();
428 if(!myMainVS->More())
430 // Nothing is selected clear selection, but don't clear the selection
431 // as it is shift selection and previous selection matters.
432 // Return state to know if something was unselected
433 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
438 UnhilightPicked (Standard_False);
441 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
443 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
444 if (myFilters->IsOk (anOwner))
446 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
447 AIS_Selection::Select (anOwner);
448 anOwner->SetSelected (toSelect);
453 HilightPicked (toUpdateViewer);
457 Standard_Integer aSelNum = AIS_Selection::Extent();
459 return (aSelNum == 1) ? AIS_SOP_OneSelected
460 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
464 //==================================================
467 //==================================================
468 void AIS_LocalContext::Hilight (const Handle(SelectMgr_EntityOwner)& theOwner,
469 const Handle(V3d_View)& theView)
471 if (theView.IsNull())
476 const Standard_Integer aHilightMode = GetHiMod (Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable()));
477 myMainPM->BeginImmediateDraw();
478 theOwner->HilightWithColor (myMainPM, myCTX->HilightColor(), aHilightMode);
479 myMainPM->EndImmediateDraw (theView);
482 //==================================================
483 // Function: Unhilight
485 //==================================================
486 void AIS_LocalContext::Unhilight (const Handle(SelectMgr_EntityOwner)& theOwner,
487 const Handle(V3d_View)& theView)
489 if (theView.IsNull())
494 const Standard_Integer aHilightMode = GetHiMod (Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable()));
495 if (IsSelected (theOwner))
497 if (theOwner->IsAutoHilight())
499 theOwner->HilightWithColor (myMainPM, myCTX->SelectionColor(), aHilightMode);
504 theOwner->Unhilight (myMainPM, aHilightMode);
508 //=======================================================================
509 //function : HilightPicked
511 //=======================================================================
512 void AIS_LocalContext::HilightPicked(const Standard_Boolean updateviewer)
514 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
515 if( Sel.IsNull() ) return;
517 typedef NCollection_DataMap <Handle(SelectMgr_SelectableObject), NCollection_Handle<SelectMgr_SequenceOfOwner> > SelectMgr_DataMapOfObjectOwners;
518 SelectMgr_DataMapOfObjectOwners aMap;
520 Handle (PrsMgr_PresentationManager3d) PM = myMainPM;
522 // to avoid problems when there is a loop searching for selected objects...
523 const AIS_NListTransient& Obj = Sel->Objects();
524 AIS_NListTransient::Iterator anIter( Obj );
525 for(; anIter.More(); anIter.Next())
527 const Handle(Standard_Transient)& Tr = anIter.Value();
529 const Handle(SelectMgr_EntityOwner)& Ownr =
530 *((const Handle(SelectMgr_EntityOwner)*) &Tr);
531 Handle(AIS_InteractiveObject) IO;
532 if(Ownr->HasSelectable()){
533 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(Ownr);
534 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
535 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
536 IO = Handle(AIS_InteractiveObject)::DownCast (SO);
539 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
540 Standard_Integer HM = GetHiMod(Handle(AIS_InteractiveObject)::DownCast (SO));
541 if ( Ownr->IsAutoHilight() )
542 Ownr->HilightWithColor(PM,myCTX->SelectionColor(),HM);
543 else if ( aMap.IsBound (SO) )
544 aMap(SO)->Append ( Ownr );
546 NCollection_Handle<SelectMgr_SequenceOfOwner> aSeq = new SelectMgr_SequenceOfOwner;
547 aSeq->Append ( Ownr );
548 aMap.Bind ( SO, aSeq );
553 for ( SelectMgr_DataMapOfObjectOwners::Iterator aMapIter(aMap);
554 aMapIter.More(); aMapIter.Next() )
556 aMapIter.Key()->HilightSelected (myMainPM, *aMapIter.Value());
561 myCTX->CurrentViewer()->Update();
565 //==================================================
568 //==================================================
569 void AIS_LocalContext::UnhilightPicked (const Standard_Boolean updateviewer)
571 myMainPM->ClearImmediateDraw();
573 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
574 if( Sel.IsNull() ) return;
575 Handle (PrsMgr_PresentationManager3d) PM = myMainPM;
576 NCollection_Map<Handle(SelectMgr_SelectableObject)> anObjMap;
578 const AIS_NListTransient& Obj = Sel->Objects();
579 AIS_NListTransient::Iterator anIter( Obj );
580 for(; anIter.More(); anIter.Next()){
581 const Handle(Standard_Transient)& Tr = anIter.Value();
583 const Handle(SelectMgr_EntityOwner)& Ownr =
584 *((const Handle(SelectMgr_EntityOwner)*) &Tr);
585 Standard_Integer HM(0);
586 if(Ownr->HasSelectable()){
587 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
588 Handle(AIS_InteractiveObject) IO = Handle(AIS_InteractiveObject)::DownCast (SO);
592 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(Ownr);
593 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
596 Ownr->Unhilight(PM,HM);
600 for (NCollection_Map<Handle(SelectMgr_SelectableObject)>::Iterator anIter1 ( anObjMap );
601 anIter1.More(); anIter1.Next() )
603 if ( !anIter1.Key()->IsAutoHilight() )
604 anIter1.Key()->ClearSelected();
608 myCTX->CurrentViewer()->Update();
611 //=======================================================================
612 //function : IsSelected
614 //=======================================================================
615 Standard_Boolean AIS_LocalContext::IsSelected(const Handle(AIS_InteractiveObject)& anIObj) const
617 return (!FindSelectedOwnerFromIO(anIObj).IsNull());
620 //=======================================================================
621 //function : IsSelected
623 //=======================================================================
625 Standard_Boolean AIS_LocalContext::IsSelected (const Handle(SelectMgr_EntityOwner)& theOwner) const
627 return !theOwner.IsNull() && theOwner->IsSelected();
630 //==================================================
633 //==================================================
634 void AIS_LocalContext::
637 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
638 AIS_Selection::CurrentSelection()->Init();
641 //==================================================
644 //==================================================
645 Standard_Boolean AIS_LocalContext::
648 return AIS_Selection::CurrentSelection()->More();
651 //==================================================
654 //==================================================
655 void AIS_LocalContext::
658 AIS_Selection::CurrentSelection()->Next();
661 //==================================================
664 //==================================================
665 Standard_Boolean AIS_LocalContext::
668 Handle(Standard_Transient) Tr = AIS_Selection::CurrentSelection()->Value();
669 if( Tr.IsNull() ) return Standard_False;
670 Handle(SelectMgr_EntityOwner) EO = Handle(SelectMgr_EntityOwner)::DownCast (Tr);
671 Handle(StdSelect_BRepOwner) BRO = Handle(StdSelect_BRepOwner)::DownCast(EO);
672 if(BRO.IsNull()) return Standard_False;
673 Standard_Boolean hasshape = BRO->HasShape();
674 Standard_Boolean comes = BRO->ComesFromDecomposition();
675 return (hasshape&&comes);
678 //================================================================
679 // Function : HasSelectedShape
680 // Purpose : Checks if there is a selected shape regardless of its decomposition status
681 //================================================================
682 Standard_Boolean AIS_LocalContext::HasSelectedShape() const
684 if (AIS_Selection::CurrentSelection()->Extent() == 0)
685 return Standard_False;
687 Handle(Standard_Transient) aCurSelection = AIS_Selection::CurrentSelection()->Value();
688 if (aCurSelection.IsNull())
689 return Standard_False;
691 Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aCurSelection);
692 Handle(StdSelect_BRepOwner) aBrepOwner = Handle(StdSelect_BRepOwner)::DownCast (anOwner);
693 if (aBrepOwner.IsNull())
695 return Standard_False;
697 return aBrepOwner->HasShape();
700 //==================================================
703 //==================================================
704 TopoDS_Shape AIS_LocalContext::SelectedShape() const
706 Handle(Standard_Transient) aTr = AIS_Selection::CurrentSelection()->Value();
707 Handle(SelectMgr_EntityOwner) anEO = Handle(SelectMgr_EntityOwner)::DownCast (aTr);
708 Handle(StdSelect_BRepOwner) aBRO = Handle(StdSelect_BRepOwner)::DownCast(anEO);
711 return TopoDS_Shape();
714 return aBRO->Shape().Located (aBRO->Location() * aBRO->Shape().Location());
717 //==================================================
720 //==================================================
721 Handle(AIS_InteractiveObject) AIS_LocalContext::
722 SelectedInteractive() const
724 Handle(AIS_InteractiveObject) IO;
725 Handle(Standard_Transient) Tr = AIS_Selection::CurrentSelection()->Value();
727 Handle(SelectMgr_EntityOwner) EO = Handle(SelectMgr_EntityOwner)::DownCast (Tr);
728 Handle(SelectMgr_SelectableObject) SO;
729 if(EO->HasSelectable()){
730 SO = EO->Selectable();
731 IO = Handle(AIS_InteractiveObject)::DownCast (SO);
736 //==================================================
739 //==================================================
740 Handle(SelectMgr_EntityOwner) AIS_LocalContext::
741 SelectedOwner() const
743 Handle(SelectMgr_EntityOwner) EO;
744 Handle(Standard_Transient) Tr = AIS_Selection::CurrentSelection()->Value();
746 EO = Handle(SelectMgr_EntityOwner)::DownCast (Tr);
750 //==================================================
753 //==================================================
754 Standard_Boolean AIS_LocalContext::
755 HasApplicative() const
757 Handle(AIS_InteractiveObject) IO = SelectedInteractive();
758 if( IO.IsNull() ) return Standard_False;
759 return IO->HasOwner();
762 //==================================================
765 //==================================================
766 const Handle(Standard_Transient)& AIS_LocalContext::
767 SelectedApplicative() const
769 return SelectedInteractive()->GetOwner();
774 //=======================================================================
775 //function : UpdateSelection
776 //purpose : should disappear...
777 //=======================================================================
778 void AIS_LocalContext::UpdateSelected(const Standard_Boolean updateviewer)
780 UnhilightPicked(Standard_False);
781 HilightPicked(updateviewer);
784 //================================================================
785 // Function : UpdateSelected
786 // Purpose : Part of advanced selection mechanism.
787 // Highlightes or clears selection presentation for the given IO
788 //================================================================
789 void AIS_LocalContext::UpdateSelected(const Handle(AIS_InteractiveObject)& anobj,
790 const Standard_Boolean updateviewer)
792 if (anobj.IsNull() || anobj->IsAutoHilight())
795 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
796 Handle(AIS_Selection) Sel = AIS_Selection::CurrentSelection();
798 SelectMgr_SequenceOfOwner aSeq;
799 for ( Sel->Init(); Sel->More(); Sel->Next() ){
800 Handle(SelectMgr_EntityOwner) aOwner = Handle(SelectMgr_EntityOwner)::DownCast(Sel->Value());
802 if ( !aOwner.IsNull() && aOwner->HasSelectable() && aOwner->Selectable() == anobj )
803 aSeq.Append( aOwner );
807 anobj->HilightSelected( myMainPM, aSeq );
809 anobj->ClearSelected();
812 myCTX->CurrentViewer()->Update();
816 //==================================================
817 // Function: ClearSelected
819 //==================================================
820 void AIS_LocalContext::ClearSelected (const Standard_Boolean updateviewer)
822 UnhilightPicked(updateviewer);
823 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
825 Handle(AIS_Selection) Sel = AIS_Selection::CurrentSelection();
826 const AIS_NListTransient& Obj = Sel->Objects();
827 AIS_NListTransient::Iterator anIter( Obj );
828 for(; anIter.More(); anIter.Next()){
829 const Handle(Standard_Transient)& Tr = anIter.Value();
832 (*((const Handle(SelectMgr_EntityOwner)*)&Tr))->SetSelected (Standard_False);
835 AIS_Selection::Select();
839 //==================================================
840 // Function: ClearOutdatedSelection
842 //==================================================
843 void AIS_LocalContext::ClearOutdatedSelection (const Handle(AIS_InteractiveObject)& theIO,
844 const Standard_Boolean toClearDeactivated)
846 // 1. Collect selectable entities
847 SelectMgr_IndexedMapOfOwner aValidOwners;
849 const TColStd_ListOfInteger& aModes = SelectionModes (theIO);
851 TColStd_ListIteratorOfListOfInteger aModeIter (aModes);
852 for (; aModeIter.More(); aModeIter.Next())
854 int aMode = aModeIter.Value();
855 if (!theIO->HasSelection(aMode))
860 if (toClearDeactivated && !mySM->IsActivated(theIO, aMode, myMainVS))
865 Handle(SelectMgr_Selection) aSelection = theIO->Selection(aMode);
866 for (aSelection->Init(); aSelection->More(); aSelection->Next())
868 Handle(SelectBasics_SensitiveEntity) anEntity = aSelection->Sensitive()->BaseSensitive();
869 if (anEntity.IsNull())
874 Handle(SelectMgr_EntityOwner) anOwner =
875 Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId());
877 if (anOwner.IsNull())
882 aValidOwners.Add(anOwner);
886 // 2. Refresh context's detection and selection and keep only active owners
887 // Keep last detected object for lastindex initialization.
888 Handle(SelectMgr_EntityOwner) aLastPicked = myMainVS->OnePicked();
890 // Remove entity owners from detected sequences
891 for (Standard_Integer anIdx = 1; anIdx <= myDetectedSeq.Length(); ++anIdx)
893 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (anIdx));
894 if (anOwner.IsNull() || anOwner->Selectable() != theIO || aValidOwners.Contains (anOwner))
899 myDetectedSeq.Remove (anIdx--);
901 if (anIdx < myCurDetected)
906 myCurDetected = Max (myCurDetected, 1);
908 Standard_Boolean isAISRemainsDetected = Standard_False;
910 // 3. AIS_Selection : remove entity owners from AIS_Selection
911 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
912 Handle(AIS_Selection) aSelection = AIS_Selection::Selection (mySelName.ToCString());
913 AIS_NListTransient::Iterator anIter (aSelection->Objects());
914 AIS_NListTransient aRemoveEntites;
915 for (; anIter.More(); anIter.Next())
917 Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anIter.Value());
918 if (anOwner.IsNull() || anOwner->Selectable() != theIO)
923 if (aValidOwners.Contains (anOwner))
925 isAISRemainsDetected = Standard_True;
929 aRemoveEntites.Append (anOwner);
930 anOwner->SetSelected (Standard_False);
931 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
933 Unhilight (anOwner, aViewer->ActiveView());
937 AIS_NListTransient::Iterator anIterRemove (aRemoveEntites);
938 for (; anIterRemove.More(); anIterRemove.Next())
940 aSelection->Select (anIterRemove.Value());
943 // 4. AIS_LocalContext - myMapOfOwner : remove entity owners from myMapOfOwner
944 SelectMgr_IndexedMapOfOwner anOwnersToKeep;
945 for (Standard_Integer anIdx = 1; anIdx <= myMapOfOwner->Extent(); anIdx++)
947 Handle(SelectMgr_EntityOwner) anOwner = myMapOfOwner->FindKey (anIdx);
948 if (anOwner.IsNull())
953 if (anOwner->Selectable() != theIO || aValidOwners.Contains (anOwner))
955 anOwnersToKeep.Add (anOwner);
959 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
961 Unhilight (anOwner, aViewer->ActiveView());
965 myMapOfOwner->Clear();
966 myMapOfOwner->Assign (anOwnersToKeep);
967 mylastindex = myMapOfOwner->FindIndex (aLastPicked);
968 if (!IsValidIndex (mylastindex))
970 myMainPM->ClearImmediateDraw();
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(AIS_Selection) sel = AIS_Selection::Selection(mySelName.ToCString());
1009 //Standard_Boolean found(Standard_False);
1010 Handle(Standard_Transient) Tr;
1011 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromIO(anIObj);
1013 //check if in selection number 0 there is an owner that can be triturated...
1014 if(anIObj->HasSelection(0)){
1015 const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0);
1018 Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->BaseSensitive()->OwnerId();
1019 EO = Handle(SelectMgr_EntityOwner)::DownCast (BO);
1023 EO = new SelectMgr_EntityOwner(anIObj);
1026 ClearSelected(Standard_False);
1028 AIS_Selection::Select(EO);
1029 EO->SetSelected (Standard_True);
1031 HilightPicked(updateviewer);
1034 //=======================================================================
1035 //function : AddOrRemoveSelected
1037 //=======================================================================
1039 void AIS_LocalContext::AddOrRemoveSelected(const Handle(AIS_InteractiveObject)& anIObj,
1040 const Standard_Boolean updateviewer)
1042 if(!IsValidForSelection(anIObj)) return;
1043 UnhilightPicked(Standard_False);
1044 // first check if it is selected...
1045 Handle(SelectMgr_EntityOwner) EO;
1047 EO = FindSelectedOwnerFromIO(anIObj);
1051 if(anIObj->HasSelection(0))
1053 const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0);
1056 Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->BaseSensitive()->OwnerId();
1057 EO = Handle(SelectMgr_EntityOwner)::DownCast (BO);
1062 EO = new SelectMgr_EntityOwner(anIObj);
1066 // cout<<"AIS_LocalContext::AddOrRemoveSelected : Selection = "<<mySelName<<endl;
1067 const Handle(AIS_Selection)& S = AIS_Selection::Selection(mySelName.ToCString());
1071 AIS_SelectStatus aStatus = S->Select(EO);
1072 EO->SetSelected (aStatus == AIS_SS_Added);
1075 HilightPicked(updateviewer);
1078 //=======================================================================
1079 //function : AddOrRemoveSelected
1080 //purpose : To check...
1081 //=======================================================================
1082 void AIS_LocalContext::AddOrRemoveSelected(const TopoDS_Shape& Sh,
1083 const Standard_Boolean updateviewer)
1085 UnhilightPicked (Standard_False);
1086 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromShape(Sh);
1089 AIS_Selection::Selection(mySelName.ToCString())->Select(EO);
1090 EO->SetSelected (Standard_True);
1092 HilightPicked (updateviewer);
1095 void AIS_LocalContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
1096 const Standard_Boolean toUpdateViewer)
1100 UnhilightPicked (Standard_False);
1103 Standard_Boolean toSelect = theOwner->IsSelected() ? Standard_False : Standard_True;
1105 AIS_Selection::Selection (mySelName.ToCString())->Select (theOwner);
1106 theOwner->SetSelected (toSelect);
1110 HilightPicked (toUpdateViewer);
1114 //==================================================
1115 // Function: manageDetected
1117 //==================================================
1118 void AIS_LocalContext::manageDetected (const Handle(SelectMgr_EntityOwner)& thePickOwner,
1119 const Handle(V3d_View)& theView,
1120 const Standard_Boolean theToRedrawImmediate)
1122 if (thePickOwner.IsNull())
1124 myMainPM->ClearImmediateDraw();
1125 if (theToRedrawImmediate)
1127 theView->RedrawImmediate();
1132 if (!myFilters->IsOk (thePickOwner))
1134 if (mylastindex != 0)
1136 mylastgood = mylastindex;
1138 if (theToRedrawImmediate)
1140 theView->RedrawImmediate();
1145 //=======================================================================================================
1146 // 2 cases : a- object is in the map of picks:
1147 // 1. this is the same index as the last detected: -> Do nothing
1149 // - if lastindex = 0 (no object was detected at the last step)
1150 // the object presentation is highlighted and lastindex = index(objet)
1152 // the presentation of the object corresponding to lastindex is "unhighlighted"
1153 // it is removed if the object is not visualized but only active
1154 // then the presentation of the detected object is highlighted and lastindex = index(objet)
1155 // b- the object is not in the map of picked objects
1156 // - if lastindex != 0 (object detected at the last step) it is unhighlighted ...
1157 // if the object was decomposed, presentation is created for the detected shape and the couple
1158 // (Proprietaire,Prs)is added in the map.
1159 // otherwise the couple(proprietaire, NullPrs) is placed in the map and the interactive object
1160 // itself is highlighted.
1162 //=======================================================================================================
1164 const Standard_Integer aNewIndex = myMapOfOwner->Contains (thePickOwner)
1165 ? myMapOfOwner->FindIndex (thePickOwner)
1166 : myMapOfOwner->Add (thePickOwner);
1168 // For the advanced mesh selection mode the owner indices comparison
1169 // is not effective because in that case only one owner manage the
1170 // selection in current selection mode. It is necessary to check the current detected
1171 // entity and hilight it only if the detected entity is not the same as
1172 // previous detected (IsForcedHilight call)
1173 if (aNewIndex != mylastindex
1174 || thePickOwner->IsForcedHilight())
1176 myMainPM->ClearImmediateDraw();
1177 if (mylastindex != 0
1178 && mylastindex <= myMapOfOwner->Extent())
1180 const Handle(SelectMgr_EntityOwner)& aLastOwner = myMapOfOwner->FindKey (mylastindex);
1181 Unhilight (aLastOwner, theView);
1186 if (!thePickOwner->IsSelected() || myCTX->ToHilightSelected())
1188 Hilight (thePickOwner, theView);
1190 if (theToRedrawImmediate)
1192 theView->RedrawImmediate();
1196 mylastindex = aNewIndex;
1199 if (mylastindex != 0)
1201 mylastgood = mylastindex;
1205 //=======================================================================
1206 //function : HasDetectedShape
1208 //=======================================================================
1210 Standard_Boolean AIS_LocalContext::HasDetectedShape() const
1212 if(mylastindex==0) return Standard_False;
1213 return IsShape(mylastindex);
1216 //=======================================================================
1217 //function : DetectedShape
1219 //=======================================================================
1222 AIS_LocalContext::DetectedShape() const
1224 static TopoDS_Shape bidsh;
1225 if(mylastindex != 0)
1227 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner->FindKey (mylastindex));
1228 if(BROwnr.IsNull()) return bidsh;
1229 return BROwnr->Shape();
1234 //=======================================================================
1235 //function : DetectedInteractive
1237 //=======================================================================
1239 Handle(AIS_InteractiveObject)
1240 AIS_LocalContext::DetectedInteractive() const
1242 Handle(AIS_InteractiveObject) Iobj;
1243 if(IsValidIndex(mylastindex)){
1244 Handle(SelectMgr_SelectableObject) SO = myMapOfOwner->FindKey(mylastindex)->Selectable();
1245 Iobj = Handle(AIS_InteractiveObject)::DownCast (SO);
1249 //=======================================================================
1250 //function : DetectedInteractive
1252 //=======================================================================
1253 Handle(SelectMgr_EntityOwner) AIS_LocalContext::DetectedOwner() const
1255 Handle(SelectMgr_EntityOwner) bid;
1256 if(!IsValidIndex(mylastindex)) return bid;
1257 return myMapOfOwner->FindKey(mylastindex);
1261 //=======================================================================
1262 //function : ComesFromDecomposition
1264 //=======================================================================
1266 Standard_Boolean AIS_LocalContext::ComesFromDecomposition(const Standard_Integer PickedIndex) const
1268 const Handle(SelectMgr_EntityOwner)& OWN = myMapOfOwner->FindKey(PickedIndex);
1269 Handle(SelectMgr_SelectableObject) aSel = OWN->Selectable();
1270 if (myActiveObjects.IsBound (aSel)) { // debug of jmi
1271 const Handle(AIS_LocalStatus)& Stat = myActiveObjects(aSel);
1272 return Stat->Decomposed();
1274 return Standard_False;
1277 //=======================================================================
1278 //function : DisplaySensitive
1280 //=======================================================================
1282 void AIS_LocalContext::DisplaySensitive(const Handle(V3d_View)& aviou)
1284 myMainVS->DisplaySensitive(aviou);
1287 //=======================================================================
1288 //function : ClearSensitive
1290 //=======================================================================
1292 void AIS_LocalContext::ClearSensitive(const Handle(V3d_View)& aviou)
1294 myMainVS->ClearSensitive(aviou);
1298 //=======================================================================
1299 //function : IsShape
1301 //=======================================================================
1302 Standard_Boolean AIS_LocalContext::IsShape(const Standard_Integer Index) const
1305 if(Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner->FindKey(Index)).IsNull())
1306 return Standard_False;
1308 ComesFromDecomposition(Index);
1311 Standard_Boolean AIS_LocalContext::IsValidForSelection(const Handle(AIS_InteractiveObject)& anIObj) const
1314 // Shape was not transfered from AIS_Shape to EntityOwner
1315 Handle(AIS_Shape) shape = Handle(AIS_Shape)::DownCast(anIObj);
1316 if( !shape.IsNull() )
1317 return myFilters->IsOk(new StdSelect_BRepOwner(shape->Shape(),shape));
1318 return myFilters->IsOk(new SelectMgr_EntityOwner(anIObj));
1322 //=======================================================================
1323 //function : HilightNextDetected
1325 //=======================================================================
1326 Standard_Integer AIS_LocalContext::HilightNextDetected (const Handle(V3d_View)& theView,
1327 const Standard_Boolean theToRedrawImmediate)
1329 // go to the next owner
1330 if (myDetectedSeq.IsEmpty())
1335 const Standard_Integer aLen = myDetectedSeq.Length();
1336 if (++myCurDetected > aLen)
1340 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1341 if (anOwner.IsNull())
1345 manageDetected (anOwner, theView, theToRedrawImmediate);
1346 return myCurDetected;
1349 //=======================================================================
1350 //function : HilightPreviousDetected
1352 //=======================================================================
1353 Standard_Integer AIS_LocalContext::HilightPreviousDetected (const Handle(V3d_View)& theView,
1354 const Standard_Boolean theToRedrawImmediate)
1356 if (myDetectedSeq.IsEmpty())
1361 const Standard_Integer aLen = myDetectedSeq.Length();
1362 if (--myCurDetected < 1)
1364 myCurDetected = aLen;
1366 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1367 if (anOwner.IsNull())
1372 manageDetected (anOwner, theView, theToRedrawImmediate);
1373 return myCurDetected;
1376 //=======================================================================
1377 //function : UnhilightLastDetected
1379 //=======================================================================
1380 Standard_Boolean AIS_LocalContext::UnhilightLastDetected (const Handle(V3d_View)& theView)
1382 if (!IsValidIndex (mylastindex))
1384 return Standard_False;
1387 myMainPM->BeginImmediateDraw();
1388 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (mylastindex);
1389 const Standard_Integer aHilightMode = anOwner->HasSelectable()
1390 ? GetHiMod (Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable()))
1393 myMapOfOwner->FindKey (mylastindex)->Unhilight (myMainPM, aHilightMode);
1394 myMainPM->EndImmediateDraw (theView);
1396 return Standard_True;
1399 //=======================================================================
1400 //function : FindSelectedOwnerFromIO
1401 //purpose : it is checked if one of the selected owners really presents IObj
1402 //=======================================================================
1403 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromIO
1404 (const Handle(AIS_InteractiveObject)& anIObj) const
1406 Handle(SelectMgr_EntityOwner) EO,bid;
1407 if (anIObj.IsNull()) return EO;
1409 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
1412 cout<<"\t\tAIS_LocalCOntext::FindSelectedOwnerFromShape : Selection "
1413 <<mySelName<<" Nulle "<<endl;
1417 Standard_Boolean found(Standard_False);
1418 const AIS_NListTransient& Obj = Sel->Objects();
1419 AIS_NListTransient::Iterator anIter( Obj );
1420 for(; anIter.More(); anIter.Next()){
1421 const Handle(Standard_Transient)& Tr = anIter.Value();
1423 EO = Handle(SelectMgr_EntityOwner)::DownCast (Tr);
1424 if(EO->HasSelectable()){
1425 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1426 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
1427 if (anIObj == EO->Selectable()){
1428 found =Standard_True;
1435 if(found) return EO;
1439 //=======================================================================
1440 //function : FindSelectedOwnerFromShape
1441 //purpose : it is checked if one of the selected owners really presents IObj
1442 //=======================================================================
1443 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromShape(const TopoDS_Shape& sh) const
1445 Handle(SelectMgr_EntityOwner) EO, bid;
1446 if (sh.IsNull()) return EO;
1448 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
1451 cout<<"\t\tAIS_LocalCOntext::FindSelectedOwnerFromShape : Selection "<<mySelName<<" Nulle "<<endl;
1456 Standard_Boolean found(Standard_False);
1459 NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
1460 myMainVS->ActiveOwners (anActiveOwners);
1461 for (NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (anActiveOwners); anOwnersIt.More(); anOwnersIt.Next())
1463 EO = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value());
1464 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1465 if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) {
1466 found = Standard_True;
1472 if(found) return EO;
1476 //=======================================================================
1477 //function : AIS_LocalContext::InitDetected
1479 //=======================================================================
1480 void AIS_LocalContext::InitDetected()
1482 myAISCurDetected = myAISDetectedSeq.Length()? 1 : 0;
1485 //=======================================================================
1486 //function : AIS_LocalContext::MoreDetected
1488 //=======================================================================
1489 Standard_Boolean AIS_LocalContext::MoreDetected() const
1491 return (myAISCurDetected > 0 && myAISCurDetected <= myAISDetectedSeq.Length());
1494 //=======================================================================
1495 //function : AIS_LocalContext::NextDetected
1497 //=======================================================================
1498 void AIS_LocalContext::NextDetected()
1503 //=======================================================================
1504 //function : DetectedCurrentShape
1506 //=======================================================================
1507 const TopoDS_Shape& AIS_LocalContext::DetectedCurrentShape() const
1509 static TopoDS_Shape aDummyShape;
1511 Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
1513 if (aCurrentShape.IsNull())
1518 return aCurrentShape->Shape();
1520 //=======================================================================
1521 //function : DetectedCurrentObject
1523 //=======================================================================
1524 Handle(AIS_InteractiveObject) AIS_LocalContext::DetectedCurrentObject() const
1526 return MoreDetected() ? myAISDetectedSeq(myAISCurDetected) : NULL;