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 #define BUC60569 //GG_051199 Enable to select the local context
22 // in any case and especially in multi selection mode.
23 // Note that right now when an hilighted owner is selected
24 // this owner is unhilighted,this permits to see the selection!
25 // Principle : an owner can have 3 state :
26 // 1 : The owner is selected and no more highlightable
27 // 0 : The owner is NOT selected
28 // -1: The owner is selected but stay highlightable (NEW)
30 // IMP230600 //GG Add protection on selection methodes
31 // when nothing is selected
33 #define BUC60726 //GG_040900 When nothing is detected,
34 // Clear the last temporary stuff in any case
36 #define BUC60765 //GG_121000 Avoid to raise when the same selection
37 // is attached to several local context.
39 #define BUC60771 //GG_261000 Avoid to crash after closing a view
40 // containing a selected entity and creating a new one.
42 #define BUC60774 //GG_261000 Returns right select status on
43 // bounding-box selection type.
45 #define BUC60818 //GG_300101 Enable detection even if
46 // SetAutomaticHilight(FALSE) has been used.
48 #define IMP300101 //GG Enable to use polygon highlighting
50 #define BUC60876 //GG_050401 Clear selection always even
51 // if the current highlight mode is not 0.
53 #define BUC60953 //SAV_060701 For Select optimization. Selection by rectangle case.
54 // for single selection no optimization done.
56 #define IMP120701 //SZV made a shape valid for selection
59 #define IMP160701 //SZV Add InitDetected(),MoreDetected(),NextDetected(),
60 // DetectedCurrentShape(),DetectedCurrentObject()
63 #define OCC138 //VTN Avoding infinit loop in AddOrRemoveSelected method.
65 #define OCC189 //SAV: 18/03/02 AIS_Selection::Objects() returns ListOfTransient
68 #define USE_MAP //san : 18/04/03 USE_MAP - additional datamap is used to speed up access
69 //to certain owners in AIS_Selection::myresult list
71 #define OCC9026 //AEL Performance optimization of the FindSelectedOwnerFromShape() method.
73 #include <AIS_LocalContext.jxx>
74 #include <StdSelect_BRepOwner.hxx>
75 #include <TColStd_MapOfTransient.hxx>
76 #include <TColStd_MapIteratorOfMapOfTransient.hxx>
77 #include <Prs3d_Presentation.hxx>
78 #include <Prs3d_Drawer.hxx>
79 #include <Prs3d_ShadingAspect.hxx>
80 #include <AIS_LocalStatus.hxx>
81 #include <StdPrs_WFShape.hxx>
82 #include <Graphic3d_ArrayOfTriangles.hxx>
83 #include <Graphic3d_Group.hxx>
84 #include <Select3D_SensitiveTriangulation.hxx>
85 #include <SelectBasics_SensitiveEntity.hxx>
86 #include <TCollection_AsciiString.hxx>
87 #include <NCollection_Map.hxx>
90 #include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
92 #include <SelectMgr_Selection.hxx>
93 #include <SelectMgr_SequenceOfOwner.hxx>
94 #include <OSD_Environment.hxx>
96 #include <Geom_Transformation.hxx>
97 #include <AIS_Selection.hxx>
98 #include <Aspect_Grid.hxx>
100 #include <AIS_Shape.hxx>
104 static Standard_Integer GetHiMod(const Handle(AIS_InteractiveObject)& IO)
106 return IO->HasHilightMode() ? IO->HilightMode():0;
109 //==================================================
112 //==================================================
113 AIS_StatusOfDetection AIS_LocalContext::MoveTo (const Standard_Integer theXpix,
114 const Standard_Integer theYpix,
115 const Handle(V3d_View)& theView,
116 const Standard_Boolean theToRedrawImmediate)
118 // check that ViewerSelector gives
119 if (theView->Viewer() != myCTX->CurrentViewer())
121 return AIS_SOD_Error;
124 myAISCurDetected = 0;
125 myAISDetectedSeq.Clear();
128 myDetectedSeq.Clear();
129 myMainVS->Pick (theXpix, theYpix, theView);
131 const Standard_Integer aDetectedNb = myMainVS->NbPicked();
132 for (Standard_Integer aDetIter = 1; aDetIter <= aDetectedNb; ++aDetIter)
134 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (aDetIter);
136 || !myFilters->IsOk (anOwner))
141 myDetectedSeq.Append (aDetIter); // normally they are already arranged in correct order...
142 Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
145 myAISDetectedSeq.Append (anObj);
149 // result of courses..
150 if (aDetectedNb == 0 || myDetectedSeq.IsEmpty())
152 if (mylastindex != 0 && mylastindex <= myMapOfOwner.Extent())
154 Unhilight (myMapOfOwner (mylastindex), theView);
155 if (theToRedrawImmediate)
157 theView->RedrawImmediate();
162 return aDetectedNb == 0
167 // all owners detected by the selector are passed to the
168 // filters and correct ones are preserved...
170 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
171 manageDetected (anOwner, theView, theToRedrawImmediate);
172 if (myDetectedSeq.Length() == 1)
174 return aDetectedNb == 1
175 ? AIS_SOD_OnlyOneDetected
176 : AIS_SOD_OnlyOneGood;
180 return AIS_SOD_SeveralGood;
184 //=======================================================================
187 //=======================================================================
188 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Boolean toUpdateViewer)
192 UnhilightPicked (Standard_False);
195 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
197 Standard_Integer aDetIndex = DetectedIndex();
200 ClearSelected (toUpdateViewer);
201 return (AIS_Selection::Extent() == 0) ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
204 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner (aDetIndex);
206 ClearSelected (Standard_False);
208 if (!anOwner->IsSelected()) // anOwner is not selected
210 anOwner->SetSelected (Standard_True);
211 AIS_Selection::Select (anOwner);
216 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
217 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
219 Unhilight (anOwner, aViewer->ActiveView());
222 // advanced selection highlighting mechanism
223 if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
225 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
226 UpdateSelected (anIO, Standard_False);
231 myCTX->CurrentViewer()->Update();
235 return (AIS_Selection::Extent() == 1) ? AIS_SOP_OneSelected : AIS_SOP_SeveralSelected;
238 //=======================================================================
241 //=======================================================================
242 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Integer theXPMin,
243 const Standard_Integer theYPMin,
244 const Standard_Integer theXPMax,
245 const Standard_Integer theYPMax,
246 const Handle(V3d_View)& theView,
247 const Standard_Boolean toUpdateViewer)
249 if (theView->Viewer() == myCTX->CurrentViewer())
251 myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
254 UnhilightPicked (Standard_False);
257 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
258 Standard_Integer aSelNum = AIS_Selection::Extent();
261 if (!myMainVS->More())
263 ClearSelected (toUpdateViewer);
265 return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
268 ClearSelected (Standard_False);
270 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
272 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
273 if (myFilters->IsOk (anOwner))
275 // it can be helpful to classify this owner immediately...
276 if (!anOwner->IsSelected())
278 anOwner->SetSelected (Standard_True);
279 AIS_Selection::Select (anOwner);
286 HilightPicked (toUpdateViewer);
290 Standard_Integer aSelNum = AIS_Selection::Extent();
292 return (aSelNum == 1) ? AIS_SOP_OneSelected
293 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
297 //==================================================
299 // Purpose : Selection by polyline
300 //==================================================
301 AIS_StatusOfPick AIS_LocalContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
302 const Handle(V3d_View)& theView,
303 const Standard_Boolean toUpdateViewer)
305 if (theView->Viewer() == myCTX->CurrentViewer())
307 myMainVS->Pick (thePolyline, theView);
309 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
311 Standard_Integer aLastSelNum = AIS_Selection::Extent();
313 if (!myMainVS->More())
315 // Nothing is selected clear selection.
316 ClearSelected (toUpdateViewer);
319 // Return state to know if something was unselected
320 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
325 UnhilightPicked (Standard_False);
328 // Clear previous selection without update to process this selection
329 ClearSelected (Standard_False);
331 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
333 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
334 if (myFilters->IsOk (anOwner))
336 // it can be helpful to classify this owner immediately...
337 if (!anOwner->IsSelected())
339 AIS_Selection::AddSelect (anOwner);
340 anOwner->SetSelected (Standard_True);
347 HilightPicked (toUpdateViewer);
351 Standard_Integer aSelNum = AIS_Selection::Extent();
352 return (aSelNum == 1) ? AIS_SOP_OneSelected
353 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
357 //=======================================================================
358 //function : ShiftSelect
360 //=======================================================================
361 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Boolean toUpdateViewer)
363 Standard_Integer aDetIndex = DetectedIndex();
364 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
368 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
369 Standard_Integer aSelNum = AIS_Selection::Extent();
370 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner (aDetIndex);
371 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
372 AIS_Selection::Select (anOwner);
373 anOwner->SetSelected (toSelect);
377 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
378 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
380 Unhilight (anOwner, aViewer->ActiveView());
383 // advanced selection highlighting mechanism
384 if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
386 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
387 UpdateSelected (anIO, Standard_False);
392 myCTX->CurrentViewer()->Update();
397 Standard_Integer NS = AIS_Selection::Extent();
398 if( NS == 1 ) return AIS_SOP_OneSelected;
399 else if( NS > 1 ) return AIS_SOP_SeveralSelected;
400 return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
403 return AIS_SOP_Error;
406 //=======================================================================
407 //function : ShiftSelect
409 //=======================================================================
410 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Integer theXPMin,
411 const Standard_Integer theYPMin,
412 const Standard_Integer theXPMax,
413 const Standard_Integer theYPMax,
414 const Handle(V3d_View)& theView,
415 const Standard_Boolean toUpdateViewer)
417 myMainPM->ClearImmediateDraw();
419 if (theView->Viewer() == myCTX->CurrentViewer())
421 myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
423 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
424 Standard_Integer aLastSelNum = AIS_Selection::Extent();
427 if (!myMainVS->More())
429 // Nothing is selected clear selection, but don't clear the selection
430 // as it is shift selection and previous selection matters.
431 // Return state to know if something was unselected
432 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
437 UnhilightPicked (Standard_False);
440 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
442 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
443 if(myFilters->IsOk (anOwner))
445 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
446 AIS_Selection::Select (anOwner);
447 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 //==================================================
466 // Purpose : Selection by polyline
467 //==================================================
468 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
469 const Handle(V3d_View)& theView,
470 const Standard_Boolean toUpdateViewer)
472 if (theView->Viewer() == myCTX->CurrentViewer())
474 myMainVS->Pick (thePolyline, theView);
476 AIS_Selection::SetCurrentSelection (mySelName.ToCString());
478 Standard_Integer aLastSelNum = AIS_Selection::Extent();
480 if(!myMainVS->More())
482 // Nothing is selected clear selection, but don't clear the selection
483 // as it is shift selection and previous selection matters.
484 // Return state to know if something was unselected
485 return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
490 UnhilightPicked (Standard_False);
493 for (myMainVS->Init(); myMainVS->More(); myMainVS->Next())
495 const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked();
496 if (myFilters->IsOk (anOwner))
498 Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
499 AIS_Selection::Select (anOwner);
500 anOwner->SetSelected (toSelect);
505 HilightPicked (toUpdateViewer);
509 Standard_Integer aSelNum = AIS_Selection::Extent();
511 return (aSelNum == 1) ? AIS_SOP_OneSelected
512 : (aSelNum > 1) ? AIS_SOP_SeveralSelected
516 //==================================================
519 //==================================================
520 void AIS_LocalContext::Hilight (const Handle(SelectMgr_EntityOwner)& theOwner,
521 const Handle(V3d_View)& theView)
523 if (theView.IsNull())
528 const Standard_Integer aHilightMode = GetHiMod (Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable()));
529 myMainPM->BeginImmediateDraw();
530 theOwner->HilightWithColor (myMainPM, myCTX->HilightColor(), aHilightMode);
531 myMainPM->EndImmediateDraw (theView);
534 //==================================================
535 // Function: Unhilight
537 //==================================================
538 void AIS_LocalContext::Unhilight (const Handle(SelectMgr_EntityOwner)& theOwner,
539 const Handle(V3d_View)& theView)
541 if (theView.IsNull())
546 myMainPM->ClearImmediateDraw();
547 const Standard_Integer aHilightMode = GetHiMod (Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable()));
548 if (IsSelected (theOwner))
550 if (theOwner->IsAutoHilight())
552 theOwner->HilightWithColor (myMainPM, myCTX->SelectionColor(), aHilightMode);
557 theOwner->Unhilight (myMainPM, aHilightMode);
561 //=======================================================================
562 //function : HilightPicked
564 //=======================================================================
565 void AIS_LocalContext::HilightPicked(const Standard_Boolean updateviewer)
567 Standard_Boolean updMain(Standard_False);
569 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
571 if( Sel.IsNull() ) return;
574 typedef NCollection_DataMap <Handle(SelectMgr_SelectableObject), NCollection_Handle<SelectMgr_SequenceOfOwner> > SelectMgr_DataMapOfObjectOwners;
575 SelectMgr_DataMapOfObjectOwners aMap;
577 Handle (PrsMgr_PresentationManager3d) PM = myMainPM;
579 // to avoid problems when there is a loop searching for selected objects...
580 #if !defined OCC189 && !defined USE_MAP
581 const TColStd_Array1OfTransient& Obj = Sel->Objects()->Array1();
582 for(Standard_Integer i =Obj.Lower();i<=Sel->NbStored();i++)
584 const Handle(Standard_Transient)& Tr = Obj(i);
586 const AIS_NListTransient& Obj = Sel->Objects();
587 AIS_NListTransient::Iterator anIter( Obj );
588 for(; anIter.More(); anIter.Next())
590 const Handle(Standard_Transient)& Tr = anIter.Value();
593 const Handle(SelectMgr_EntityOwner)& Ownr =
594 *((const Handle(SelectMgr_EntityOwner)*) &Tr);
595 Handle(AIS_InteractiveObject) IO;
596 if(Ownr->HasSelectable()){
597 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(Ownr);
598 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
599 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
600 IO = *((Handle(AIS_InteractiveObject)*)&SO);
601 updMain = Standard_True;
604 updMain = Standard_True;
607 updMain = Standard_True;
608 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
609 Standard_Integer HM = GetHiMod(*((Handle(AIS_InteractiveObject)*)&SO));
610 if ( Ownr->IsAutoHilight() )
611 Ownr->HilightWithColor(PM,myCTX->SelectionColor(),HM);
612 else if ( aMap.IsBound (SO) )
613 aMap(SO)->Append ( Ownr );
615 NCollection_Handle<SelectMgr_SequenceOfOwner> aSeq = new SelectMgr_SequenceOfOwner;
616 aSeq->Append ( Ownr );
617 aMap.Bind ( SO, aSeq );
622 for ( SelectMgr_DataMapOfObjectOwners::Iterator aMapIter(aMap);
623 aMapIter.More(); aMapIter.Next() )
625 aMapIter.Key()->HilightSelected (myMainPM, *aMapIter.Value());
630 myCTX->CurrentViewer()->Update();
634 //==================================================
637 //==================================================
638 void AIS_LocalContext::UnhilightPicked (const Standard_Boolean updateviewer)
640 myMainPM->ClearImmediateDraw();
642 Standard_Boolean updMain(Standard_False);
644 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
646 if( Sel.IsNull() ) return;
648 Handle (PrsMgr_PresentationManager3d) PM = myMainPM;
649 NCollection_Map<Handle(SelectMgr_SelectableObject)> anObjMap;
651 #if !defined OCC189 && !defined USE_MAP
652 const TColStd_Array1OfTransient& Obj = Sel->Objects()->Array1();
653 for(Standard_Integer i =Obj.Lower();i<=Sel->NbStored();i++){
654 const Handle(Standard_Transient)& Tr = Obj(i);
656 const AIS_NListTransient& Obj = Sel->Objects();
657 AIS_NListTransient::Iterator anIter( Obj );
658 for(; anIter.More(); anIter.Next()){
659 const Handle(Standard_Transient)& Tr = anIter.Value();
662 const Handle(SelectMgr_EntityOwner)& Ownr =
663 *((const Handle(SelectMgr_EntityOwner)*) &Tr);
664 Standard_Integer HM(0);
665 if(Ownr->HasSelectable()){
667 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
668 Handle(AIS_InteractiveObject) IO = *((Handle(AIS_InteractiveObject)*)&SO);
673 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(Ownr);
674 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
676 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
677 Handle(AIS_InteractiveObject) IO = *((Handle(AIS_InteractiveObject)*)&SO);
680 updMain = Standard_True;
683 updMain = Standard_True;
685 Ownr->Unhilight(PM,HM);
689 for (NCollection_Map<Handle(SelectMgr_SelectableObject)>::Iterator anIter1 ( anObjMap );
690 anIter1.More(); anIter1.Next() )
692 if ( !anIter1.Key()->IsAutoHilight() )
693 anIter1.Key()->ClearSelected();
698 myCTX->CurrentViewer()->Update();
700 if(updMain) myCTX->CurrentViewer()->Update();
706 //=======================================================================
707 //function : IsSelected
709 //=======================================================================
710 Standard_Boolean AIS_LocalContext::IsSelected(const Handle(AIS_InteractiveObject)& anIObj) const
712 return (!FindSelectedOwnerFromIO(anIObj).IsNull());
715 //=======================================================================
716 //function : IsSelected
718 //=======================================================================
720 Standard_Boolean AIS_LocalContext::IsSelected (const Handle(SelectMgr_EntityOwner)& theOwner) const
722 return !theOwner.IsNull() && theOwner->IsSelected();
725 //==================================================
728 //==================================================
729 void AIS_LocalContext::
732 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
733 AIS_Selection::CurrentSelection()->Init();
736 //==================================================
739 //==================================================
740 Standard_Boolean AIS_LocalContext::
743 return AIS_Selection::CurrentSelection()->More();
746 //==================================================
749 //==================================================
750 void AIS_LocalContext::
753 AIS_Selection::CurrentSelection()->Next();
756 //==================================================
759 //==================================================
760 Standard_Boolean AIS_LocalContext::
763 Handle(Standard_Transient) Tr = AIS_Selection::CurrentSelection()->Value();
764 if( Tr.IsNull() ) return Standard_False;
765 Handle(SelectMgr_EntityOwner) EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
766 Handle(StdSelect_BRepOwner) BRO = Handle(StdSelect_BRepOwner)::DownCast(EO);
767 if(BRO.IsNull()) return Standard_False;
768 Standard_Boolean hasshape = BRO->HasShape();
769 Standard_Boolean comes = BRO->ComesFromDecomposition();
770 return (hasshape&&comes);
773 //==================================================
776 //==================================================
777 TopoDS_Shape AIS_LocalContext::SelectedShape() const
779 static TopoDS_Shape aSh;
780 Handle(Standard_Transient) Tr = AIS_Selection::CurrentSelection()->Value();
781 Handle(SelectMgr_EntityOwner) EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
782 Handle(StdSelect_BRepOwner) BRO = Handle(StdSelect_BRepOwner)::DownCast(EO);
787 return BRO->Shape().Located (BRO->Location());
790 //==================================================
793 //==================================================
794 Handle(AIS_InteractiveObject) AIS_LocalContext::
795 SelectedInteractive() const
797 Handle(AIS_InteractiveObject) IO;
798 Handle(Standard_Transient) Tr = AIS_Selection::CurrentSelection()->Value();
800 Handle(SelectMgr_EntityOwner) EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
801 Handle(SelectMgr_SelectableObject) SO;
802 if(EO->HasSelectable()){
803 SO = EO->Selectable();
804 IO = *((Handle(AIS_InteractiveObject)*)&SO);
809 //==================================================
812 //==================================================
813 Handle(SelectMgr_EntityOwner) AIS_LocalContext::
814 SelectedOwner() const
816 Handle(SelectMgr_EntityOwner) EO;
817 Handle(Standard_Transient) Tr = AIS_Selection::CurrentSelection()->Value();
819 EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
823 //==================================================
826 //==================================================
827 Standard_Boolean AIS_LocalContext::
828 HasApplicative() const
830 Handle(AIS_InteractiveObject) IO = SelectedInteractive();
831 if( IO.IsNull() ) return Standard_False;
832 return IO->HasOwner();
835 //==================================================
838 //==================================================
839 const Handle(Standard_Transient)& AIS_LocalContext::
840 SelectedApplicative() const
842 return SelectedInteractive()->GetOwner();
847 //=======================================================================
848 //function : UpdateSelection
849 //purpose : should disappear...
850 //=======================================================================
851 void AIS_LocalContext::UpdateSelected(const Standard_Boolean updateviewer)
853 UnhilightPicked(Standard_False);
854 HilightPicked(updateviewer);
857 //================================================================
858 // Function : UpdateSelected
859 // Purpose : Part of advanced selection mechanism.
860 // Highlightes or clears selection presentation for the given IO
861 //================================================================
862 void AIS_LocalContext::UpdateSelected(const Handle(AIS_InteractiveObject)& anobj,
863 const Standard_Boolean updateviewer)
865 if (anobj.IsNull() || anobj->IsAutoHilight())
868 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
869 Handle(AIS_Selection) Sel = AIS_Selection::CurrentSelection();
871 SelectMgr_SequenceOfOwner aSeq;
872 for ( Sel->Init(); Sel->More(); Sel->Next() ){
873 Handle(SelectMgr_EntityOwner) aOwner = Handle(SelectMgr_EntityOwner)::DownCast(Sel->Value());
875 if ( !aOwner.IsNull() && aOwner->HasSelectable() && aOwner->Selectable() == anobj )
876 aSeq.Append( aOwner );
880 anobj->HilightSelected( myMainPM, aSeq );
882 anobj->ClearSelected();
885 myCTX->CurrentViewer()->Update();
889 //==================================================
890 // Function: ClearSelected
892 //==================================================
893 void AIS_LocalContext::ClearSelected (const Standard_Boolean updateviewer)
895 UnhilightPicked(updateviewer);
896 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
898 Handle(AIS_Selection) Sel = AIS_Selection::CurrentSelection();
899 #if !defined OCC189 && !defined USE_MAP
900 const TColStd_Array1OfTransient& Obj = Sel->Objects()->Array1();
901 for(Standard_Integer i =Obj.Lower();i<=Sel->NbStored();i++){
902 const Handle(Standard_Transient)& Tr = Obj(i);
904 const AIS_NListTransient& Obj = Sel->Objects();
905 AIS_NListTransient::Iterator anIter( Obj );
906 for(; anIter.More(); anIter.Next()){
907 const Handle(Standard_Transient)& Tr = anIter.Value();
911 (*((const Handle(SelectMgr_EntityOwner)*)&Tr))->SetSelected (Standard_False);
914 AIS_Selection::Select();
918 //==================================================
919 // Function: ClearSelected
921 //==================================================
922 void AIS_LocalContext::ClearSelected (const Handle(AIS_InteractiveObject)& theIO,
923 const Standard_Boolean toUpdateViewer)
925 // Keep last detected object for lastindex initialization.
926 Handle(SelectMgr_EntityOwner) aLastPicked = myMainVS->OnePicked();
928 // Remove the interactive object from detected sequence
929 for (Standard_Integer anIdx = 1; anIdx <= myAISDetectedSeq.Length(); ++anIdx)
931 Handle(AIS_InteractiveObject) aDetectedIO = myAISDetectedSeq.Value (anIdx);
932 if (!aDetectedIO.IsNull() && aDetectedIO == theIO)
934 myAISDetectedSeq.Remove (anIdx--);
938 Standard_Integer aHilightMode = theIO->HasHilightMode() ? theIO->HilightMode() : 0;
940 // Remove entity owners from AIS_Selection
941 Handle(AIS_Selection) aSelection = AIS_Selection::Selection (mySelName.ToCString());
942 AIS_NListTransient::Iterator anIter (aSelection->Objects());
943 AIS_NListTransient aRemoveEntites;
944 for (; anIter.More(); anIter.Next())
946 Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anIter.Value());
947 if (anOwner.IsNull() || anOwner->Selectable() != theIO)
952 aRemoveEntites.Append (anOwner);
954 if (IsSelected (anOwner))
956 anOwner->Unhilight (myMainPM, aHilightMode);
959 AIS_NListTransient::Iterator anIterRemove (aRemoveEntites);
960 for (; anIterRemove.More(); anIterRemove.Next())
962 aSelection->Select (anIterRemove.Value());
965 // Remove entity owners from myMapOfOwner
966 SelectMgr_IndexedMapOfOwner anOwnersToKeep;
967 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
968 for (Standard_Integer anIdx = 1; anIdx <= myMapOfOwner.Extent(); anIdx++)
970 Handle(SelectMgr_EntityOwner) anOwner = myMapOfOwner (anIdx);
971 if (anOwner.IsNull())
976 if (anOwner->Selectable() != theIO)
978 anOwnersToKeep.Add (anOwner);
982 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
984 Unhilight (anOwner, aViewer->ActiveView());
988 myMapOfOwner.Clear();
989 myMapOfOwner.Assign (anOwnersToKeep);
990 mylastindex = myMapOfOwner.FindIndex (aLastPicked);
998 //=======================================================================
999 //function : SetSelected
1001 //=======================================================================
1002 void AIS_LocalContext::SetSelected(const Handle(AIS_InteractiveObject)& anIObj,
1003 const Standard_Boolean updateviewer)
1005 if(!IsValidForSelection(anIObj)) return;
1006 UnhilightPicked(Standard_False);
1008 //1st case, owner already <anIObj> as owner
1009 // and not separated is found...
1011 Handle(AIS_Selection) sel = AIS_Selection::Selection(mySelName.ToCString());
1012 //Standard_Boolean found(Standard_False);
1013 Handle(Standard_Transient) Tr;
1014 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromIO(anIObj);
1016 //check if in selection number 0 there is an owner that can be triturated...
1017 if(anIObj->HasSelection(0)){
1018 const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0);
1021 Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->OwnerId();
1022 EO = *((Handle(SelectMgr_EntityOwner)*)&BO);
1026 EO = new SelectMgr_EntityOwner(anIObj);
1029 ClearSelected(Standard_False);
1031 AIS_Selection::Select(EO);
1032 EO->SetSelected (Standard_True);
1034 HilightPicked(updateviewer);
1037 //=======================================================================
1038 //function : AddOrRemoveSelected
1040 //=======================================================================
1042 void AIS_LocalContext::AddOrRemoveSelected(const Handle(AIS_InteractiveObject)& anIObj,
1043 const Standard_Boolean updateviewer)
1045 if(!IsValidForSelection(anIObj)) return;
1046 UnhilightPicked(Standard_False);
1047 // first check if it is selected...
1048 Handle(SelectMgr_EntityOwner) EO;
1050 EO = FindSelectedOwnerFromIO(anIObj);
1054 if(anIObj->HasSelection(0))
1056 const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0);
1060 Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->OwnerId();
1061 EO = *((Handle(SelectMgr_EntityOwner)*)&BO);
1066 EO = new SelectMgr_EntityOwner(anIObj);
1070 // cout<<"AIS_LocalContext::AddOrRemoveSelected : Selection = "<<mySelName<<endl;
1071 const Handle(AIS_Selection)& S = AIS_Selection::Selection(mySelName.ToCString());
1075 AIS_SelectStatus aStatus = S->Select(EO);
1076 EO->SetSelected (aStatus == AIS_SS_Added);
1079 HilightPicked(updateviewer);
1082 //=======================================================================
1083 //function : AddOrRemoveSelected
1084 //purpose : To check...
1085 //=======================================================================
1086 void AIS_LocalContext::AddOrRemoveSelected(const TopoDS_Shape& Sh,
1087 const Standard_Boolean updateviewer)
1089 UnhilightPicked (Standard_False);
1090 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromShape(Sh);
1093 AIS_Selection::Selection(mySelName.ToCString())->Select(EO);
1094 EO->SetSelected (Standard_True);
1096 HilightPicked (updateviewer);
1099 void AIS_LocalContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
1100 const Standard_Boolean toUpdateViewer)
1104 UnhilightPicked (Standard_False);
1107 Standard_Boolean toSelect = theOwner->IsSelected() ? Standard_False : Standard_True;
1109 AIS_Selection::Selection (mySelName.ToCString())->Select (theOwner);
1110 theOwner->SetSelected (toSelect);
1114 HilightPicked (toUpdateViewer);
1118 //==================================================
1119 // Function: manageDetected
1121 //==================================================
1122 void AIS_LocalContext::manageDetected (const Handle(SelectMgr_EntityOwner)& thePickOwner,
1123 const Handle(V3d_View)& theView,
1124 const Standard_Boolean theToRedrawImmediate)
1126 if (thePickOwner.IsNull())
1128 if (theToRedrawImmediate)
1130 theView->RedrawImmediate();
1135 if (!myFilters->IsOk (thePickOwner))
1137 if (mylastindex != 0)
1139 mylastgood = mylastindex;
1141 if (theToRedrawImmediate)
1143 theView->RedrawImmediate();
1148 //=======================================================================================================
1149 // 2 cases : a- object is in the map of picks:
1150 // 1. this is the same index as the last detected: -> Do nothing
1152 // - if lastindex = 0 (no object was detected at the last step)
1153 // the object presentation is highlighted and lastindex = index(objet)
1155 // the presentation of the object corresponding to lastindex is "unhighlighted"
1156 // it is removed if the object is not visualized but only active
1157 // then the presentation of the detected object is highlighted and lastindex = index(objet)
1158 // b- the object is not in the map of picked objects
1159 // - if lastindex != 0 (object detected at the last step) it is unhighlighted ...
1160 // if the object was decomposed, presentation is created for the detected shape and the couple
1161 // (Proprietaire,Prs)is added in the map.
1162 // otherwise the couple(proprietaire, NullPrs) is placed in the map and the interactive object
1163 // itself is highlighted.
1165 //=======================================================================================================
1167 const Standard_Integer aNewIndex = myMapOfOwner.Contains (thePickOwner)
1168 ? myMapOfOwner.FindIndex (thePickOwner)
1169 : myMapOfOwner.Add (thePickOwner);
1171 // For the advanced mesh selection mode the owner indices comparison
1172 // is not effective because in that case only one owner manage the
1173 // selection in current selection mode. It is necessary to check the current detected
1174 // entity and hilight it only if the detected entity is not the same as
1175 // previous detected (IsForcedHilight call)
1176 if (aNewIndex != mylastindex
1177 || thePickOwner->IsForcedHilight())
1179 if (mylastindex != 0
1180 && mylastindex <= myMapOfOwner.Extent())
1182 const Handle(SelectMgr_EntityOwner)& aLastOwner = myMapOfOwner (mylastindex);
1183 Unhilight (aLastOwner, theView);
1188 if (!thePickOwner->IsSelected() || myCTX->ToHilightSelected())
1190 Hilight (thePickOwner, theView);
1192 if (theToRedrawImmediate)
1194 theView->RedrawImmediate();
1198 mylastindex = aNewIndex;
1203 mylastgood = mylastindex;
1207 //=======================================================================
1208 //function : HasDetectedShape
1210 //=======================================================================
1212 Standard_Boolean AIS_LocalContext::HasDetectedShape() const
1214 if(mylastindex==0) return Standard_False;
1215 return IsShape(mylastindex);
1218 //=======================================================================
1219 //function : DetectedShape
1221 //=======================================================================
1224 AIS_LocalContext::DetectedShape() const
1226 static TopoDS_Shape bidsh;
1227 if(mylastindex != 0)
1229 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner(mylastindex));
1230 if(BROwnr.IsNull()) return bidsh;
1231 return BROwnr->Shape();
1236 //=======================================================================
1237 //function : DetectedInteractive
1239 //=======================================================================
1241 Handle(AIS_InteractiveObject)
1242 AIS_LocalContext::DetectedInteractive() const
1244 Handle(AIS_InteractiveObject) Iobj;
1245 if(IsValidIndex(mylastindex)){
1246 Handle(SelectMgr_SelectableObject) SO = myMapOfOwner.FindKey(mylastindex)->Selectable();
1247 Iobj = *((Handle(AIS_InteractiveObject)*) &SO);
1251 //=======================================================================
1252 //function : DetectedInteractive
1254 //=======================================================================
1255 Handle(SelectMgr_EntityOwner) AIS_LocalContext::DetectedOwner() const
1257 Handle(SelectMgr_EntityOwner) bid;
1258 if(!IsValidIndex(mylastindex)) return bid;
1259 return myMapOfOwner.FindKey(mylastindex);
1263 //=======================================================================
1264 //function : ComesFromDecomposition
1266 //=======================================================================
1268 Standard_Boolean AIS_LocalContext::ComesFromDecomposition(const Standard_Integer PickedIndex) const
1270 const Handle(SelectMgr_EntityOwner)& OWN = myMapOfOwner.FindKey(PickedIndex);
1271 Handle(SelectMgr_SelectableObject) aSel = OWN->Selectable();
1272 if (myActiveObjects.IsBound (aSel)) { // debug of jmi
1273 const Handle(AIS_LocalStatus)& Stat = myActiveObjects(aSel);
1274 return Stat->Decomposed();
1276 return Standard_False;
1280 //=======================================================================
1281 //function : DisplayAreas
1283 //=======================================================================
1285 void AIS_LocalContext::DisplayAreas(const Handle(V3d_View)& aviou)
1287 myMainVS->DisplayAreas(aviou);
1290 //=======================================================================
1291 //function : ClearAreas
1293 //=======================================================================
1295 void AIS_LocalContext::ClearAreas(const Handle(V3d_View)& aviou)
1297 myMainVS->ClearAreas(aviou);
1300 //=======================================================================
1301 //function : DisplaySensitive
1303 //=======================================================================
1305 void AIS_LocalContext::DisplaySensitive(const Handle(V3d_View)& aviou)
1307 myMainVS->DisplaySensitive(aviou);
1310 //=======================================================================
1311 //function : ClearSensitive
1313 //=======================================================================
1315 void AIS_LocalContext::ClearSensitive(const Handle(V3d_View)& aviou)
1317 myMainVS->ClearSensitive(aviou);
1321 //=======================================================================
1322 //function : IsShape
1324 //=======================================================================
1325 Standard_Boolean AIS_LocalContext::IsShape(const Standard_Integer Index) const
1328 if(Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner.FindKey(Index)).IsNull())
1329 return Standard_False;
1331 ComesFromDecomposition(Index);
1334 Standard_Boolean AIS_LocalContext::IsValidForSelection(const Handle(AIS_InteractiveObject)& anIObj) const
1338 // Shape was not transfered from AIS_Shape to EntityOwner
1339 Handle(AIS_Shape) shape = Handle(AIS_Shape)::DownCast(anIObj);
1340 if( !shape.IsNull() )
1341 return myFilters->IsOk(new StdSelect_BRepOwner(shape->Shape(),shape));
1343 return myFilters->IsOk(new SelectMgr_EntityOwner(anIObj));
1347 //=======================================================================
1348 //function : HilightNextDetected
1350 //=======================================================================
1351 Standard_Integer AIS_LocalContext::HilightNextDetected (const Handle(V3d_View)& theView,
1352 const Standard_Boolean theToRedrawImmediate)
1354 // go to the next owner
1355 if (myDetectedSeq.IsEmpty())
1360 const Standard_Integer aLen = myDetectedSeq.Length();
1361 if (++myCurDetected > aLen)
1365 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myCurDetected);
1366 if (anOwner.IsNull())
1370 manageDetected (anOwner, theView, theToRedrawImmediate);
1371 return myCurDetected;
1374 //=======================================================================
1375 //function : HilightPreviousDetected
1377 //=======================================================================
1378 Standard_Integer AIS_LocalContext::HilightPreviousDetected (const Handle(V3d_View)& theView,
1379 const Standard_Boolean theToRedrawImmediate)
1381 if (myDetectedSeq.IsEmpty())
1386 if (--myCurDetected < 1)
1390 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myCurDetected);
1391 if (anOwner.IsNull())
1396 manageDetected (anOwner, theView, theToRedrawImmediate);
1397 return myCurDetected;
1400 //=======================================================================
1401 //function : UnhilightLastDetected
1403 //=======================================================================
1404 Standard_Boolean AIS_LocalContext::UnhilightLastDetected (const Handle(V3d_View)& theView)
1406 if (!IsValidIndex (mylastindex))
1408 return Standard_False;
1411 myMainPM->BeginImmediateDraw();
1412 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner (mylastindex);
1413 const Standard_Integer aHilightMode = anOwner->HasSelectable()
1414 ? GetHiMod (Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable()))
1417 myMapOfOwner (mylastindex)->Unhilight (myMainPM, aHilightMode);
1418 myMainPM->EndImmediateDraw (theView);
1420 return Standard_True;
1423 //=======================================================================
1424 //function : FindSelectedOwnerFromIO
1425 //purpose : it is checked if one of the selected owners really presents IObj
1426 //=======================================================================
1427 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromIO
1428 (const Handle(AIS_InteractiveObject)& anIObj) const
1430 Handle(SelectMgr_EntityOwner) EO,bid;
1431 if (anIObj.IsNull()) return EO;
1433 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
1436 cout<<"\t\tAIS_LocalCOntext::FindSelectedOwnerFromShape : Selection "
1437 <<mySelName<<" Nulle "<<endl;
1441 Standard_Boolean found(Standard_False);
1442 #if !defined OCC189 && !defined USE_MAP
1443 const TColStd_Array1OfTransient& Obj = Sel->Objects()->Array1();
1444 for(Standard_Integer i =Obj.Lower();i<=Sel->NbStored();i++){
1445 const Handle(Standard_Transient)& Tr = Obj(i);
1447 const AIS_NListTransient& Obj = Sel->Objects();
1448 AIS_NListTransient::Iterator anIter( Obj );
1449 for(; anIter.More(); anIter.Next()){
1450 const Handle(Standard_Transient)& Tr = anIter.Value();
1453 EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
1454 if(EO->HasSelectable()){
1455 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1456 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
1457 if (anIObj == EO->Selectable()){
1458 found =Standard_True;
1465 if(found) return EO;
1469 //=======================================================================
1470 //function : FindSelectedOwnerFromShape
1471 //purpose : it is checked if one of the selected owners really presents IObj
1472 //=======================================================================
1473 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromShape(const TopoDS_Shape& sh) const
1476 Handle(SelectMgr_EntityOwner) EO, bid;
1478 Handle(SelectMgr_EntityOwner) EO;
1480 if (sh.IsNull()) return EO;
1482 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
1485 cout<<"\t\tAIS_LocalCOntext::FindSelectedOwnerFromShape : Selection "<<mySelName<<" Nulle "<<endl;
1490 Standard_Boolean found(Standard_False);
1494 SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive aSensitiveIt (myMainVS->Primitives());
1495 for (; aSensitiveIt.More(); aSensitiveIt.Next()) {
1496 EO = Handle(SelectMgr_EntityOwner)::DownCast (aSensitiveIt.Value()->OwnerId());
1497 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1498 if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) {
1499 found = Standard_True;
1505 #if !defined OCC189 && !defined USE_MAP
1506 const TColStd_Array1OfTransient& Obj = Sel->Objects()->Array1();
1507 for(Standard_Integer i =Obj.Lower();i<=Sel->NbStored();i++){
1508 const Handle(Standard_Transient)& Tr = Obj(i);
1510 const AIS_NListTransient& Obj = Sel->Objects();
1511 AIS_NListTransient::Iterator anIter( Obj );
1512 for(; anIter.More(); anIter.Next()){
1513 const Handle(Standard_Transient)& Tr = anIter.Value();
1517 EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
1519 if ( EO->Shape() == sh)
1520 found =Standard_True;
1526 if(found) return EO;
1531 //=======================================================================
1532 //function : AIS_LocalContext::InitDetected
1534 //=======================================================================
1535 void AIS_LocalContext::InitDetected()
1537 myAISCurDetected = myAISDetectedSeq.Length()? 1 : 0;
1540 //=======================================================================
1541 //function : AIS_LocalContext::MoreDetected
1543 //=======================================================================
1544 Standard_Boolean AIS_LocalContext::MoreDetected() const
1546 return (myAISCurDetected > 0 && myAISCurDetected <= myAISDetectedSeq.Length());
1549 //=======================================================================
1550 //function : AIS_LocalContext::NextDetected
1552 //=======================================================================
1553 void AIS_LocalContext::NextDetected()
1558 //=======================================================================
1559 //function : DetectedCurrentShape
1561 //=======================================================================
1562 const TopoDS_Shape& AIS_LocalContext::DetectedCurrentShape() const
1564 static TopoDS_Shape aDummyShape;
1566 Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
1568 if (aCurrentShape.IsNull())
1573 return aCurrentShape->Shape();
1575 //=======================================================================
1576 //function : DetectedCurrentObject
1578 //=======================================================================
1579 Handle(AIS_InteractiveObject) AIS_LocalContext::DetectedCurrentObject() const
1581 return MoreDetected() ? myAISDetectedSeq(myAISCurDetected) : NULL;