0024623: Visualization - improve selection mechanism
[occt.git] / samples / mfc / standard / 09_Animation / src / AnimationView3D.cpp
1 // AnimationView3D.cpp : implementation of the CAnimationView3D class
2 //
3
4 #include "stdafx.h"
5
6 #include "AnimationView3D.h"
7
8 #include "AnimationApp.h"
9 #include "ShadingDialog.h"
10 #include "AnimationDoc.h"
11
12 #include "Sensitivity.h"
13
14 #ifdef _DEBUG
15 //#define new DEBUG_NEW by CasCade
16 #undef THIS_FILE
17 static char THIS_FILE[] = __FILE__;
18 #endif
19 static int rotCount = 0;
20
21 // for elastic bean selection
22 #define ValZWMin 1
23
24
25 /////////////////////////////////////////////////////////////////////////////
26 // CAnimationView3D
27
28 IMPLEMENT_DYNCREATE(CAnimationView3D, CView)
29
30 BEGIN_MESSAGE_MAP(CAnimationView3D, CView)
31         //{{AFX_MSG_MAP(CAnimationView3D)
32         ON_COMMAND(ID_BUTTONAxo, OnBUTTONAxo)
33         ON_COMMAND(ID_BUTTONBack, OnBUTTONBack)
34         ON_COMMAND(ID_BUTTONBottom, OnBUTTONBottom)
35         ON_COMMAND(ID_BUTTONFront, OnBUTTONFront)
36         ON_COMMAND(ID_BUTTONHlrOff, OnBUTTONHlrOff)
37         ON_COMMAND(ID_BUTTONHlrOn, OnBUTTONHlrOn)
38         ON_COMMAND(ID_BUTTONLeft, OnBUTTONLeft)
39         ON_COMMAND(ID_BUTTONPan, OnBUTTONPan)
40         ON_COMMAND(ID_BUTTONPanGlo, OnBUTTONPanGlo)
41         ON_COMMAND(ID_BUTTONReset, OnBUTTONReset)
42         ON_COMMAND(ID_BUTTONRight, OnBUTTONRight)
43         ON_COMMAND(ID_BUTTONRot, OnBUTTONRot)
44         ON_COMMAND(ID_BUTTONTop, OnBUTTONTop)
45         ON_COMMAND(ID_BUTTONZoomAll, OnBUTTONZoomAll)
46     ON_COMMAND(ID_FILE_EXPORT_IMAGE, OnFileExportImage)
47         ON_WM_SIZE()
48         ON_COMMAND(ID_BUTTONZoomProg, OnBUTTONZoomProg)
49         ON_COMMAND(ID_BUTTONZoomWin, OnBUTTONZoomWin)
50         ON_WM_LBUTTONDOWN()
51         ON_WM_LBUTTONUP()
52         ON_WM_MBUTTONDOWN()
53         ON_WM_MBUTTONUP()
54         ON_WM_MOUSEMOVE()
55         ON_WM_RBUTTONDOWN()
56         ON_WM_RBUTTONUP()
57         ON_UPDATE_COMMAND_UI(ID_BUTTONHlrOff, OnUpdateBUTTONHlrOff)
58         ON_UPDATE_COMMAND_UI(ID_BUTTONHlrOn, OnUpdateBUTTONHlrOn)
59         ON_UPDATE_COMMAND_UI(ID_BUTTONPanGlo, OnUpdateBUTTONPanGlo)
60         ON_UPDATE_COMMAND_UI(ID_BUTTONPan, OnUpdateBUTTONPan)
61         ON_UPDATE_COMMAND_UI(ID_BUTTONZoomProg, OnUpdateBUTTONZoomProg)
62         ON_UPDATE_COMMAND_UI(ID_BUTTONZoomWin, OnUpdateBUTTONZoomWin)
63         ON_UPDATE_COMMAND_UI(ID_BUTTONRot, OnUpdateBUTTONRot)
64
65         ON_COMMAND(ID_Modify_ChangeBackground     , OnChangeBackground)
66         ON_WM_TIMER()
67         ON_COMMAND(ID_STOP, OnStop)
68         ON_COMMAND(ID_RESTART, OnRestart)
69
70         ON_COMMAND(ID_SENSITIVITY, OnSensitivity)
71         ON_COMMAND(ID_BUTTONFly, OnBUTTONFly)
72         ON_COMMAND(ID_BUTTONTurn, OnBUTTONTurn)
73         ON_UPDATE_COMMAND_UI(ID_BUTTONFly, OnUpdateBUTTONFly)
74         ON_UPDATE_COMMAND_UI(ID_BUTTONTurn, OnUpdateBUTTONTurn)
75         ON_COMMAND(ID_VIEW_DISPLAYSTATUS, OnViewDisplaystatus)
76         ON_UPDATE_COMMAND_UI(ID_VIEW_DISPLAYSTATUS, OnUpdateViewDisplaystatus)
77         //}}AFX_MSG_MAP
78 // CasCade
79
80 END_MESSAGE_MAP()
81
82 /////////////////////////////////////////////////////////////////////////////
83 // CAnimationView3D construction/destruction
84
85 CAnimationView3D::CAnimationView3D()
86 : myXmin (0),
87   myYmin (0),
88   myXmax (0),
89   myYmax (0),
90   myCurZoom (0.0),
91   myHlrModeIsOn (Standard_False),
92   myCurrentMode  (CurrentAction3d_Nothing),
93   m_FlySens  (500.0),
94   m_TurnSens (M_PI / 40.0),
95   m_Pen (NULL)
96 {
97   // TODO: add construction code here
98 }
99
100 CAnimationView3D::~CAnimationView3D()
101 {
102     myView->Remove();
103     if (m_Pen) delete m_Pen;
104 }
105
106 BOOL CAnimationView3D::PreCreateWindow(CREATESTRUCT& cs)
107 {
108         // TODO: Modify the Window class or styles here by modifying
109         //  the CREATESTRUCT cs
110
111         return CView::PreCreateWindow(cs);
112 }
113
114 /////////////////////////////////////////////////////////////////////////////
115 // CAnimationView3D drawing
116
117 void CAnimationView3D::OnDraw(CDC* /*pDC*/)
118 {
119         CAnimationDoc* pDoc = GetDocument();
120         ASSERT_VALID(pDoc);
121
122         // TODO: add draw code for native data here
123
124           myView->Redraw();
125
126 }
127 void CAnimationView3D::OnInitialUpdate() 
128 {
129   CView::OnInitialUpdate();
130
131   // TODO: Add your specialized code here and/or call the base class
132   //    myView = GetDocument()->GetViewer()->CreateView();
133
134   Handle(V3d_Viewer) aViewer;
135
136   aViewer = GetDocument()->GetViewer();
137   aViewer->SetDefaultTypeOfView (V3d_PERSPECTIVE);
138
139   myView = aViewer->CreateView();
140
141   // store for restore state after rotation (witch is in Degenerated mode)
142   myHlrModeIsOn = myView->ComputedMode();
143
144   Handle(WNT_Window) aWNTWindow = new WNT_Window (GetSafeHwnd());
145   myView->SetWindow(aWNTWindow);
146   if (!aWNTWindow->IsMapped()) aWNTWindow->Map();
147
148   // store the mode ( nothing , dynamic zooming, dynamic ... )
149   myCurrentMode = CurrentAction3d_Nothing;
150   CFrameWnd* pParentFrm = GetParentFrame();
151   pParentFrm->ActivateFrame(SW_SHOWMAXIMIZED);
152
153   Standard_Integer w=100 , h=100 ;   /* Debug Matrox                         */
154   aWNTWindow->Size (w,h) ;           /* Keeps me unsatisfied (rlb).....      */
155                                    /* Resize is not supposed to be done on */
156                                    /* Matrox                               */
157                                    /* I suspect another problem elsewhere  */
158   ::PostMessage ( GetSafeHwnd () , WM_SIZE , SIZE_RESTORED , w + h*65536 ) ;
159
160   m_Tune.Create ( IDD_TUNE , NULL ) ;
161
162   RECT dlgrect;
163   m_Tune.GetWindowRect(&dlgrect);
164   LONG width = dlgrect.right-dlgrect.left;
165   LONG height = dlgrect.bottom-dlgrect.top;
166   RECT MainWndRect;
167   AfxGetApp()->m_pMainWnd->GetWindowRect(&MainWndRect);
168   LONG left = MainWndRect.left+3;
169   LONG top = MainWndRect.top + 112;
170   m_Tune.MoveWindow(left,top,width,height);
171
172   m_Tune.m_pView = this ;
173
174   m_Tune.ShowWindow ( SW_HIDE );
175
176   // store the mode ( nothing , dynamic zooming, dynamic ... )
177
178   myCurrentMode = CurrentAction3d_Nothing;
179
180   ReloadData () ;
181
182 }
183
184 void CAnimationView3D::DisplayTuneDialog()
185 {
186         m_Tune.Create ( IDD_TUNE , NULL ) ;
187         
188         RECT dlgrect;
189         m_Tune.GetWindowRect(&dlgrect);
190         LONG width = dlgrect.right-dlgrect.left;
191         LONG height = dlgrect.bottom-dlgrect.top;
192         RECT MainWndRect;
193         AfxGetApp()->m_pMainWnd->GetWindowRect(&MainWndRect);
194         LONG left = MainWndRect.left+3;
195         LONG top = MainWndRect.top + 112;
196         m_Tune.MoveWindow(left,top,width,height);
197         
198         m_Tune.m_pView = this ;
199 }
200
201
202 /////////////////////////////////////////////////////////////////////////////
203 // CAnimationView3D diagnostics
204
205 #ifdef _DEBUG
206 void CAnimationView3D::AssertValid() const
207 {
208         CView::AssertValid();
209 }
210
211 void CAnimationView3D::Dump(CDumpContext& dc) const
212 {
213         CView::Dump(dc);
214 }
215
216 CAnimationDoc* CAnimationView3D::GetDocument() // non-debug version is inline
217 {
218         ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CAnimationDoc)));
219         return (CAnimationDoc*)m_pDocument;
220 }
221 #endif //_DEBUG
222
223 /////////////////////////////////////////////////////////////////////////////
224 // CAnimationView3D message handlers
225 void CAnimationView3D::OnFileExportImage()
226 {
227   GetDocument()->ExportView (myView);
228 }
229
230 void CAnimationView3D::OnSize(UINT /*nType*/, int cx, int cy) 
231 {
232         m_cx = cx ;
233         m_cy = cy ;
234         if (!myView.IsNull())
235                 myView->MustBeResized();
236 }
237
238 void CAnimationView3D::OnBUTTONBack() 
239 { myView->SetProj(V3d_Xneg); } // See the back View
240 void CAnimationView3D::OnBUTTONFront() 
241 { myView->SetProj(V3d_Xpos); } // See the front View
242
243 void CAnimationView3D::OnBUTTONBottom() 
244 { myView->SetProj(V3d_Zneg); } // See the bottom View
245 void CAnimationView3D::OnBUTTONTop() 
246 { myView->SetProj(V3d_Zpos); } // See the top View      
247
248 void CAnimationView3D::OnBUTTONLeft() 
249 { myView->SetProj(V3d_Ypos); } // See the left View     
250 void CAnimationView3D::OnBUTTONRight() 
251 { myView->SetProj(V3d_Yneg); } // See the right View
252
253 void CAnimationView3D::OnBUTTONAxo() 
254 { myView->SetProj(V3d_XposYnegZpos); } // See the axonometric View
255
256 void CAnimationView3D::OnBUTTONHlrOff() 
257 {
258   myHlrModeIsOn = Standard_False;
259   myView->SetComputedMode (myHlrModeIsOn);
260 }
261
262 void CAnimationView3D::OnBUTTONHlrOn() 
263 {
264   SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
265   myHlrModeIsOn = Standard_True;
266   myView->SetComputedMode (myHlrModeIsOn);
267   SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
268 }
269
270 void CAnimationView3D::OnBUTTONPan() 
271 {  
272         myCurrentMode = CurrentAction3d_DynamicPanning; 
273 }
274
275 void CAnimationView3D::OnBUTTONPanGlo() 
276 {
277   // save the current zoom value 
278   myCurZoom = myView->Scale();
279   // Do a Global Zoom 
280   myView->FitAll();
281   // Set the mode 
282   myCurrentMode = CurrentAction3d_GlobalPanning;
283 }
284
285 void CAnimationView3D::OnBUTTONReset() 
286 {   myView->Reset(); 
287         ReloadData();
288 }
289
290 void CAnimationView3D::OnBUTTONRot() 
291 {   myCurrentMode = CurrentAction3d_DynamicRotation; }
292
293
294 void CAnimationView3D::OnBUTTONZoomAll() 
295 {
296         SetDimensions();
297         myView->FitAll();
298         myView->ZFitAll();
299 }
300
301 void CAnimationView3D::OnBUTTONZoomProg() 
302 {  myCurrentMode = CurrentAction3d_DynamicZooming; }
303
304 void CAnimationView3D::OnBUTTONZoomWin() 
305 {  myCurrentMode = CurrentAction3d_WindowZooming; }
306
307 void CAnimationView3D::OnBUTTONFly() 
308 {  myCurrentMode = CurrentAction3d_Fly; }
309
310 void CAnimationView3D::OnBUTTONTurn() 
311 {  myCurrentMode = CurrentAction3d_Turn; }
312
313
314 void CAnimationView3D::OnLButtonDown(UINT nFlags, CPoint point) 
315 {
316   //  save the current mouse coordinate in min 
317   myXmin=point.x;  myYmin=point.y;
318   myXmax=point.x;  myYmax=point.y;
319
320   if ( nFlags & MK_CONTROL ) 
321           {
322             // Button MB1 down Control :start zomming 
323         // SetCursor(AfxGetApp()->LoadStandardCursor());
324           }
325         else // if ( Ctrl )
326           {
327         switch (myCurrentMode)
328         {
329          case CurrentAction3d_Nothing : // start a drag
330            if (nFlags & MK_SHIFT)
331                 GetDocument()->ShiftDragEvent(myXmax,myYmax,-1,myView);
332            else
333                 GetDocument()->DragEvent(myXmax,myYmax,-1,myView);
334         break;
335          break;
336          case CurrentAction3d_DynamicZooming : // noting
337              // SetCursor(AfxGetApp()->LoadStandardCursor());
338          break;
339          case CurrentAction3d_WindowZooming : // noting
340          break;
341          case CurrentAction3d_DynamicPanning :// noting
342          break;
343          case CurrentAction3d_GlobalPanning :// noting
344         break;
345         case  CurrentAction3d_DynamicRotation :
346           if (myHlrModeIsOn)
347           {
348             myView->SetComputedMode (Standard_False);
349           }
350           myView->StartRotation (point.x, point.y);
351         break;
352                 case  CurrentAction3d_Fly :
353                         KillTimer (1) ;
354                         SetTimer ( 1 , 100 , NULL ) ;
355                 break ;
356         case  CurrentAction3d_Turn :
357                         KillTimer (1) ;
358                         SetTimer ( 1 , 100 , NULL ) ;
359                 break ;
360         default :
361            Standard_Failure::Raise(" incompatible Current Mode ");
362         break;
363         }
364     }
365 }
366
367 void CAnimationView3D::OnLButtonUp(UINT nFlags, CPoint point) 
368 {
369    if ( nFlags & MK_CONTROL ) 
370           {
371         return;
372           }
373         else // if ( Ctrl )
374           {
375         switch (myCurrentMode)
376         {
377          case CurrentAction3d_Nothing :
378          if (point.x == myXmin && point.y == myYmin)
379          { // no offset between down and up --> selectEvent
380             myXmax=point.x;  
381             myYmax=point.y;
382             if (nFlags & MK_SHIFT )
383               GetDocument()->ShiftInputEvent(point.x,point.y,myView);
384             else
385               GetDocument()->InputEvent     (point.x,point.y,myView);
386          } else
387          {
388             DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False);
389             myXmax=point.x;  
390             myYmax=point.y;
391                     if (nFlags & MK_SHIFT)
392                                 GetDocument()->ShiftDragEvent(point.x,point.y,1,myView);
393                         else
394                                 GetDocument()->DragEvent(point.x,point.y,1,myView);
395          }
396          break;
397          case CurrentAction3d_DynamicZooming :
398              // SetCursor(AfxGetApp()->LoadStandardCursor());         
399                myCurrentMode = CurrentAction3d_Nothing;
400          break;
401          case CurrentAction3d_WindowZooming :
402            myXmax=point.x;            myYmax=point.y;
403             DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False,LongDash);
404                if ((abs(myXmin-myXmax)>ValZWMin) || (abs(myYmin-myYmax)>ValZWMin))
405                                          // Test if the zoom window is greater than a minimale window.
406                         {
407                           // Do the zoom window between Pmin and Pmax
408                           myView->WindowFitAll(myXmin,myYmin,myXmax,myYmax);  
409                         }  
410                myCurrentMode = CurrentAction3d_Nothing;
411          break;
412          case CurrentAction3d_DynamicPanning :
413            myCurrentMode = CurrentAction3d_Nothing;
414          break;
415          case CurrentAction3d_GlobalPanning :
416                myView->Place(point.x,point.y,myCurZoom); 
417                myCurrentMode = CurrentAction3d_Nothing;
418         break;
419         case  CurrentAction3d_DynamicRotation :
420                myCurrentMode = CurrentAction3d_Nothing;
421         break;
422                 case  CurrentAction3d_Fly :
423                         KillTimer ( 1 ) ;
424         case  CurrentAction3d_Turn :
425                         KillTimer ( 1 ) ;
426                 break;
427         default :
428            Standard_Failure::Raise(" incompatible Current Mode ");
429         break;
430         } //switch (myCurrentMode)
431     } //        else // if ( Ctrl )
432 }
433
434 void CAnimationView3D::OnMButtonDown(UINT nFlags, CPoint /*point*/) 
435 {
436    if ( nFlags & MK_CONTROL ) 
437           {
438         // Button MB2 down Control : panning init  
439         // SetCursor(AfxGetApp()->LoadStandardCursor());   
440           }
441 }
442
443 void CAnimationView3D::OnMButtonUp(UINT nFlags, CPoint /*point*/) 
444 {
445    if ( nFlags & MK_CONTROL ) 
446           {
447         // Button MB2 down Control : panning init  
448         // SetCursor(AfxGetApp()->LoadStandardCursor());   
449           }
450 }
451
452 void CAnimationView3D::OnRButtonDown(UINT nFlags, CPoint point) 
453 {
454   if ( nFlags & MK_CONTROL )
455   {
456     // SetCursor(AfxGetApp()->LoadStandardCursor());
457     if (myHlrModeIsOn)
458     {
459       myView->SetComputedMode (Standard_False);
460     }
461     myView->StartRotation (point.x, point.y);
462   }
463   else // if ( Ctrl )
464   {
465     GetDocument()->Popup(point.x,point.y,myView);
466   }
467 }
468
469 void CAnimationView3D::OnRButtonUp(UINT /*nFlags*/, CPoint /*point*/) 
470 {
471     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
472     myView->SetComputedMode (myHlrModeIsOn);
473     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
474 }
475
476 void CAnimationView3D::OnMouseMove(UINT nFlags, CPoint point) 
477 {
478     //   ============================  LEFT BUTTON =======================
479   m_curx = point.x ;
480   m_cury = point.y ;
481
482   if ( nFlags & MK_LBUTTON)
483     {
484      if ( nFlags & MK_CONTROL ) 
485           {
486             // move with MB1 and Control : on the dynamic zooming  
487             // Do the zoom in function of mouse's coordinates  
488             myView->Zoom(myXmax,myYmax,point.x,point.y); 
489             // save the current mouse coordinate in min 
490                 myXmax = point.x; 
491         myYmax = point.y;       
492           }
493           else // if ( Ctrl )
494           {
495         switch (myCurrentMode)
496         {
497          case CurrentAction3d_Nothing :
498                    myXmax = point.x;            myYmax = point.y;
499             DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False);
500            if (nFlags & MK_SHIFT)               
501              GetDocument()->ShiftDragEvent(myXmax,myYmax,0,myView);
502            else
503              GetDocument()->DragEvent(myXmax,myYmax,0,myView);
504             DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_True);
505           break;
506          case CurrentAction3d_DynamicZooming :
507                myView->Zoom(myXmax,myYmax,point.x,point.y); 
508                // save the current mouse coordinate in min \n";
509                myXmax=point.x;  myYmax=point.y;
510          break;
511          case CurrentAction3d_WindowZooming :
512                    myXmax = point.x; myYmax = point.y;  
513             DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False,LongDash);
514             DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_True,LongDash);
515          break;
516          case CurrentAction3d_DynamicPanning :
517                    myView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
518                    myXmax = point.x; myYmax = point.y;  
519          break;
520          case CurrentAction3d_GlobalPanning : // nothing           
521         break;
522         case  CurrentAction3d_DynamicRotation :
523           myView->Rotation(point.x,point.y);
524               myView->Redraw();
525         break;
526                 case CurrentAction3d_Fly :
527                         break ;
528                 case CurrentAction3d_Turn :
529                         break ;
530         default :
531            Standard_Failure::Raise(" incompatible Current Mode ");
532         break;
533         }//  switch (myCurrentMode)
534       }// if ( nFlags & MK_CONTROL )  else 
535     } else //   if ( nFlags & MK_LBUTTON) 
536     //   ============================  MIDDLE BUTTON =======================
537     if ( nFlags & MK_MBUTTON)
538     {
539      if ( nFlags & MK_CONTROL ) 
540           {
541                 myView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
542                 myXmax = point.x; myYmax = point.y;     
543
544           }
545     } else //  if ( nFlags & MK_MBUTTON)
546     //   ============================  RIGHT BUTTON =======================
547     if ( nFlags & MK_RBUTTON)
548     {
549      if ( nFlags & MK_CONTROL ) 
550           {
551              rotCount++;
552          myView->Rotation(point.x,point.y);
553           }
554     }else //if ( nFlags & MK_RBUTTON)
555     //   ============================  NO BUTTON =======================
556     {  // No buttons 
557           myXmax = point.x; myYmax = point.y;   
558           if (nFlags & MK_SHIFT)
559                 GetDocument()->ShiftMoveEvent(point.x,point.y,myView);
560           else
561                 GetDocument()->MoveEvent(point.x,point.y,myView);
562    }
563 }
564
565 void CAnimationView3D::OnUpdateBUTTONHlrOff(CCmdUI* pCmdUI) 
566 {
567   pCmdUI->SetCheck (!myHlrModeIsOn);
568   pCmdUI->Enable   (myHlrModeIsOn);
569 }
570
571 void CAnimationView3D::OnUpdateBUTTONHlrOn(CCmdUI* pCmdUI) 
572 {
573   pCmdUI->SetCheck (myHlrModeIsOn);
574   pCmdUI->Enable   (!myHlrModeIsOn);
575 }
576
577 void CAnimationView3D::OnUpdateBUTTONPanGlo(CCmdUI* pCmdUI) 
578 {
579     pCmdUI->SetCheck (myCurrentMode == CurrentAction3d_GlobalPanning);
580         pCmdUI->Enable   (myCurrentMode != CurrentAction3d_GlobalPanning);      
581         
582 }
583
584 void CAnimationView3D::OnUpdateBUTTONPan(CCmdUI* pCmdUI) 
585 {
586     pCmdUI->SetCheck (myCurrentMode == CurrentAction3d_DynamicPanning);
587         pCmdUI->Enable   (myCurrentMode != CurrentAction3d_DynamicPanning );    
588 }
589
590 void CAnimationView3D::OnUpdateBUTTONZoomProg(CCmdUI* pCmdUI) 
591 {
592     pCmdUI->SetCheck (myCurrentMode == CurrentAction3d_DynamicZooming );
593         pCmdUI->Enable   (myCurrentMode != CurrentAction3d_DynamicZooming);     
594 }
595
596 void CAnimationView3D::OnUpdateBUTTONZoomWin(CCmdUI* pCmdUI) 
597 {
598     pCmdUI->SetCheck (myCurrentMode == CurrentAction3d_WindowZooming);
599         pCmdUI->Enable   (myCurrentMode != CurrentAction3d_WindowZooming);      
600 }
601
602 void CAnimationView3D::OnUpdateBUTTONRot(CCmdUI* pCmdUI) 
603 {
604     pCmdUI->SetCheck (myCurrentMode == CurrentAction3d_DynamicRotation);
605         pCmdUI->Enable   (myCurrentMode != CurrentAction3d_DynamicRotation);    
606 }
607
608 void CAnimationView3D::OnUpdateBUTTONFly(CCmdUI* pCmdUI) 
609 {
610         pCmdUI->Enable(GetDocument()->m_bIsGridLoaded);
611     pCmdUI->SetCheck (myCurrentMode == CurrentAction3d_Fly);
612 }
613
614 void CAnimationView3D::OnUpdateBUTTONTurn(CCmdUI* pCmdUI) 
615 {
616         pCmdUI->Enable(GetDocument()->m_bIsGridLoaded);
617     pCmdUI->SetCheck (myCurrentMode == CurrentAction3d_Turn);
618 }
619
620 void CAnimationView3D::OnChangeBackground() 
621 {
622         Standard_Real R1;
623         Standard_Real G1;
624         Standard_Real B1;
625     myView->BackgroundColor(Quantity_TOC_RGB,R1,G1,B1);
626         COLORREF m_clr ;
627         m_clr = RGB(R1*255,G1*255,B1*255);
628
629         CColorDialog dlgColor(m_clr);
630         if (dlgColor.DoModal() == IDOK)
631         {
632                 m_clr = dlgColor.GetColor();
633                 R1 = GetRValue(m_clr)/255.;
634                 G1 = GetGValue(m_clr)/255.;
635                 B1 = GetBValue(m_clr)/255.;
636         myView->SetBackgroundColor(Quantity_TOC_RGB,R1,G1,B1);
637         }
638     myView->Redraw();
639 }
640
641 //==========================================================================================
642 //==========================================================================================
643 //==========================================================================================
644
645 //-----------------------------------------------------------------------------------------
646 //
647 //-----------------------------------------------------------------------------------------
648 void CAnimationView3D::DrawRectangle(const Standard_Integer  MinX    ,
649                                                             const Standard_Integer  MinY    ,
650                                         const Standard_Integer  MaxX ,
651                                                             const Standard_Integer  MaxY ,
652                                                             const Standard_Boolean  Draw , 
653                                         const LineStyle aLineStyle)
654 {
655     static int m_DrawMode;
656     if  (!m_Pen && aLineStyle ==Solid )
657         {m_Pen = new CPen(PS_SOLID, 1, RGB(0,0,0)); m_DrawMode = R2_MERGEPENNOT;}
658     else if (!m_Pen && aLineStyle ==Dot )
659         {m_Pen = new CPen(PS_DOT, 1, RGB(0,0,0));   m_DrawMode = R2_XORPEN;}
660     else if (!m_Pen && aLineStyle == ShortDash)
661         {m_Pen = new CPen(PS_DASH, 1, RGB(255,0,0));    m_DrawMode = R2_XORPEN;}
662     else if (!m_Pen && aLineStyle == LongDash)
663         {m_Pen = new CPen(PS_DASH, 1, RGB(0,0,0));      m_DrawMode = R2_NOTXORPEN;}
664     else if (aLineStyle == Default) 
665         { m_Pen = NULL; m_DrawMode = R2_MERGEPENNOT;}
666
667     CPen* aOldPen = NULL;
668     CClientDC clientDC(this);
669     if (m_Pen) aOldPen = clientDC.SelectObject(m_Pen);
670     clientDC.SetROP2(m_DrawMode);
671
672     static              Standard_Integer StoredMinX, StoredMaxX, StoredMinY, StoredMaxY;
673     static              Standard_Boolean m_IsVisible;
674
675     if ( m_IsVisible && !Draw) // move or up  : erase at the old position 
676     {
677      clientDC.MoveTo(StoredMinX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMaxY); 
678      clientDC.LineTo(StoredMaxX,StoredMaxY); 
679          clientDC.LineTo(StoredMaxX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMinY);
680      m_IsVisible = false;
681     }
682
683     StoredMinX = Min ( MinX, MaxX );
684     StoredMinY = Min ( MinY, MaxY );
685     StoredMaxX = Max ( MinX, MaxX );
686     StoredMaxY = Max ( MinY, MaxY);
687
688     if (Draw) // move : draw
689     {
690      clientDC.MoveTo(StoredMinX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMaxY); 
691      clientDC.LineTo(StoredMaxX,StoredMaxY); 
692          clientDC.LineTo(StoredMaxX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMinY);
693      m_IsVisible = true;
694    }
695
696    if (m_Pen) 
697        clientDC.SelectObject(aOldPen);
698 }
699 void CAnimationView3D::OnStop() 
700 {
701         KillTimer(GetDocument()->myCount);            
702 }
703
704 void CAnimationView3D::OnRestart() 
705 {
706         KillTimer(GetDocument()->myCount);            
707         SetTimer(GetDocument()->myCount, 1 , NULL); 
708 }
709
710 /*
711 void CAnimationView3D::OnTimer(UINT nIDEvent) 
712 {
713         // TODO: Add your message handler code here and/or call default
714         GetDocument()->OnMyTimer();
715         CView::OnTimer(nIDEvent);
716 }
717 */
718
719
720 /*********************************************************************************
721 **************  W A L K  T H R O U G H  ******************************************
722 /********************************************************************************/
723
724 void CAnimationView3D::OnTimer(UINT_PTR nIDEvent) 
725 {
726         if ( !GetDocument()->m_bIsGridLoaded )
727         {
728                 // TODO: Add your message handler code here and/or call default
729                 GetDocument()->OnMyTimer();
730                 CView::OnTimer(nIDEvent);
731         }
732         else
733         {
734                 CView::OnTimer(nIDEvent);
735                 if ( nIDEvent == 1 ) {
736                   myView->SetImmediateUpdate ( Standard_False ) ;
737                   if ( myCurrentMode == CurrentAction3d_Fly ) {
738
739                          Fly  ( m_curx , m_cury ) ;
740                          if ( m_bShift )
741                            Roll ( m_curx , m_cury ) ;
742                          else
743                            Turn ( m_curx , m_cury ) ;
744
745                         myView->SetAt  ( m_Atx  , m_Aty  , m_Atz  ) ;
746                         myView->SetEye ( m_Eyex , m_Eyey , m_Eyez ) ;
747
748                   }
749                   else if ( myCurrentMode == CurrentAction3d_Turn ) {
750                            Twist ( m_curx , m_cury ) ;
751                   }
752                   else
753                           KillTimer (1) ;
754
755
756                   myView->SetImmediateUpdate ( Standard_True ) ;
757
758                   myView->Update ();
759                 }
760
761                 ReloadData () ;
762         }
763 }
764
765 void CAnimationView3D::OnSensitivity() 
766 {
767         CSensitivity dial ;
768
769         dial.m_SensFly   = m_FlySens  ;
770         dial.m_SensTurn  = m_TurnSens ;
771         if ( dial.DoModal () ) {
772                 m_FlySens  = dial.m_SensFly   ;
773         m_TurnSens = dial.m_SensTurn  ;
774         }
775 }
776
777 void CAnimationView3D::Fly (int /*x*/ , int y)
778 {
779         double v [3] ;
780         double l ;
781         double sens ;
782         int    i     ;
783
784         sens = (double) myYmin - (double) y ;
785         sens /= (double) m_cy ;
786         sens *= m_FlySens ;
787
788         v [0] = m_Atx - m_Eyex ;
789         v [1] = m_Aty - m_Eyey ;
790         v [2] = m_Atz - m_Eyez ;
791         l = sqrt ( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] ) ;
792         if ( l > 1.e-3 ) {
793                 for ( i=0 ; i<3 ; i++ )
794           v [i] = v [i] / l * sens ;
795
796                 m_Atx += v [0] ;
797                 m_Aty += v [1] ;
798                 m_Atz += v [2] ;
799
800                 m_Eyex += v [0] ;
801                 m_Eyey += v [1] ;
802                 m_Eyez += v [2] ;
803
804         }
805 }
806
807 /* Rotation */
808
809 void CAnimationView3D::Turn (int x , int /*y*/)
810 {
811         gp_Vec z (0.,0.,1.) ;
812
813         double v [3] ;
814         double sens ;
815         double aX , aY , aZ ;
816
817         sens = (double) x - (double) myXmin ;
818         sens /= (double) m_cx ;
819         sens *= m_TurnSens ;
820
821         v [0] = m_Atx - m_Eyex ;
822         v [1] = m_Aty - m_Eyey ;
823         v [2] = m_Atz - m_Eyez ;
824
825         gp_Pnt eye ( m_Eyex , m_Eyey , m_Eyez ) ;
826
827         gp_Vec reg (v[0],v[1],v[2] );
828
829         gp_Vec vert = reg ^ z ;
830         gp_Vec haut = vert ^ reg ;
831
832         gp_Dir dh (haut) ;
833         gp_Ax1 rot (eye,dh);
834
835         reg.Rotate (rot,sens) ;
836
837         reg.Coord ( aX , aY , aZ ) ;
838
839         m_Atx = m_Eyex + aX ;
840         m_Aty = m_Eyey + aY ;
841         m_Atz = m_Eyez + aZ ;
842 }
843
844 void CAnimationView3D::Roll (int x , int /*y*/)
845 {
846         gp_Vec z (0.,0.,1.) ;
847
848         double v [3] ;
849         double sens ;
850         double aX , aY , aZ ;
851
852         sens = (double) x - (double) myXmin ;
853         sens /= (double) m_cx ;
854         sens *= m_TurnSens ;
855
856         v [0] = m_Atx - m_Eyex ;
857         v [1] = m_Aty - m_Eyey ;
858         v [2] = m_Atz - m_Eyez ;
859
860         gp_Pnt eye ( m_Eyex , m_Eyey , m_Eyez ) ;
861
862         gp_Vec reg (v[0],v[1],v[2] );
863
864         gp_Vec vert = reg ^ z ;
865
866         gp_Dir dh (vert) ;
867         gp_Ax1 rot (eye,dh);
868
869         reg.Rotate (rot,sens) ;
870
871         reg.Coord ( aX , aY , aZ ) ;
872
873         m_Atx = m_Eyex + aX ;
874         m_Aty = m_Eyey + aY ;
875         m_Atz = m_Eyez + aZ ;
876 }
877
878 void CAnimationView3D::Twist (int x , int /*y*/)
879 {
880         double sens ;
881         double a ;
882         
883         a = myView->Twist () ;
884
885         sens = (double) x - (double) myXmin ;
886         sens /= (double) m_cx ;
887         sens *= m_TurnSens ;
888
889         a += sens ;
890
891         myView->SetTwist (a) ;
892 }
893
894 //=============================================================================
895 // function: SetFocal
896 // purpose:
897 //=============================================================================
898 void CAnimationView3D::SetFocal (double theFocus, double theAngle)
899 {
900
901   Handle(Graphic3d_Camera) aCamera = myView->Camera();
902
903   gp_Pnt anAt  = aCamera->Center();
904   gp_Pnt anEye = aCamera->Eye();
905
906   gp_Vec aLook (anAt, anEye);
907
908   if (aCamera->Distance() > 1.e-3)
909   {
910     aLook = aLook / aCamera->Distance() * theFocus;
911
912     m_Focus = theFocus;
913
914     anAt.SetX (aLook.X() + anEye.X());
915     anAt.SetY (aLook.Y() + anEye.Y());
916     anAt.SetZ (aLook.Z() + anEye.Z());
917
918     m_dAngle = theAngle;
919
920     aCamera->SetCenter (anAt);
921     aCamera->SetFOVy (theAngle);
922
923     myView->Update();
924   }
925 }
926
927 void CAnimationView3D::ReloadData()
928 {
929         myView->At  ( m_Atx  , m_Aty  , m_Atz  ) ;
930         myView->Eye ( m_Eyex , m_Eyey , m_Eyez ) ;
931   double dTwist = myView->Twist() * 180. / M_PI;
932
933   CString aMsg;
934   aMsg.Format (L"%lf", m_Atx);
935         m_Tune.GetDlgItem (IDC_XAT)->SetWindowText (aMsg);
936   aMsg.Format (L"%lf", m_Aty);
937         m_Tune.GetDlgItem (IDC_YAT)->SetWindowText (aMsg);
938         aMsg.Format (L"%lf", m_Atz);
939         m_Tune.GetDlgItem (IDC_ZAT)->SetWindowText (aMsg);
940
941   aMsg.Format (L"%lf", m_Eyex);
942         m_Tune.GetDlgItem (IDC_XEYE)->SetWindowText (aMsg);
943         aMsg.Format (L"%lf", m_Eyey);
944         m_Tune.GetDlgItem (IDC_YEYE)->SetWindowText (aMsg);
945         aMsg.Format (L"%lf", m_Eyez);
946         m_Tune.GetDlgItem (IDC_ZEYE)->SetWindowText (aMsg);
947
948   aMsg.Format (L"%lf", dTwist);
949         m_Tune.GetDlgItem (IDC_TWIST)->SetWindowText (aMsg);
950
951         double dx,dy,dz ;
952         dx = m_Atx - m_Eyex ;
953         dy = m_Aty - m_Eyey ;
954         dz = m_Atz - m_Eyez ;
955
956   m_Focus = sqrt (dx * dx + dy * dy + dz * dz);
957
958   m_dAngle = myView->Camera()->FOVy();
959
960         m_Tune.m_dAngle = m_dAngle ;
961         m_Tune.m_dFocus = m_Focus  ;
962         m_Tune.UpdateData ( FALSE ) ;
963 }
964
965 void CAnimationView3D::SetDimensions()
966 {
967
968   CAnimationDoc* pDoc = GetDocument();
969
970   myView->SetImmediateUpdate ( Standard_False ) ;
971
972   m_Atx  = ( pDoc->m_Xmin + pDoc->m_Xmax ) / 2. ;
973   m_Aty  = ( pDoc->m_Ymin + pDoc->m_Ymax ) / 2. ;
974   m_Atz  = ( pDoc->m_Zmin + pDoc->m_Zmax ) / 2. ;
975   m_Eyex = pDoc->m_Xmax ;
976   m_Eyey = pDoc->m_Ymax ;
977   m_Eyez = pDoc->m_Zmax ;
978
979   myView->SetAt    ( m_Atx  , m_Aty  , m_Atz  ) ;
980   myView->SetEye   ( m_Eyex , m_Eyey , m_Eyez ) ;
981   myView->SetTwist (0.) ;
982
983   myView->SetImmediateUpdate ( Standard_False ) ;
984   myView->FitAll();
985   myView->SetImmediateUpdate ( Standard_False ) ;
986   myView->ZFitAll();
987
988   myView->SetImmediateUpdate ( Standard_True ) ;
989
990   ReloadData () ;
991   myView->Update ();
992 }
993
994 void CAnimationView3D::OnViewDisplaystatus() 
995 {
996         // TODO: Add your command handler code here
997
998         if ( m_Tune.IsWindowVisible () ) {
999
1000         }
1001         else {
1002                 m_Tune.ShowWindow ( SW_SHOWNORMAL ) ;
1003         }
1004 }
1005
1006 void CAnimationView3D::OnUpdateViewDisplaystatus(CCmdUI* pCmdUI) 
1007 {
1008         // TODO: Add your command update UI handler code here
1009
1010         if ( m_Tune.IsWindowVisible () ) {
1011                 pCmdUI->SetCheck ( 1 ) ;
1012         }
1013         else {
1014                 pCmdUI->SetCheck ( 0 ) ;
1015         }
1016 }