0024623: Visualization - improve selection mechanism
[occt.git] / samples / mfc / standard / 10_Convert / src / WNT / OCCDemoView.cpp
1 // OCCDemoView.cpp : implementation of the COCCDemoView class
2 //
3
4 #include "stdafx.h"
5 #include "MainFrm.h"
6 #include "OCCDemo.h"
7 #include "OCCDemoDoc.h"
8 #include "OCCDemoView.h"
9
10 #include <Graphic3d_GraphicDriver.hxx>
11
12 #define ValZWMin 1
13
14 #ifdef _DEBUG
15 #undef THIS_FILE
16 static char THIS_FILE[] = __FILE__;
17 #endif
18
19 /////////////////////////////////////////////////////////////////////////////
20 // COCCDemoView
21
22 IMPLEMENT_DYNCREATE(COCCDemoView, CView)
23
24 BEGIN_MESSAGE_MAP(COCCDemoView, CView)
25         //{{AFX_MSG_MAP(COCCDemoView)
26         ON_COMMAND(ID_BUTTONAxo, OnBUTTONAxo)
27         ON_COMMAND(ID_BUTTONBack, OnBUTTONBack)
28         ON_COMMAND(ID_BUTTONBottom, OnBUTTONBottom)
29         ON_COMMAND(ID_BUTTONFront, OnBUTTONFront)
30         ON_COMMAND(ID_BUTTONHlrOn, OnBUTTONHlrOn)
31         ON_COMMAND(ID_BUTTONLeft, OnBUTTONLeft)
32         ON_COMMAND(ID_BUTTONPan, OnBUTTONPan)
33         ON_COMMAND(ID_BUTTONPanGlo, OnBUTTONPanGlo)
34         ON_COMMAND(ID_BUTTONReset, OnBUTTONReset)
35         ON_COMMAND(ID_BUTTONRight, OnBUTTONRight)
36         ON_COMMAND(ID_BUTTONRot, OnBUTTONRot)
37         ON_COMMAND(ID_BUTTONTop, OnBUTTONTop)
38         ON_COMMAND(ID_BUTTONZoomAll, OnBUTTONZoomAll)
39         ON_WM_SIZE()
40         ON_COMMAND(ID_BUTTONZoomProg, OnBUTTONZoomProg)
41         ON_COMMAND(ID_BUTTONZoomWin, OnBUTTONZoomWin)
42         ON_WM_LBUTTONDOWN()
43         ON_WM_LBUTTONUP()
44         ON_WM_MOUSEMOVE()
45         ON_WM_RBUTTONDOWN()
46         ON_WM_RBUTTONUP()
47         ON_UPDATE_COMMAND_UI(ID_BUTTONPanGlo, OnUpdateBUTTONPanGlo)
48         ON_UPDATE_COMMAND_UI(ID_BUTTONPan, OnUpdateBUTTONPan)
49         ON_UPDATE_COMMAND_UI(ID_BUTTONZoomProg, OnUpdateBUTTONZoomProg)
50         ON_UPDATE_COMMAND_UI(ID_BUTTONZoomWin, OnUpdateBUTTONZoomWin)
51         ON_UPDATE_COMMAND_UI(ID_BUTTONRot, OnUpdateBUTTONRot)
52         ON_COMMAND(ID_BUTTONWire, OnBUTTONWire)
53         ON_COMMAND(ID_BUTTONShade, OnBUTTONShade)
54         ON_UPDATE_COMMAND_UI(ID_BUTTONHlrOn, OnUpdateBUTTONHlrOn)
55         ON_UPDATE_COMMAND_UI(ID_BUTTONShade, OnUpdateBUTTONShade)
56         ON_UPDATE_COMMAND_UI(ID_BUTTONWire, OnUpdateBUTTONWire)
57         //}}AFX_MSG_MAP
58 END_MESSAGE_MAP()
59
60 /////////////////////////////////////////////////////////////////////////////
61 // COCCDemoView construction/destruction
62
63 COCCDemoView::COCCDemoView()
64 {
65   myXmin=0;
66   myYmin=0;  
67   myXmax=0;
68   myYmax=0;
69   myCurZoom=0;
70   myCurrentMode = CurAction3d_Nothing;
71   myVisMode = VIS_SHADE;
72   m_Pen = NULL;
73   myGraphicDriver = ((COCCDemoApp*)AfxGetApp())->GetGraphicDriver();
74 }
75
76 COCCDemoView::~COCCDemoView()
77 {
78         if (!myView.IsNull())
79     myView->Remove();
80   if (m_Pen)
81     delete m_Pen;
82 }
83
84 BOOL COCCDemoView::PreCreateWindow(CREATESTRUCT& cs)
85 {
86         // TODO: Modify the Window class or styles here by modifying
87         //  the CREATESTRUCT cs
88
89         return CView::PreCreateWindow(cs);
90 }
91
92 /////////////////////////////////////////////////////////////////////////////
93 // COCCDemoView drawing
94
95 void COCCDemoView::OnInitialUpdate() 
96 {
97   CView::OnInitialUpdate();
98   
99   myView = GetDocument()->GetViewer()->CreateView();
100   myView->SetViewMappingDefault();
101   myView->SetViewOrientationDefault();
102
103   Handle(WNT_Window) aWNTWindow = new WNT_Window(GetSafeHwnd ());
104   myView->SetWindow(aWNTWindow);
105   if (!aWNTWindow->IsMapped()) aWNTWindow->Map();
106
107   myCurrentMode = CurAction3d_Nothing;
108   myVisMode = VIS_SHADE;
109   RedrawVisMode();
110 }
111
112 void COCCDemoView::OnDraw(CDC* /*pDC*/)
113 {
114         COCCDemoDoc* pDoc = GetDocument();
115         ASSERT_VALID(pDoc);
116         // TODO: add draw code for native data here
117   myView->Redraw();
118 }
119
120 /////////////////////////////////////////////////////////////////////////////
121 // COCCDemoView diagnostics
122
123 #ifdef _DEBUG
124 void COCCDemoView::AssertValid() const
125 {
126         CView::AssertValid();
127 }
128
129 void COCCDemoView::Dump(CDumpContext& dc) const
130 {
131         CView::Dump(dc);
132 }
133
134 COCCDemoDoc* COCCDemoView::GetDocument() // non-debug version is inline
135 {
136         ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(COCCDemoDoc)));
137         return (COCCDemoDoc*)m_pDocument;
138 }
139 #endif //_DEBUG
140
141 /////////////////////////////////////////////////////////////////////////////
142 // COCCDemoView message handlers
143
144 void COCCDemoView::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/) 
145 {
146   if (!myView.IsNull())
147     myView->MustBeResized();
148 }
149
150 void COCCDemoView::OnBUTTONBack() 
151
152   myView->SetProj(V3d_Ypos);
153 }
154
155 void COCCDemoView::OnBUTTONFront() 
156
157         myView->SetProj(V3d_Yneg);
158 }
159
160 void COCCDemoView::OnBUTTONBottom() 
161
162         myView->SetProj(V3d_Zneg); 
163 }
164
165 void COCCDemoView::OnBUTTONTop() 
166
167         myView->SetProj(V3d_Zpos); 
168 }
169
170 void COCCDemoView::OnBUTTONLeft() 
171
172         myView->SetProj(V3d_Xneg);
173 }
174
175 void COCCDemoView::OnBUTTONRight() 
176
177         myView->SetProj(V3d_Xpos);
178 }
179
180 void COCCDemoView::OnBUTTONAxo() 
181
182         myView->SetProj(V3d_XposYnegZpos); 
183 }
184
185 void COCCDemoView::OnBUTTONPan() 
186 {
187   myCurrentMode = CurAction3d_DynamicPanning;
188 }
189
190 void COCCDemoView::OnBUTTONPanGlo() 
191 {
192   // save the current zoom value 
193   myCurZoom = myView->Scale();
194   // Do a Global Zoom 
195   myView->FitAll();
196   // Set the mode 
197   myCurrentMode = CurAction3d_GlobalPanning;
198 }
199
200 void COCCDemoView::OnBUTTONReset() 
201 {
202   myView->Reset();
203 }
204
205 void COCCDemoView::OnBUTTONRot() 
206 {
207   myCurrentMode = CurAction3d_DynamicRotation;
208 }
209
210 void COCCDemoView::OnBUTTONZoomAll() 
211 {
212   myView->FitAll();
213   myView->ZFitAll();
214 }
215
216 void COCCDemoView::OnBUTTONZoomProg() 
217 {
218   myCurrentMode = CurAction3d_DynamicZooming;
219 }
220
221 void COCCDemoView::OnBUTTONZoomWin() 
222 {
223   myCurrentMode = CurAction3d_WindowZooming;
224 }
225
226 void COCCDemoView::OnLButtonDown(UINT nFlags, CPoint point) 
227 {
228   //  save the current mouse coordinate in min 
229   myXmin=point.x;  myYmin=point.y;
230   myXmax=point.x;  myYmax=point.y;
231   
232   if ( ! (nFlags & MK_CONTROL) ) 
233   {
234     if (myCurrentMode == CurAction3d_DynamicRotation)
235     {
236       myView->SetComputedMode(Standard_False);
237       myView->StartRotation(point.x,point.y);  
238     }
239   }
240 }
241
242 void COCCDemoView::OnLButtonUp(UINT nFlags, CPoint point) 
243 {
244   if ( !(nFlags & MK_CONTROL) )
245   {
246     switch (myCurrentMode)
247     {
248     case CurAction3d_Nothing :
249       myXmax=point.x;  
250       myYmax=point.y;
251       break;
252     case CurAction3d_DynamicZooming :
253       myCurrentMode = CurAction3d_Nothing;
254       break;
255     case CurAction3d_WindowZooming :
256       DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False);
257       myXmax=point.x;
258       myYmax=point.y;
259       if ((abs(myXmin-myXmax)>ValZWMin) || (abs(myYmin-myYmax)>ValZWMin))
260         // Test if the zoom window is greater than a minimale window.
261       {
262         // Do the zoom window between Pmin and Pmax
263         myView->WindowFitAll(myXmin,myYmin,myXmax,myYmax);  
264       }  
265       myCurrentMode = CurAction3d_Nothing;
266       break;
267     case CurAction3d_DynamicPanning :
268       myCurrentMode = CurAction3d_Nothing;
269       break;
270     case CurAction3d_GlobalPanning :
271       myView->Place(point.x,point.y,myCurZoom); 
272       myCurrentMode = CurAction3d_Nothing;
273       break;
274     case  CurAction3d_DynamicRotation :
275       if (myVisMode == VIS_HLR)
276       {
277         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
278         myView->SetComputedMode(Standard_True);
279         SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
280       }
281       myCurrentMode = CurAction3d_Nothing;
282       break;
283     } //switch (myCurrentMode)
284   }
285 }
286
287 void COCCDemoView::OnRButtonDown(UINT nFlags, CPoint point) 
288 {
289   if ( nFlags & MK_CONTROL ) 
290   {
291     myView->SetComputedMode(Standard_False);
292     myView->StartRotation(point.x,point.y);  
293   }
294 }
295
296 void COCCDemoView::OnRButtonUp(UINT /*nFlags*/, CPoint /*point*/) 
297 {
298   if (myVisMode == VIS_HLR)
299   {
300     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
301     myView->SetComputedMode(Standard_True);
302     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
303   }
304 }
305
306 void COCCDemoView::OnMouseMove(UINT nFlags, CPoint point) 
307 {
308   //   ============================  LEFT BUTTON =======================
309   if ( nFlags & MK_LBUTTON)
310   {
311     if ( nFlags & MK_CONTROL ) 
312     {
313       // move with MB1 and Control : on the dynamic zooming  
314       // Do the zoom in function of mouse's coordinates  
315       myView->Zoom(myXmax,myYmax,point.x,point.y); 
316       // save the current mouse coordinate in max
317       myXmax = point.x; 
318       myYmax = point.y; 
319     }
320     else // if ( Ctrl )
321     {
322       switch (myCurrentMode)
323       {
324       case CurAction3d_Nothing :
325         myXmax = point.x;
326         myYmax = point.y;
327         break;
328       case CurAction3d_DynamicZooming :
329         myView->Zoom(myXmax,myYmax,point.x,point.y); 
330         // save the current mouse coordinate in max;
331         myXmax=point.x;
332         myYmax=point.y;
333         break;
334       case CurAction3d_WindowZooming :
335         myXmax = point.x; myYmax = point.y;     
336         DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False,LongDash);
337         DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_True,LongDash);
338         break;
339       case CurAction3d_DynamicPanning :
340         myView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
341         myXmax = point.x; myYmax = point.y;     
342         break;
343       case CurAction3d_GlobalPanning : // nothing           
344         break;
345       case  CurAction3d_DynamicRotation :
346         myView->Rotation(point.x,point.y);
347         myView->Redraw();
348         break;
349       }
350     }
351   }
352   //   ============================  MIDDLE BUTTON =======================
353   else if ( nFlags & MK_MBUTTON)
354   {
355     if ( nFlags & MK_CONTROL ) 
356     {
357       myView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
358       myXmax = point.x; myYmax = point.y;       
359     }
360   }
361   //   ============================  RIGHT BUTTON =======================
362   else if ( nFlags & MK_RBUTTON)
363   {
364     if ( nFlags & MK_CONTROL ) 
365     {
366       myView->Rotation(point.x,point.y);
367     }
368   }
369   //   ============================  NO BUTTON =======================
370   else
371   {
372     myXmax = point.x;
373     myYmax = point.y;   
374   }
375 }
376
377 void COCCDemoView::OnUpdateBUTTONPanGlo(CCmdUI* pCmdUI) 
378 {
379   pCmdUI->SetCheck (myCurrentMode == CurAction3d_GlobalPanning);
380         pCmdUI->Enable   (myCurrentMode != CurAction3d_GlobalPanning);  
381 }
382
383 void COCCDemoView::OnUpdateBUTTONPan(CCmdUI* pCmdUI) 
384 {
385   pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicPanning);
386         pCmdUI->Enable   (myCurrentMode != CurAction3d_DynamicPanning );        
387 }
388
389 void COCCDemoView::OnUpdateBUTTONZoomProg(CCmdUI* pCmdUI) 
390 {
391   pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicZooming );
392         pCmdUI->Enable   (myCurrentMode != CurAction3d_DynamicZooming); 
393 }
394
395 void COCCDemoView::OnUpdateBUTTONZoomWin(CCmdUI* pCmdUI) 
396 {
397   pCmdUI->SetCheck (myCurrentMode == CurAction3d_WindowZooming);
398         pCmdUI->Enable   (myCurrentMode != CurAction3d_WindowZooming);  
399 }
400
401 void COCCDemoView::OnUpdateBUTTONRot(CCmdUI* pCmdUI) 
402 {
403   pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicRotation);
404         pCmdUI->Enable   (myCurrentMode != CurAction3d_DynamicRotation);        
405 }
406
407 void COCCDemoView::DrawRectangle(const Standard_Integer  MinX,
408                                         const Standard_Integer  MinY,
409                                         const Standard_Integer  MaxX,
410                                         const Standard_Integer  MaxY,
411                                         const Standard_Boolean  Draw, 
412                                         const LineStyle aLineStyle)
413 {
414   static int m_DrawMode;
415   if  (!m_Pen && aLineStyle ==Solid )
416   {
417     m_Pen = new CPen(PS_SOLID, 1, RGB(0,0,0)); m_DrawMode = R2_MERGEPENNOT;
418   }
419   else if (!m_Pen && aLineStyle ==Dot )
420   {
421     m_Pen = new CPen(PS_DOT, 1, RGB(0,0,0));   m_DrawMode = R2_XORPEN;
422   }
423   else if (!m_Pen && aLineStyle == ShortDash)
424   {
425     m_Pen = new CPen(PS_DASH, 1, RGB(255,0,0)); m_DrawMode = R2_XORPEN;
426   }
427   else if (!m_Pen && aLineStyle == LongDash)
428   {
429     m_Pen = new CPen(PS_DASH, 1, RGB(0,0,0));   m_DrawMode = R2_NOTXORPEN;
430   }
431   else if (aLineStyle == Default) 
432   {
433     m_Pen = NULL;       m_DrawMode = R2_MERGEPENNOT;
434   }
435
436   CPen* aOldPen = NULL;
437   CClientDC clientDC(this);
438   if (m_Pen) 
439     aOldPen = clientDC.SelectObject(m_Pen);
440   clientDC.SetROP2(m_DrawMode);
441
442   static                Standard_Integer StoredMinX, StoredMaxX, StoredMinY, StoredMaxY;
443   static                Standard_Boolean m_IsVisible = Standard_False;
444
445   if ( m_IsVisible && !Draw) // move or up  : erase at the old position 
446   {
447     clientDC.MoveTo(StoredMinX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMaxY); 
448     clientDC.LineTo(StoredMaxX,StoredMaxY); 
449     clientDC.LineTo(StoredMaxX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMinY);
450     m_IsVisible = false;
451   }
452
453   StoredMinX = Min ( MinX, MaxX );
454   StoredMinY = Min ( MinY, MaxY );
455   StoredMaxX = Max ( MinX, MaxX );
456   StoredMaxY = Max ( MinY, MaxY);
457
458   if (Draw) // move : draw
459   {
460     clientDC.MoveTo(StoredMinX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMaxY); 
461     clientDC.LineTo(StoredMaxX,StoredMaxY); 
462     clientDC.LineTo(StoredMaxX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMinY);
463     m_IsVisible = true;
464   }
465
466   if (m_Pen) 
467     clientDC.SelectObject(aOldPen);
468 }
469
470 void COCCDemoView::InitButtons()
471 {
472   myXmin=0;
473   myYmin=0;  
474   myXmax=0;
475   myYmax=0;
476   myCurZoom=0;
477   myCurrentMode = CurAction3d_Nothing;
478 }
479
480 void COCCDemoView::Reset()
481 {
482   InitButtons();
483   myVisMode = VIS_SHADE;
484   if (!myView.IsNull())
485   {
486     RedrawVisMode();
487     myView->Reset();
488   }
489 }
490
491 void COCCDemoView::RedrawVisMode()
492 {
493   switch (myVisMode)
494   {
495   case VIS_WIREFRAME:
496     GetDocument()->GetAISContext()->SetDisplayMode(AIS_WireFrame);
497     myView->SetComputedMode (Standard_False);
498     break;
499   case VIS_SHADE:
500     GetDocument()->GetAISContext()->SetDisplayMode(AIS_Shaded);
501     myView->SetComputedMode (Standard_False);
502     break;
503   case VIS_HLR:
504     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
505     myView->SetComputedMode (Standard_True);
506     SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
507     GetDocument()->GetAISContext()->SetDisplayMode(AIS_WireFrame);
508     break;
509   }
510 }
511
512 void COCCDemoView::OnBUTTONWire() 
513 {
514   myVisMode = VIS_WIREFRAME;
515   RedrawVisMode();
516 }
517
518 void COCCDemoView::OnBUTTONShade() 
519 {
520   myVisMode = VIS_SHADE;
521   RedrawVisMode();
522 }
523
524 void COCCDemoView::OnBUTTONHlrOn() 
525 {
526   myVisMode = VIS_HLR;
527   RedrawVisMode();
528 }
529
530 void COCCDemoView::OnUpdateBUTTONWire(CCmdUI* pCmdUI) 
531 {
532   pCmdUI->SetCheck (myVisMode == VIS_WIREFRAME);
533         pCmdUI->Enable   (myVisMode != VIS_WIREFRAME);  
534 }
535
536 void COCCDemoView::OnUpdateBUTTONShade(CCmdUI* pCmdUI) 
537 {
538   pCmdUI->SetCheck (myVisMode == VIS_SHADE);
539         pCmdUI->Enable   (myVisMode != VIS_SHADE);      
540 }
541
542 void COCCDemoView::OnUpdateBUTTONHlrOn(CCmdUI* pCmdUI) 
543 {
544   pCmdUI->SetCheck (myVisMode == VIS_HLR);
545         pCmdUI->Enable   (myVisMode != VIS_HLR);        
546 }
547
548 void COCCDemoView::GetViewAt (V3d_Coordinate& theX, V3d_Coordinate& theY, V3d_Coordinate& theZ) const
549 {
550   myView->At (theX, theY, theZ);
551 }
552
553 void COCCDemoView::SetViewAt (const V3d_Coordinate theX, const V3d_Coordinate theY, const V3d_Coordinate theZ)
554 {
555   myView->SetAt (theX, theY, theZ);
556 }
557
558 void COCCDemoView::GetViewEye(V3d_Coordinate& X, V3d_Coordinate& Y, V3d_Coordinate& Z)
559 {
560         myView->Eye(X,Y,Z);
561 }
562
563 void COCCDemoView::SetViewEye(V3d_Coordinate X, V3d_Coordinate Y, V3d_Coordinate Z)
564 {
565         myView->SetEye(X,Y,Z);
566 }
567
568 Quantity_Factor COCCDemoView::GetViewScale()
569 {
570         return myView->Scale();
571 }
572
573 void COCCDemoView::SetViewScale(Quantity_Factor Coef)
574 {
575         myView->SetScale(Coef);
576 }
577
578 void COCCDemoView::Translate (const Standard_Real theX, const Standard_Real theY)
579 {
580   myView->Panning (theX, theY);
581 }