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 updateviewer)
191 UnhilightPicked(Standard_False);
193 Standard_Integer DI = DetectedIndex();
194 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
195 Standard_Integer NbSel = AIS_Selection::Extent();
198 ClearSelected(updateviewer);
199 return NbSel== 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
202 const Handle(SelectMgr_EntityOwner)& EO = myMapOfOwner(DI);
205 ClearSelected(Standard_False);
206 Standard_Integer state = EO->State();
209 if( state == 0 ) AIS_Selection::Select(EO);
213 AIS_Selection::ClearAndSelect(EO);
218 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
219 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
221 Unhilight (EO, aViewer->ActiveView());
224 // advanced selection highlighting mechanism
225 if (!EO->IsAutoHilight() && EO->HasSelectable())
227 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(EO->Selectable());
228 UpdateSelected (anIO, Standard_False);
233 myCTX->CurrentViewer()->Update();
236 return ( AIS_Selection::Extent() == 1)? AIS_SOP_OneSelected : AIS_SOP_SeveralSelected ;
238 //==================================================
241 //==================================================
242 AIS_StatusOfPick AIS_LocalContext::Select(const Standard_Integer XPMin,
243 const Standard_Integer YPMin,
244 const Standard_Integer XPMax,
245 const Standard_Integer YPMax,
246 const Handle(V3d_View)& aView,
247 const Standard_Boolean updateviewer)
249 if(aView->Viewer()== myCTX->CurrentViewer()){
250 myMainVS->Pick( XPMin,YPMin,XPMax,YPMax,aView);
251 if (myAutoHilight) UnhilightPicked(Standard_False);
253 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
254 Standard_Integer LastExt = AIS_Selection::Extent();
257 if(!myMainVS->More()) {
258 ClearSelected(updateviewer);
260 return LastExt == 0 ? AIS_SOP_NothingSelected:AIS_SOP_Removed;
263 ClearSelected(Standard_False);
265 for(myMainVS->Init();myMainVS->More();myMainVS->Next()){
266 const Handle(SelectMgr_EntityOwner)& OWNR = myMainVS->Picked();
267 if(myFilters->IsOk(OWNR)){
268 // it can be helpfil to classify this owner immediately...
270 Standard_Integer state = OWNR->State();
273 if( state == 0 ) AIS_Selection::Select(OWNR);
277 if( state == 0 ) AIS_Selection::Select(OWNR);
281 if(!IsSelected(OWNR)){
283 AIS_Selection::Select(OWNR);
289 HilightPicked(updateviewer);
292 Standard_Integer NS = AIS_Selection::Extent();
293 if( NS == 1 ) return AIS_SOP_OneSelected;
294 else if( NS > 1 ) return AIS_SOP_SeveralSelected;
296 return AIS_SOP_Error;
301 //==================================================
304 //==================================================
305 AIS_StatusOfPick AIS_LocalContext::ShiftSelect(const Standard_Boolean updateviewer)
307 Standard_Integer I = DetectedIndex();
310 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
312 Standard_Integer NbSel = AIS_Selection::Extent();
314 const Handle(SelectMgr_EntityOwner)& EO = myMapOfOwner(I);
316 Standard_Integer mod = EO->State()==0 ? -1 : 0;
318 Standard_Integer mod = EO->State()==0 ? 1 : 0;
322 AIS_Selection::Select(EO);
327 AIS_Selection::Select(EO);
332 const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
333 for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
335 Unhilight (EO, aViewer->ActiveView());
338 // advanced selection highlighting mechanism
339 if (!EO->IsAutoHilight() && EO->HasSelectable())
341 Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (EO->Selectable());
342 UpdateSelected (anIO, Standard_False);
347 myCTX->CurrentViewer()->Update();
351 Standard_Integer NS = AIS_Selection::Extent();
352 if( NS == 1 ) return AIS_SOP_OneSelected;
353 else if( NS > 1 ) return AIS_SOP_SeveralSelected;
354 return NbSel== 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
357 return AIS_SOP_Error;
359 //==================================================
360 // Function: the already selected objects are unselected
361 // Purpose : others are selected.
362 //==================================================
363 AIS_StatusOfPick AIS_LocalContext::ShiftSelect(const Standard_Integer XPMin,
364 const Standard_Integer YPMin,
365 const Standard_Integer XPMax,
366 const Standard_Integer YPMax,
367 const Handle(V3d_View)& aView,
368 const Standard_Boolean updateviewer)
370 myMainPM->ClearImmediateDraw();
372 if(aView->Viewer()== myCTX->CurrentViewer()) {
373 myMainVS->Pick( XPMin,YPMin,XPMax,YPMax,aView);
375 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
376 Standard_Integer LastExt = AIS_Selection::Extent();
379 if(!myMainVS->More())
381 return LastExt == 0 ? AIS_SOP_NothingSelected:AIS_SOP_Removed;
383 return AIS_SOP_NothingSelected; // no effet if click on empty space
386 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
387 if (myAutoHilight) UnhilightPicked(Standard_False);
389 for(myMainVS->Init();myMainVS->More();myMainVS->Next()){
390 const Handle(SelectMgr_EntityOwner)& EO = myMainVS->Picked();
391 if(myFilters->IsOk(EO)){
393 Standard_Integer mod = EO->State()==0 ? -1 : 0;
395 Standard_Integer mod = EO->State()==0 ? 1 : 0;
399 AIS_Selection::Select(EO);
403 AIS_Selection::Select(EO);
407 if (myAutoHilight) HilightPicked(updateviewer);
411 Standard_Integer NS = AIS_Selection::Extent();
412 if( NS == 1 ) return AIS_SOP_OneSelected;
413 else if( NS > 1 ) return AIS_SOP_SeveralSelected;
415 return AIS_SOP_Error;
418 //==================================================
420 // Purpose : Selection by polyline
421 //==================================================
422 AIS_StatusOfPick AIS_LocalContext::Select(const TColgp_Array1OfPnt2d& aPolyline,
423 const Handle(V3d_View)& aView,
424 const Standard_Boolean updateviewer)
426 if(aView->Viewer()== myCTX->CurrentViewer()){
427 myMainVS->Pick(aPolyline,aView);
428 if (myAutoHilight) UnhilightPicked(Standard_False);
430 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
431 Standard_Integer LastExt = AIS_Selection::Extent();
434 if(!myMainVS->More()) {
435 ClearSelected(updateviewer);
437 return LastExt == 0 ? AIS_SOP_NothingSelected:AIS_SOP_Removed;
440 ClearSelected(Standard_False);
442 for(myMainVS->Init();myMainVS->More();myMainVS->Next()){
443 const Handle(SelectMgr_EntityOwner)& OWNR = myMainVS->Picked();
444 if(myFilters->IsOk(OWNR)){
445 // it can be helpfil to classify this owner immediately...
447 Standard_Integer state = OWNR->State();
449 if( state == 0 ) AIS_Selection::AddSelect(OWNR);
453 if(!IsSelected(OWNR)){
455 AIS_Selection::AddSelect(OWNR);
462 HilightPicked(updateviewer);
465 Standard_Integer NS = AIS_Selection::Extent();
466 if( NS == 1 ) return AIS_SOP_OneSelected;
467 else if( NS > 1 ) return AIS_SOP_SeveralSelected;
469 return AIS_SOP_Error;
472 //==================================================
474 // Purpose : Selection by polyline
475 //==================================================
476 AIS_StatusOfPick AIS_LocalContext::ShiftSelect( const TColgp_Array1OfPnt2d& aPolyline,
477 const Handle(V3d_View)& aView,
478 const Standard_Boolean updateviewer )
480 if( aView->Viewer() == myCTX->CurrentViewer() ) {
481 myMainVS->Pick( aPolyline, aView );
483 AIS_Selection::SetCurrentSelection( mySelName.ToCString() );
484 Standard_Integer LastExt = AIS_Selection::Extent();
486 if( !myMainVS->More() )
487 return LastExt == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
489 AIS_Selection::SetCurrentSelection( mySelName.ToCString() );
492 UnhilightPicked( Standard_False );
493 for( myMainVS->Init(); myMainVS->More(); myMainVS->Next() ) {
494 const Handle(SelectMgr_EntityOwner)& EO = myMainVS->Picked();
495 if( myFilters->IsOk( EO ) ) {
496 Standard_Integer mod = EO->State() == 0 ? -1 : 0;
497 AIS_Selection::Select(EO);
502 HilightPicked( updateviewer );
504 Standard_Integer NS = AIS_Selection::Extent();
506 return AIS_SOP_OneSelected;
508 return AIS_SOP_SeveralSelected;
509 return AIS_SOP_Error;
512 //==================================================
515 //==================================================
516 void AIS_LocalContext::Hilight (const Handle(SelectMgr_EntityOwner)& theOwner,
517 const Handle(V3d_View)& theView)
519 if (theView.IsNull())
524 const Standard_Integer aHilightMode = GetHiMod (Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable()));
525 myMainPM->BeginImmediateDraw();
526 theOwner->HilightWithColor (myMainPM, myCTX->HilightColor(), aHilightMode);
527 myMainPM->EndImmediateDraw (theView);
530 //==================================================
531 // Function: Unhilight
533 //==================================================
534 void AIS_LocalContext::Unhilight (const Handle(SelectMgr_EntityOwner)& theOwner,
535 const Handle(V3d_View)& theView)
537 if (theView.IsNull())
542 myMainPM->ClearImmediateDraw();
543 const Standard_Integer aHilightMode = GetHiMod (Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable()));
544 if (IsSelected (theOwner))
546 if (theOwner->IsAutoHilight())
548 theOwner->HilightWithColor (myMainPM, myCTX->SelectionColor(), aHilightMode);
553 theOwner->Unhilight (myMainPM, aHilightMode);
557 //=======================================================================
558 //function : HilightPicked
560 //=======================================================================
561 void AIS_LocalContext::HilightPicked(const Standard_Boolean updateviewer)
563 Standard_Boolean updMain(Standard_False);
565 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
567 if( Sel.IsNull() ) return;
570 typedef NCollection_DataMap <Handle(SelectMgr_SelectableObject), NCollection_Handle<SelectMgr_SequenceOfOwner> > SelectMgr_DataMapOfObjectOwners;
571 SelectMgr_DataMapOfObjectOwners aMap;
573 Handle (PrsMgr_PresentationManager3d) PM = myMainPM;
575 // to avoid problems when there is a loop searching for selected objects...
576 #if !defined OCC189 && !defined USE_MAP
577 const TColStd_Array1OfTransient& Obj = Sel->Objects()->Array1();
578 for(Standard_Integer i =Obj.Lower();i<=Sel->NbStored();i++)
580 const Handle(Standard_Transient)& Tr = Obj(i);
582 const AIS_NListTransient& Obj = Sel->Objects();
583 AIS_NListTransient::Iterator anIter( Obj );
584 for(; anIter.More(); anIter.Next())
586 const Handle(Standard_Transient)& Tr = anIter.Value();
589 const Handle(SelectMgr_EntityOwner)& Ownr =
590 *((const Handle(SelectMgr_EntityOwner)*) &Tr);
591 Handle(AIS_InteractiveObject) IO;
592 if(Ownr->HasSelectable()){
593 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(Ownr);
594 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
595 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
596 IO = *((Handle(AIS_InteractiveObject)*)&SO);
597 updMain = Standard_True;
600 updMain = Standard_True;
603 updMain = Standard_True;
604 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
605 Standard_Integer HM = GetHiMod(*((Handle(AIS_InteractiveObject)*)&SO));
606 if ( Ownr->IsAutoHilight() )
607 Ownr->HilightWithColor(PM,myCTX->SelectionColor(),HM);
608 else if ( aMap.IsBound (SO) )
609 aMap(SO)->Append ( Ownr );
611 NCollection_Handle<SelectMgr_SequenceOfOwner> aSeq = new SelectMgr_SequenceOfOwner;
612 aSeq->Append ( Ownr );
613 aMap.Bind ( SO, aSeq );
618 for ( SelectMgr_DataMapOfObjectOwners::Iterator aMapIter(aMap);
619 aMapIter.More(); aMapIter.Next() )
621 aMapIter.Key()->HilightSelected (myMainPM, *aMapIter.Value());
626 myCTX->CurrentViewer()->Update();
630 //==================================================
633 //==================================================
634 void AIS_LocalContext::UnhilightPicked (const Standard_Boolean updateviewer)
636 myMainPM->ClearImmediateDraw();
638 Standard_Boolean updMain(Standard_False);
640 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
642 if( Sel.IsNull() ) return;
644 Handle (PrsMgr_PresentationManager3d) PM = myMainPM;
645 NCollection_Map<Handle(SelectMgr_SelectableObject)> anObjMap;
647 #if !defined OCC189 && !defined USE_MAP
648 const TColStd_Array1OfTransient& Obj = Sel->Objects()->Array1();
649 for(Standard_Integer i =Obj.Lower();i<=Sel->NbStored();i++){
650 const Handle(Standard_Transient)& Tr = Obj(i);
652 const AIS_NListTransient& Obj = Sel->Objects();
653 AIS_NListTransient::Iterator anIter( Obj );
654 for(; anIter.More(); anIter.Next()){
655 const Handle(Standard_Transient)& Tr = anIter.Value();
658 const Handle(SelectMgr_EntityOwner)& Ownr =
659 *((const Handle(SelectMgr_EntityOwner)*) &Tr);
660 Standard_Integer HM(0);
661 if(Ownr->HasSelectable()){
663 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
664 Handle(AIS_InteractiveObject) IO = *((Handle(AIS_InteractiveObject)*)&SO);
669 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(Ownr);
670 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
672 Handle(SelectMgr_SelectableObject) SO = Ownr->Selectable();
673 Handle(AIS_InteractiveObject) IO = *((Handle(AIS_InteractiveObject)*)&SO);
676 updMain = Standard_True;
679 updMain = Standard_True;
681 Ownr->Unhilight(PM,HM);
685 for (NCollection_Map<Handle(SelectMgr_SelectableObject)>::Iterator anIter1 ( anObjMap );
686 anIter1.More(); anIter1.Next() )
688 if ( !anIter1.Key()->IsAutoHilight() )
689 anIter1.Key()->ClearSelected();
694 myCTX->CurrentViewer()->Update();
696 if(updMain) myCTX->CurrentViewer()->Update();
702 //=======================================================================
703 //function : IsSelected
705 //=======================================================================
706 Standard_Boolean AIS_LocalContext::IsSelected(const Handle(AIS_InteractiveObject)& anIObj) const
708 return (!FindSelectedOwnerFromIO(anIObj).IsNull());
711 //=======================================================================
712 //function : IsSelected
714 //=======================================================================
716 Standard_Boolean AIS_LocalContext::IsSelected(const Handle(SelectMgr_EntityOwner)& Ownr) const
718 if (Ownr.IsNull()) return Standard_False;
720 Standard_Boolean state = (Ownr->State()!=0);
722 Standard_Boolean state = (Ownr->State()==1);
727 //==================================================
730 //==================================================
731 void AIS_LocalContext::
734 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
735 AIS_Selection::CurrentSelection()->Init();
738 //==================================================
741 //==================================================
742 Standard_Boolean AIS_LocalContext::
745 return AIS_Selection::CurrentSelection()->More();
748 //==================================================
751 //==================================================
752 void AIS_LocalContext::
755 AIS_Selection::CurrentSelection()->Next();
758 //==================================================
761 //==================================================
762 Standard_Boolean AIS_LocalContext::
765 Handle(Standard_Transient) Tr = AIS_Selection::CurrentSelection()->Value();
766 if( Tr.IsNull() ) return Standard_False;
767 Handle(SelectMgr_EntityOwner) EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
768 Handle(StdSelect_BRepOwner) BRO = Handle(StdSelect_BRepOwner)::DownCast(EO);
769 if(BRO.IsNull()) return Standard_False;
770 Standard_Boolean hasshape = BRO->HasShape();
771 Standard_Boolean comes = BRO->ComesFromDecomposition();
772 return (hasshape&&comes);
775 //==================================================
778 //==================================================
779 const TopoDS_Shape& AIS_LocalContext::
780 SelectedShape() const
782 static TopoDS_Shape aSh;
783 Handle(Standard_Transient) Tr = AIS_Selection::CurrentSelection()->Value();
784 Handle(SelectMgr_EntityOwner) EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
785 Handle(StdSelect_BRepOwner) BRO = Handle(StdSelect_BRepOwner)::DownCast(EO);
793 //==================================================
796 //==================================================
797 Handle(AIS_InteractiveObject) AIS_LocalContext::
798 SelectedInteractive() const
800 Handle(AIS_InteractiveObject) IO;
801 Handle(Standard_Transient) Tr = AIS_Selection::CurrentSelection()->Value();
803 Handle(SelectMgr_EntityOwner) EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
804 Handle(SelectMgr_SelectableObject) SO;
805 if(EO->HasSelectable()){
806 SO = EO->Selectable();
807 IO = *((Handle(AIS_InteractiveObject)*)&SO);
812 //==================================================
815 //==================================================
816 Handle(SelectMgr_EntityOwner) AIS_LocalContext::
817 SelectedOwner() const
819 Handle(SelectMgr_EntityOwner) EO;
820 Handle(Standard_Transient) Tr = AIS_Selection::CurrentSelection()->Value();
822 EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
826 //==================================================
829 //==================================================
830 Standard_Boolean AIS_LocalContext::
831 HasApplicative() const
833 Handle(AIS_InteractiveObject) IO = SelectedInteractive();
834 if( IO.IsNull() ) return Standard_False;
835 return IO->HasOwner();
838 //==================================================
841 //==================================================
842 const Handle(Standard_Transient)& AIS_LocalContext::
843 SelectedApplicative() const
845 return SelectedInteractive()->GetOwner();
850 //=======================================================================
851 //function : UpdateSelection
852 //purpose : should disappear...
853 //=======================================================================
854 void AIS_LocalContext::UpdateSelected(const Standard_Boolean updateviewer)
856 UnhilightPicked(Standard_False);
857 HilightPicked(updateviewer);
860 //================================================================
861 // Function : UpdateSelected
862 // Purpose : Part of advanced selection mechanism.
863 // Highlightes or clears selection presentation for the given IO
864 //================================================================
865 void AIS_LocalContext::UpdateSelected(const Handle(AIS_InteractiveObject)& anobj,
866 const Standard_Boolean updateviewer)
868 if (anobj.IsNull() || anobj->IsAutoHilight())
871 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
872 Handle(AIS_Selection) Sel = AIS_Selection::CurrentSelection();
874 SelectMgr_SequenceOfOwner aSeq;
875 for ( Sel->Init(); Sel->More(); Sel->Next() ){
876 Handle(SelectMgr_EntityOwner) aOwner = Handle(SelectMgr_EntityOwner)::DownCast(Sel->Value());
878 if ( !aOwner.IsNull() && aOwner->HasSelectable() && aOwner->Selectable() == anobj )
879 aSeq.Append( aOwner );
883 anobj->HilightSelected( myMainPM, aSeq );
885 anobj->ClearSelected();
888 myCTX->CurrentViewer()->Update();
892 //==================================================
893 // Function: ClearSelected
895 //==================================================
896 void AIS_LocalContext::ClearSelected(const Standard_Boolean updateviewer)
898 UnhilightPicked(updateviewer);
899 AIS_Selection::SetCurrentSelection(mySelName.ToCString());
901 Handle(AIS_Selection) Sel = AIS_Selection::CurrentSelection();
902 #if !defined OCC189 && !defined USE_MAP
903 const TColStd_Array1OfTransient& Obj = Sel->Objects()->Array1();
904 for(Standard_Integer i =Obj.Lower();i<=Sel->NbStored();i++){
905 const Handle(Standard_Transient)& Tr = Obj(i);
907 const AIS_NListTransient& Obj = Sel->Objects();
908 AIS_NListTransient::Iterator anIter( Obj );
909 for(; anIter.More(); anIter.Next()){
910 const Handle(Standard_Transient)& Tr = anIter.Value();
913 (*((const Handle(SelectMgr_EntityOwner)*)&Tr))->State(0);
916 AIS_Selection::Select();
921 //=======================================================================
922 //function : SetSelected
924 //=======================================================================
925 void AIS_LocalContext::SetSelected(const Handle(AIS_InteractiveObject)& anIObj,
926 const Standard_Boolean updateviewer)
928 if(!IsValidForSelection(anIObj)) return;
929 UnhilightPicked(Standard_False);
931 //1st case, owner already <anIObj> as owner
932 // and not separated is found...
934 Handle(AIS_Selection) sel = AIS_Selection::Selection(mySelName.ToCString());
935 //Standard_Boolean found(Standard_False);
936 Handle(Standard_Transient) Tr;
937 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromIO(anIObj);
939 //check if in selection number 0 there is an owner that can be triturated...
940 if(anIObj->HasSelection(0)){
941 const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0);
944 Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->OwnerId();
945 EO = *((Handle(SelectMgr_EntityOwner)*)&BO);
949 EO = new SelectMgr_EntityOwner(anIObj);
952 ClearSelected(Standard_False);
954 AIS_Selection::Select(EO);
958 AIS_Selection::Select(EO);
960 HilightPicked(updateviewer);
963 //=======================================================================
964 //function : AddOrRemoveSelected
966 //=======================================================================
968 void AIS_LocalContext::AddOrRemoveSelected(const Handle(AIS_InteractiveObject)& anIObj,
969 const Standard_Boolean updateviewer)
971 if(!IsValidForSelection(anIObj)) return;
972 UnhilightPicked(Standard_False);
973 // first check if it is selected...
974 Handle(SelectMgr_EntityOwner) EO;
976 EO = FindSelectedOwnerFromIO(anIObj);
984 if(anIObj->HasSelection(0)){
985 const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0);
988 Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->OwnerId();
989 EO = *((Handle(SelectMgr_EntityOwner)*)&BO);
993 EO = new SelectMgr_EntityOwner(anIObj);
999 // cout<<"AIS_LocalContext::AddOrRemoveSelected : Selection = "<<mySelName<<endl;
1000 const Handle(AIS_Selection)& S = AIS_Selection::Selection(mySelName.ToCString());
1003 AIS_SelectStatus aStatus = S->Select(EO);
1004 if(aStatus == AIS_SS_Added)
1013 HilightPicked(updateviewer);
1016 //=======================================================================
1017 //function : AddOrRemoveSelected
1018 //purpose : To check...
1019 //=======================================================================
1020 void AIS_LocalContext::AddOrRemoveSelected(const TopoDS_Shape& Sh,
1021 const Standard_Boolean updateviewer)
1023 UnhilightPicked(Standard_False);
1024 Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromShape(Sh);
1026 // cout<<"AIS_LocalContext::AddOrRemoveSelected(sh) : Selection = "<<mySelName<<endl;
1029 AIS_Selection::Selection(mySelName.ToCString())->Select(EO);
1033 AIS_Selection::Selection(mySelName.ToCString())->Select(EO);
1036 HilightPicked(updateviewer);
1039 void AIS_LocalContext::AddOrRemoveSelected(const Handle(SelectMgr_EntityOwner)& Ownr,
1040 const Standard_Boolean updateviewer)
1042 //Not Yet Implemented
1044 UnhilightPicked(Standard_False);
1045 // cout<<"AIS_LocalContext::AddOrRemoveSelected(ownr) : Selection = "<<mySelName<<endl;
1047 Standard_Integer mod = Ownr->State()==0 ? 1 : 0;
1049 AIS_Selection::Selection(mySelName.ToCString())->Select(Ownr);
1055 AIS_Selection::Selection(mySelName.ToCString())->Select(Ownr);
1058 HilightPicked(updateviewer);
1061 //==================================================
1062 // Function: manageDetected
1064 //==================================================
1065 void AIS_LocalContext::manageDetected (const Handle(SelectMgr_EntityOwner)& thePickOwner,
1066 const Handle(V3d_View)& theView,
1067 const Standard_Boolean theToRedrawImmediate)
1069 if (thePickOwner.IsNull())
1071 if (theToRedrawImmediate)
1073 theView->RedrawImmediate();
1078 if (!myFilters->IsOk (thePickOwner))
1080 if (mylastindex != 0)
1082 mylastgood = mylastindex;
1084 if (theToRedrawImmediate)
1086 theView->RedrawImmediate();
1091 //=======================================================================================================
1092 // 2 cases : a- object is in the map of picks:
1093 // 1. this is the same index as the last detected: -> Do nothing
1095 // - if lastindex = 0 (no object was detected at the last step)
1096 // the object presentation is highlighted and lastindex = index(objet)
1098 // the presentation of the object corresponding to lastindex is "unhighlighted"
1099 // it is removed if the object is not visualized but only active
1100 // then the presentation of the detected object is highlighted and lastindex = index(objet)
1101 // b- the object is not in the map of picked objects
1102 // - if lastindex != 0 (object detected at the last step) it is unhighlighted ...
1103 // if the object was decomposed, presentation is created for the detected shape and the couple
1104 // (Proprietaire,Prs)is added in the map.
1105 // otherwise the couple(proprietaire, NullPrs) is placed in the map and the interactive object
1106 // itself is highlighted.
1108 //=======================================================================================================
1110 const Standard_Integer aNewIndex = myMapOfOwner.Contains (thePickOwner)
1111 ? myMapOfOwner.FindIndex (thePickOwner)
1112 : myMapOfOwner.Add (thePickOwner);
1114 // For the advanced mesh selection mode the owner indices comparison
1115 // is not effective because in that case only one owner manage the
1116 // selection in current selection mode. It is necessary to check the current detected
1117 // entity and hilight it only if the detected entity is not the same as
1118 // previous detected (IsForcedHilight call)
1119 if (aNewIndex != mylastindex
1120 || thePickOwner->IsForcedHilight())
1122 if (mylastindex != 0
1123 && mylastindex <= myMapOfOwner.Extent())
1125 const Handle(SelectMgr_EntityOwner)& aLastOwner = myMapOfOwner (mylastindex);
1126 Unhilight (aLastOwner, theView);
1131 if (thePickOwner->State() <= 0
1132 || myCTX->ToHilightSelected())
1134 Hilight (thePickOwner, theView);
1136 if (theToRedrawImmediate)
1138 theView->RedrawImmediate();
1142 mylastindex = aNewIndex;
1147 mylastgood = mylastindex;
1151 //=======================================================================
1152 //function : HasDetectedShape
1154 //=======================================================================
1156 Standard_Boolean AIS_LocalContext::HasDetectedShape() const
1158 if(mylastindex==0) return Standard_False;
1159 return IsShape(mylastindex);
1162 //=======================================================================
1163 //function : DetectedShape
1165 //=======================================================================
1168 AIS_LocalContext::DetectedShape() const
1170 static TopoDS_Shape bidsh;
1171 if(mylastindex != 0)
1173 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner(mylastindex));
1174 if(BROwnr.IsNull()) return bidsh;
1175 return BROwnr->Shape();
1180 //=======================================================================
1181 //function : DetectedInteractive
1183 //=======================================================================
1185 Handle(AIS_InteractiveObject)
1186 AIS_LocalContext::DetectedInteractive() const
1188 Handle(AIS_InteractiveObject) Iobj;
1189 if(IsValidIndex(mylastindex)){
1190 Handle(SelectMgr_SelectableObject) SO = myMapOfOwner.FindKey(mylastindex)->Selectable();
1191 Iobj = *((Handle(AIS_InteractiveObject)*) &SO);
1195 //=======================================================================
1196 //function : DetectedInteractive
1198 //=======================================================================
1199 Handle(SelectMgr_EntityOwner) AIS_LocalContext::DetectedOwner() const
1201 Handle(SelectMgr_EntityOwner) bid;
1202 if(!IsValidIndex(mylastindex)) return bid;
1203 return myMapOfOwner.FindKey(mylastindex);
1207 //=======================================================================
1208 //function : ComesFromDecomposition
1210 //=======================================================================
1212 Standard_Boolean AIS_LocalContext::ComesFromDecomposition(const Standard_Integer PickedIndex) const
1214 const Handle(SelectMgr_EntityOwner)& OWN = myMapOfOwner.FindKey(PickedIndex);
1215 Handle(SelectMgr_SelectableObject) aSel = OWN->Selectable();
1216 if (myActiveObjects.IsBound (aSel)) { // debug of jmi
1217 const Handle(AIS_LocalStatus)& Stat = myActiveObjects(aSel);
1218 return Stat->Decomposed();
1220 return Standard_False;
1224 //=======================================================================
1225 //function : DisplayAreas
1227 //=======================================================================
1229 void AIS_LocalContext::DisplayAreas(const Handle(V3d_View)& aviou)
1231 myMainVS->DisplayAreas(aviou);
1234 //=======================================================================
1235 //function : ClearAreas
1237 //=======================================================================
1239 void AIS_LocalContext::ClearAreas(const Handle(V3d_View)& aviou)
1241 myMainVS->ClearAreas(aviou);
1244 //=======================================================================
1245 //function : DisplaySensitive
1247 //=======================================================================
1249 void AIS_LocalContext::DisplaySensitive(const Handle(V3d_View)& aviou)
1251 myMainVS->DisplaySensitive(aviou);
1254 //=======================================================================
1255 //function : ClearSensitive
1257 //=======================================================================
1259 void AIS_LocalContext::ClearSensitive(const Handle(V3d_View)& aviou)
1261 myMainVS->ClearSensitive(aviou);
1265 //=======================================================================
1266 //function : IsShape
1268 //=======================================================================
1269 Standard_Boolean AIS_LocalContext::IsShape(const Standard_Integer Index) const
1272 if(Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner.FindKey(Index)).IsNull())
1273 return Standard_False;
1275 ComesFromDecomposition(Index);
1278 Standard_Boolean AIS_LocalContext::IsValidForSelection(const Handle(AIS_InteractiveObject)& anIObj) const
1282 // Shape was not transfered from AIS_Shape to EntityOwner
1283 Handle(AIS_Shape) shape = Handle(AIS_Shape)::DownCast(anIObj);
1284 if( !shape.IsNull() )
1285 return myFilters->IsOk(new StdSelect_BRepOwner(shape->Shape(),shape));
1287 return myFilters->IsOk(new SelectMgr_EntityOwner(anIObj));
1291 //=======================================================================
1292 //function : HilightNextDetected
1294 //=======================================================================
1295 Standard_Integer AIS_LocalContext::HilightNextDetected (const Handle(V3d_View)& theView,
1296 const Standard_Boolean theToRedrawImmediate)
1298 // go to the next owner
1299 if (myDetectedSeq.IsEmpty())
1304 const Standard_Integer aLen = myDetectedSeq.Length();
1305 if (++myCurDetected > aLen)
1309 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myCurDetected);
1310 if (anOwner.IsNull())
1314 manageDetected (anOwner, theView, theToRedrawImmediate);
1315 return myCurDetected;
1318 //=======================================================================
1319 //function : HilightPreviousDetected
1321 //=======================================================================
1322 Standard_Integer AIS_LocalContext::HilightPreviousDetected (const Handle(V3d_View)& theView,
1323 const Standard_Boolean theToRedrawImmediate)
1325 if (myDetectedSeq.IsEmpty())
1330 if (--myCurDetected < 1)
1334 Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myCurDetected);
1335 if (anOwner.IsNull())
1340 manageDetected (anOwner, theView, theToRedrawImmediate);
1341 return myCurDetected;
1344 //=======================================================================
1345 //function : UnhilightLastDetected
1347 //=======================================================================
1348 Standard_Boolean AIS_LocalContext::UnhilightLastDetected (const Handle(V3d_View)& theView)
1350 if (!IsValidIndex (mylastindex))
1352 return Standard_False;
1355 myMainPM->BeginImmediateDraw();
1356 const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner (mylastindex);
1357 const Standard_Integer aHilightMode = anOwner->HasSelectable()
1358 ? GetHiMod (Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable()))
1361 myMapOfOwner (mylastindex)->Unhilight (myMainPM, aHilightMode);
1362 myMainPM->EndImmediateDraw (theView);
1364 return Standard_True;
1367 //=======================================================================
1368 //function : FindSelectedOwnerFromIO
1369 //purpose : it is checked if one of the selected owners really presents IObj
1370 //=======================================================================
1371 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromIO
1372 (const Handle(AIS_InteractiveObject)& anIObj) const
1374 Handle(SelectMgr_EntityOwner) EO,bid;
1375 if (anIObj.IsNull()) return EO;
1377 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
1380 cout<<"\t\tAIS_LocalCOntext::FindSelectedOwnerFromShape : Selection "
1381 <<mySelName<<" Nulle "<<endl;
1385 Standard_Boolean found(Standard_False);
1386 #if !defined OCC189 && !defined USE_MAP
1387 const TColStd_Array1OfTransient& Obj = Sel->Objects()->Array1();
1388 for(Standard_Integer i =Obj.Lower();i<=Sel->NbStored();i++){
1389 const Handle(Standard_Transient)& Tr = Obj(i);
1391 const AIS_NListTransient& Obj = Sel->Objects();
1392 AIS_NListTransient::Iterator anIter( Obj );
1393 for(; anIter.More(); anIter.Next()){
1394 const Handle(Standard_Transient)& Tr = anIter.Value();
1397 EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
1398 if(EO->HasSelectable()){
1399 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1400 if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
1401 if (anIObj == EO->Selectable()){
1402 found =Standard_True;
1409 if(found) return EO;
1413 //=======================================================================
1414 //function : FindSelectedOwnerFromShape
1415 //purpose : it is checked if one of the selected owners really presents IObj
1416 //=======================================================================
1417 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromShape(const TopoDS_Shape& sh) const
1420 Handle(SelectMgr_EntityOwner) EO, bid;
1422 Handle(SelectMgr_EntityOwner) EO;
1424 if (sh.IsNull()) return EO;
1426 Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
1429 cout<<"\t\tAIS_LocalCOntext::FindSelectedOwnerFromShape : Selection "<<mySelName<<" Nulle "<<endl;
1434 Standard_Boolean found(Standard_False);
1438 SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive aSensitiveIt (myMainVS->Primitives());
1439 for (; aSensitiveIt.More(); aSensitiveIt.Next()) {
1440 EO = Handle(SelectMgr_EntityOwner)::DownCast (aSensitiveIt.Value()->OwnerId());
1441 Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1442 if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) {
1443 found = Standard_True;
1449 #if !defined OCC189 && !defined USE_MAP
1450 const TColStd_Array1OfTransient& Obj = Sel->Objects()->Array1();
1451 for(Standard_Integer i =Obj.Lower();i<=Sel->NbStored();i++){
1452 const Handle(Standard_Transient)& Tr = Obj(i);
1454 const AIS_NListTransient& Obj = Sel->Objects();
1455 AIS_NListTransient::Iterator anIter( Obj );
1456 for(; anIter.More(); anIter.Next()){
1457 const Handle(Standard_Transient)& Tr = anIter.Value();
1461 EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
1463 if ( EO->Shape() == sh)
1464 found =Standard_True;
1470 if(found) return EO;
1475 //=======================================================================
1476 //function : AIS_LocalContext::InitDetected
1478 //=======================================================================
1479 void AIS_LocalContext::InitDetected()
1481 myAISCurDetected = myAISDetectedSeq.Length()? 1 : 0;
1484 //=======================================================================
1485 //function : AIS_LocalContext::MoreDetected
1487 //=======================================================================
1488 Standard_Boolean AIS_LocalContext::MoreDetected() const
1490 return (myAISCurDetected > 0 && myAISCurDetected <= myAISDetectedSeq.Length());
1493 //=======================================================================
1494 //function : AIS_LocalContext::NextDetected
1496 //=======================================================================
1497 void AIS_LocalContext::NextDetected()
1502 //=======================================================================
1503 //function : DetectedCurrentShape
1505 //=======================================================================
1506 const TopoDS_Shape& AIS_LocalContext::DetectedCurrentShape() const
1508 static TopoDS_Shape aDummyShape;
1510 Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
1512 if (aCurrentShape.IsNull())
1517 return aCurrentShape->Shape();
1519 //=======================================================================
1520 //function : DetectedCurrentObject
1522 //=======================================================================
1523 Handle(AIS_InteractiveObject) AIS_LocalContext::DetectedCurrentObject() const
1525 return MoreDetected() ? myAISDetectedSeq(myAISCurDetected) : NULL;