1 // Viewer3dView.cpp : implementation of the CViewer3dView class
6 #include "Viewer3dView.h"
8 #include "OCC_MainFrame.h"
9 #include "Viewer3dApp.h"
10 #include "Viewer3dDoc.h"
12 #include "ShadingModelDlg.h"
13 #include "ModelClippingDlg.h"
14 #include "TrihedronDlg.h"
16 #include <V3d_AmbientLight.hxx>
17 #include <V3d_DirectionalLight.hxx>
18 #include <V3d_PositionalLight.hxx>
19 #include <V3d_PositionLight.hxx>
20 #include <V3d_SpotLight.hxx>
21 #include <TopoDS_Solid.hxx>
22 #include <Precision.hxx>
23 #include <Graphic3d_GraphicDriver.hxx>
34 static char THIS_FILE[] = __FILE__;
37 //gp_Pnt ConvertClickToPoint(Standard_Real x, Standard_Real y, Handle(V3d_View) aView);
40 Handle(AIS_Shape) spotConeShape=new AIS_Shape(TopoDS_Solid());
41 Handle(AIS_Shape) directionalEdgeShape=new AIS_Shape(TopoDS_Edge());
43 /////////////////////////////////////////////////////////////////////////////
46 IMPLEMENT_DYNCREATE(CViewer3dView, CView)
48 BEGIN_MESSAGE_MAP(CViewer3dView, CView)
49 //{{AFX_MSG_MAP(CViewer3dView)
50 ON_COMMAND(ID_BUTTONAxo, OnBUTTONAxo)
51 ON_COMMAND(ID_BUTTONBack, OnBUTTONBack)
52 ON_COMMAND(ID_BUTTONBottom, OnBUTTONBottom)
53 ON_COMMAND(ID_BUTTONFront, OnBUTTONFront)
54 ON_COMMAND(ID_BUTTONHlrOff, OnBUTTONHlrOff)
55 ON_COMMAND(ID_BUTTONHlrOn, OnBUTTONHlrOn)
56 ON_COMMAND(ID_BUTTONLeft, OnBUTTONLeft)
57 ON_COMMAND(ID_BUTTONPan, OnBUTTONPan)
58 ON_COMMAND(ID_BUTTONPanGlo, OnBUTTONPanGlo)
59 ON_COMMAND(ID_BUTTONReset, OnBUTTONReset)
60 ON_COMMAND(ID_BUTTONRight, OnBUTTONRight)
61 ON_COMMAND(ID_BUTTONRot, OnBUTTONRot)
62 ON_COMMAND(ID_BUTTONTop, OnBUTTONTop)
63 ON_COMMAND(ID_BUTTONZoomAll, OnBUTTONZoomAll)
65 ON_COMMAND(ID_BUTTONZoomProg, OnBUTTONZoomProg)
66 ON_COMMAND(ID_BUTTONZoomWin, OnBUTTONZoomWin)
75 ON_UPDATE_COMMAND_UI(ID_BUTTONHlrOff, OnUpdateBUTTONHlrOff)
76 ON_UPDATE_COMMAND_UI(ID_BUTTONHlrOn, OnUpdateBUTTONHlrOn)
77 ON_UPDATE_COMMAND_UI(ID_BUTTONPanGlo, OnUpdateBUTTONPanGlo)
78 ON_UPDATE_COMMAND_UI(ID_BUTTONPan, OnUpdateBUTTONPan)
79 ON_UPDATE_COMMAND_UI(ID_BUTTONZoomProg, OnUpdateBUTTONZoomProg)
80 ON_UPDATE_COMMAND_UI(ID_BUTTONZoomWin, OnUpdateBUTTONZoomWin)
81 ON_UPDATE_COMMAND_UI(ID_BUTTONRot, OnUpdateBUTTONRot)
82 ON_COMMAND(ID_Modify_ChangeBackground , OnModifyChangeBackground)
83 ON_COMMAND(ID_DIRECTIONAL_LIGHT, OnDirectionalLight)
84 ON_COMMAND(ID_SPOT_LIGHT, OnSpotLight)
85 ON_COMMAND(ID_POSITIONAL_LIGHT, OnPositionalLight)
86 ON_COMMAND(ID_AMBIENT_LIGHT, OnAmbientLight)
87 ON_COMMAND(ID_SCALE, OnScale)
88 ON_COMMAND(ID_SHADINGMODEL, OnShadingmodel)
89 ON_COMMAND(ID_ANTIALIASINGONOFF, OnAntialiasingonoff)
90 ON_COMMAND(ID_CLEAR_LIGHTS, OnClearLights)
91 ON_COMMAND(ID_MODELCLIPPING, OnModelclipping)
92 ON_COMMAND(ID_OPTIONS_TRIHEDRON_STATIC_TRIHEDRON, OnOptionsTrihedronStaticTrihedron)
96 /////////////////////////////////////////////////////////////////////////////
97 // CViewer3dView construction/destruction
99 CViewer3dView::CViewer3dView()
103 myVisMode (VIS_SHADE),
104 myCurrentMode (CurAction3d_Nothing),
110 NbActiveLights (2), // There are 2 default active lights
111 myHlrModeIsOn (Standard_False),
116 // TODO: add construction code here
117 myGraphicDriver = ((CViewer3dApp*)AfxGetApp())->GetGraphicDriver();
120 CViewer3dView::~CViewer3dView()
123 if (m_Pen) delete m_Pen;
126 BOOL CViewer3dView::PreCreateWindow(CREATESTRUCT& cs)
128 // TODO: Modify the Window class or styles here by modifying
129 // the CREATESTRUCT cs
130 cs.lpszClass = ::AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC, ::LoadCursor(NULL, IDC_ARROW), NULL, NULL);
131 return CView::PreCreateWindow(cs);
134 /////////////////////////////////////////////////////////////////////////////
135 // CViewer3dView drawing
136 void CViewer3dView::OnInitialUpdate()
138 CView::OnInitialUpdate();
140 myView = GetDocument()->GetViewer()->CreateView();
142 // store for restore state after rotation (witch is in Degenerated mode)
143 myHlrModeIsOn = Standard_False;
144 myView->SetComputedMode (myHlrModeIsOn);
146 Handle(WNT_Window) aWNTWindow = new WNT_Window (GetSafeHwnd());
147 myView->SetWindow(aWNTWindow);
148 if (!aWNTWindow->IsMapped()) aWNTWindow->Map();
150 // Standard_Integer w=100 , h=100 ; /* Debug Matrox */
151 // aWNTWindow->Size (w,h) ; /* Keeps me unsatisfied (rlb)..... */
152 /* Resize is not supposed to be done on */
154 /* I suspect another problem elsewhere */
155 // ::PostMessage ( GetSafeHwnd () , WM_SIZE , SIZE_RESTORED , w + h*65536 ) ;
157 // store the mode ( nothing , dynamic zooming, dynamic ... )
158 myCurrentMode = CurAction3d_Nothing;
159 myVisMode = VIS_SHADE;
163 void CViewer3dView::OnDraw(CDC* /*pDC*/)
165 CViewer3dDoc* pDoc = GetDocument();
170 /////////////////////////////////////////////////////////////////////////////
171 // CViewer3dView diagnostics
174 void CViewer3dView::AssertValid() const
176 CView::AssertValid();
179 void CViewer3dView::Dump(CDumpContext& dc) const
184 CViewer3dDoc* CViewer3dView::GetDocument() // non-debug version is inline
186 ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CViewer3dDoc)));
187 return (CViewer3dDoc*)m_pDocument;
191 /////////////////////////////////////////////////////////////////////////////
192 // CViewer3dView message handlers
194 gp_Pnt ConvertClickToPoint(Standard_Real x, Standard_Real y, Handle(V3d_View) aView)
196 V3d_Coordinate XEye,YEye,ZEye,XAt,YAt,ZAt;
197 aView->Eye(XEye,YEye,ZEye);
198 aView->At(XAt,YAt,ZAt);
199 gp_Pnt EyePoint(XEye,YEye,ZEye);
200 gp_Pnt AtPoint(XAt,YAt,ZAt);
202 gp_Vec EyeVector(EyePoint,AtPoint);
203 gp_Dir EyeDir(EyeVector);
205 gp_Pln PlaneOfTheView = gp_Pln(AtPoint,EyeDir);
207 aView->Convert(int(x),int(y),X,Y,Z);
208 gp_Pnt ConvertedPoint(X,Y,Z);
209 gp_Pnt2d ConvertedPointOnPlane = ProjLib::Project(PlaneOfTheView,ConvertedPoint);
211 gp_Pnt ResultPoint = ElSLib::Value(ConvertedPointOnPlane.X(),
212 ConvertedPointOnPlane.Y(),
217 void CViewer3dView::OnSize(UINT nType, int cx, int cy)
219 CView::OnSize (nType, cx, cy);
220 if (!myView.IsNull())
221 myView->MustBeResized();
224 void CViewer3dView::OnBUTTONBack()
226 myView->SetProj(V3d_Ypos);
228 TCollection_AsciiString Message("\
229 myView->SetProj(V3d_Ypos);\n\
232 // Update The Result Message Dialog
233 GetDocument()->UpdateResultMessageDlg("SetProj",Message);
234 } // See the back View
235 void CViewer3dView::OnBUTTONFront()
237 myView->SetProj(V3d_Yneg);
239 TCollection_AsciiString Message("\
240 myView->SetProj(V3d_Yneg);\n\
243 // Update The Result Message Dialog
244 GetDocument()->UpdateResultMessageDlg("SetProj",Message);
245 } // See the front View
247 void CViewer3dView::OnBUTTONBottom()
249 myView->SetProj(V3d_Zneg);
251 TCollection_AsciiString Message("\
252 myView->SetProj(V3d_Zneg);\n\
255 // Update The Result Message Dialog
256 GetDocument()->UpdateResultMessageDlg("SetProj",Message);
257 } // See the bottom View
258 void CViewer3dView::OnBUTTONTop()
260 myView->SetProj(V3d_Zpos);
262 TCollection_AsciiString Message("\
263 myView->SetProj(V3d_Zpos);\n\
266 // Update The Result Message Dialog
267 GetDocument()->UpdateResultMessageDlg("SetProj",Message);
268 } // See the top View
270 void CViewer3dView::OnBUTTONLeft()
272 myView->SetProj(V3d_Xneg);
274 TCollection_AsciiString Message("\
275 myView->SetProj(V3d_Xneg);\n\
278 // Update The Result Message Dialog
279 GetDocument()->UpdateResultMessageDlg("SetProj",Message);
280 } // See the left View
281 void CViewer3dView::OnBUTTONRight()
283 myView->SetProj(V3d_Xpos);
285 TCollection_AsciiString Message("\
286 myView->SetProj(V3d_Xpos);\n\
289 // Update The Result Message Dialog
290 GetDocument()->UpdateResultMessageDlg("SetProj",Message);
291 } // See the right View
293 void CViewer3dView::OnBUTTONAxo()
295 myView->SetProj(V3d_XposYnegZpos);
297 TCollection_AsciiString Message("\
298 myView->SetProj(V3d_XposYnegZpos);\n\
301 // Update The Result Message Dialog
302 GetDocument()->UpdateResultMessageDlg("SetProj",Message);
303 } // See the axonometric View
305 void CViewer3dView::OnBUTTONHlrOff()
307 myHlrModeIsOn = Standard_False;
308 myView->SetComputedMode (myHlrModeIsOn);
310 TCollection_AsciiString aMsg ("myView->SetComputedMode (Standard_False);\n"
313 // Update The Result Message Dialog
314 GetDocument()->UpdateResultMessageDlg ("SetComputedMode", aMsg);
317 void CViewer3dView::OnBUTTONHlrOn()
319 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
320 myHlrModeIsOn = Standard_True;
321 myView->SetComputedMode (myHlrModeIsOn);
322 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
324 TCollection_AsciiString aMsg ("myView->SetComputedMode (Standard_True);\n"
327 // Update The Result Message Dialog
328 GetDocument()->UpdateResultMessageDlg ("SetComputedMode", aMsg);
331 void CViewer3dView::OnBUTTONPan()
332 { myCurrentMode = CurAction3d_DynamicPanning; }
334 void CViewer3dView::OnBUTTONPanGlo()
336 // save the current zoom value
337 myCurZoom = myView->Scale();
341 myCurrentMode = CurAction3d_GlobalPanning;
344 void CViewer3dView::OnBUTTONReset()
347 void CViewer3dView::OnBUTTONRot()
348 { myCurrentMode = CurAction3d_DynamicRotation; }
351 void CViewer3dView::OnBUTTONZoomAll()
357 void CViewer3dView::OnBUTTONZoomProg()
358 { myCurrentMode = CurAction3d_DynamicZooming; }
360 void CViewer3dView::OnBUTTONZoomWin()
361 { myCurrentMode = CurAction3d_WindowZooming; }
363 void CViewer3dView::OnLButtonDown(UINT nFlags, CPoint point)
365 // save the current mouse coordinate in min
366 myXmin=point.x; myYmin=point.y;
367 myXmax=point.x; myYmax=point.y;
369 if ( nFlags & MK_CONTROL )
371 // Button MB1 down Control :start zomming
372 // SetCursor(AfxGetApp()->LoadStandardCursor());
376 switch (myCurrentMode)
378 case CurAction3d_Nothing : // start a drag
379 if (nFlags & MK_SHIFT)
380 GetDocument()->ShiftDragEvent(myXmax,myYmax,-1,myView);
382 GetDocument()->DragEvent(myXmax,myYmax,-1,myView);
385 case CurAction3d_DynamicZooming : // noting
387 case CurAction3d_WindowZooming :
389 case CurAction3d_DynamicPanning :// noting
391 case CurAction3d_GlobalPanning :// noting
393 case CurAction3d_DynamicRotation :
396 myView->SetComputedMode (Standard_False);
398 myView->StartRotation (point.x, point.y);
400 case CurAction3d_BeginPositionalLight :
402 p1 = ConvertClickToPoint(point.x,point.y,myView);
403 myCurrent_PositionalLight->SetPosition(p1.X(),p1.Y(),p1.Z()) ;
404 GetDocument()->GetAISContext()->CloseLocalContext();
405 ((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Ready");
406 myCurrentMode = CurAction3d_Nothing;
408 TCollection_AsciiString Message("\
409 myCurrent_PositionalLight->SetPosition(Xp, Yp, Zp) ;\n\
411 // Update The Result Message Dialog
412 GetDocument()->UpdateResultMessageDlg("SetPosition",Message);
415 case CurAction3d_BeginSpotLight :
417 p1 = ConvertClickToPoint(point.x,point.y,myView);
418 myCurrent_SpotLight = new V3d_SpotLight(myView->Viewer(),0.,0.,1., p1.X(),p1.Y(),p1.Z(),Quantity_NOC_RED);
419 myView->SetLightOn(myCurrent_SpotLight);
421 p2 = gp_Pnt(p1.X(),p1.Y(),p1.Z()+1.);
422 Standard_Real coneHeigth=p1.Distance(p2);
423 BRepPrimAPI_MakeCone MakeCone(gp_Ax2(p1, gp_Dir(gp_Vec(p1, p2))),
424 0, (p1.Distance(p2))/tan(1.04), coneHeigth);
425 spotConeShape->Set(MakeCone.Solid());
426 GetDocument()->GetAISContext()->Display(spotConeShape,0,-1);
427 ((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick the target point");
428 myCurrentMode = CurAction3d_TargetSpotLight;
430 TCollection_AsciiString Message("\
431 myCurrent_SpotLight->SetDirection(Xv, Yv, Zv);\n\
433 // Update The Result Message Dialog
434 GetDocument()->UpdateResultMessageDlg("SetDirection",Message);
437 case CurAction3d_TargetSpotLight :
439 p2 = ConvertClickToPoint(point.x,point.y,myView);
440 ((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick a third point (to define the angle)");
441 myCurrentMode = CurAction3d_EndSpotLight;
443 TCollection_AsciiString Message("\
444 myCurrent_SpotLight->SetAngle(Angle) ;\n\
446 // Update The Result Message Dialog
447 GetDocument()->UpdateResultMessageDlg("SetAngle",Message);
450 case CurAction3d_EndSpotLight :
451 GetDocument()->GetAISContext()->Erase(spotConeShape);
452 GetDocument()->GetAISContext()->CloseLocalContext();
453 ((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Ready");
454 myCurrentMode = CurAction3d_Nothing;
456 case CurAction3d_BeginDirectionalLight:
458 p1 = ConvertClickToPoint(point.x,point.y,myView);
459 p2 = gp_Pnt(p1.X(),p1.Y(),p1.Z()+1.);
460 BRepBuilderAPI_MakeEdge MakeEdge(p1, p2);
461 directionalEdgeShape->Set(MakeEdge.Edge());
462 GetDocument()->GetAISContext()->Display(directionalEdgeShape,0,-1);
463 // Create a directional light
464 myCurrent_DirectionalLight = new V3d_DirectionalLight(myView->Viewer(), p1.X(),p1.Y(),p1.Z(),0.,0.,1.);
465 myView->SetLightOn(myCurrent_DirectionalLight);
467 ((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick the target point");
468 myCurrentMode = CurAction3d_EndDirectionalLight;
471 TCollection_AsciiString Message("\
472 myCurrent_DirectionalLight->SetDirection(Xv, Yv, Zv);\n\
474 // Update The Result Message Dialog
475 GetDocument()->UpdateResultMessageDlg("SetDirection",Message);
478 case CurAction3d_EndDirectionalLight:
479 GetDocument()->GetAISContext()->Erase(directionalEdgeShape);
480 GetDocument()->GetAISContext()->CloseLocalContext();
481 ((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Ready");
482 myCurrentMode = CurAction3d_Nothing;
488 void CViewer3dView::OnKeyDown(UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/)
491 if( nChar == X_Key || nChar == Y_Key || nChar == Z_Key )
493 else if( (nChar == VK_ADD || nChar == VK_SUBTRACT) && myAxisKey )
495 myScaleDirection = nChar;
496 if( myAxisKey && myScaleDirection )
501 if( myScaleDirection == VK_ADD ) scaleX ++;
502 if( myScaleDirection == VK_SUBTRACT ) scaleX --;
505 if( myScaleDirection == VK_ADD ) scaleY ++;
506 if( myScaleDirection == VK_SUBTRACT ) scaleY --;
509 if( myScaleDirection == VK_ADD ) scaleZ ++;
510 if( myScaleDirection == VK_SUBTRACT ) scaleZ --;
515 if( scaleX < 1 ) scaleX = 1;
516 if( scaleY < 1 ) scaleY = 1;
517 if( scaleZ < 1 ) scaleZ = 1;
519 myView->SetAxialScale( scaleX, scaleY, scaleZ );
524 void CViewer3dView::OnLButtonUp(UINT nFlags, CPoint point)
526 if ( nFlags & MK_CONTROL )
532 switch (myCurrentMode)
534 case CurAction3d_Nothing :
535 if (point.x == myXmin && point.y == myYmin)
536 { // no offset between down and up --> selectEvent
539 if (nFlags & MK_SHIFT )
540 GetDocument()->ShiftInputEvent(point.x,point.y,myView);
542 GetDocument()->InputEvent (point.x,point.y,myView);
545 DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False);
548 if (nFlags & MK_SHIFT)
549 GetDocument()->ShiftDragEvent(point.x,point.y,1,myView);
551 GetDocument()->DragEvent(point.x,point.y,1,myView);
554 case CurAction3d_DynamicZooming :
555 // SetCursor(AfxGetApp()->LoadStandardCursor());
556 myCurrentMode = CurAction3d_Nothing;
558 case CurAction3d_WindowZooming :
559 DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False);
562 if ((abs(myXmin-myXmax)>ValZWMin) || (abs(myYmin-myYmax)>ValZWMin))
563 // Test if the zoom window is greater than a minimale window.
565 // Do the zoom window between Pmin and Pmax
566 myView->WindowFitAll(myXmin,myYmin,myXmax,myYmax);
568 myCurrentMode = CurAction3d_Nothing;
570 case CurAction3d_DynamicPanning :
571 myCurrentMode = CurAction3d_Nothing;
573 case CurAction3d_GlobalPanning :
574 myView->Place(point.x,point.y,myCurZoom);
575 myCurrentMode = CurAction3d_Nothing;
577 case CurAction3d_DynamicRotation :
578 myCurrentMode = CurAction3d_Nothing;
580 } //switch (myCurrentMode)
581 } // else // if ( Ctrl )
584 void CViewer3dView::OnMButtonDown(UINT nFlags, CPoint /*point*/)
586 if ( nFlags & MK_CONTROL )
588 // Button MB2 down Control : panning init
589 // SetCursor(AfxGetApp()->LoadStandardCursor());
593 void CViewer3dView::OnMButtonUp(UINT nFlags, CPoint /*point*/)
595 if ( nFlags & MK_CONTROL )
597 // Button MB2 down Control : panning init
598 // SetCursor(AfxGetApp()->LoadStandardCursor());
602 void CViewer3dView::OnRButtonDown(UINT nFlags, CPoint point)
604 if ( nFlags & MK_CONTROL )
606 // SetCursor(AfxGetApp()->LoadStandardCursor());
609 myView->SetComputedMode (Standard_False);
611 myView->StartRotation (point.x, point.y);
615 GetDocument()->Popup (point.x, point.y, myView);
619 void CViewer3dView::OnRButtonUp(UINT /*nFlags*/, CPoint /*point*/)
621 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
622 myView->SetComputedMode (myHlrModeIsOn);
623 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
626 void CViewer3dView::OnMouseMove(UINT nFlags, CPoint point)
628 // ============================ LEFT BUTTON =======================
629 if ( nFlags & MK_LBUTTON)
631 if ( nFlags & MK_CONTROL )
633 // move with MB1 and Control : on the dynamic zooming
634 // Do the zoom in function of mouse's coordinates
635 myView->Zoom(myXmax,myYmax,point.x,point.y);
636 // save the current mouse coordinate in min
642 switch (myCurrentMode)
644 case CurAction3d_Nothing :
646 DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False);
647 myXmax = point.x; myYmax = point.y;
648 if (nFlags & MK_SHIFT)
649 GetDocument()->ShiftDragEvent(myXmax,myYmax,0,myView);
651 GetDocument()->DragEvent(myXmax,myYmax,0,myView);
652 DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_True);
654 case CurAction3d_DynamicZooming :
655 myView->Zoom(myXmax,myYmax,point.x,point.y);
656 // save the current mouse coordinate in min \n";
657 myXmax=point.x; myYmax=point.y;
659 case CurAction3d_WindowZooming :
660 myXmax = point.x; myYmax = point.y;
661 DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False,LongDash);
662 DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_True,LongDash);
665 case CurAction3d_DynamicPanning :
666 myView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
667 myXmax = point.x; myYmax = point.y;
669 case CurAction3d_GlobalPanning : // nothing
671 case CurAction3d_DynamicRotation :
672 myView->Rotation(point.x,point.y);
675 }// switch (myCurrentMode)
676 }// if ( nFlags & MK_CONTROL ) else
677 } else // if ( nFlags & MK_LBUTTON)
678 // ============================ MIDDLE BUTTON =======================
679 if ( nFlags & MK_MBUTTON)
681 if ( nFlags & MK_CONTROL )
683 myView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
684 myXmax = point.x; myYmax = point.y;
687 } else // if ( nFlags & MK_MBUTTON)
688 // ============================ RIGHT BUTTON =======================
689 if ( nFlags & MK_RBUTTON)
691 if ( nFlags & MK_CONTROL )
693 myView->Rotation(point.x,point.y);
695 }else //if ( nFlags & MK_RBUTTON)
696 // ============================ NO BUTTON =======================
698 myXmax = point.x; myYmax = point.y;
699 if (myCurrentMode == CurAction3d_EndDirectionalLight)
701 p2 = ConvertClickToPoint(point.x,point.y,myView);
702 //Update the light dynamically
703 if( p1.Distance(p2)>Precision::Confusion())
705 BRepBuilderAPI_MakeEdge MakeEdge(p1, p2);
706 directionalEdgeShape->Set(MakeEdge.Edge());
707 GetDocument()->GetAISContext()->Redisplay(directionalEdgeShape,0,Standard_True);
708 myCurrent_DirectionalLight->SetDirection(p2.X()-p1.X(),p2.Y()-p1.Y(),p2.Z()-p1.Z());
709 myView->UpdateLights();
712 else if (myCurrentMode == CurAction3d_BeginPositionalLight)
714 p2 = ConvertClickToPoint(point.x,point.y,myView);
715 //Update the light dynamically
716 myCurrent_PositionalLight->SetPosition(p2.X(),p2.Y(),p2.Z());
717 myView->UpdateLights();
719 else if (myCurrentMode == CurAction3d_TargetSpotLight)
721 p2 = ConvertClickToPoint(point.x,point.y,myView);
722 //Update the light dynamically
723 Standard_Real coneHeigth=p1.Distance(p2);
724 if( coneHeigth>Precision::Confusion())
726 BRepPrimAPI_MakeCone MakeCone(gp_Ax2(p1, gp_Dir(gp_Vec(p1, p2))),
727 0, (p1.Distance(p2))/tan(1.04), coneHeigth);
728 spotConeShape->Set(MakeCone.Solid());
729 GetDocument()->GetAISContext()->Redisplay(spotConeShape,0,Standard_True);
730 myCurrent_SpotLight->SetDirection(p2.X()-p1.X(),p2.Y()-p1.Y(),p2.Z()-p1.Z());
731 myView->UpdateLights();
734 else if (myCurrentMode == CurAction3d_EndSpotLight)
736 p3 = ConvertClickToPoint(point.x,point.y,myView);
737 //Update the light dynamically
738 Standard_Real coneHeigth=p1.Distance(p2);
739 if( (p2.Distance(p3))>Precision::Confusion())
741 BRepPrimAPI_MakeCone MakeCone(gp_Ax2(p1, gp_Dir(gp_Vec(p1, p2))),
742 0, p2.Distance(p3), coneHeigth);
743 spotConeShape->Set(MakeCone.Solid());
744 GetDocument()->GetAISContext()->Redisplay(spotConeShape,0,Standard_True);
745 myCurrent_SpotLight->SetAngle(atan(p2.Distance(p3)/p1.Distance(p2))) ;
746 myView->UpdateLights();
749 if (nFlags & MK_SHIFT)
750 GetDocument()->ShiftMoveEvent(point.x,point.y,myView);
752 GetDocument()->MoveEvent(point.x,point.y,myView);
756 void CViewer3dView::OnUpdateBUTTONHlrOff (CCmdUI* pCmdUI)
758 pCmdUI->SetCheck (!myHlrModeIsOn);
759 pCmdUI->Enable (myHlrModeIsOn);
762 void CViewer3dView::OnUpdateBUTTONHlrOn (CCmdUI* pCmdUI)
764 pCmdUI->SetCheck (myHlrModeIsOn);
765 pCmdUI->Enable (!myHlrModeIsOn);
768 void CViewer3dView::OnUpdateBUTTONPanGlo(CCmdUI* pCmdUI)
770 pCmdUI->SetCheck (myCurrentMode == CurAction3d_GlobalPanning);
771 pCmdUI->Enable (myCurrentMode != CurAction3d_GlobalPanning);
775 void CViewer3dView::OnUpdateBUTTONPan(CCmdUI* pCmdUI)
777 pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicPanning);
778 pCmdUI->Enable (myCurrentMode != CurAction3d_DynamicPanning );
781 void CViewer3dView::OnUpdateBUTTONZoomProg(CCmdUI* pCmdUI)
783 pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicZooming );
784 pCmdUI->Enable (myCurrentMode != CurAction3d_DynamicZooming);
787 void CViewer3dView::OnUpdateBUTTONZoomWin(CCmdUI* pCmdUI)
789 pCmdUI->SetCheck (myCurrentMode == CurAction3d_WindowZooming);
790 pCmdUI->Enable (myCurrentMode != CurAction3d_WindowZooming);
793 void CViewer3dView::OnUpdateBUTTONRot(CCmdUI* pCmdUI)
795 pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicRotation);
796 pCmdUI->Enable (myCurrentMode != CurAction3d_DynamicRotation);
799 void CViewer3dView::DrawRectangle(const Standard_Integer MinX ,
800 const Standard_Integer MinY ,
801 const Standard_Integer MaxX ,
802 const Standard_Integer MaxY ,
803 const Standard_Boolean Draw ,
804 const LineStyle aLineStyle)
806 static int m_DrawMode;
807 if (!m_Pen && aLineStyle ==Solid )
808 {m_Pen = new CPen(PS_SOLID, 1, RGB(0,0,0)); m_DrawMode = R2_MERGEPENNOT;}
809 else if (!m_Pen && aLineStyle ==Dot )
810 {m_Pen = new CPen(PS_DOT, 1, RGB(0,0,0)); m_DrawMode = R2_XORPEN;}
811 else if (!m_Pen && aLineStyle == ShortDash)
812 {m_Pen = new CPen(PS_DASH, 1, RGB(255,0,0)); m_DrawMode = R2_XORPEN;}
813 else if (!m_Pen && aLineStyle == LongDash)
814 {m_Pen = new CPen(PS_DASH, 1, RGB(0,0,0)); m_DrawMode = R2_NOTXORPEN;}
815 else if (aLineStyle == Default)
816 { m_Pen = NULL; m_DrawMode = R2_MERGEPENNOT;}
818 CPen* aOldPen = NULL;
819 CClientDC clientDC(this);
820 if (m_Pen) aOldPen = clientDC.SelectObject(m_Pen);
821 clientDC.SetROP2(m_DrawMode);
823 static Standard_Integer StoredMinX, StoredMaxX, StoredMinY, StoredMaxY;
824 static Standard_Boolean m_IsVisible;
826 if ( m_IsVisible && !Draw) // move or up : erase at the old position
828 clientDC.MoveTo(StoredMinX,StoredMinY);
829 clientDC.LineTo(StoredMinX,StoredMaxY);
830 clientDC.LineTo(StoredMaxX,StoredMaxY);
831 clientDC.LineTo(StoredMaxX,StoredMinY);
832 clientDC.LineTo(StoredMinX,StoredMinY);
836 StoredMinX = Min ( MinX, MaxX );
837 StoredMinY = Min ( MinY, MaxY );
838 StoredMaxX = Max ( MinX, MaxX );
839 StoredMaxY = Max ( MinY, MaxY);
841 if (Draw) // move : draw
843 clientDC.MoveTo(StoredMinX,StoredMinY);
844 clientDC.LineTo(StoredMinX,StoredMaxY);
845 clientDC.LineTo(StoredMaxX,StoredMaxY);
846 clientDC.LineTo(StoredMaxX,StoredMinY);
847 clientDC.LineTo(StoredMinX,StoredMinY);
852 clientDC.SelectObject(aOldPen);
855 void CViewer3dView::OnModifyChangeBackground()
860 myView->BackgroundColor(Quantity_TOC_RGB,R1,G1,B1);
862 m_clr = RGB(R1*255,G1*255,B1*255);
864 CColorDialog dlgColor(m_clr);
865 if (dlgColor.DoModal() == IDOK)
867 m_clr = dlgColor.GetColor();
868 R1 = GetRValue(m_clr)/255.;
869 G1 = GetGValue(m_clr)/255.;
870 B1 = GetBValue(m_clr)/255.;
871 myView->SetBackgroundColor(Quantity_TOC_RGB,R1,G1,B1);
876 void CViewer3dView::OnDirectionalLight()
878 // Directional light source creation
880 // Checking if the Active lights limit number is not reached
881 if( NbActiveLights>=myGraphicDriver->InquireLightLimit() )
884 aMsg.Format (L"You have reach the limit number of active lights (%d).\n Clear lights to create new ones.", myGraphicDriver->InquireLightLimit());
885 MessageBox (aMsg, L"Light creation", MB_OK);
890 ((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick a first point");
891 GetDocument()->GetAISContext()->OpenLocalContext();
892 myCurrentMode = CurAction3d_BeginDirectionalLight;
894 TCollection_AsciiString Message("\
895 myCurrent_DirectionalLight = new V3d_DirectionalLight(myView->Viewer(), Xt, Yt, Zt, Xp, Yp, Zp);\n\
897 myView->SetLightOn(myCurrent_DirectionalLight);\n\
900 // Update The Result Message Dialog
901 GetDocument()->UpdateResultMessageDlg("V3d_DirectionalLight",Message);
904 void CViewer3dView::OnSpotLight()
906 // Spot light source creation
908 // Checking if the Active lights limit number is not reached
909 if( NbActiveLights>=myGraphicDriver->InquireLightLimit() )
912 aMsg.Format(L"You have reach the limit number of active lights (%d).\n Clear lights to create new ones.", myGraphicDriver->InquireLightLimit());
913 MessageBox (aMsg, L"Light creation", MB_OK);
917 GetDocument()->GetAISContext()->OpenLocalContext();
918 ((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick the light position");
919 myCurrentMode = CurAction3d_BeginSpotLight;
921 TCollection_AsciiString Message("\
922 myCurrent_SpotLight = new V3d_SpotLight(myView->Viewer(), Xt, Yt, Zt, Xp, Yp, Zp,Quantity_NOC_RED);\n\
924 myView->SetLightOn(myCurrent_SpotLight);\n\
927 // Update The Result Message Dialog
928 GetDocument()->UpdateResultMessageDlg("V3d_SpotLight",Message);
931 void CViewer3dView::OnPositionalLight()
933 // Positional light source creation
935 // Checking if the Active lights limit number is not reached
936 if( NbActiveLights>=myGraphicDriver->InquireLightLimit() )
939 aMsg.Format(L"You have reach the limit number of active lights (%d).\n Clear lights to create new ones.", myGraphicDriver->InquireLightLimit());
940 MessageBox(aMsg, L"Light creation", MB_OK);
944 GetDocument()->GetAISContext()->OpenLocalContext();
945 myCurrent_PositionalLight=new V3d_PositionalLight(myView->Viewer(),0,0,0,Quantity_NOC_GREEN,1,0);
946 myView->SetLightOn(myCurrent_PositionalLight);
948 ((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick the light position");
949 myCurrentMode = CurAction3d_BeginPositionalLight;
951 TCollection_AsciiString Message("\
952 myCurrent_PositionalLight=new V3d_PositionalLight(myView->Viewer(),Xp, Yp, Zp,Quantity_NOC_GREEN,1,0);\n\
954 myView->SetLightOn(myCurrent_PositionalLight) ;\n\
957 // Update The Result Message Dialog
958 GetDocument()->UpdateResultMessageDlg("V3d_PositionalLight",Message);
961 void CViewer3dView::OnAmbientLight()
963 // Ambiant light source creation
965 // Checking if the Active lights limit number is not reached
966 if( NbActiveLights>=myGraphicDriver->InquireLightLimit() )
969 aMsg.Format(L"You have reach the limit number of active lights (%d).\n Clear lights to create new ones.", myGraphicDriver->InquireLightLimit());
970 MessageBox(aMsg, L"Light creation", MB_OK);
974 GetDocument()->GetAISContext()->OpenLocalContext();
975 myCurrent_AmbientLight=new V3d_AmbientLight(myView->Viewer(), Quantity_NOC_GRAY);
976 myView->SetLightOn(myCurrent_AmbientLight) ;
978 GetDocument()->GetAISContext()->CloseLocalContext();
980 myView->UpdateLights();
982 TCollection_AsciiString Message("\
983 myCurrent_AmbientLight=new V3d_AmbientLight(myView->Viewer(), Quantity_NOC_GRAY);\n\
985 myView->SetLightOn(myCurrent_AmbientLight) ;\n\
988 // Update The Result Message Dialog
989 GetDocument()->UpdateResultMessageDlg("V3d_AmbientLight",Message);
993 void CViewer3dView::OnScale()
995 ScaleDlg Dlg(myView, this);
1002 void CViewer3dView::OnShadingmodel()
1004 TCollection_AsciiString Message("\
1005 myView->SetShadingModel(V3d_TypeOfShadingModel myTypeOfShadingModel);\n\
1007 myCurrent_V3d_View->Update();\n\
1010 // Update The Result Message Dialog
1011 GetDocument()->UpdateResultMessageDlg("SetShadingModel",Message);
1013 CShadingModelDlg Dlg(myView);
1019 void CViewer3dView::OnAntialiasingonoff()
1021 Graphic3d_RenderingParams& aParams = myView->ChangeRenderingParams();
1022 aParams.NbMsaaSamples = aParams.NbMsaaSamples == 0 ? 8 : 0;
1025 TCollection_AsciiString Message("\
1026 Graphic3d_RenderingParams& aParams = myView->ChangeRenderingParams();\n\
1027 aParams.NbMsaaSamples = aParams.NbMsaaSamples == 0 ? 8 : 0;\n\
1030 // Update The Result Message Dialog
1031 GetDocument()->UpdateResultMessageDlg("SetAntialiasingOn/SetAntialiasingOff",Message);
1034 void CViewer3dView::OnClearLights()
1036 // Setting Off all viewer active lights
1037 TColStd_ListOfTransient lights;
1038 for(myView->Viewer()->InitActiveLights(); myView->Viewer()->MoreActiveLights(); myView->Viewer()->NextActiveLights())
1040 lights.Append(myView->Viewer()->ActiveLight());
1042 TColStd_ListIteratorOfListOfTransient itrLights(lights);
1043 for (; itrLights.More(); itrLights.Next())
1045 Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());
1046 myView->Viewer()->SetLightOff(light);
1049 // Setting Off all view active lights
1051 for(myView->InitActiveLights(); myView->MoreActiveLights(); myView->NextActiveLights())
1053 lights.Append(myView->ActiveLight());
1055 itrLights.Initialize(lights);
1056 for (; itrLights.More(); itrLights.Next())
1058 Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());
1059 myView->SetLightOff(light);
1062 myView->Viewer()->SetDefaultLights();// Setting the default lights on
1064 NbActiveLights = 2;// There are 2 default active lights
1068 TCollection_AsciiString Message("\
1069 // Setting Off all viewer active lights\n\
1070 TColStd_ListOfTransient lights;\n\
1071 for(myView->Viewer()->InitActiveLights(); myView->Viewer()->MoreActiveLights(); myView->Viewer()->NextActiveLights())\n\
1073 lights.Append(myView->Viewer()->ActiveLight());\n\
1075 TColStd_ListIteratorOfListOfTransient itrLights(lights);\n\
1076 for (; itrLights.More(); itrLights.Next())\n\
1078 Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());\n\
1079 myView->Viewer()->SetLightOff(light);\n\
1082 // Setting Off all view active lights\n\
1084 for(myView->InitActiveLights(); myView->MoreActiveLights(); myView->NextActiveLights())\n\
1086 lights.Append(myView->ActiveLight());\n\
1088 itrLights.Initialize(lights);\n\
1089 for (; itrLights.More(); itrLights.Next())\n\
1091 Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());\n\
1092 myView->SetLightOff(light);\n\
1095 myView->Viewer()->SetDefaultLights();// Setting the default lights on\n\
1098 // Update The Result Message Dialog
1099 GetDocument()->UpdateResultMessageDlg("SetLightOff",Message);
1102 void CViewer3dView::OnModelclipping()
1104 if (myClippingPlane.IsNull())
1106 gp_Pln aClipPlane (gp_Pnt (0.0, 0.0, 0.0), gp_Dir (1.0, 0.0, 0.0));
1107 gp_Pln aFacePlane (gp_Pnt (0.1, 0.0, 0.0), gp_Dir (1.0, 0.0, 0.0));
1109 // create clipping plane and add to view
1110 myClippingPlane = new Graphic3d_ClipPlane (aClipPlane);
1112 // shape to represent clipping plane
1113 BRepBuilderAPI_MakeFace aMakeFaceCommand (aFacePlane, 200.0, -200.0, 410.0, -410.0);
1114 TopoDS_Face aShape = aMakeFaceCommand.Face();
1115 myShape = new AIS_Shape (aShape);
1116 myShape->SetTransparency (0.5);
1119 CModelClippingDlg aClippingDlg (myView, myShape, myClippingPlane, GetDocument());
1121 aClippingDlg.DoModal();
1124 void CViewer3dView::OnOptionsTrihedronStaticTrihedron()
1126 CTrihedronDlg Dlg(myView, GetDocument());
1130 void CViewer3dView::InitButtons()
1137 myCurrentMode = CurAction3d_Nothing;
1140 void CViewer3dView::Reset()
1143 myVisMode = VIS_SHADE;
1144 if (!myView.IsNull())
1151 void CViewer3dView::GetViewAt (V3d_Coordinate& theX, V3d_Coordinate& theY, V3d_Coordinate& theZ) const
1153 myView->At (theX, theY, theZ);
1156 void CViewer3dView::SetViewAt (const V3d_Coordinate theX, const V3d_Coordinate theY, const V3d_Coordinate theZ)
1158 myView->SetAt (theX, theY, theZ);
1161 void CViewer3dView::GetViewEye(V3d_Coordinate& X, V3d_Coordinate& Y, V3d_Coordinate& Z)
1166 void CViewer3dView::SetViewEye(V3d_Coordinate X, V3d_Coordinate Y, V3d_Coordinate Z)
1168 myView->SetEye(X,Y,Z);
1171 Quantity_Factor CViewer3dView::GetViewScale()
1173 return myView->Scale();
1176 void CViewer3dView::SetViewScale(Quantity_Factor Coef)
1178 myView->SetScale(Coef);
1181 void CViewer3dView::RedrawVisMode()
1186 GetDocument()->GetAISContext()->SetDisplayMode(AIS_WireFrame);
1187 myView->SetComputedMode (Standard_False);
1190 GetDocument()->GetAISContext()->SetDisplayMode(AIS_Shaded);
1191 myView->SetComputedMode (Standard_False);
1194 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
1195 myView->SetComputedMode (Standard_True);
1196 SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
1197 GetDocument()->GetAISContext()->SetDisplayMode(AIS_WireFrame);