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