0031412: Visualization - entity behind is returned as topmost at the edges
[occt.git] / src / ViewerTest / ViewerTest_EventManager.cxx
1 // Created on: 1998-08-27
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1998-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 #include <ViewerTest_EventManager.hxx>
18
19 #include <AIS_AnimationCamera.hxx>
20 #include <AIS_InteractiveContext.hxx>
21 #include <AIS_Shape.hxx>
22 #include <Aspect_Grid.hxx>
23 #include <Draw.hxx>
24 #include <ViewerTest_ContinuousRedrawer.hxx>
25 #include <ViewerTest_V3dView.hxx>
26
27 Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
28
29 IMPLEMENT_STANDARD_RTTIEXT(ViewerTest_EventManager,Standard_Transient)
30
31 //=======================================================================
32 //function : GlobalViewAnimation
33 //purpose  :
34 //=======================================================================
35 const Handle(AIS_AnimationCamera)& ViewerTest_EventManager::GlobalViewAnimation()
36 {
37   static Handle(AIS_AnimationCamera) THE_CAMERA_ANIM = new AIS_AnimationCamera ("ViewerTest_EventManager_ViewAnimation", Handle(V3d_View)());
38   return THE_CAMERA_ANIM;
39 }
40
41 //=======================================================================
42 //function : ViewerTest_EventManager
43 //purpose  :
44 //=======================================================================
45 ViewerTest_EventManager::ViewerTest_EventManager (const Handle(V3d_View)&               theView,
46                                                   const Handle(AIS_InteractiveContext)& theCtx)
47 : myCtx  (theCtx),
48   myView (theView),
49   myToPickPnt (Standard_False),
50   myIsTmpContRedraw (Standard_False)
51 {
52   myViewAnimation = GlobalViewAnimation();
53 }
54
55 //=======================================================================
56 //function : ~ViewerTest_EventManager
57 //purpose  :
58 //=======================================================================
59 ViewerTest_EventManager::~ViewerTest_EventManager()
60 {
61   if (!myViewAnimation.IsNull()
62     && myViewAnimation->View() == myView)
63   {
64     myViewAnimation->Stop();
65     myViewAnimation->SetView (Handle(V3d_View)());
66   }
67 }
68
69 //=======================================================================
70 //function : UpdateMouseButtons
71 //purpose  :
72 //=======================================================================
73 bool ViewerTest_EventManager::UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
74                                                   Aspect_VKeyMouse theButtons,
75                                                   Aspect_VKeyFlags theModifiers,
76                                                   bool theIsEmulated)
77 {
78   SetAllowRotation (!ViewerTest_V3dView::IsCurrentViewIn2DMode());
79
80   if (theButtons == Aspect_VKeyMouse_LeftButton)
81   {
82     if (myToPickPnt && (theModifiers & Aspect_VKeyFlags_CTRL) != 0)
83     {
84       Graphic3d_Vec3d anXYZ;
85       myView->Convert (thePoint.x(), thePoint.y(), anXYZ.x(), anXYZ.y(), anXYZ.z());
86       Draw::Set (myPickPntArgVec[0].ToCString(), anXYZ.x());
87       Draw::Set (myPickPntArgVec[1].ToCString(), anXYZ.y());
88       Draw::Set (myPickPntArgVec[2].ToCString(), anXYZ.z());
89       myToPickPnt = false;
90     }
91   }
92
93   return AIS_ViewController::UpdateMouseButtons (thePoint, theButtons, theModifiers, theIsEmulated);
94 }
95
96 //==============================================================================
97 //function : ProcessExpose
98 //purpose  :
99 //==============================================================================
100 void ViewerTest_EventManager::ProcessExpose()
101 {
102   if (!myView.IsNull())
103   {
104     myView->Invalidate();
105     FlushViewEvents (myCtx, myView, true);
106   }
107 }
108
109 //==============================================================================
110 //function : handleViewRedraw
111 //purpose  :
112 //==============================================================================
113 void ViewerTest_EventManager::handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
114                                                 const Handle(V3d_View)& theView)
115 {
116   AIS_ViewController::handleViewRedraw (theCtx, theView);
117
118   // On non-Windows platforms Aspect_Window::InvalidateContent() from rendering thread does not work as expected
119   // as in Tcl event loop the new message might go to sleep with new event remaining in queue.
120   // As a workaround - use dedicated background thread to ping Tcl event loop.
121   if (myToAskNextFrame)
122   {
123     ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
124     if (!myIsTmpContRedraw
125      && (!aRedrawer.IsStarted() || aRedrawer.IsPaused()))
126     {
127       myIsTmpContRedraw = true;
128     #ifndef _WIN32
129       aRedrawer.Start (theView->Window(), 60.0);
130     #endif
131     }
132   }
133   else if (myIsTmpContRedraw)
134   {
135     myIsTmpContRedraw = false;
136   #ifndef _WIN32
137     ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
138     aRedrawer.Pause();
139   #endif
140   }
141 }
142
143 //==============================================================================
144 //function : ProcessConfigure
145 //purpose  :
146 //==============================================================================
147 void ViewerTest_EventManager::ProcessConfigure()
148 {
149   if (!myView.IsNull())
150   {
151     myView->MustBeResized();
152     FlushViewEvents (myCtx, myView, true);
153   }
154 }
155
156 //=======================================================================
157 //function : KeyUp
158 //purpose  :
159 //=======================================================================
160 void ViewerTest_EventManager::KeyUp (Aspect_VKey theKey,
161                                      double theTime)
162 {
163   AIS_ViewController::KeyUp (theKey, theTime);
164   ProcessKeyPress (theKey);
165 }
166
167 //==============================================================================
168 //function : ProcessKeyPress
169 //purpose  :
170 //==============================================================================
171 void ViewerTest_EventManager::ProcessKeyPress (Aspect_VKey theKey)
172 {
173   if (myCtx.IsNull()
174    || myView.IsNull())
175   {
176     return;
177   }
178
179   switch (theKey)
180   {
181     case Aspect_VKey_A: // AXO
182     {
183       if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
184       {
185         myView->SetProj(V3d_XposYnegZpos);
186       }
187       break;
188     }
189     case Aspect_VKey_D: // Reset
190     {
191       if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
192       {
193         myView->Reset();
194       }
195       break;
196     }
197     case Aspect_VKey_F:
198     {
199       if (myCtx->NbSelected() > 0)
200       {
201         myCtx->FitSelected (myView);
202       }
203       else
204       {
205         myView->FitAll();
206       }
207       break;
208     }
209     case Aspect_VKey_H: // HLR
210     {
211       std::cout << "HLR\n";
212       myView->SetComputedMode (!myView->ComputedMode());
213       myView->Redraw();
214       break;
215     }
216     case Aspect_VKey_P: // Type of HLR
217     {
218       myCtx->DefaultDrawer()->SetTypeOfHLR (myCtx->DefaultDrawer()->TypeOfHLR() == Prs3d_TOH_Algo
219                                           ? Prs3d_TOH_PolyAlgo
220                                           : Prs3d_TOH_Algo);
221       if (myCtx->NbSelected() == 0)
222       {
223         AIS_ListOfInteractive aListOfShapes;
224         myCtx->DisplayedObjects (aListOfShapes);
225         for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
226         {
227           if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (anIter.Value()))
228           {
229             aShape->SetTypeOfHLR (aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo
230                                 ? Prs3d_TOH_Algo
231                                 : Prs3d_TOH_PolyAlgo);
232             myCtx->Redisplay (aShape, Standard_False);
233           }
234         }
235       }
236       else
237       {
238         for (myCtx->InitSelected(); myCtx->MoreSelected(); myCtx->NextSelected())
239         {
240           if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (myCtx->SelectedInteractive()))
241           {
242             aShape->SetTypeOfHLR (aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo
243                                 ? Prs3d_TOH_Algo
244                                 : Prs3d_TOH_PolyAlgo);
245             myCtx->Redisplay (aShape, Standard_False);
246           }
247         }
248       }
249       myCtx->UpdateCurrentViewer();
250       break;
251     }
252     case Aspect_VKey_S:
253     case Aspect_VKey_W:
254     {
255       Standard_Integer aDispMode = AIS_Shaded;
256       if (theKey == Aspect_VKey_S)
257       {
258         aDispMode = AIS_Shaded;
259         std::cout << "setup Shaded display mode\n";
260       }
261       else
262       {
263         aDispMode = AIS_WireFrame;
264         std::cout << "setup WireFrame display mode\n";
265       }
266
267       if (myCtx->NbSelected() == 0)
268       {
269         myCtx->SetDisplayMode (aDispMode, true);
270       }
271       else
272       {
273         for (myCtx->InitSelected(); myCtx->MoreSelected(); myCtx->NextSelected())
274         {
275           myCtx->SetDisplayMode (myCtx->SelectedInteractive(), aDispMode, false);
276         }
277         myCtx->UpdateCurrentViewer();
278       }
279       break;
280     }
281     case Aspect_VKey_U: // Unset display mode
282     {
283       std::cout << "reset display mode to defaults\n";
284       if (myCtx->NbSelected() == 0)
285       {
286         myCtx->SetDisplayMode (AIS_WireFrame, true);
287       }
288       else
289       {
290         for (myCtx->InitSelected(); myCtx->MoreSelected(); myCtx->NextSelected())
291         {
292           myCtx->UnsetDisplayMode (myCtx->SelectedInteractive(), false);
293         }
294         myCtx->UpdateCurrentViewer();
295       }
296       break;
297     }
298     case Aspect_VKey_T:
299     {
300       if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
301       {
302         myView->SetProj (V3d_TypeOfOrientation_Zup_Top);
303       }
304       break;
305     }
306     case Aspect_VKey_B:
307     {
308       if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
309       {
310         myView->SetProj (V3d_TypeOfOrientation_Zup_Bottom);
311       }
312       break;
313     }
314     case Aspect_VKey_L:
315     {
316       if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
317       {
318         myView->SetProj (V3d_TypeOfOrientation_Zup_Left);
319       }
320       break;
321     }
322     case Aspect_VKey_R:
323     {
324       if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
325       {
326         myView->SetProj (V3d_TypeOfOrientation_Zup_Right);
327       }
328       break;
329     }
330     case Aspect_VKey_Comma:
331     {
332       myCtx->HilightNextDetected (myView);
333       break;
334     }
335     case Aspect_VKey_Period:
336     {
337       myCtx->HilightPreviousDetected (myView);
338       break;
339     }
340     case Aspect_VKey_Slash:
341     case Aspect_VKey_NumpadDivide:
342     {
343       Handle(Graphic3d_Camera) aCamera = myView->Camera();
344       if (aCamera->IsStereo())
345       {
346         aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() - 0.01);
347         myView->Redraw();
348       }
349       break;
350     }
351     case Aspect_VKey_NumpadMultiply:
352     {
353       Handle(Graphic3d_Camera) aCamera = myView->Camera();
354       if (aCamera->IsStereo())
355       {
356         aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() + 0.01);
357         myView->Redraw();
358       }
359       break;
360     }
361     case Aspect_VKey_Delete:
362     {
363       if (!myCtx.IsNull()
364         && myCtx->NbSelected() > 0)
365       {
366         Draw_Interprete ("verase");
367       }
368       break;
369     }
370     case Aspect_VKey_Escape:
371     {
372       if (!myCtx.IsNull()
373         && ViewerTest_EventManager::ToCloseViewOnEscape())
374       {
375         Draw_Interprete (ViewerTest_EventManager::ToExitOnCloseView() ? "exit" : "vclose");
376       }
377     }
378   }
379
380   if (theKey >= Aspect_VKey_0
381    && theKey <= Aspect_VKey_7)
382   {
383     const Standard_Integer aSelMode = theKey - Aspect_VKey_0;
384     bool toEnable = true;
385     if (!myCtx.IsNull())
386     {
387       AIS_ListOfInteractive aPrsList;
388       myCtx->DisplayedObjects (aPrsList);
389       for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More() && toEnable; aPrsIter.Next())
390       {
391         TColStd_ListOfInteger aModes;
392         myCtx->ActivatedModes (aPrsIter.Value(), aModes);
393         for (TColStd_ListOfInteger::Iterator aModeIter (aModes); aModeIter.More() && toEnable; aModeIter.Next())
394         {
395           if (aModeIter.Value() == aSelMode)
396           {
397             toEnable = false;
398           }
399         }
400       }
401     }
402     TCollection_AsciiString aCmd = TCollection_AsciiString ("vselmode ") + aSelMode + (toEnable ? " 1" : " 0");
403     Draw_Interprete (aCmd.ToCString());
404   }
405 }