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>
49 static Standard_Integer GetHiMod(const Handle(AIS_InteractiveObject)& IO)
51 return IO->HasHilightMode() ? IO->HilightMode():0;
54 //==================================================
57 //==================================================
58 AIS_StatusOfDetection AIS_LocalContext::MoveTo (const Standard_Integer theXpix,
59 const Standard_Integer theYpix,
60 const Handle(V3d_View)& theView,
61 const Standard_Boolean theToRedrawImmediate)
63 // check that ViewerSelector gives
64 if (theView->Viewer() != myCTX->CurrentViewer())
70 myAISDetectedSeq.Clear();
73 myDetectedSeq.Clear();
74 myFilters->SetDisabledObjects (theView->View()->HiddenObjects());
75 myMainVS->Pick (theXpix, theYpix, theView);
77 const Standard_Integer aDetectedNb = myMainVS->NbPicked();
78 for (Standard_Integer aDetIter = 1; aDetIter <= aDetectedNb; ++aDetIter)
80 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (aDetIter);
82 || !myFilters->IsOk (anOwner))
87 myDetectedSeq.Append (aDetIter); // normally they are already arranged in correct order...
88 Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
91 myAISDetectedSeq.Append (anObj);
95 // result of courses..
96 if (aDetectedNb == 0 || myDetectedSeq.IsEmpty())
98 if (mylastindex != 0 && mylastindex <= myMapOfOwner->Extent())
100 myMainPM->ClearImmediateDraw();
101 Unhilight (myMapOfOwner->FindKey (mylastindex), theView);
102 if (theToRedrawImmediate)
104 theView->RedrawImmediate();
109 return aDetectedNb == 0
114 // all owners detected by the selector are passed to the
115 // filters and correct ones are preserved...
117 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
118 manageDetected (anOwner, theView, theToRedrawImmediate);
119 if (myDetectedSeq.Length() == 1)
121 return aDetectedNb == 1
122 ? AIS_SOD_OnlyOneDetected
123 : AIS_SOD_OnlyOneGood;
127 return AIS_SOD_SeveralGood;
131 //=======================================================================
134 //=======================================================================
135 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Boolean toUpdateViewer)
139 UnhilightPicked (Standard_False);
142 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
144 Standard_Integer aDetIndex = DetectedIndex();
147 ClearSelected (toUpdateViewer);
148 return (AIS_Selection::Extent() == 0) ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
151 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex);
153 ClearSelected (Standard_False);
155 if (!anOwner->IsSelected()) // anOwner is not selected
157 anOwner->SetSelected (Standard_True);
158 AIS_Selection::Select (anOwner);
163 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
164 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
166 Unhilight (anOwner, aViewer->ActiveView());
169 // advanced selection highlighting mechanism
170 if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
172 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
173 UpdateSelected (anIO, Standard_False);
178 myCTX->CurrentViewer()->Update();
182 return (AIS_Selection::Extent() == 1) ? AIS_SOP_OneSelected : AIS_SOP_SeveralSelected;
185 //=======================================================================
188 //=======================================================================
189 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Integer theXPMin,
190 const Standard_Integer theYPMin,
191 const Standard_Integer theXPMax,
192 const Standard_Integer theYPMax,
193 const Handle(V3d_View)& theView,
194 const Standard_Boolean toUpdateViewer)
196 if (theView->Viewer() == myCTX->CurrentViewer())
198 myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
201 UnhilightPicked (Standard_False);
204 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
205 Standard_Integer aSelNum = AIS_Selection::Extent();
208 if (!myMainVS->More())
210 ClearSelected (toUpdateViewer);
212 return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
215 ClearSelected (Standard_False);
217 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
219 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
220 if (myFilters->IsOk (anOwner))
222 // it can be helpful to classify this owner immediately...
223 if (!anOwner->IsSelected())
225 anOwner->SetSelected (Standard_True);
226 AIS_Selection::Select (anOwner);
233 HilightPicked (toUpdateViewer);
237 Standard_Integer aSelNum = AIS_Selection::Extent();
239 return (aSelNum == 1) ? AIS_SOP_OneSelected
240 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
244 //==================================================
246 // Purpose : Selection by polyline
247 //==================================================
248 AIS_StatusOfPick AIS_LocalContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
249 const Handle(V3d_View)& theView,
250 const Standard_Boolean toUpdateViewer)
252 if (theView->Viewer() == myCTX->CurrentViewer())
254 myMainVS->Pick (thePolyline, theView);
256 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
258 Standard_Integer aLastSelNum = AIS_Selection::Extent();
260 if (!myMainVS->More())
262 // Nothing is selected clear selection.
263 ClearSelected (toUpdateViewer);
266 // Return state to know if something was unselected
267 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
272 UnhilightPicked (Standard_False);
275 // Clear previous selection without update to process this selection
276 ClearSelected (Standard_False);
278 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
280 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
281 if (myFilters->IsOk (anOwner))
283 // it can be helpful to classify this owner immediately...
284 if (!anOwner->IsSelected())
286 AIS_Selection::AddSelect (anOwner);
287 anOwner->SetSelected (Standard_True);
294 HilightPicked (toUpdateViewer);
298 Standard_Integer aSelNum = AIS_Selection::Extent();
299 return (aSelNum == 1) ? AIS_SOP_OneSelected
300 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
304 //=======================================================================
305 //function : ShiftSelect
307 //=======================================================================
308 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Boolean toUpdateViewer)
310 Standard_Integer aDetIndex = DetectedIndex();
311 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
315 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
316 Standard_Integer aSelNum = AIS_Selection::Extent();
317 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex);
318 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
319 AIS_Selection::Select (anOwner);
320 anOwner->SetSelected (toSelect);
324 myMainPM->ClearImmediateDraw();
325 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
326 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
328 Unhilight (anOwner, aViewer->ActiveView());
331 // advanced selection highlighting mechanism
332 if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
334 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
335 UpdateSelected (anIO, Standard_False);
340 myCTX->CurrentViewer()->Update();
344 Standard_Integer NS = AIS_Selection::Extent();
345 if( NS == 1 ) return AIS_SOP_OneSelected;
346 else if( NS > 1 ) return AIS_SOP_SeveralSelected;
347 return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
349 return AIS_SOP_Error;
352 //=======================================================================
353 //function : ShiftSelect
355 //=======================================================================
356 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Integer theXPMin,
357 const Standard_Integer theYPMin,
358 const Standard_Integer theXPMax,
359 const Standard_Integer theYPMax,
360 const Handle(V3d_View)& theView,
361 const Standard_Boolean toUpdateViewer)
363 myMainPM->ClearImmediateDraw();
365 if (theView->Viewer() == myCTX->CurrentViewer())
367 myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
369 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
370 Standard_Integer aLastSelNum = AIS_Selection::Extent();
373 if (!myMainVS->More())
375 // Nothing is selected clear selection, but don't clear the selection
376 // as it is shift selection and previous selection matters.
377 // Return state to know if something was unselected
378 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
383 UnhilightPicked (Standard_False);
386 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
388 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
389 if(myFilters->IsOk (anOwner))
391 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
392 AIS_Selection::Select (anOwner);
393 anOwner->SetSelected (toSelect);
399 HilightPicked (toUpdateViewer);
403 Standard_Integer aSelNum = AIS_Selection::Extent();
405 return (aSelNum == 1) ? AIS_SOP_OneSelected
406 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
410 //==================================================
412 // Purpose : Selection by polyline
413 //==================================================
414 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
415 const Handle(V3d_View)& theView,
416 const Standard_Boolean toUpdateViewer)
418 if (theView->Viewer() == myCTX->CurrentViewer())
420 myMainVS->Pick (thePolyline, theView);
422 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
424 Standard_Integer aLastSelNum = AIS_Selection::Extent();
426 if(!myMainVS->More())
428 // Nothing is selected clear selection, but don't clear the selection
429 // as it is shift selection and previous selection matters.
430 // Return state to know if something was unselected
431 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
436 UnhilightPicked (Standard_False);
439 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
441 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
442 if (myFilters->IsOk (anOwner))
444 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
445 AIS_Selection::Select (anOwner);
446 anOwner->SetSelected (toSelect);
451 HilightPicked (toUpdateViewer);
455 Standard_Integer aSelNum = AIS_Selection::Extent();
457 return (aSelNum == 1) ? AIS_SOP_OneSelected
458 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
462 //==================================================
465 //==================================================
466 void AIS_LocalContext::Hilight (const Handle(SelectMgr_EntityOwner)& theOwner,
467 const Handle(V3d_View)& theView)
469 if (theView.IsNull())
474 const Standard_Integer aHilightMode = GetHiMod (Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable()));
475 myMainPM->BeginImmediateDraw();
476 theOwner->HilightWithColor (myMainPM, myCTX->HilightColor(), aHilightMode);
477 myMainPM->EndImmediateDraw (theView);
480 //==================================================
481 // Function: Unhilight
483 //==================================================
484 void AIS_LocalContext::Unhilight (const Handle(SelectMgr_EntityOwner)& theOwner,
485 const Handle(V3d_View)& theView)
487 if (theView.IsNull())
492 const Standard_Integer aHilightMode = GetHiMod (Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable()));
493 if (IsSelected (theOwner))
495 if (theOwner->IsAutoHilight())
497 theOwner->HilightWithColor (myMainPM, myCTX->SelectionColor(), aHilightMode);
502 theOwner->Unhilight (myMainPM, aHilightMode);
506 //=======================================================================
507 //function : HilightPicked
509 //=======================================================================
510 void AIS_LocalContext::HilightPicked(const Standard_Boolean updateviewer)
512 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
513 if( Sel.IsNull() ) return;
515 typedef NCollection_DataMap <Handle(SelectMgr_SelectableObject), NCollection_Handle<SelectMgr_SequenceOfOwner> > SelectMgr_DataMapOfObjectOwners;
516 SelectMgr_DataMapOfObjectOwners aMap;
518 Handle (PrsMgr_PresentationManager3d) PM = myMainPM;
520 // to avoid problems when there is a loop searching for selected objects...
521 const AIS_NListTransient& Obj = Sel->Objects();
522 AIS_NListTransient::Iterator anIter( Obj );
523 for(; anIter.More(); anIter.Next())
525 const Handle(Standard_Transient)& Tr = anIter.Value();
527 const Handle(SelectMgr_EntityOwner)& Ownr =
528 *((const Handle(SelectMgr_EntityOwner)*) &Tr);
529 Handle(AIS_InteractiveObject) IO;
530 if(Ownr->HasSelectable()){
531 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(Ownr);
532 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
533 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
534 IO = *((Handle(AIS_InteractiveObject)*)&SO);
537 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
538 Standard_Integer HM = GetHiMod(*((Handle(AIS_InteractiveObject)*)&SO));
539 if ( Ownr->IsAutoHilight() )
540 Ownr->HilightWithColor(PM,myCTX->SelectionColor(),HM);
541 else if ( aMap.IsBound (SO) )
542 aMap(SO)->Append ( Ownr );
544 NCollection_Handle<SelectMgr_SequenceOfOwner> aSeq = new SelectMgr_SequenceOfOwner;
545 aSeq->Append ( Ownr );
546 aMap.Bind ( SO, aSeq );
551 for ( SelectMgr_DataMapOfObjectOwners::Iterator aMapIter(aMap);
552 aMapIter.More(); aMapIter.Next() )
554 aMapIter.Key()->HilightSelected (myMainPM, *aMapIter.Value());
559 myCTX->CurrentViewer()->Update();
563 //==================================================
566 //==================================================
567 void AIS_LocalContext::UnhilightPicked (const Standard_Boolean updateviewer)
569 myMainPM->ClearImmediateDraw();
571 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
572 if( Sel.IsNull() ) return;
573 Handle (PrsMgr_PresentationManager3d) PM = myMainPM;
574 NCollection_Map<Handle(SelectMgr_SelectableObject)> anObjMap;
576 const AIS_NListTransient& Obj = Sel->Objects();
577 AIS_NListTransient::Iterator anIter( Obj );
578 for(; anIter.More(); anIter.Next()){
579 const Handle(Standard_Transient)& Tr = anIter.Value();
581 const Handle(SelectMgr_EntityOwner)& Ownr =
582 *((const Handle(SelectMgr_EntityOwner)*) &Tr);
583 Standard_Integer HM(0);
584 if(Ownr->HasSelectable()){
585 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
586 Handle(AIS_InteractiveObject) IO = *((Handle(AIS_InteractiveObject)*)&SO);
590 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(Ownr);
591 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
594 Ownr->Unhilight(PM,HM);
598 for (NCollection_Map<Handle(SelectMgr_SelectableObject)>::Iterator anIter1 ( anObjMap );
599 anIter1.More(); anIter1.Next() )
601 if ( !anIter1.Key()->IsAutoHilight() )
602 anIter1.Key()->ClearSelected();
606 myCTX->CurrentViewer()->Update();
609 //=======================================================================
610 //function : IsSelected
612 //=======================================================================
613 Standard_Boolean AIS_LocalContext::IsSelected(const Handle(AIS_InteractiveObject)& anIObj) const
615 return (!FindSelectedOwnerFromIO(anIObj).IsNull());
618 //=======================================================================
619 //function : IsSelected
621 //=======================================================================
623 Standard_Boolean AIS_LocalContext::IsSelected (const Handle(SelectMgr_EntityOwner)& theOwner) const
625 return !theOwner.IsNull() && theOwner->IsSelected();
628 //==================================================
631 //==================================================
632 void AIS_LocalContext::
635 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
636 AIS_Selection::CurrentSelection()->Init();
639 //==================================================
642 //==================================================
643 Standard_Boolean AIS_LocalContext::
646 return AIS_Selection::CurrentSelection()->More();
649 //==================================================
652 //==================================================
653 void AIS_LocalContext::
656 AIS_Selection::CurrentSelection()->Next();
659 //==================================================
662 //==================================================
663 Standard_Boolean AIS_LocalContext::
666 Handle(Standard_Transient) Tr = AIS_Selection::CurrentSelection()->Value();
667 if( Tr.IsNull() ) return Standard_False;
668 Handle(SelectMgr_EntityOwner) EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
669 Handle(StdSelect_BRepOwner) BRO = Handle(StdSelect_BRepOwner)::DownCast(EO);
670 if(BRO.IsNull()) return Standard_False;
671 Standard_Boolean hasshape = BRO->HasShape();
672 Standard_Boolean comes = BRO->ComesFromDecomposition();
673 return (hasshape&&comes);
676 //================================================================
677 // Function : HasSelectedShape
678 // Purpose : Checks if there is a selected shape regardless of its decomposition status
679 //================================================================
680 Standard_Boolean AIS_LocalContext::HasSelectedShape() const
682 if (AIS_Selection::CurrentSelection()->Extent() == 0)
683 return Standard_False;
685 Handle(Standard_Transient) aCurSelection = AIS_Selection::CurrentSelection()->Value();
686 if (aCurSelection.IsNull())
687 return Standard_False;
689 Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aCurSelection);
690 Handle(StdSelect_BRepOwner) aBrepOwner = Handle(StdSelect_BRepOwner)::DownCast (anOwner);
691 if (aBrepOwner.IsNull())
693 return Standard_False;
695 return aBrepOwner->HasShape();
698 //==================================================
701 //==================================================
702 TopoDS_Shape AIS_LocalContext::SelectedShape() const
704 Handle(Standard_Transient) aTr = AIS_Selection::CurrentSelection()->Value();
705 Handle(SelectMgr_EntityOwner) anEO = *((Handle(SelectMgr_EntityOwner)*)&aTr);
706 Handle(StdSelect_BRepOwner) aBRO = Handle(StdSelect_BRepOwner)::DownCast(anEO);
709 return TopoDS_Shape();
712 return aBRO->Shape().Located (aBRO->Location() * aBRO->Shape().Location());
715 //==================================================
718 //==================================================
719 Handle(AIS_InteractiveObject) AIS_LocalContext::
720 SelectedInteractive() const
722 Handle(AIS_InteractiveObject) IO;
723 Handle(Standard_Transient) Tr = AIS_Selection::CurrentSelection()->Value();
725 Handle(SelectMgr_EntityOwner) EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
726 Handle(SelectMgr_SelectableObject) SO;
727 if(EO->HasSelectable()){
728 SO = EO->Selectable();
729 IO = *((Handle(AIS_InteractiveObject)*)&SO);
734 //==================================================
737 //==================================================
738 Handle(SelectMgr_EntityOwner) AIS_LocalContext::
739 SelectedOwner() const
741 Handle(SelectMgr_EntityOwner) EO;
742 Handle(Standard_Transient) Tr = AIS_Selection::CurrentSelection()->Value();
744 EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
748 //==================================================
751 //==================================================
752 Standard_Boolean AIS_LocalContext::
753 HasApplicative() const
755 Handle(AIS_InteractiveObject) IO = SelectedInteractive();
756 if( IO.IsNull() ) return Standard_False;
757 return IO->HasOwner();
760 //==================================================
763 //==================================================
764 const Handle(Standard_Transient)& AIS_LocalContext::
765 SelectedApplicative() const
767 return SelectedInteractive()->GetOwner();
772 //=======================================================================
773 //function : UpdateSelection
774 //purpose : should disappear...
775 //=======================================================================
776 void AIS_LocalContext::UpdateSelected(const Standard_Boolean updateviewer)
778 UnhilightPicked(Standard_False);
779 HilightPicked(updateviewer);
782 //================================================================
783 // Function : UpdateSelected
784 // Purpose : Part of advanced selection mechanism.
785 // Highlightes or clears selection presentation for the given IO
786 //================================================================
787 void AIS_LocalContext::UpdateSelected(const Handle(AIS_InteractiveObject)& anobj,
788 const Standard_Boolean updateviewer)
790 if (anobj.IsNull() || anobj->IsAutoHilight())
793 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
794 Handle(AIS_Selection) Sel = AIS_Selection::CurrentSelection();
796 SelectMgr_SequenceOfOwner aSeq;
797 for ( Sel->Init(); Sel->More(); Sel->Next() ){
798 Handle(SelectMgr_EntityOwner) aOwner = Handle(SelectMgr_EntityOwner)::DownCast(Sel->Value());
800 if ( !aOwner.IsNull() && aOwner->HasSelectable() && aOwner->Selectable() == anobj )
801 aSeq.Append( aOwner );
805 anobj->HilightSelected( myMainPM, aSeq );
807 anobj->ClearSelected();
810 myCTX->CurrentViewer()->Update();
814 //==================================================
815 // Function: ClearSelected
817 //==================================================
818 void AIS_LocalContext::ClearSelected (const Standard_Boolean updateviewer)
820 UnhilightPicked(updateviewer);
821 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
823 Handle(AIS_Selection) Sel = AIS_Selection::CurrentSelection();
824 const AIS_NListTransient& Obj = Sel->Objects();
825 AIS_NListTransient::Iterator anIter( Obj );
826 for(; anIter.More(); anIter.Next()){
827 const Handle(Standard_Transient)& Tr = anIter.Value();
830 (*((const Handle(SelectMgr_EntityOwner)*)&Tr))->SetSelected (Standard_False);
833 AIS_Selection::Select();
837 //==================================================
838 // Function: ClearOutdatedSelection
840 //==================================================
841 void AIS_LocalContext::ClearOutdatedSelection (const Handle(AIS_InteractiveObject)& theIO,
842 const Standard_Boolean toClearDeactivated)
844 // 1. Collect selectable entities
845 SelectMgr_IndexedMapOfOwner aValidOwners;
847 const TColStd_ListOfInteger& aModes = SelectionModes (theIO);
849 TColStd_ListIteratorOfListOfInteger aModeIter (aModes);
850 for (; aModeIter.More(); aModeIter.Next())
852 int aMode = aModeIter.Value();
853 if (!theIO->HasSelection(aMode))
858 if (toClearDeactivated && !mySM->IsActivated(theIO, aMode, myMainVS))
863 Handle(SelectMgr_Selection) aSelection = theIO->Selection(aMode);
864 for (aSelection->Init(); aSelection->More(); aSelection->Next())
866 Handle(SelectBasics_SensitiveEntity) anEntity = aSelection->Sensitive()->BaseSensitive();
867 if (anEntity.IsNull())
872 Handle(SelectMgr_EntityOwner) anOwner =
873 Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId());
875 if (anOwner.IsNull())
880 aValidOwners.Add(anOwner);
884 // 2. Refresh context's detection and selection and keep only active owners
885 // Keep last detected object for lastindex initialization.
886 Handle(SelectMgr_EntityOwner) aLastPicked = myMainVS->OnePicked();
888 // Remove entity owners from detected sequences
889 for (Standard_Integer anIdx = 1; anIdx <= myDetectedSeq.Length(); ++anIdx)
891 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (anIdx));
892 if (anOwner.IsNull() || anOwner->Selectable() != theIO || aValidOwners.Contains (anOwner))
897 myDetectedSeq.Remove (anIdx--);
899 if (anIdx < myCurDetected)
904 myCurDetected = Max (myCurDetected, 1);
906 Standard_Boolean isAISRemainsDetected = Standard_False;
908 // 3. AIS_Selection : remove entity owners from AIS_Selection
909 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
910 Handle(AIS_Selection) aSelection = AIS_Selection::Selection (mySelName.ToCString());
911 AIS_NListTransient::Iterator anIter (aSelection->Objects());
912 AIS_NListTransient aRemoveEntites;
913 for (; anIter.More(); anIter.Next())
915 Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anIter.Value());
916 if (anOwner.IsNull() || anOwner->Selectable() != theIO)
921 if (aValidOwners.Contains (anOwner))
923 isAISRemainsDetected = Standard_True;
927 aRemoveEntites.Append (anOwner);
928 anOwner->SetSelected (Standard_False);
929 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
931 Unhilight (anOwner, aViewer->ActiveView());
935 AIS_NListTransient::Iterator anIterRemove (aRemoveEntites);
936 for (; anIterRemove.More(); anIterRemove.Next())
938 aSelection->Select (anIterRemove.Value());
941 // 4. AIS_LocalContext - myMapOfOwner : remove entity owners from myMapOfOwner
942 SelectMgr_IndexedMapOfOwner anOwnersToKeep;
943 for (Standard_Integer anIdx = 1; anIdx <= myMapOfOwner->Extent(); anIdx++)
945 Handle(SelectMgr_EntityOwner) anOwner = myMapOfOwner->FindKey (anIdx);
946 if (anOwner.IsNull())
951 if (anOwner->Selectable() != theIO || aValidOwners.Contains (anOwner))
953 anOwnersToKeep.Add (anOwner);
957 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
959 Unhilight (anOwner, aViewer->ActiveView());
963 myMapOfOwner->Clear();
964 myMapOfOwner->Assign (anOwnersToKeep);
965 mylastindex = myMapOfOwner->FindIndex (aLastPicked);
966 if (!IsValidIndex (mylastindex))
968 myMainPM->ClearImmediateDraw();
971 if (!isAISRemainsDetected)
973 // Remove the interactive object from detected sequences
974 for (Standard_Integer anIdx = 1; anIdx <= myAISDetectedSeq.Length(); ++anIdx)
976 Handle(AIS_InteractiveObject) aDetectedIO = myAISDetectedSeq.Value (anIdx);
977 if (aDetectedIO.IsNull() || aDetectedIO != theIO)
982 myAISDetectedSeq.Remove (anIdx--);
984 if (anIdx < myAISCurDetected)
989 myAISCurDetected = Max (myAISCurDetected, 1);
993 //=======================================================================
994 //function : SetSelected
996 //=======================================================================
997 void AIS_LocalContext::SetSelected(const Handle(AIS_InteractiveObject)& anIObj,
998 const Standard_Boolean updateviewer)
1000 if(!IsValidForSelection(anIObj)) return;
1001 UnhilightPicked(Standard_False);
1003 //1st case, owner already <anIObj> as owner
1004 // and not separated is found...
1006 Handle(AIS_Selection) sel = AIS_Selection::Selection(mySelName.ToCString());
1007 //Standard_Boolean found(Standard_False);
1008 Handle(Standard_Transient) Tr;
1009 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromIO(anIObj);
1011 //check if in selection number 0 there is an owner that can be triturated...
1012 if(anIObj->HasSelection(0)){
1013 const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0);
1016 Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->BaseSensitive()->OwnerId();
1017 EO = *((Handle(SelectMgr_EntityOwner)*)&BO);
1021 EO = new SelectMgr_EntityOwner(anIObj);
1024 ClearSelected(Standard_False);
1026 AIS_Selection::Select(EO);
1027 EO->SetSelected (Standard_True);
1029 HilightPicked(updateviewer);
1032 //=======================================================================
1033 //function : AddOrRemoveSelected
1035 //=======================================================================
1037 void AIS_LocalContext::AddOrRemoveSelected(const Handle(AIS_InteractiveObject)& anIObj,
1038 const Standard_Boolean updateviewer)
1040 if(!IsValidForSelection(anIObj)) return;
1041 UnhilightPicked(Standard_False);
1042 // first check if it is selected...
1043 Handle(SelectMgr_EntityOwner) EO;
1045 EO = FindSelectedOwnerFromIO(anIObj);
1049 if(anIObj->HasSelection(0))
1051 const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0);
1054 Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->BaseSensitive()->OwnerId();
1055 EO = *((Handle(SelectMgr_EntityOwner)*)&BO);
1060 EO = new SelectMgr_EntityOwner(anIObj);
1064 // cout<<"AIS_LocalContext::AddOrRemoveSelected : Selection = "<<mySelName<<endl;
1065 const Handle(AIS_Selection)& S = AIS_Selection::Selection(mySelName.ToCString());
1069 AIS_SelectStatus aStatus = S->Select(EO);
1070 EO->SetSelected (aStatus == AIS_SS_Added);
1073 HilightPicked(updateviewer);
1076 //=======================================================================
1077 //function : AddOrRemoveSelected
1078 //purpose : To check...
1079 //=======================================================================
1080 void AIS_LocalContext::AddOrRemoveSelected(const TopoDS_Shape& Sh,
1081 const Standard_Boolean updateviewer)
1083 UnhilightPicked (Standard_False);
1084 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromShape(Sh);
1087 AIS_Selection::Selection(mySelName.ToCString())->Select(EO);
1088 EO->SetSelected (Standard_True);
1090 HilightPicked (updateviewer);
1093 void AIS_LocalContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
1094 const Standard_Boolean toUpdateViewer)
1098 UnhilightPicked (Standard_False);
1101 Standard_Boolean toSelect = theOwner->IsSelected() ? Standard_False : Standard_True;
1103 AIS_Selection::Selection (mySelName.ToCString())->Select (theOwner);
1104 theOwner->SetSelected (toSelect);
1108 HilightPicked (toUpdateViewer);
1112 //==================================================
1113 // Function: manageDetected
1115 //==================================================
1116 void AIS_LocalContext::manageDetected (const Handle(SelectMgr_EntityOwner)& thePickOwner,
1117 const Handle(V3d_View)& theView,
1118 const Standard_Boolean theToRedrawImmediate)
1120 if (thePickOwner.IsNull())
1122 myMainPM->ClearImmediateDraw();
1123 if (theToRedrawImmediate)
1125 theView->RedrawImmediate();
1130 if (!myFilters->IsOk (thePickOwner))
1132 if (mylastindex != 0)
1134 mylastgood = mylastindex;
1136 if (theToRedrawImmediate)
1138 theView->RedrawImmediate();
1143 //=======================================================================================================
1144 // 2 cases : a- object is in the map of picks:
1145 // 1. this is the same index as the last detected: -> Do nothing
1147 // - if lastindex = 0 (no object was detected at the last step)
1148 // the object presentation is highlighted and lastindex = index(objet)
1150 // the presentation of the object corresponding to lastindex is "unhighlighted"
1151 // it is removed if the object is not visualized but only active
1152 // then the presentation of the detected object is highlighted and lastindex = index(objet)
1153 // b- the object is not in the map of picked objects
1154 // - if lastindex != 0 (object detected at the last step) it is unhighlighted ...
1155 // if the object was decomposed, presentation is created for the detected shape and the couple
1156 // (Proprietaire,Prs)is added in the map.
1157 // otherwise the couple(proprietaire, NullPrs) is placed in the map and the interactive object
1158 // itself is highlighted.
1160 //=======================================================================================================
1162 const Standard_Integer aNewIndex = myMapOfOwner->Contains (thePickOwner)
1163 ? myMapOfOwner->FindIndex (thePickOwner)
1164 : myMapOfOwner->Add (thePickOwner);
1166 // For the advanced mesh selection mode the owner indices comparison
1167 // is not effective because in that case only one owner manage the
1168 // selection in current selection mode. It is necessary to check the current detected
1169 // entity and hilight it only if the detected entity is not the same as
1170 // previous detected (IsForcedHilight call)
1171 if (aNewIndex != mylastindex
1172 || thePickOwner->IsForcedHilight())
1174 myMainPM->ClearImmediateDraw();
1175 if (mylastindex != 0
1176 && mylastindex <= myMapOfOwner->Extent())
1178 const Handle(SelectMgr_EntityOwner)& aLastOwner = myMapOfOwner->FindKey (mylastindex);
1179 Unhilight (aLastOwner, theView);
1184 if (!thePickOwner->IsSelected() || myCTX->ToHilightSelected())
1186 Hilight (thePickOwner, theView);
1188 if (theToRedrawImmediate)
1190 theView->RedrawImmediate();
1194 mylastindex = aNewIndex;
1197 if (mylastindex != 0)
1199 mylastgood = mylastindex;
1203 //=======================================================================
1204 //function : HasDetectedShape
1206 //=======================================================================
1208 Standard_Boolean AIS_LocalContext::HasDetectedShape() const
1210 if(mylastindex==0) return Standard_False;
1211 return IsShape(mylastindex);
1214 //=======================================================================
1215 //function : DetectedShape
1217 //=======================================================================
1220 AIS_LocalContext::DetectedShape() const
1222 static TopoDS_Shape bidsh;
1223 if(mylastindex != 0)
1225 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner->FindKey (mylastindex));
1226 if(BROwnr.IsNull()) return bidsh;
1227 return BROwnr->Shape();
1232 //=======================================================================
1233 //function : DetectedInteractive
1235 //=======================================================================
1237 Handle(AIS_InteractiveObject)
1238 AIS_LocalContext::DetectedInteractive() const
1240 Handle(AIS_InteractiveObject) Iobj;
1241 if(IsValidIndex(mylastindex)){
1242 Handle(SelectMgr_SelectableObject) SO = myMapOfOwner->FindKey(mylastindex)->Selectable();
1243 Iobj = *((Handle(AIS_InteractiveObject)*) &SO);
1247 //=======================================================================
1248 //function : DetectedInteractive
1250 //=======================================================================
1251 Handle(SelectMgr_EntityOwner) AIS_LocalContext::DetectedOwner() const
1253 Handle(SelectMgr_EntityOwner) bid;
1254 if(!IsValidIndex(mylastindex)) return bid;
1255 return myMapOfOwner->FindKey(mylastindex);
1259 //=======================================================================
1260 //function : ComesFromDecomposition
1262 //=======================================================================
1264 Standard_Boolean AIS_LocalContext::ComesFromDecomposition(const Standard_Integer PickedIndex) const
1266 const Handle(SelectMgr_EntityOwner)& OWN = myMapOfOwner->FindKey(PickedIndex);
1267 Handle(SelectMgr_SelectableObject) aSel = OWN->Selectable();
1268 if (myActiveObjects.IsBound (aSel)) { // debug of jmi
1269 const Handle(AIS_LocalStatus)& Stat = myActiveObjects(aSel);
1270 return Stat->Decomposed();
1272 return Standard_False;
1275 //=======================================================================
1276 //function : DisplaySensitive
1278 //=======================================================================
1280 void AIS_LocalContext::DisplaySensitive(const Handle(V3d_View)& aviou)
1282 myMainVS->DisplaySensitive(aviou);
1285 //=======================================================================
1286 //function : ClearSensitive
1288 //=======================================================================
1290 void AIS_LocalContext::ClearSensitive(const Handle(V3d_View)& aviou)
1292 myMainVS->ClearSensitive(aviou);
1296 //=======================================================================
1297 //function : IsShape
1299 //=======================================================================
1300 Standard_Boolean AIS_LocalContext::IsShape(const Standard_Integer Index) const
1303 if(Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner->FindKey(Index)).IsNull())
1304 return Standard_False;
1306 ComesFromDecomposition(Index);
1309 Standard_Boolean AIS_LocalContext::IsValidForSelection(const Handle(AIS_InteractiveObject)& anIObj) const
1312 // Shape was not transfered from AIS_Shape to EntityOwner
1313 Handle(AIS_Shape) shape = Handle(AIS_Shape)::DownCast(anIObj);
1314 if( !shape.IsNull() )
1315 return myFilters->IsOk(new StdSelect_BRepOwner(shape->Shape(),shape));
1316 return myFilters->IsOk(new SelectMgr_EntityOwner(anIObj));
1320 //=======================================================================
1321 //function : HilightNextDetected
1323 //=======================================================================
1324 Standard_Integer AIS_LocalContext::HilightNextDetected (const Handle(V3d_View)& theView,
1325 const Standard_Boolean theToRedrawImmediate)
1327 // go to the next owner
1328 if (myDetectedSeq.IsEmpty())
1333 const Standard_Integer aLen = myDetectedSeq.Length();
1334 if (++myCurDetected > aLen)
1338 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1339 if (anOwner.IsNull())
1343 manageDetected (anOwner, theView, theToRedrawImmediate);
1344 return myCurDetected;
1347 //=======================================================================
1348 //function : HilightPreviousDetected
1350 //=======================================================================
1351 Standard_Integer AIS_LocalContext::HilightPreviousDetected (const Handle(V3d_View)& theView,
1352 const Standard_Boolean theToRedrawImmediate)
1354 if (myDetectedSeq.IsEmpty())
1359 const Standard_Integer aLen = myDetectedSeq.Length();
1360 if (--myCurDetected < 1)
1362 myCurDetected = aLen;
1364 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1365 if (anOwner.IsNull())
1370 manageDetected (anOwner, theView, theToRedrawImmediate);
1371 return myCurDetected;
1374 //=======================================================================
1375 //function : UnhilightLastDetected
1377 //=======================================================================
1378 Standard_Boolean AIS_LocalContext::UnhilightLastDetected (const Handle(V3d_View)& theView)
1380 if (!IsValidIndex (mylastindex))
1382 return Standard_False;
1385 myMainPM->BeginImmediateDraw();
1386 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (mylastindex);
1387 const Standard_Integer aHilightMode = anOwner->HasSelectable()
1388 ? GetHiMod (Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable()))
1391 myMapOfOwner->FindKey (mylastindex)->Unhilight (myMainPM, aHilightMode);
1392 myMainPM->EndImmediateDraw (theView);
1394 return Standard_True;
1397 //=======================================================================
1398 //function : FindSelectedOwnerFromIO
1399 //purpose : it is checked if one of the selected owners really presents IObj
1400 //=======================================================================
1401 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromIO
1402 (const Handle(AIS_InteractiveObject)& anIObj) const
1404 Handle(SelectMgr_EntityOwner) EO,bid;
1405 if (anIObj.IsNull()) return EO;
1407 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
1410 cout<<"\t\tAIS_LocalCOntext::FindSelectedOwnerFromShape : Selection "
1411 <<mySelName<<" Nulle "<<endl;
1415 Standard_Boolean found(Standard_False);
1416 const AIS_NListTransient& Obj = Sel->Objects();
1417 AIS_NListTransient::Iterator anIter( Obj );
1418 for(; anIter.More(); anIter.Next()){
1419 const Handle(Standard_Transient)& Tr = anIter.Value();
1421 EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
1422 if(EO->HasSelectable()){
1423 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1424 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
1425 if (anIObj == EO->Selectable()){
1426 found =Standard_True;
1433 if(found) return EO;
1437 //=======================================================================
1438 //function : FindSelectedOwnerFromShape
1439 //purpose : it is checked if one of the selected owners really presents IObj
1440 //=======================================================================
1441 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromShape(const TopoDS_Shape& sh) const
1443 Handle(SelectMgr_EntityOwner) EO, bid;
1444 if (sh.IsNull()) return EO;
1446 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
1449 cout<<"\t\tAIS_LocalCOntext::FindSelectedOwnerFromShape : Selection "<<mySelName<<" Nulle "<<endl;
1454 Standard_Boolean found(Standard_False);
1457 NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (myMainVS->ActiveOwners());
1458 for (; anOwnersIt.More(); anOwnersIt.Next()) {
1459 EO = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value());
1460 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1461 if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) {
1462 found = Standard_True;
1468 if(found) return EO;
1472 //=======================================================================
1473 //function : AIS_LocalContext::InitDetected
1475 //=======================================================================
1476 void AIS_LocalContext::InitDetected()
1478 myAISCurDetected = myAISDetectedSeq.Length()? 1 : 0;
1481 //=======================================================================
1482 //function : AIS_LocalContext::MoreDetected
1484 //=======================================================================
1485 Standard_Boolean AIS_LocalContext::MoreDetected() const
1487 return (myAISCurDetected > 0 && myAISCurDetected <= myAISDetectedSeq.Length());
1490 //=======================================================================
1491 //function : AIS_LocalContext::NextDetected
1493 //=======================================================================
1494 void AIS_LocalContext::NextDetected()
1499 //=======================================================================
1500 //function : DetectedCurrentShape
1502 //=======================================================================
1503 const TopoDS_Shape& AIS_LocalContext::DetectedCurrentShape() const
1505 static TopoDS_Shape aDummyShape;
1507 Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
1509 if (aCurrentShape.IsNull())
1514 return aCurrentShape->Shape();
1516 //=======================================================================
1517 //function : DetectedCurrentObject
1519 //=======================================================================
1520 Handle(AIS_InteractiveObject) AIS_LocalContext::DetectedCurrentObject() const
1522 return MoreDetected() ? myAISDetectedSeq(myAISCurDetected) : NULL;