1222c2f7f3c01b138168b6f0141070a4fd80868d
[occt.git] / samples / mfc / standard / Common / OCC_3dView.cpp
1 // OCC_3dView.cpp: implementation of the OCC_3dView class.
2 //
3
4 #include "stdafx.h"
5
6 #include "OCC_3dView.h"
7 #include "OCC_App.h"
8 #include "OCC_3dBaseDoc.h"
9 #include <res\OCC_Resource.h>
10
11 #include <Graphic3d_ExportFormat.hxx>
12 #include <Graphic3d_Camera.hxx>
13
14 #include <OpenGl_GraphicDriver.hxx>
15
16 #define ValZWMin 1
17
18 IMPLEMENT_DYNCREATE(OCC_3dView, CView)
19
20 BEGIN_MESSAGE_MAP(OCC_3dView, CView)
21         //{{AFX_MSG_MAP(OCC_3dView)
22         ON_COMMAND(ID_BUTTONAxo, OnBUTTONAxo)
23         ON_COMMAND(ID_BUTTONBack, OnBUTTONBack)
24         ON_COMMAND(ID_BUTTONBottom, OnBUTTONBottom)
25         ON_COMMAND(ID_BUTTONFront, OnBUTTONFront)
26         ON_COMMAND(ID_BUTTONHlrOff, OnBUTTONHlrOff)
27         ON_COMMAND(ID_BUTTONHlrOn, OnBUTTONHlrOn)
28         ON_COMMAND(ID_BUTTONLeft, OnBUTTONLeft)
29         ON_COMMAND(ID_BUTTONPan, OnBUTTONPan)
30         ON_COMMAND(ID_BUTTONPanGlo, OnBUTTONPanGlo)
31         ON_COMMAND(ID_BUTTONReset, OnBUTTONReset)
32         ON_COMMAND(ID_BUTTONRight, OnBUTTONRight)
33         ON_COMMAND(ID_BUTTONRot, OnBUTTONRot)
34         ON_COMMAND(ID_BUTTONTop, OnBUTTONTop)
35         ON_COMMAND(ID_BUTTONZoomAll, OnBUTTONZoomAll)
36   ON_COMMAND(ID_BUTTON_STEREOCONFIG, OnStereoConfigButton)
37         ON_WM_SIZE()
38     ON_COMMAND(ID_FILE_EXPORT_IMAGE, OnFileExportImage)
39         ON_COMMAND(ID_BUTTONZoomProg, OnBUTTONZoomProg)
40         ON_COMMAND(ID_BUTTONZoomWin, OnBUTTONZoomWin)
41         ON_WM_LBUTTONDOWN()
42         ON_WM_LBUTTONUP()
43         ON_WM_MBUTTONDOWN()
44         ON_WM_MBUTTONUP()
45         ON_WM_MOUSEMOVE()
46         ON_WM_RBUTTONDOWN()
47         ON_WM_RBUTTONUP()
48         ON_UPDATE_COMMAND_UI(ID_BUTTONHlrOff, OnUpdateBUTTONHlrOff)
49         ON_UPDATE_COMMAND_UI(ID_BUTTONHlrOn, OnUpdateBUTTONHlrOn)
50         ON_UPDATE_COMMAND_UI(ID_BUTTONPanGlo, OnUpdateBUTTONPanGlo)
51         ON_UPDATE_COMMAND_UI(ID_BUTTONPan, OnUpdateBUTTONPan)
52         ON_UPDATE_COMMAND_UI(ID_BUTTONZoomProg, OnUpdateBUTTONZoomProg)
53         ON_UPDATE_COMMAND_UI(ID_BUTTONZoomWin, OnUpdateBUTTONZoomWin)
54         ON_UPDATE_COMMAND_UI(ID_BUTTONRot, OnUpdateBUTTONRot)
55   ON_UPDATE_COMMAND_UI(ID_BUTTON_STEREOCONFIG, OnUpdateStereoConfigButton)
56         ON_COMMAND(ID_Modify_ChangeBackground     , OnModifyChangeBackground)
57         //}}AFX_MSG_MAP
58 END_MESSAGE_MAP()
59
60 /////////////////////////////////////////////////////////////////////////////
61 // OCC_3dView construction/destruction
62
63 OCC_3dView::OCC_3dView()
64 : myCurrentMode (CurAction3d_Nothing),
65   myWidth  (0),
66   myHeight (0),
67   myHlrModeIsOn (Standard_False)
68 {
69   // TODO: add construction code here
70 }
71
72 OCC_3dView::~OCC_3dView()
73 {
74         if (myView.IsNull())
75   {
76     myView->Remove();
77   }
78
79   delete m_pStereoDlg;
80 }
81
82 BOOL OCC_3dView::PreCreateWindow(CREATESTRUCT& cs)
83 {
84   // TODO: Modify the Window class or styles here by modifying
85   //  the CREATESTRUCT cs
86   cs.lpszClass = ::AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC, ::LoadCursor(NULL, IDC_ARROW), NULL, NULL);
87   return CView::PreCreateWindow(cs);
88 }
89
90 /////////////////////////////////////////////////////////////////////////////
91 // OCC_3dView drawing
92 void OCC_3dView::OnInitialUpdate() 
93 {
94   CView::OnInitialUpdate();
95
96   myView = GetDocument()->GetViewer()->CreateView();
97
98   // store for restore state after rotation (which is in Degenerated mode)
99   myHlrModeIsOn = Standard_False;
100   myView->SetComputedMode (myHlrModeIsOn);
101
102   Handle(OpenGl_GraphicDriver) aDriver = 
103     Handle(OpenGl_GraphicDriver)::DownCast (((OCC_App*)AfxGetApp())->GetGraphicDriver());
104
105   Handle(WNT_Window) aWNTWindow = new WNT_Window(GetSafeHwnd());
106
107   myView->SetWindow(aWNTWindow);
108   myView->Camera()->SetProjectionType (aDriver->Options().contextStereo
109     ? Graphic3d_Camera::Projection_Stereo
110     : Graphic3d_Camera::Projection_Orthographic);
111
112   if (!aWNTWindow->IsMapped())
113   {
114     aWNTWindow->Map();
115   }
116
117   // store the mode ( nothing , dynamic zooming, dynamic ... )
118   myCurrentMode = CurAction3d_Nothing;
119
120   m_pStereoDlg = new OCC_StereoConfigDlg (this);
121   m_pStereoDlg->SetView (myView);
122   m_pStereoDlg->Create (IDD_DIALOG_STEREO, this);
123 }
124
125 void OCC_3dView::OnDraw(CDC* /*pDC*/)
126 {
127   CRect aRect;
128   GetWindowRect(aRect);
129   if(myWidth != aRect.Width() || myHeight != aRect.Height()) {
130     myWidth = aRect.Width();
131     myHeight = aRect.Height();
132     ::PostMessage ( GetSafeHwnd() , WM_SIZE , SW_SHOW , myWidth + myHeight*65536 );
133   }
134   myView->Redraw();
135 }
136
137 /////////////////////////////////////////////////////////////////////////////
138 // OCC_3dView diagnostics
139
140 #ifdef _DEBUG
141 void OCC_3dView::AssertValid() const
142 {
143         CView::AssertValid();
144 }
145
146 void OCC_3dView::Dump(CDumpContext& dc) const
147 {
148         CView::Dump(dc);
149 }
150
151 OCC_3dDoc* OCC_3dView::GetDocument() // non-debug version is inline
152 {
153 //      ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(OCC_3dBaseDoc)));
154         return (OCC_3dDoc*)m_pDocument;
155 }
156
157 #endif //_DEBUG
158
159 /////////////////////////////////////////////////////////////////////////////
160 // OCC_3dView message handlers
161 void OCC_3dView::OnFileExportImage()
162 {
163   GetDocument()->ExportView (myView);
164 }
165
166 void OCC_3dView::OnSize(UINT nType, int cx, int cy)
167 {
168   OCC_BaseView::OnSize (nType, cx, cy);
169   if (!myView.IsNull())
170    myView->MustBeResized();
171 }
172
173 // See the back View
174 void OCC_3dView::OnBUTTONBack() 
175 {
176   myView->SetProj(V3d_Ypos);
177
178
179 // See the front View
180 void OCC_3dView::OnBUTTONFront() 
181 {
182   myView->SetProj(V3d_Yneg);
183
184
185 // See the bottom View
186 void OCC_3dView::OnBUTTONBottom() 
187 {
188   myView->SetProj(V3d_Zneg);
189 }
190
191 // See the top View
192 void OCC_3dView::OnBUTTONTop() 
193 {
194   myView->SetProj(V3d_Zpos);
195 }       
196
197 // See the left View
198 void OCC_3dView::OnBUTTONLeft() 
199 {
200   myView->SetProj(V3d_Xneg);
201 }
202
203 // See the right View
204 void OCC_3dView::OnBUTTONRight() 
205 {
206   myView->SetProj(V3d_Xpos);
207
208
209 // See the axonometric View
210 void OCC_3dView::OnBUTTONAxo() 
211 {
212   myView->SetProj(V3d_XposYnegZpos);
213
214
215 void OCC_3dView::OnBUTTONHlrOff() 
216 {
217   myHlrModeIsOn = Standard_False;
218   myView->SetComputedMode (myHlrModeIsOn);
219   myView->Redraw();
220 }
221
222 void OCC_3dView::OnBUTTONHlrOn() 
223 {
224   SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
225   myHlrModeIsOn = Standard_True;
226   myView->SetComputedMode (myHlrModeIsOn);
227   myView->Redraw();
228   SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
229 }
230
231 void OCC_3dView::OnBUTTONPan() 
232 {
233   myCurrentMode = CurAction3d_DynamicPanning;
234 }
235
236 void OCC_3dView::OnBUTTONPanGlo() 
237 {
238   // save the current zoom value 
239   myCurZoom = myView->Scale();
240   // Do a Global Zoom 
241   //myView->FitAll();
242   // Set the mode 
243   myCurrentMode = CurAction3d_GlobalPanning;
244 }
245
246 void OCC_3dView::OnBUTTONReset() 
247 {
248   myView->Reset();
249 }
250
251 void OCC_3dView::OnBUTTONRot() 
252 {
253   myCurrentMode = CurAction3d_DynamicRotation; 
254 }
255
256 void OCC_3dView::OnBUTTONZoomAll() 
257 {
258   myView->FitAll();
259   myView->ZFitAll();
260 }
261
262 void OCC_3dView::OnBUTTONZoomProg() 
263 {  myCurrentMode = CurAction3d_DynamicZooming; }
264
265 void OCC_3dView::OnBUTTONZoomWin() 
266 {  myCurrentMode = CurAction3d_WindowZooming; }
267
268 void OCC_3dView::OnLButtonDown(UINT nFlags, CPoint point) 
269 {
270   //  save the current mouse coordinate in min 
271   myXmin=point.x;  myYmin=point.y;
272   myXmax=point.x;  myYmax=point.y;
273
274   if ( nFlags & MK_CONTROL ) 
275   {
276     // Button MB1 down Control :start zomming 
277     // SetCursor(AfxGetApp()->LoadStandardCursor());
278   }
279   else // if ( Ctrl )
280   {
281     switch (myCurrentMode)
282     {
283     case CurAction3d_Nothing : // start a drag
284       if (nFlags & MK_SHIFT)
285         GetDocument()->ShiftDragEvent(myXmax,myYmax,-1,myView);
286       else
287         GetDocument()->DragEvent(myXmax,myYmax,-1,myView);
288       break;
289       break;
290     case CurAction3d_DynamicZooming : // noting
291       break;
292     case CurAction3d_WindowZooming : // noting
293       break;
294     case CurAction3d_DynamicPanning :// noting
295       break;
296     case CurAction3d_GlobalPanning :// noting
297       break;
298     case  CurAction3d_DynamicRotation :
299       if (myHlrModeIsOn)
300       {
301         myView->SetComputedMode (Standard_False);
302       }
303
304       myView->StartRotation(point.x,point.y);  
305       break;
306     default :
307       throw Standard_Failure(" incompatible Current Mode ");
308       break;
309     }
310   }
311 }
312
313 void OCC_3dView::OnLButtonUp(UINT nFlags, CPoint point) 
314 {
315   if ( nFlags & MK_CONTROL ) 
316   {
317     return;
318   }
319   else // if ( Ctrl )
320   {
321     const Handle(AIS_InteractiveContext)& aContext = GetDocument()->GetAISContext();
322     switch (myCurrentMode)
323     {
324     case CurAction3d_Nothing :
325       if (point.x == myXmin && point.y == myYmin)
326       { // no offset between down and up --> selectEvent
327         myXmax=point.x;  
328         myYmax=point.y;
329         if (nFlags & MK_SHIFT )
330           GetDocument()->ShiftInputEvent(point.x,point.y,myView);
331         else
332           GetDocument()->InputEvent     (point.x,point.y,myView);
333       } else
334       {
335         myXmax=point.x;    myYmax=point.y;
336         drawRectangle (myXmin, myYmin, myXmax, myYmax, aContext, Standard_False);
337         if (nFlags & MK_SHIFT)
338           GetDocument()->ShiftDragEvent(point.x,point.y,1,myView);
339         else
340           GetDocument()->DragEvent(point.x,point.y,1,myView);
341       }
342       break;
343     case CurAction3d_DynamicZooming :
344       myCurrentMode = CurAction3d_Nothing;
345       break;
346     case CurAction3d_WindowZooming :
347       myXmax=point.x;        myYmax=point.y;
348       drawRectangle (myXmin, myYmin, myXmax, myYmax, aContext, Standard_False);
349       if ((abs(myXmin-myXmax)>ValZWMin) || (abs(myYmin-myYmax)>ValZWMin))
350         // Test if the zoom window is greater than a minimale window.
351       {
352         // Do the zoom window between Pmin and Pmax
353         myView->WindowFitAll(myXmin,myYmin,myXmax,myYmax);  
354       }  
355       myCurrentMode = CurAction3d_Nothing;
356       break;
357     case CurAction3d_DynamicPanning :
358       myCurrentMode = CurAction3d_Nothing;
359       break;
360     case CurAction3d_GlobalPanning :
361       myView->Place(point.x,point.y,myCurZoom); 
362       myCurrentMode = CurAction3d_Nothing;
363       break;
364     case  CurAction3d_DynamicRotation :
365       myCurrentMode = CurAction3d_Nothing;
366       if (myHlrModeIsOn)
367       {
368         CWaitCursor aWaitCursor;
369         myView->SetComputedMode (myHlrModeIsOn);
370         myView->Redraw();
371       }
372       else
373       {
374         myView->SetComputedMode (myHlrModeIsOn);
375       }
376       break;
377     default :
378       throw Standard_Failure(" incompatible Current Mode ");
379       break;
380     } //switch (myCurrentMode)
381   } //  else // if ( Ctrl )
382 }
383
384 void OCC_3dView::OnMButtonDown(UINT nFlags, CPoint /*point*/) 
385 {
386   if ( nFlags & MK_CONTROL ) 
387   {
388     // Button MB2 down Control : panning init  
389     // SetCursor(AfxGetApp()->LoadStandardCursor());   
390   }
391 }
392
393 void OCC_3dView::OnMButtonUp(UINT nFlags, CPoint /*point*/) 
394 {
395   if ( nFlags & MK_CONTROL ) 
396   {
397     // Button MB2 down Control : panning init  
398     // SetCursor(AfxGetApp()->LoadStandardCursor());   
399   }
400 }
401
402 void OCC_3dView::OnRButtonDown(UINT nFlags, CPoint point) 
403 {
404   if ( nFlags & MK_CONTROL )
405   {
406     if (myHlrModeIsOn)
407     {
408       myView->SetComputedMode (Standard_False);
409     }
410     myView->StartRotation(point.x,point.y);  
411   }
412   else // if ( Ctrl )
413   {
414     GetDocument()->Popup(point.x,point.y,myView);
415   }     
416 }
417
418 void OCC_3dView::OnRButtonUp(UINT /*nFlags*/, CPoint /*point*/) 
419 {
420     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
421     if (myHlrModeIsOn)
422     {
423       myView->SetComputedMode (myHlrModeIsOn);
424       myView->Redraw();
425     }
426     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
427 }
428
429 void OCC_3dView::OnMouseMove(UINT nFlags, CPoint point) 
430 {
431    //   ============================  LEFT BUTTON =======================
432   if ( nFlags & MK_LBUTTON)
433   {
434     if ( nFlags & MK_CONTROL ) 
435     {
436       // move with MB1 and Control : on the dynamic zooming  
437       // Do the zoom in function of mouse's coordinates  
438       myView->Zoom (myXmax,myYmax,point.x,point.y); 
439       // save the current mouse coordinate in min 
440       myXmax = point.x; 
441       myYmax = point.y; 
442     }
443     else // if ( Ctrl )
444     {
445       const Handle(AIS_InteractiveContext)& aContext = GetDocument()->GetAISContext();
446       switch (myCurrentMode)
447       {
448       case CurAction3d_Nothing :
449         myXmax = point.x;
450         myYmax = point.y;
451
452         if (nFlags & MK_SHIFT)
453           GetDocument()->ShiftDragEvent(myXmax,myYmax,0,myView);
454         else
455           GetDocument()->DragEvent(myXmax,myYmax,0,myView);
456
457         drawRectangle (myXmin, myYmin, myXmax, myYmax, aContext);
458
459         break;
460       case CurAction3d_DynamicZooming :
461         myView->Zoom(myXmax,myYmax,point.x,point.y); 
462         // save the current mouse coordinate in min \n";
463         myXmax = point.x;
464         myYmax = point.y;
465         break;
466       case CurAction3d_WindowZooming :
467         myXmax = point.x;
468         myYmax = point.y;
469         drawRectangle (myXmin, myYmin, myXmax, myYmax, aContext);
470         break;
471       case CurAction3d_DynamicPanning :
472         myView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
473         myXmax = point.x; myYmax = point.y;     
474         break;
475       case CurAction3d_GlobalPanning : // nothing           
476         break;
477       case  CurAction3d_DynamicRotation :
478         myView->Rotation(point.x,point.y);
479         myView->Redraw();
480         break;
481       default :
482         throw Standard_Failure(" incompatible Current Mode ");
483         break;
484       }//  switch (myCurrentMode)
485     }// if ( nFlags & MK_CONTROL )  else 
486   } 
487   else if ( nFlags & MK_MBUTTON)
488   {
489     if ( nFlags & MK_CONTROL ) 
490     {
491       myView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
492       myXmax = point.x;
493       myYmax = point.y;
494     }
495   } 
496   else if ( nFlags & MK_RBUTTON)
497   {
498     if ( nFlags & MK_CONTROL ) 
499     {
500       myView->Rotation(point.x,point.y);
501     }
502   }
503   else 
504   {  // No buttons
505     myXmax = point.x;
506     myYmax = point.y;
507     if (nFlags & MK_SHIFT)
508       GetDocument()->ShiftMoveEvent(point.x,point.y,myView);
509     else
510       GetDocument()->MoveEvent(point.x,point.y,myView);
511   }
512 }
513
514 void OCC_3dView::OnUpdateBUTTONHlrOff(CCmdUI* pCmdUI) 
515 {
516   pCmdUI->SetCheck (!myHlrModeIsOn);
517   pCmdUI->Enable   (myHlrModeIsOn);
518 }
519
520 void OCC_3dView::OnUpdateBUTTONHlrOn(CCmdUI* pCmdUI)
521 {
522   pCmdUI->SetCheck (myHlrModeIsOn);
523   pCmdUI->Enable   (!myHlrModeIsOn);
524 }
525
526 void OCC_3dView::OnUpdateBUTTONPanGlo(CCmdUI* pCmdUI) 
527 {
528     pCmdUI->SetCheck (myCurrentMode == CurAction3d_GlobalPanning);
529         pCmdUI->Enable   (myCurrentMode != CurAction3d_GlobalPanning);  
530         
531 }
532
533 void OCC_3dView::OnUpdateBUTTONPan(CCmdUI* pCmdUI) 
534 {
535     pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicPanning);
536         pCmdUI->Enable   (myCurrentMode != CurAction3d_DynamicPanning );        
537 }
538
539 void OCC_3dView::OnUpdateBUTTONZoomProg(CCmdUI* pCmdUI) 
540 {
541     pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicZooming );
542         pCmdUI->Enable   (myCurrentMode != CurAction3d_DynamicZooming); 
543 }
544
545 void OCC_3dView::OnUpdateBUTTONZoomWin(CCmdUI* pCmdUI) 
546 {
547     pCmdUI->SetCheck (myCurrentMode == CurAction3d_WindowZooming);
548         pCmdUI->Enable   (myCurrentMode != CurAction3d_WindowZooming);  
549 }
550
551 void OCC_3dView::OnUpdateBUTTONRot(CCmdUI* pCmdUI) 
552 {
553     pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicRotation);
554         pCmdUI->Enable   (myCurrentMode != CurAction3d_DynamicRotation);        
555 }
556
557 void OCC_3dView::OnModifyChangeBackground() 
558 {
559         Standard_Real R1;
560         Standard_Real G1;
561         Standard_Real B1;
562     myView->BackgroundColor(Quantity_TOC_RGB,R1,G1,B1);
563         COLORREF m_clr ;
564         m_clr = RGB(R1*255,G1*255,B1*255);
565
566         CColorDialog dlgColor(m_clr);
567         if (dlgColor.DoModal() == IDOK)
568         {
569                 m_clr = dlgColor.GetColor();
570                 R1 = GetRValue(m_clr)/255.;
571                 G1 = GetGValue(m_clr)/255.;
572                 B1 = GetBValue(m_clr)/255.;
573         myView->SetBackgroundColor(Quantity_TOC_RGB,R1,G1,B1);
574         }
575     myView->Redraw();
576 }
577
578 //=============================================================================
579 // function: OnStereoConfigButton
580 // purpose: Open stereographic configuration dialog
581 //=============================================================================
582 void OCC_3dView::OnStereoConfigButton()
583 {
584   m_pStereoDlg->ShowWindow (SW_SHOW);
585 }
586
587 //=============================================================================
588 // function: OnUpdateStereoConfigButton
589 // purpose: Enable / disable state of stereo configuration button
590 //=============================================================================
591 void OCC_3dView::OnUpdateStereoConfigButton (CCmdUI* theCmdUI)
592 {
593   // get camera
594   Handle(Graphic3d_Camera) aCamera = myView->Camera();
595
596   // check that button is enabled
597   Standard_Boolean isEnabled = !aCamera.IsNull() && aCamera->IsStereo();
598
599   // update toggle state
600   theCmdUI->Enable (isEnabled);
601
602   if (!isEnabled)
603   {
604     m_pStereoDlg->ShowWindow (SW_HIDE);
605   }
606 }