0026195: Visualization - optimize selection algorithms
[occt.git] / src / AIS / AIS_LocalContext.cxx
1 // Created on: 1997-01-17
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 //Modified by ROB : Traque des UpdateConversion intempestifs.
18
19 #include <AIS_DataMapIteratorOfDataMapOfSelStat.hxx>
20 #include <AIS_InteractiveContext.hxx>
21 #include <AIS_InteractiveObject.hxx>
22 #include <AIS_ListIteratorOfListOfInteractive.hxx>
23 #include <AIS_ListOfInteractive.hxx>
24 #include <AIS_LocalContext.hxx>
25 #include <AIS_LocalStatus.hxx>
26 #include <AIS_Selection.hxx>
27 #include <AIS_Shape.hxx>
28 #include <Aspect_TypeOfMarker.hxx>
29 #include <Graphic3d_Structure.hxx>
30 #include <Prs3d_LineAspect.hxx>
31 #include <Prs3d_PlaneAspect.hxx>
32 #include <Prs3d_PointAspect.hxx>
33 #include <Prs3d_Presentation.hxx>
34 #include <SelectMgr_CompositionFilter.hxx>
35 #include <SelectMgr_EntityOwner.hxx>
36 #include <SelectMgr_Filter.hxx>
37 #include <SelectMgr_OrFilter.hxx>
38 #include <SelectMgr_SelectableObject.hxx>
39 #include <SelectMgr_SelectionManager.hxx>
40 #include <Standard_Transient.hxx>
41 #include <Standard_Type.hxx>
42 #include <StdSelect_ShapeTypeFilter.hxx>
43 #include <StdSelect_ViewerSelector3d.hxx>
44 #include <TCollection_AsciiString.hxx>
45 #include <TColStd_ListIteratorOfListOfInteger.hxx>
46 #include <TopAbs_ShapeEnum.hxx>
47 #include <TopoDS_Shape.hxx>
48 #include <V3d_View.hxx>
49 #include <V3d_Viewer.hxx>
50 #include <Visual3d_View.hxx>
51
52 #include <stdio.h>
53 static TCollection_AsciiString AIS_Local_SelName(const Standard_Address address,
54                                                  const Standard_Integer anIndex)
55 {
56 //  TCollection_AsciiString SelName;
57   char string[100];
58   sprintf(string,"%p_%d", address, anIndex);    // works under any system 
59   TCollection_AsciiString SelName(string);
60   return SelName;
61 }
62
63
64 //=======================================================================
65 //function : AIS_LocalContext
66 //purpose  : 
67 //=======================================================================
68
69
70 AIS_LocalContext::AIS_LocalContext(){}
71
72 AIS_LocalContext::AIS_LocalContext(const Handle(AIS_InteractiveContext)& aCtx,
73                                    const Standard_Integer Index,
74                                    const Standard_Boolean LoadDisplayed,
75                                    const Standard_Boolean AcceptStandardModes,
76                                    const Standard_Boolean AcceptEraseOfTemp,
77                                    const Standard_Boolean /*BothViewers*/):
78 myCTX(aCtx),
79 myLoadDisplayed(LoadDisplayed),
80 myAcceptStdMode(AcceptStandardModes),
81 myAcceptErase(AcceptEraseOfTemp),
82 mySM(aCtx->SelectionManager()),
83 myMainVS(aCtx->MainSelector()),
84 myFilters(new SelectMgr_OrFilter()),
85 myAutoHilight(Standard_True),
86 myMapOfOwner (new SelectMgr_IndexedMapOfOwner()),
87 mylastindex(0),
88 mylastgood(0),
89 myCurDetected(0),
90 myAISCurDetected(0)
91
92 {
93   // bind self to AIS_InteractiveContext::myLocalContexts. Further, the
94   // constructor executes logic that implies that the context is already
95   // created and mapped.
96   aCtx->myLocalContexts.Bind (Index, this);
97
98   myMainVS->ResetSelectionActivationStatus();
99   myMainPM = aCtx->MainPrsMgr();
100   mySelName = AIS_Local_SelName(this, Index);
101   AIS_Selection::CreateSelection(mySelName.ToCString());
102
103   mySM->Add(myMainVS);
104   if(myLoadDisplayed) LoadContextObjects();
105   Process();
106
107 }
108
109
110 //=======================================================================
111 //function : SetContext
112 //purpose  : 
113 //=======================================================================
114
115 void AIS_LocalContext::SetContext(const Handle(AIS_InteractiveContext)& aCtx)
116 {  myCTX = aCtx;}
117
118 //=======================================================================
119 //function : Display
120 //purpose  : 
121 //=======================================================================
122
123 Standard_Boolean AIS_LocalContext::Display(const Handle(AIS_InteractiveObject)& anInteractive,
124                                            const Standard_Integer WhichMode,
125                                            const Standard_Boolean AllowShapeDecomposition,
126                                            const Standard_Integer ActivationMode)
127 {
128   if(myActiveObjects.IsBound(anInteractive)){
129     const Handle(AIS_LocalStatus)& STAT = myActiveObjects(anInteractive);
130     
131     if(STAT->DisplayMode() == -1){
132       if(!myMainPM->IsDisplayed(anInteractive,WhichMode))
133         myMainPM->Display(anInteractive,WhichMode);
134       if(STAT->IsTemporary())
135         STAT->SetDisplayMode(WhichMode);
136     }
137     else if(STAT->DisplayMode()!=WhichMode && STAT->IsTemporary()){
138       myMainPM->Erase(anInteractive,STAT->DisplayMode());
139       STAT->SetDisplayMode(WhichMode);
140       if(!myMainPM->IsDisplayed(anInteractive,WhichMode))
141         myMainPM->Display(anInteractive,WhichMode);
142     }
143     
144     if(ActivationMode!=-1){
145       if(!STAT->IsActivated(ActivationMode)){
146         STAT->ClearSelectionModes();
147         mySM->Load(anInteractive,myMainVS);
148         STAT->AddSelectionMode(ActivationMode);
149         mySM->Activate(anInteractive,ActivationMode,myMainVS);
150       }
151     }
152   }
153   else {
154     Handle(AIS_LocalStatus) Att = new AIS_LocalStatus();
155     
156     if(anInteractive->AcceptShapeDecomposition() && AllowShapeDecomposition)
157       Att->SetDecomposition(Standard_True);
158     else 
159       Att->SetDecomposition(Standard_False);
160     // status temporary or not
161     if(myCTX->DisplayStatus(anInteractive) == AIS_DS_None ||
162        myCTX->DisplayStatus(anInteractive) == AIS_DS_Temporary)
163       Att->SetTemporary(Standard_True);
164     else
165       Att->SetTemporary(Standard_False); 
166
167
168     
169     if(!myCTX->IsDisplayed(anInteractive,WhichMode)){
170       
171       //storing information....
172       Att->SetDisplayMode(WhichMode);
173       if (ActivationMode!=-1)
174         Att->AddSelectionMode(ActivationMode);
175       Standard_Integer HiMod = anInteractive->HasHilightMode()? anInteractive->HilightMode(): WhichMode;
176       Att->SetHilightMode(HiMod);
177
178       if(!myMainPM->IsDisplayed(anInteractive,WhichMode))
179         myMainPM->Display(anInteractive,WhichMode);
180       
181       if(ActivationMode!=-1){
182         mySM->Load(anInteractive,myMainVS);
183         mySM->Activate(anInteractive,ActivationMode,myMainVS);
184       }
185     }
186     else{
187       Standard_Integer HiMod = anInteractive->HasHilightMode()? anInteractive->HilightMode(): WhichMode;
188       Att->SetHilightMode(HiMod);
189     }
190     myActiveObjects.Bind(anInteractive,Att);
191   }  
192   Process(anInteractive);
193
194   
195   
196
197   return Standard_True;
198 }
199
200 //=======================================================================
201 //function : Load
202 //purpose  : 
203 //=======================================================================
204
205 Standard_Boolean AIS_LocalContext::
206 Load(const Handle(AIS_InteractiveObject)& anInteractive,
207      const Standard_Boolean AllowShapeDecomposition,
208      const Standard_Integer ActivationMode)
209 {
210   if (myActiveObjects.IsBound (anInteractive))
211   {
212     if (anInteractive->HasSelection (ActivationMode))
213     {
214       const Handle(SelectMgr_Selection)& aSel = anInteractive->Selection (ActivationMode);
215       if (aSel->GetSelectionState() != SelectMgr_SOS_Activated)
216       {
217         if (!myMainVS->Contains (anInteractive))
218         {
219           mySM->Load (anInteractive, myMainVS);
220         }
221         mySM->Activate (anInteractive, ActivationMode, myMainVS);
222         return Standard_True;
223       }
224     }
225     return Standard_False;
226   }
227
228   Handle(AIS_LocalStatus) Att = new AIS_LocalStatus();
229   
230   if(anInteractive->AcceptShapeDecomposition() && AllowShapeDecomposition)
231     Att->SetDecomposition(Standard_True);
232   else 
233     Att->SetDecomposition(Standard_False);
234   
235   if(!myCTX->IsDisplayed(anInteractive))
236     Att->SetTemporary(Standard_True);
237   else
238     Att->SetTemporary(Standard_False);
239   Att->SetDisplayMode(-1);
240   
241   //storing information....
242   if(ActivationMode!=-1)
243     Att->AddSelectionMode(ActivationMode);
244   Standard_Integer HiMod = anInteractive->HasHilightMode()? anInteractive->HilightMode():0;
245   Att->SetHilightMode(HiMod);
246   //Action
247   
248   mySM->Load(anInteractive,myMainVS);
249   if(ActivationMode != -1){
250     mySM->Activate(anInteractive,ActivationMode,myMainVS);
251   }
252   myActiveObjects.Bind(anInteractive,Att);
253   Process(anInteractive);
254   return Standard_True;
255 }
256
257 //=======================================================================
258 //function : ClearPrs
259 //purpose  : 
260 //=======================================================================
261
262 Standard_Boolean AIS_LocalContext::
263 ClearPrs(const Handle(AIS_InteractiveObject)& anInteractive,
264          const Standard_Integer aMode)
265 {
266   if(!myActiveObjects.IsBound(anInteractive))
267     return Standard_False;
268
269   Standard_Boolean jobdone(Standard_False);
270   const Handle(AIS_LocalStatus)& STAT = myActiveObjects(anInteractive);
271   
272   //Display step
273   if(STAT->IsSubIntensityOn()) {
274     STAT->SubIntensityOff();
275     if(STAT->HilightMode()==aMode)
276       myMainPM->Unhighlight(anInteractive,STAT->HilightMode());
277   }
278   myMainPM->Clear(anInteractive,aMode); // correction connexions 23/09/97
279   jobdone = Standard_True;
280   if(STAT->DisplayMode()==aMode)
281     STAT->SetDisplayMode(-1);
282   return jobdone;
283 }
284 //=======================================================================
285 //function : Erase
286 //purpose  : 
287 //=======================================================================
288
289 Standard_Boolean AIS_LocalContext::
290 Erase(const Handle(AIS_InteractiveObject)& anInteractive)
291 {
292   if(!myActiveObjects.IsBound(anInteractive))
293     return Standard_False;
294   const Handle(AIS_LocalStatus)& STAT = myActiveObjects(anInteractive);
295   
296   //Display step
297   if(STAT->IsSubIntensityOn()) {
298     STAT->SubIntensityOff();
299     myMainPM->Unhighlight(anInteractive,STAT->HilightMode());
300   }
301
302   Standard_Boolean status(Standard_False);
303
304   if(STAT->DisplayMode()!=-1) {
305     if(IsSelected(anInteractive))
306       AddOrRemoveSelected(anInteractive);
307     if(myMainPM->IsHighlighted(anInteractive,STAT->HilightMode()))
308       myMainPM->Unhighlight(anInteractive,STAT->HilightMode());
309     myMainPM->SetVisibility (anInteractive, STAT->DisplayMode(), Standard_False);
310     STAT->SetDisplayMode(-1);
311     status = Standard_True;
312   }
313   if(STAT->IsTemporary()){
314     if(myMainPM->IsDisplayed(anInteractive,STAT->HilightMode()))
315       myMainPM->SetVisibility (anInteractive, STAT->HilightMode(), Standard_False);
316   }
317
318   // Deactivate selectable entities of interactive object
319   const Handle(SelectMgr_SelectableObject)& anObj = anInteractive; // to avoid ambiguity
320   if (mySM->Contains (anObj))
321   {
322     while (!STAT->SelectionModes().IsEmpty())
323     {
324       mySM->Deactivate (anInteractive, STAT->SelectionModes().Last(), myMainVS);
325       STAT->RemoveSelectionMode (STAT->SelectionModes().Last());
326     }
327   }
328
329   ClearOutdatedSelection (anInteractive, Standard_True);
330
331   return status;
332 }
333
334
335 //=======================================================================
336 //function : SetShapeDecomposition
337 //purpose  : 
338 //=======================================================================
339
340 void AIS_LocalContext::SetShapeDecomposition(const Handle(AIS_InteractiveObject)& aStoredObject, 
341                                                 const Standard_Boolean aStatus)
342 {
343   if(!myActiveObjects.IsBound(aStoredObject)) return;
344   
345   if(aStatus == myActiveObjects(aStoredObject)->Decomposed()) 
346     return;
347   
348   myActiveObjects(aStoredObject)->SetDecomposition(aStatus);
349
350   Process(aStoredObject);
351 }
352
353 //=======================================================================
354 //function : Clear
355 //purpose  : 
356 //=======================================================================
357
358 void AIS_LocalContext::Clear(const AIS_ClearMode aType)
359 {
360   switch (aType){
361   case AIS_CM_All:
362     {
363       ClearObjects();
364       myFilters->Clear();
365       while(!myListOfStandardMode.IsEmpty())
366         DeactivateStandardMode(AIS_Shape::SelectionType(myListOfStandardMode.Last()));
367       break;
368     }
369   case AIS_CM_Interactive:
370     ClearObjects();
371     break;
372   case AIS_CM_Filters:
373     myFilters->Clear();
374     break;
375   case AIS_CM_StandardModes:
376     {
377       while(!myListOfStandardMode.IsEmpty())
378         DeactivateStandardMode(AIS_Shape::SelectionType(myListOfStandardMode.Last()));
379       break;
380     }
381   case AIS_CM_TemporaryShapePrs:
382     ClearDetected();
383   }
384 }
385 //=======================================================================
386 //function : ActivateMode
387 //purpose  : 
388 //=======================================================================
389
390 void AIS_LocalContext::ActivateMode(const Handle(AIS_InteractiveObject)& aSelectable,
391                                        const Standard_Integer aMode)
392 {
393   if(!myActiveObjects.IsBound(aSelectable)) return;
394 //  if(myActiveObjects(aSelectable)->SelectionMode()!=aMode)
395 //    mySM->Deactivate(aSelectable,aMode,myMainVS);
396   if(aMode != -1){
397     myActiveObjects(aSelectable)->AddSelectionMode(aMode);
398     mySM->Activate(aSelectable,aMode,myMainVS);
399   }
400 }
401 //=======================================================================
402 //function : ActivateMode
403 //purpose  : 
404 //=======================================================================
405
406 void AIS_LocalContext::DeactivateMode(const Handle(AIS_InteractiveObject)& aSelectable,
407                                          const Standard_Integer aMode)
408 {
409   if(!myActiveObjects.IsBound(aSelectable)) return;
410   
411   if(aMode==-1) return;
412   
413   myActiveObjects(aSelectable)->RemoveSelectionMode(aMode);
414   mySM->Deactivate(aSelectable,aMode,myMainVS);
415 }
416 //=======================================================================
417 //function : ActivateMode
418 //purpose  : 
419 //=======================================================================
420
421 void AIS_LocalContext::Deactivate(const Handle(AIS_InteractiveObject)& aSelectable)
422 {
423   if(!myActiveObjects.IsBound(aSelectable)) return;
424   
425   mySM->Deactivate(aSelectable, -1, myMainVS);
426   myActiveObjects(aSelectable)->ClearSelectionModes();
427 }
428
429 //=======================================================================
430 //function : Remove
431 //purpose  : 
432 //=======================================================================
433
434 Standard_Boolean AIS_LocalContext::Remove(const Handle(AIS_InteractiveObject)& aSelectable)
435 {
436   if(!myActiveObjects.IsBound (aSelectable))
437   {
438     return Standard_False;
439   }
440
441   if (IsSelected (aSelectable))
442   {
443     AddOrRemoveSelected (aSelectable, Standard_False);
444   }
445
446   const Handle(AIS_LocalStatus)& Att = myActiveObjects (aSelectable);
447
448   TColStd_ListIteratorOfListOfInteger It;
449
450   // Deactivate standard modes
451   if (Att->Decomposed())
452   {
453     for (It.Initialize (myListOfStandardMode); It.More(); It.Next())
454     {
455       mySM->Deactivate (aSelectable, It.Value(), myMainVS);
456     }
457   }
458
459   // If object or temporary presentations
460   if (Att->IsTemporary())
461   {
462     if (Att->IsSubIntensityOn())
463     {
464       myMainPM->Unhighlight (aSelectable, Att->HilightMode());
465     }
466
467     myMainPM->Erase (aSelectable, Att->DisplayMode());
468     myMainPM->Clear (aSelectable, Att->DisplayMode());
469     if (myMainPM->IsDisplayed (aSelectable, Att->HilightMode()))
470     {
471       myMainPM->Erase (aSelectable, Att->HilightMode());
472     }
473   }
474   // If subintensity used
475   else if (Att->IsSubIntensityOn())
476   {
477     myCTX->SubIntensityOff (aSelectable);
478   }
479
480   // Deactivate stored selection modes
481   for (It.Initialize (Att->SelectionModes()); It.More(); It.Next())
482   {
483     mySM->Deactivate (aSelectable, It.Value(), myMainVS);
484   }
485
486   // Remove the interactive object from selection manager
487   const Handle(SelectMgr_SelectableObject)& anObj = aSelectable; // to avoid ambiguity
488   if (mySM->Contains (anObj))
489   {
490     mySM->Remove (anObj);
491   }
492   ClearOutdatedSelection (aSelectable, Standard_True);
493
494   // This should be done at the very end because most methods use
495   // myActiveObjects even during clean-up
496   myActiveObjects.UnBind (aSelectable);
497   return Standard_True;
498 }
499
500 //=======================================================================
501 //function : ActivateStandardMode
502 //purpose  : 
503 //=======================================================================
504
505 void AIS_LocalContext::ActivateStandardMode(const TopAbs_ShapeEnum aType)
506 {
507   
508   //check if it is not in the list
509   TColStd_ListIteratorOfListOfInteger It(myListOfStandardMode);
510   for(;It.More();It.Next())
511     if(It.Value()==aType)  return;
512   Standard_Integer IMode = AIS_Shape::SelectionMode(aType);
513   
514
515   // create a hidden filter answering ok to the type except for :
516   // if the type is shape...
517   // if the filters already impact at the type <aType>
518   if(aType != TopAbs_SHAPE){
519     if(myStdFilters[IMode].IsNull())
520       myStdFilters[IMode] = new StdSelect_ShapeTypeFilter(aType);
521     if(!HasFilters(aType))
522       myFilters->Add(myStdFilters[IMode]);
523   }
524   
525   // the mode is activated for all objects of type Shape 
526   // accepting the decomposition in standard mode.
527   myListOfStandardMode.Append(IMode);
528   
529   AIS_DataMapIteratorOfDataMapOfSelStat ItM(myActiveObjects);
530
531   for(;ItM.More();ItM.Next()){
532     if(ItM.Value()->Decomposed())
533       myCTX->SelectionManager()->Activate(ItM.Key(),
534                                           IMode,
535                                           myMainVS);
536   }
537   
538 }
539
540 //=======================================================================
541 //function : DeActivateStandardMode
542 //purpose  : 
543 //=======================================================================
544
545 void AIS_LocalContext::DeactivateStandardMode(const TopAbs_ShapeEnum aType)
546 {
547   TColStd_ListIteratorOfListOfInteger It(myListOfStandardMode);
548   Standard_Integer IMode = AIS_Shape::SelectionMode(aType);
549   for(;It.More();It.Next())
550     if(It.Value()==IMode) {
551       AIS_DataMapIteratorOfDataMapOfSelStat ItM(myActiveObjects);
552       
553       for(;ItM.More();ItM.Next()){
554         if(ItM.Value()->Decomposed()){
555           myCTX->SelectionManager()->Deactivate(ItM.Key(),
556                                                 IMode,
557                                                 myMainVS);
558           ItM.Value()->RemoveSelectionMode(IMode);
559         }
560       }
561       myListOfStandardMode.Remove(It);
562       if(myFilters->IsIn(myStdFilters[IMode]))
563         myFilters->Remove(myStdFilters[IMode]);
564       return;
565     }   
566 }
567
568 //=======================================================================
569 //function : AddFilter
570 //purpose  : 
571 //=======================================================================
572
573 void AIS_LocalContext::AddFilter(const Handle(SelectMgr_Filter)& aFilter)
574 {
575   // it is checked if the filter impacts at the type of active sub-shape 
576   // for which a filter of type has been already implemented...
577
578   TColStd_ListIteratorOfListOfInteger It(myListOfStandardMode);
579   
580   for(;It.More();It.Next()){
581     if(aFilter->ActsOn(AIS_Shape::SelectionType(It.Value())))
582       if(myFilters->IsIn(myStdFilters[It.Value()]))
583         myFilters->Remove(myStdFilters[It.Value()]);
584   } 
585   myFilters->Add(aFilter);
586 }
587
588 //=======================================================================
589 //function : RemoveFilter
590 //purpose  : 
591 //=======================================================================
592
593 void AIS_LocalContext::RemoveFilter(const Handle(SelectMgr_Filter)& aFilter)
594 {
595   if(myFilters->IsIn(aFilter)) myFilters->Remove(aFilter);
596   
597   // it is checked if the filter for type standard is active.
598   // if yes, it is checked there are still similarities among the
599   // remaining filters...
600   //     otherwise, the standard filter is restored to
601   //     continu selecting active modes...
602   TColStd_ListIteratorOfListOfInteger It(myListOfStandardMode);
603   TopAbs_ShapeEnum SE;
604   for(;It.More();It.Next()){
605     SE = AIS_Shape::SelectionType(It.Value());
606     if(aFilter->ActsOn(SE))
607       if(!HasFilters(SE))
608         myFilters->Add(myStdFilters[It.Value()]);
609   }
610 }
611
612 //=======================================================================
613 //function : Terminate
614 //purpose  :
615 //=======================================================================
616
617 void AIS_LocalContext::Terminate (const Standard_Boolean theToUpdate)
618 {
619   ClearDetected();
620   Clear();
621   myMapOfOwner->Clear();
622   
623   mylastindex=0;
624   // clear the selector...
625   myMainVS->Clear();
626   
627
628   AIS_Selection::SetCurrentSelection(mySelName.ToCString());
629   Handle(AIS_Selection) S = AIS_Selection::CurrentSelection();
630   Handle(Standard_Transient) Tr;
631   for(S->Init();S->More();S->Next()){
632     Tr = S->Value();
633     Handle(SelectMgr_EntityOwner)::DownCast (Tr)->SetSelected (Standard_False);
634   }
635
636       
637   AIS_Selection::Select();
638   AIS_Selection::Remove(mySelName.ToCString());
639
640   Handle(V3d_View) aDummyView;
641   myMainVS->ClearSensitive (aDummyView);
642
643   if (theToUpdate)
644   {
645     myCTX->UpdateCurrentViewer();
646   }
647 }
648
649
650 //=======================================================================
651 //function : SubIntensity
652 //purpose  : 
653 //=======================================================================
654
655 void AIS_LocalContext::SubIntensityOn(const Handle(AIS_InteractiveObject)& anObject)
656 {
657   if(!myActiveObjects.IsBound(anObject)) return;
658   
659   const Handle(AIS_LocalStatus)& Att = myActiveObjects(anObject);
660
661   if(Att->IsTemporary()) 
662     myMainPM->Color(anObject,myCTX->SubIntensityColor(),Att->DisplayMode());
663   
664   Att->SubIntensityOn();
665 }
666 //=======================================================================
667 //function : SubIntensity
668 //purpose  : 
669 //=======================================================================
670
671 void AIS_LocalContext::SubIntensityOff(const Handle(AIS_InteractiveObject)& anObject)
672 {
673   if(!myActiveObjects.IsBound(anObject)) return;
674   
675   const Handle(AIS_LocalStatus)& Att = myActiveObjects(anObject);
676
677   if(Att->IsTemporary()) 
678     myMainPM->Unhighlight(anObject);
679   Att->SubIntensityOff();
680 }
681
682
683 //=======================================================================
684 //function : Hilight
685 //purpose  : 
686 //=======================================================================
687
688 void AIS_LocalContext::Hilight(const  Handle(AIS_InteractiveObject)& anObject)
689 {
690   if(!myActiveObjects.IsBound(anObject)){
691     Standard_Integer HiMod = anObject->HasHilightMode()? anObject->HilightMode() : 0; 
692     Handle(AIS_LocalStatus) Att = new AIS_LocalStatus(Standard_True,
693                                                       Standard_False,
694                                                       -1,-1,HiMod);
695     myActiveObjects.Bind(anObject,Att);
696     
697   }
698   const Handle(AIS_LocalStatus)& Att = myActiveObjects(anObject);
699   myMainPM->Color(anObject,myCTX->HilightColor(),Att->HilightMode());
700   Att->SubIntensityOn();
701 }
702 //=======================================================================
703 //function : Hilight
704 //purpose  : 
705 //=======================================================================
706
707 void AIS_LocalContext::Hilight(const  Handle(AIS_InteractiveObject)& anObject,
708                                const Quantity_NameOfColor Col)
709 {
710   if(!myActiveObjects.IsBound(anObject)){
711     Standard_Integer HiMod = anObject->HasHilightMode()? anObject->HilightMode() : 0; 
712     Handle(AIS_LocalStatus) Att = new AIS_LocalStatus(Standard_True,
713                                                       Standard_False,
714                                                       -1,-1,HiMod);
715     myActiveObjects.Bind(anObject,Att);
716     
717   }
718   const Handle(AIS_LocalStatus)& Att = myActiveObjects(anObject);
719   myMainPM->Color(anObject,Col,Att->HilightMode());
720   Att->SubIntensityOn();
721   Att->SetHilightColor(Col);
722 }
723
724 //=======================================================================
725 //function : Unhilight
726 //purpose  : 
727 //=======================================================================
728
729 void AIS_LocalContext::Unhilight(const Handle(AIS_InteractiveObject)& anObject)
730 {
731   if(!myActiveObjects.IsBound(anObject)) return;
732   
733   // chieck if by hazard the object is somewhere else...
734   Standard_Integer Indx;
735   Standard_Boolean IsSomeWhereElse  = 
736     myCTX->IsInLocal(anObject,Indx) && Indx != myCTX->IndexOfCurrentLocal();
737   
738   const Handle(AIS_LocalStatus)& Att = myActiveObjects(anObject);
739   myMainPM->Unhighlight(anObject,Att->HilightMode());
740   if(Att->IsTemporary() && Att->DisplayMode()==-1)
741     if(!IsSomeWhereElse)
742       myMainPM->SetVisibility (anObject, Att->HilightMode(), Standard_False);
743
744   Att->SubIntensityOff();
745   Att->SetHilightColor(Quantity_NOC_WHITE);
746 }
747
748
749 //=======================================================================
750 //function : IsIn
751 //purpose  : 
752 //=======================================================================
753
754 Standard_Boolean AIS_LocalContext::
755 IsIn(const Handle(AIS_InteractiveObject)& anObject) const 
756 {
757   return myActiveObjects.IsBound(anObject);
758 }
759
760 //=======================================================================
761 //function : IsHilighted
762 //purpose  : 
763 //=======================================================================
764
765 Standard_Boolean AIS_LocalContext::IsHilighted(const Handle(AIS_InteractiveObject)& anObject) const 
766 {
767   if(!myActiveObjects.IsBound(anObject)) return Standard_False;
768   return myActiveObjects(anObject)->IsSubIntensityOn();
769 }
770
771 Standard_Boolean AIS_LocalContext::IsHilighted(const Handle(AIS_InteractiveObject)& anObject,
772                                                Standard_Boolean& WithColor,
773                                                Quantity_NameOfColor& HiCol) const 
774 {
775   if(!myActiveObjects.IsBound(anObject)) return Standard_False;
776   if( myActiveObjects(anObject)->IsSubIntensityOn()){
777     HiCol = myActiveObjects(anObject)->HilightColor();
778     if(HiCol==Quantity_NOC_WHITE)
779       WithColor = Standard_True;
780     else
781       WithColor = Standard_False;
782     return Standard_True;
783   }
784   return Standard_False;
785 }
786
787
788 void AIS_LocalContext::SetDisplayPriority(const Handle(AIS_InteractiveObject)& anObject,
789                                           const Standard_Integer Prior)
790 {
791   if(!myActiveObjects.IsBound(anObject)) return;
792   const Handle(AIS_LocalStatus)& STAT = myActiveObjects(anObject);
793   if(STAT->DisplayMode()==-1) return;
794   myMainPM->SetDisplayPriority(anObject,STAT->DisplayMode(),Prior);
795   if(STAT->IsSubIntensityOn())
796     myMainPM->SetDisplayPriority(anObject,STAT->HilightMode(),Prior);
797   
798   
799 }
800
801 //=======================================================================
802 //function : DisplayedObjects
803 //purpose  : 
804 //=======================================================================
805 Standard_Integer AIS_LocalContext::DisplayedObjects(TColStd_MapOfTransient& theMap) const
806 {
807   Standard_Integer NbDisp(0);
808   for(AIS_DataMapIteratorOfDataMapOfSelStat it(myActiveObjects);it.More();it.Next()){
809     const Handle(SelectMgr_SelectableObject)& SO = it.Key();
810     if(!theMap.Contains(SO))
811       if(it.Value()->DisplayMode()!=-1){
812         theMap.Add(SO);
813         NbDisp++;
814       }
815   }
816   return NbDisp;
817 }
818
819
820 //=======================================================================
821 //function : IsDisplayed
822 //purpose  : 
823 //=======================================================================
824
825 Standard_Boolean AIS_LocalContext::IsDisplayed(const Handle(AIS_InteractiveObject)& anObject) const 
826 {
827   if(!myActiveObjects.IsBound(anObject)) return Standard_False;
828   return (myActiveObjects(anObject)->DisplayMode()!=-1);
829 }
830
831 //=======================================================================
832 //function : IsDisplayed
833 //purpose  : 
834 //=======================================================================
835
836 Standard_Boolean AIS_LocalContext::IsDisplayed(const Handle(AIS_InteractiveObject)& anObject,
837                                                   const Standard_Integer aMode) const 
838 {
839   if(!myActiveObjects.IsBound(anObject)) return Standard_False;
840   return (myActiveObjects(anObject)->DisplayMode()==aMode);
841 }
842
843 //=======================================================================
844 //function : SelectionModes
845 //purpose  : 
846 //=======================================================================
847
848 const TColStd_ListOfInteger& AIS_LocalContext::
849 SelectionModes(const Handle(AIS_InteractiveObject)& anObject) const 
850 {
851   return myActiveObjects(anObject)->SelectionModes(); 
852 }
853
854 //=======================================================================
855 //function : Status
856 //purpose  : 
857 //=======================================================================
858
859 TCollection_AsciiString AIS_LocalContext::Status() const 
860 {
861   TCollection_AsciiString t;
862   return t;
863 }
864
865 const Handle(AIS_LocalStatus)& AIS_LocalContext::Status(const Handle(AIS_InteractiveObject)& anObject) const 
866 {
867   return myActiveObjects(anObject);
868 }
869
870 //=======================================================================
871 //function : LoadContextObjects
872 //purpose  : 
873 //=======================================================================
874
875 void AIS_LocalContext::LoadContextObjects()
876 {
877   AIS_ListIteratorOfListOfInteractive It;
878   if(myLoadDisplayed) {
879     AIS_ListOfInteractive LL;
880     myCTX->DisplayedObjects(LL,Standard_True);
881     Handle(AIS_LocalStatus) Att;
882     for (It.Initialize(LL);It.More();It.Next()){
883       const Handle(AIS_InteractiveObject)& anObj = It.Value();
884       Att= new AIS_LocalStatus();
885       Att->SetDecomposition((anObj->AcceptShapeDecomposition() && myAcceptStdMode));
886       Att->SetTemporary(Standard_False);
887       Att->SetHilightMode(anObj->HasHilightMode()? anObj->HilightMode(): 0);
888       for (anObj->Init(); anObj->More(); anObj->Next())
889       {
890         const Handle(SelectMgr_Selection)& aSel = anObj->CurrentSelection();
891         aSel->SetSelectionState (SelectMgr_SOS_Deactivated);
892       }
893       myActiveObjects.Bind(anObj,Att);
894     }
895   }
896 }
897
898 void AIS_LocalContext::UnloadContextObjects()
899 {
900   AIS_ListIteratorOfListOfInteractive It;
901   if(myLoadDisplayed) 
902   {
903     AIS_ListOfInteractive LL;
904     myCTX->DisplayedObjects(LL,Standard_True);
905     
906     for (It.Initialize(LL);It.More();It.Next())
907     {
908       myActiveObjects.UnBind(It.Value());
909     }
910   }
911 }
912 //=======================================================================
913 //function : Process
914 //purpose  : 
915 //=======================================================================
916
917 void AIS_LocalContext::Process(const Handle(SelectMgr_SelectableObject)& anObject)
918
919   if(!myActiveObjects.IsBound(anObject)) return;
920   if(myActiveObjects(anObject)->Decomposed())
921     ActivateStandardModes(anObject);
922   else
923     {
924       TColStd_ListIteratorOfListOfInteger It(myActiveObjects(anObject)->SelectionModes());
925       for(;It.More();It.Next())
926         myCTX->SelectionManager()->Activate(anObject,It.Value(),myMainVS);
927     }
928 }
929
930 //=======================================================================
931 //function : Process
932 //purpose  : 
933 //=======================================================================
934
935 void AIS_LocalContext::Process()
936
937
938   myMainVS->Clear();
939   
940   AIS_DataMapIteratorOfDataMapOfSelStat It(myActiveObjects);
941   
942   for(;It.More();It.Next()){
943     myCTX->SelectionManager()->Load(It.Key(),myMainVS);
944     if(It.Value()->Decomposed()) 
945       ActivateStandardModes(It.Key());
946     else if( myCTX->GetAutoActivateSelection() )
947     {
948       It.Value()->AddSelectionMode(0);
949       myCTX->SelectionManager()->Activate(It.Key(),0,myMainVS);
950     }
951   }
952
953 }
954
955 //=======================================================================
956 //function : ActivateModes
957 //purpose  : 
958 //=======================================================================
959
960 void AIS_LocalContext::ActivateStandardModes(const Handle(SelectMgr_SelectableObject)& anObject)
961
962   if(!myActiveObjects.IsBound(anObject)) return;
963   
964   TColStd_ListIteratorOfListOfInteger itl (myListOfStandardMode);
965
966   const Handle(AIS_LocalStatus)&  LS = myActiveObjects(anObject);
967   if(LS->Decomposed()){
968     for(;itl.More();itl.Next()){
969       myCTX->SelectionManager()->Activate(anObject,itl.Value(),myMainVS);
970       LS->AddSelectionMode(itl.Value());
971     }
972   }
973 }
974
975
976 //=======================================================================
977 //function : ClearObjects
978 //purpose  : 
979 //=======================================================================
980
981 void AIS_LocalContext::ClearObjects()
982 {
983   AIS_DataMapIteratorOfDataMapOfSelStat It(myActiveObjects);
984   for(;It.More();It.Next())
985     {
986       Handle(AIS_InteractiveObject) SO =
987         Handle(AIS_InteractiveObject)::DownCast(It.Key());
988       
989       const Handle(AIS_LocalStatus)& CurAtt = It.Value();
990       //TColStd_ListIteratorOfListOfInteger ItL;
991       // if object is temporary the presentations managed by myMainPM are removed
992       AIS_DisplayStatus TheDS = myCTX->DisplayStatus(SO);
993       
994       if(TheDS != AIS_DS_Displayed){
995         if(myMainPM->IsDisplayed(SO,CurAtt->DisplayMode())){
996           if(CurAtt->IsSubIntensityOn()&&
997              myMainPM->IsHighlighted(SO,CurAtt->HilightMode()))
998             myMainPM->Unhighlight(SO,CurAtt->HilightMode());
999           myMainPM->Erase(SO,CurAtt->DisplayMode());
1000         }
1001         
1002         if(CurAtt->IsTemporary()){
1003           myMainPM->Erase(SO,CurAtt->DisplayMode());}
1004 //        myMainPM->Clear(SO,CurAtt->DisplayMode());}
1005       }
1006       else {
1007         if (CurAtt->IsSubIntensityOn()){
1008           myCTX->SubIntensityOff(Handle(AIS_InteractiveObject)::DownCast(SO));}
1009         Standard_Integer DiMo = SO->HasDisplayMode()?
1010           SO->DisplayMode():myCTX->DisplayMode();
1011         if(CurAtt->DisplayMode()!=-1 &&
1012            CurAtt->DisplayMode()!= DiMo)
1013           myMainPM->Erase(SO,CurAtt->DisplayMode());
1014       }
1015       
1016       TColStd_ListIteratorOfListOfInteger aSelModeIter (CurAtt->SelectionModes());
1017       for ( ; aSelModeIter.More(); aSelModeIter.Next())
1018       {
1019         Standard_Integer aSelMode = aSelModeIter.Value();
1020         mySM->Deactivate (SO, aSelMode, myMainVS);
1021       }
1022
1023     }
1024   ClearSelected( Standard_False );
1025
1026   // Clear selection structures for temporary objects, created in local context
1027   for (AIS_DataMapIteratorOfDataMapOfSelStat anIter (myActiveObjects); anIter.More(); anIter.Next())
1028   {
1029     if (anIter.Value()->IsTemporary())
1030     {
1031       mySM->Remove (anIter.Key(), myMainVS);
1032     }
1033   }
1034
1035   myActiveObjects.Clear();
1036 }
1037
1038
1039 Standard_Boolean AIS_LocalContext::IsDecompositionOn() const 
1040 {return !myListOfStandardMode.IsEmpty();}
1041
1042
1043
1044
1045 //=======================================================================
1046 //function : HasAlreadyFilters
1047 //purpose  : 
1048 //=======================================================================
1049
1050 Standard_Boolean AIS_LocalContext::
1051 HasFilters(const TopAbs_ShapeEnum aType) const 
1052 {
1053   return myFilters->ActsOn(aType);
1054 }
1055
1056 void AIS_LocalContext::ClearDetected()
1057 {
1058   for(Standard_Integer I=1;I<=myMapOfOwner->Extent();I++)
1059   {
1060     if(!myMapOfOwner->FindKey (I).IsNull())
1061     {
1062       if(myMapOfOwner->FindKey (I)->IsHilighted(myMainPM))
1063         myMapOfOwner->FindKey (I)->Unhilight(myMainPM);
1064       else
1065       {
1066         const Handle(SelectMgr_SelectableObject)& SO = 
1067           myMapOfOwner->FindKey (I)->Selectable();
1068         if(myActiveObjects.IsBound(SO))
1069         {
1070           const Handle(AIS_LocalStatus)& Att = myActiveObjects(SO);
1071
1072           if(Att->IsTemporary() &&
1073              Att->DisplayMode()==-1 && 
1074              Att->SelectionModes().IsEmpty())
1075           {
1076             myMapOfOwner->FindKey (I)->Clear(myMainPM);
1077           }
1078         }
1079       }
1080     }
1081   }
1082 }
1083
1084 //=======================================================================
1085 //function : BeginImmediateDraw
1086 //purpose  :
1087 //=======================================================================
1088 Standard_Boolean AIS_LocalContext::BeginImmediateDraw()
1089 {
1090   if (myMainPM->IsImmediateModeOn())
1091   {
1092     myMainPM->BeginImmediateDraw();
1093     return Standard_True;
1094   }
1095   return Standard_False;
1096 }
1097
1098 //=======================================================================
1099 //function : ImmediateAdd
1100 //purpose  :
1101 //=======================================================================
1102 Standard_Boolean AIS_LocalContext::ImmediateAdd (const Handle(AIS_InteractiveObject)& theObj,
1103                                                  const Standard_Integer               theMode)
1104 {
1105   if (!myMainPM->IsImmediateModeOn())
1106   {
1107     return Standard_False;
1108   }
1109
1110   myMainPM->AddToImmediateList (myMainPM->Presentation (theObj, theMode)->Presentation());
1111   return Standard_True;
1112 }
1113
1114 //=======================================================================
1115 //function : EndImmediateDraw
1116 //purpose  :
1117 //=======================================================================
1118 Standard_Boolean AIS_LocalContext::EndImmediateDraw (const Handle(V3d_Viewer)& theViewer)
1119 {
1120   if (!myMainPM->IsImmediateModeOn())
1121   {
1122     return Standard_False;
1123   }
1124
1125   myMainPM->EndImmediateDraw (theViewer);
1126   return Standard_True;
1127 }
1128
1129 // =======================================================================
1130 // function : ClearImmediateDraw
1131 // purpose  :
1132 // =======================================================================
1133 void AIS_LocalContext::ClearImmediateDraw()
1134 {
1135   myMainPM->ClearImmediateDraw();
1136 }
1137
1138 //=======================================================================
1139 //function : IsImmediateModeOn
1140 //purpose  :
1141 //=======================================================================
1142 Standard_Boolean AIS_LocalContext::IsImmediateModeOn() const
1143 {
1144   return myMainPM->IsImmediateModeOn();
1145 }
1146
1147 void AIS_LocalContext::SetPixelTolerance(const Standard_Integer aPrecision) {
1148
1149   myMainVS->SetPixelTolerance(aPrecision);
1150 }
1151
1152 Standard_Integer AIS_LocalContext::PixelTolerance() const {
1153
1154   return myMainVS->PixelTolerance();
1155 }