1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-06-10 11:34:06 +03:00
occt/samples/mfc/standard/04_Viewer3d/src/Viewer3dView.cpp
vro cc1d74e225 0021189: Clean up KAS:dev:ros and Products
Removal of VoxelClient
VoxelDemo sample is redesigned so that it doesn't require compilation of OpenGl classes. It refers to TKOpenGl.dll as to an external library.
Some minor bugs are fixed in OCAF and Viewer 3d standard MFC samples
2012-10-05 14:17:17 +04:00

1258 lines
37 KiB
C++
Executable File

// Viewer3dView.cpp : implementation of the CViewer3dView class
//
#include "stdafx.h"
#include "Viewer3dView.h"
#include "OCC_MainFrame.h"
#include "Viewer3dApp.h"
#include "Viewer3dDoc.h"
#include "ZClippingDlg.h"
#include "ZCueingDlg.h"
#include "ScaleDlg.h"
#include "ShadingModelDlg.h"
#include "ModelClippingDlg.h"
#include "TrihedronDlg.h"
#include <V3d_AmbientLight.hxx>
#include <V3d_DirectionalLight.hxx>
#include <V3d_PositionalLight.hxx>
#include <V3d_PositionLight.hxx>
#include <V3d_SpotLight.hxx>
#include <TopoDS_Solid.hxx>
#include <Precision.hxx>
#include <Graphic3d_GraphicDriver.hxx>
#define ValZWMin 1
#define X_Key 0x58
#define Y_Key 0x59
#define Z_Key 0x5A
#define ModelClipping
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//gp_Pnt ConvertClickToPoint(Standard_Real x, Standard_Real y, Handle(V3d_View) aView);
gp_Pnt p1,p2,p3;
Handle(AIS_Shape) spotConeShape=new AIS_Shape(TopoDS_Solid());
Handle(AIS_Shape) directionalEdgeShape=new AIS_Shape(TopoDS_Edge());
/////////////////////////////////////////////////////////////////////////////
// CViewer3dView
IMPLEMENT_DYNCREATE(CViewer3dView, CView)
BEGIN_MESSAGE_MAP(CViewer3dView, CView)
//{{AFX_MSG_MAP(CViewer3dView)
ON_COMMAND(ID_BUTTONAxo, OnBUTTONAxo)
ON_COMMAND(ID_BUTTONBack, OnBUTTONBack)
ON_COMMAND(ID_BUTTONBottom, OnBUTTONBottom)
ON_COMMAND(ID_BUTTONFront, OnBUTTONFront)
ON_COMMAND(ID_BUTTONHlrOff, OnBUTTONHlrOff)
ON_COMMAND(ID_BUTTONHlrOn, OnBUTTONHlrOn)
ON_COMMAND(ID_BUTTONLeft, OnBUTTONLeft)
ON_COMMAND(ID_BUTTONPan, OnBUTTONPan)
ON_COMMAND(ID_BUTTONPanGlo, OnBUTTONPanGlo)
ON_COMMAND(ID_BUTTONReset, OnBUTTONReset)
ON_COMMAND(ID_BUTTONRight, OnBUTTONRight)
ON_COMMAND(ID_BUTTONRot, OnBUTTONRot)
ON_COMMAND(ID_BUTTONTop, OnBUTTONTop)
ON_COMMAND(ID_BUTTONZoomAll, OnBUTTONZoomAll)
ON_WM_SIZE()
ON_COMMAND(ID_BUTTONZoomProg, OnBUTTONZoomProg)
ON_COMMAND(ID_BUTTONZoomWin, OnBUTTONZoomWin)
ON_WM_LBUTTONDOWN()
ON_WM_KEYDOWN()
ON_WM_LBUTTONUP()
ON_WM_MBUTTONDOWN()
ON_WM_MBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
ON_UPDATE_COMMAND_UI(ID_BUTTONHlrOff, OnUpdateBUTTONHlrOff)
ON_UPDATE_COMMAND_UI(ID_BUTTONHlrOn, OnUpdateBUTTONHlrOn)
ON_UPDATE_COMMAND_UI(ID_BUTTONPanGlo, OnUpdateBUTTONPanGlo)
ON_UPDATE_COMMAND_UI(ID_BUTTONPan, OnUpdateBUTTONPan)
ON_UPDATE_COMMAND_UI(ID_BUTTONZoomProg, OnUpdateBUTTONZoomProg)
ON_UPDATE_COMMAND_UI(ID_BUTTONZoomWin, OnUpdateBUTTONZoomWin)
ON_UPDATE_COMMAND_UI(ID_BUTTONRot, OnUpdateBUTTONRot)
ON_COMMAND(ID_Modify_ChangeBackground , OnModifyChangeBackground)
ON_COMMAND(ID_DIRECTIONAL_LIGHT, OnDirectionalLight)
ON_COMMAND(ID_SPOT_LIGHT, OnSpotLight)
ON_COMMAND(ID_POSITIONAL_LIGHT, OnPositionalLight)
ON_COMMAND(ID_AMBIENT_LIGHT, OnAmbientLight)
ON_COMMAND(ID_ZCUEING, OnZcueing)
ON_COMMAND(ID_SCALE, OnScale)
ON_COMMAND(ID_ZCLIPPING, OnZclipping)
ON_COMMAND(ID_SHADINGMODEL, OnShadingmodel)
ON_COMMAND(ID_ANTIALIASINGONOFF, OnAntialiasingonoff)
ON_COMMAND(ID_CLEAR_LIGHTS, OnClearLights)
ON_COMMAND(ID_MODELCLIPPING, OnModelclipping)
ON_COMMAND(ID_OPTIONS_TRIHEDRON_STATIC_TRIHEDRON, OnOptionsTrihedronStaticTrihedron)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CViewer3dView construction/destruction
CViewer3dView::CViewer3dView()
{
// TODO: add construction code here
myXmin=0;
myYmin=0;
myXmax=0;
myYmax=0;
myCurZoom=0;
myWidth=0;
myHeight=0;
scaleX = 1;
scaleY = 1;
scaleZ = 1;
myAxisKey = 0;
myScaleDirection = 0;
myVisMode = VIS_SHADE;
// will be set in OnInitial update, but, for more security :
myCurrentMode = CurAction3d_Nothing;
myDegenerateModeIsOn=Standard_True;
m_Pen = NULL;
NbActiveLights=2; // There are 2 default active lights
myGraphicDriver = Handle(Graphic3d_GraphicDriver)::DownCast(
((CViewer3dApp*)AfxGetApp())->GetGraphicDevice()->GraphicDriver() );
}
CViewer3dView::~CViewer3dView()
{
myView->Remove();
if (m_Pen) delete m_Pen;
}
BOOL CViewer3dView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CViewer3dView drawing
void CViewer3dView::OnInitialUpdate()
{
CView::OnInitialUpdate();
myView = GetDocument()->GetViewer()->CreateView();
// set the default mode in wireframe ( not hidden line ! )
myView->SetDegenerateModeOn();
// store for restore state after rotation (witch is in Degenerated mode)
myDegenerateModeIsOn = Standard_True;
Handle(Graphic3d_WNTGraphicDevice) theGraphicDevice =
((CViewer3dApp*)AfxGetApp())->GetGraphicDevice();
Handle(WNT_Window) aWNTWindow = new WNT_Window(theGraphicDevice,GetSafeHwnd ());
myView->SetWindow(aWNTWindow);
if (!aWNTWindow->IsMapped()) aWNTWindow->Map();
// Standard_Integer w=100 , h=100 ; /* Debug Matrox */
// aWNTWindow->Size (w,h) ; /* Keeps me unsatisfied (rlb)..... */
/* Resize is not supposed to be done on */
/* Matrox */
/* I suspect another problem elsewhere */
// ::PostMessage ( GetSafeHwnd () , WM_SIZE , SIZE_RESTORED , w + h*65536 ) ;
// store the mode ( nothing , dynamic zooming, dynamic ... )
myCurrentMode = CurAction3d_Nothing;
myVisMode = VIS_SHADE;
RedrawVisMode();
}
void CViewer3dView::OnDraw(CDC* pDC)
{
CViewer3dDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CRect aRect;
GetWindowRect(aRect);
if(myWidth != aRect.Width() || myHeight != aRect.Height()) {
myWidth = aRect.Width();
myHeight = aRect.Height();
::PostMessage ( GetSafeHwnd () , WM_SIZE , SW_SHOW , myWidth + myHeight*65536 );
}
myView->Redraw();
}
/////////////////////////////////////////////////////////////////////////////
// CViewer3dView diagnostics
#ifdef _DEBUG
void CViewer3dView::AssertValid() const
{
CView::AssertValid();
}
void CViewer3dView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CViewer3dDoc* CViewer3dView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CViewer3dDoc)));
return (CViewer3dDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CViewer3dView message handlers
gp_Pnt ConvertClickToPoint(Standard_Real x, Standard_Real y, Handle(V3d_View) aView)
{
V3d_Coordinate XEye,YEye,ZEye,XAt,YAt,ZAt;
aView->Eye(XEye,YEye,ZEye);
aView->At(XAt,YAt,ZAt);
gp_Pnt EyePoint(XEye,YEye,ZEye);
gp_Pnt AtPoint(XAt,YAt,ZAt);
gp_Vec EyeVector(EyePoint,AtPoint);
gp_Dir EyeDir(EyeVector);
gp_Pln PlaneOfTheView = gp_Pln(AtPoint,EyeDir);
Standard_Real X,Y,Z;
aView->Convert(int(x),int(y),X,Y,Z);
gp_Pnt ConvertedPoint(X,Y,Z);
gp_Pnt2d ConvertedPointOnPlane = ProjLib::Project(PlaneOfTheView,ConvertedPoint);
gp_Pnt ResultPoint = ElSLib::Value(ConvertedPointOnPlane.X(),
ConvertedPointOnPlane.Y(),
PlaneOfTheView);
return ResultPoint;
}
void CViewer3dView::OnSize(UINT nType, int cx, int cy)
{
if (!myView.IsNull())
myView->MustBeResized();
}
void CViewer3dView::OnBUTTONBack()
{
myView->SetProj(V3d_Xneg);
TCollection_AsciiString Message("\
myView->SetProj(V3d_Xneg);\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetProj",Message);
} // See the back View
void CViewer3dView::OnBUTTONFront()
{
myView->SetProj(V3d_Xpos);
TCollection_AsciiString Message("\
myView->SetProj(V3d_Xpos);\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetProj",Message);
} // See the front View
void CViewer3dView::OnBUTTONBottom()
{
myView->SetProj(V3d_Zneg);
TCollection_AsciiString Message("\
myView->SetProj(V3d_Zneg);\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetProj",Message);
} // See the bottom View
void CViewer3dView::OnBUTTONTop()
{
myView->SetProj(V3d_Zpos);
TCollection_AsciiString Message("\
myView->SetProj(V3d_Zpos);\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetProj",Message);
} // See the top View
void CViewer3dView::OnBUTTONLeft()
{
myView->SetProj(V3d_Ypos);
TCollection_AsciiString Message("\
myView->SetProj(V3d_Ypos);\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetProj",Message);
} // See the left View
void CViewer3dView::OnBUTTONRight()
{
myView->SetProj(V3d_Yneg);
TCollection_AsciiString Message("\
myView->SetProj(V3d_Yneg);\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetProj",Message);
} // See the right View
void CViewer3dView::OnBUTTONAxo()
{
myView->SetProj(V3d_XposYnegZpos);
TCollection_AsciiString Message("\
myView->SetProj(V3d_XposYnegZpos);\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetProj",Message);
} // See the axonometric View
void CViewer3dView::OnBUTTONHlrOff()
{
myView->SetDegenerateModeOn();
myDegenerateModeIsOn = Standard_True;
TCollection_AsciiString Message("\
myView->SetDegenerateModeOn();\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetDegenerateModeOn",Message);
}
void CViewer3dView::OnBUTTONHlrOn()
{
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
myView->SetDegenerateModeOff();
myDegenerateModeIsOn = Standard_False;
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
TCollection_AsciiString Message("\
myView->SetDegenerateModeOff();\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetDegenerateModeOff",Message);
}
void CViewer3dView::OnBUTTONPan()
{ myCurrentMode = CurAction3d_DynamicPanning; }
void CViewer3dView::OnBUTTONPanGlo()
{
// save the current zoom value
myCurZoom = myView->Scale();
// Do a Global Zoom
myView->FitAll();
// Set the mode
myCurrentMode = CurAction3d_GlobalPanning;
}
void CViewer3dView::OnBUTTONReset()
{ myView->Reset(); }
void CViewer3dView::OnBUTTONRot()
{ myCurrentMode = CurAction3d_DynamicRotation; }
void CViewer3dView::OnBUTTONZoomAll()
{
myView->FitAll();
myView->ZFitAll();
}
void CViewer3dView::OnBUTTONZoomProg()
{ myCurrentMode = CurAction3d_DynamicZooming; }
void CViewer3dView::OnBUTTONZoomWin()
{ myCurrentMode = CurAction3d_WindowZooming; }
void CViewer3dView::OnLButtonDown(UINT nFlags, CPoint point)
{
// save the current mouse coordinate in min
myXmin=point.x; myYmin=point.y;
myXmax=point.x; myYmax=point.y;
if ( nFlags & MK_CONTROL )
{
// Button MB1 down Control :start zomming
// SetCursor(AfxGetApp()->LoadStandardCursor());
}
else // if ( Ctrl )
{
switch (myCurrentMode)
{
case CurAction3d_Nothing : // start a drag
if (nFlags & MK_SHIFT)
GetDocument()->ShiftDragEvent(myXmax,myYmax,-1,myView);
else
GetDocument()->DragEvent(myXmax,myYmax,-1,myView);
break;
break;
case CurAction3d_DynamicZooming : // noting
break;
case CurAction3d_WindowZooming :
break;
case CurAction3d_DynamicPanning :// noting
break;
case CurAction3d_GlobalPanning :// noting
break;
case CurAction3d_DynamicRotation :
if (!myDegenerateModeIsOn)
myView->SetDegenerateModeOn();
myView->StartRotation(point.x,point.y);
break;
case CurAction3d_BeginPositionalLight :
{
p1 = ConvertClickToPoint(point.x,point.y,myView);
myCurrent_PositionalLight->SetPosition(p1.X(),p1.Y(),p1.Z()) ;
GetDocument()->GetAISContext()->CloseLocalContext();
((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Ready");
myCurrentMode = CurAction3d_Nothing;
TCollection_AsciiString Message("\
myCurrent_PositionalLight->SetPosition(Xp, Yp, Zp) ;\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetPosition",Message);
}
break;
case CurAction3d_BeginSpotLight :
{
p1 = ConvertClickToPoint(point.x,point.y,myView);
myCurrent_SpotLight = new V3d_SpotLight(myView->Viewer(),0.,0.,1., p1.X(),p1.Y(),p1.Z(),Quantity_NOC_RED);
myView->SetLightOn(myCurrent_SpotLight);
NbActiveLights++;
p2 = gp_Pnt(p1.X(),p1.Y(),p1.Z()+1.);
Standard_Real coneHeigth=p1.Distance(p2);
BRepPrimAPI_MakeCone MakeCone(gp_Ax2(p1, gp_Dir(gp_Vec(p1, p2))),
0, (p1.Distance(p2))/tan(1.04), coneHeigth);
spotConeShape->Set(MakeCone.Solid());
GetDocument()->GetAISContext()->Display(spotConeShape,0,-1);
((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick the target point");
myCurrentMode = CurAction3d_TargetSpotLight;
TCollection_AsciiString Message("\
myCurrent_SpotLight->SetDirection(Xv, Yv, Zv);\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetDirection",Message);
}
break;
case CurAction3d_TargetSpotLight :
{
p2 = ConvertClickToPoint(point.x,point.y,myView);
((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick a third point (to define the angle)");
myCurrentMode = CurAction3d_EndSpotLight;
TCollection_AsciiString Message("\
myCurrent_SpotLight->SetAngle(Angle) ;\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetAngle",Message);
}
break;
case CurAction3d_EndSpotLight :
GetDocument()->GetAISContext()->Erase(spotConeShape);
GetDocument()->GetAISContext()->CloseLocalContext();
((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Ready");
myCurrentMode = CurAction3d_Nothing;
break;
case CurAction3d_BeginDirectionalLight:
{
p1 = ConvertClickToPoint(point.x,point.y,myView);
p2 = gp_Pnt(p1.X(),p1.Y(),p1.Z()+1.);
BRepBuilderAPI_MakeEdge MakeEdge(p1, p2);
directionalEdgeShape->Set(MakeEdge.Edge());
GetDocument()->GetAISContext()->Display(directionalEdgeShape,0,-1);
// Create a directional light
myCurrent_DirectionalLight = new V3d_DirectionalLight(myView->Viewer(), p1.X(),p1.Y(),p1.Z(),0.,0.,1.);
myView->SetLightOn(myCurrent_DirectionalLight);
NbActiveLights++;
((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick the target point");
myCurrentMode = CurAction3d_EndDirectionalLight;
TCollection_AsciiString Message("\
myCurrent_DirectionalLight->SetDirection(Xv, Yv, Zv);\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetDirection",Message);
}
break;
case CurAction3d_EndDirectionalLight:
GetDocument()->GetAISContext()->Erase(directionalEdgeShape);
GetDocument()->GetAISContext()->CloseLocalContext();
((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Ready");
myCurrentMode = CurAction3d_Nothing;
break;
}
}
}
void CViewer3dView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if( nChar == X_Key || nChar == Y_Key || nChar == Z_Key )
myAxisKey = nChar;
else if( (nChar == VK_ADD || nChar == VK_SUBTRACT) && myAxisKey )
{
myScaleDirection = nChar;
if( myAxisKey && myScaleDirection )
{
switch( myAxisKey )
{
case X_Key:
if( myScaleDirection == VK_ADD ) scaleX ++;
if( myScaleDirection == VK_SUBTRACT ) scaleX --;
break;
case Y_Key:
if( myScaleDirection == VK_ADD ) scaleY ++;
if( myScaleDirection == VK_SUBTRACT ) scaleY --;
break;
case Z_Key:
if( myScaleDirection == VK_ADD ) scaleZ ++;
if( myScaleDirection == VK_SUBTRACT ) scaleZ --;
break;
default:
break;
}
if( scaleX < 1 ) scaleX = 1;
if( scaleY < 1 ) scaleY = 1;
if( scaleZ < 1 ) scaleZ = 1;
myView->SetAxialScale( scaleX, scaleY, scaleZ );
}
}
}
void CViewer3dView::OnLButtonUp(UINT nFlags, CPoint point)
{
if ( nFlags & MK_CONTROL )
{
return;
}
else // if ( Ctrl )
{
switch (myCurrentMode)
{
case CurAction3d_Nothing :
if (point.x == myXmin && point.y == myYmin)
{ // no offset between down and up --> selectEvent
myXmax=point.x;
myYmax=point.y;
if (nFlags & MK_SHIFT )
GetDocument()->ShiftInputEvent(point.x,point.y,myView);
else
GetDocument()->InputEvent (point.x,point.y,myView);
} else
{
DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False);
myXmax=point.x;
myYmax=point.y;
if (nFlags & MK_SHIFT)
GetDocument()->ShiftDragEvent(point.x,point.y,1,myView);
else
GetDocument()->DragEvent(point.x,point.y,1,myView);
}
break;
case CurAction3d_DynamicZooming :
// SetCursor(AfxGetApp()->LoadStandardCursor());
myCurrentMode = CurAction3d_Nothing;
break;
case CurAction3d_WindowZooming :
DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False);
myXmax=point.x;
myYmax=point.y;
if ((abs(myXmin-myXmax)>ValZWMin) || (abs(myYmin-myYmax)>ValZWMin))
// Test if the zoom window is greater than a minimale window.
{
// Do the zoom window between Pmin and Pmax
myView->WindowFitAll(myXmin,myYmin,myXmax,myYmax);
}
myCurrentMode = CurAction3d_Nothing;
break;
case CurAction3d_DynamicPanning :
myCurrentMode = CurAction3d_Nothing;
break;
case CurAction3d_GlobalPanning :
myView->Place(point.x,point.y,myCurZoom);
myCurrentMode = CurAction3d_Nothing;
break;
case CurAction3d_DynamicRotation :
myCurrentMode = CurAction3d_Nothing;
break;
} //switch (myCurrentMode)
} // else // if ( Ctrl )
}
void CViewer3dView::OnMButtonDown(UINT nFlags, CPoint point)
{
if ( nFlags & MK_CONTROL )
{
// Button MB2 down Control : panning init
// SetCursor(AfxGetApp()->LoadStandardCursor());
}
}
void CViewer3dView::OnMButtonUp(UINT nFlags, CPoint point)
{
if ( nFlags & MK_CONTROL )
{
// Button MB2 down Control : panning init
// SetCursor(AfxGetApp()->LoadStandardCursor());
}
}
void CViewer3dView::OnRButtonDown(UINT nFlags, CPoint point)
{
if ( nFlags & MK_CONTROL )
{
// SetCursor(AfxGetApp()->LoadStandardCursor());
if (!myDegenerateModeIsOn)
myView->SetDegenerateModeOn();
myView->StartRotation(point.x,point.y);
}
else // if ( Ctrl )
{
GetDocument()->Popup(point.x,point.y,myView);
}
}
void CViewer3dView::OnRButtonUp(UINT nFlags, CPoint point)
{
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
if (!myDegenerateModeIsOn)
{
myView->SetDegenerateModeOff();
myDegenerateModeIsOn = Standard_False;
} else
{
myView->SetDegenerateModeOn();
myDegenerateModeIsOn = Standard_True;
}
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
}
void CViewer3dView::OnMouseMove(UINT nFlags, CPoint point)
{
// ============================ LEFT BUTTON =======================
if ( nFlags & MK_LBUTTON)
{
if ( nFlags & MK_CONTROL )
{
// move with MB1 and Control : on the dynamic zooming
// Do the zoom in function of mouse's coordinates
myView->Zoom(myXmax,myYmax,point.x,point.y);
// save the current mouse coordinate in min
myXmax = point.x;
myYmax = point.y;
}
else // if ( Ctrl )
{
switch (myCurrentMode)
{
case CurAction3d_Nothing :
myXmax = point.x; myYmax = point.y;
DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False);
if (nFlags & MK_SHIFT)
GetDocument()->ShiftDragEvent(myXmax,myYmax,0,myView);
else
GetDocument()->DragEvent(myXmax,myYmax,0,myView);
DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_True);
break;
case CurAction3d_DynamicZooming :
myView->Zoom(myXmax,myYmax,point.x,point.y);
// save the current mouse coordinate in min \n";
myXmax=point.x; myYmax=point.y;
break;
case CurAction3d_WindowZooming :
myXmax = point.x; myYmax = point.y;
DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False,LongDash);
DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_True,LongDash);
break;
case CurAction3d_DynamicPanning :
myView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
myXmax = point.x; myYmax = point.y;
break;
case CurAction3d_GlobalPanning : // nothing
break;
case CurAction3d_DynamicRotation :
myView->Rotation(point.x,point.y);
myView->Redraw();
break;
}// switch (myCurrentMode)
}// if ( nFlags & MK_CONTROL ) else
} else // if ( nFlags & MK_LBUTTON)
// ============================ MIDDLE BUTTON =======================
if ( nFlags & MK_MBUTTON)
{
if ( nFlags & MK_CONTROL )
{
myView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
myXmax = point.x; myYmax = point.y;
}
} else // if ( nFlags & MK_MBUTTON)
// ============================ RIGHT BUTTON =======================
if ( nFlags & MK_RBUTTON)
{
if ( nFlags & MK_CONTROL )
{
myView->Rotation(point.x,point.y);
}
}else //if ( nFlags & MK_RBUTTON)
// ============================ NO BUTTON =======================
{ // No buttons
myXmax = point.x; myYmax = point.y;
if (myCurrentMode == CurAction3d_EndDirectionalLight)
{
p2 = ConvertClickToPoint(point.x,point.y,myView);
//Update the light dynamically
if( p1.Distance(p2)>Precision::Confusion())
{
BRepBuilderAPI_MakeEdge MakeEdge(p1, p2);
directionalEdgeShape->Set(MakeEdge.Edge());
GetDocument()->GetAISContext()->Redisplay(directionalEdgeShape,0,-1);
myCurrent_DirectionalLight->SetDirection(p2.X()-p1.X(),p2.Y()-p1.Y(),p2.Z()-p1.Z());
myView->UpdateLights();
}
}
else if (myCurrentMode == CurAction3d_BeginPositionalLight)
{
p2 = ConvertClickToPoint(point.x,point.y,myView);
//Update the light dynamically
myCurrent_PositionalLight->SetPosition(p2.X(),p2.Y(),p2.Z());
myView->UpdateLights();
}
else if (myCurrentMode == CurAction3d_TargetSpotLight)
{
p2 = ConvertClickToPoint(point.x,point.y,myView);
//Update the light dynamically
Standard_Real coneHeigth=p1.Distance(p2);
if( coneHeigth>Precision::Confusion())
{
BRepPrimAPI_MakeCone MakeCone(gp_Ax2(p1, gp_Dir(gp_Vec(p1, p2))),
0, (p1.Distance(p2))/tan(1.04), coneHeigth);
spotConeShape->Set(MakeCone.Solid());
GetDocument()->GetAISContext()->Redisplay(spotConeShape,0,-1);
myCurrent_SpotLight->SetDirection(p2.X()-p1.X(),p2.Y()-p1.Y(),p2.Z()-p1.Z());
myView->UpdateLights();
}
}
else if (myCurrentMode == CurAction3d_EndSpotLight)
{
p3 = ConvertClickToPoint(point.x,point.y,myView);
//Update the light dynamically
Standard_Real coneHeigth=p1.Distance(p2);
if( (p2.Distance(p3))>Precision::Confusion())
{
BRepPrimAPI_MakeCone MakeCone(gp_Ax2(p1, gp_Dir(gp_Vec(p1, p2))),
0, p2.Distance(p3), coneHeigth);
spotConeShape->Set(MakeCone.Solid());
GetDocument()->GetAISContext()->Redisplay(spotConeShape,0,-1);
myCurrent_SpotLight->SetAngle(atan(p2.Distance(p3)/p1.Distance(p2))) ;
myView->UpdateLights();
}
}
if (nFlags & MK_SHIFT)
GetDocument()->ShiftMoveEvent(point.x,point.y,myView);
else
GetDocument()->MoveEvent(point.x,point.y,myView);
}
}
void CViewer3dView::OnUpdateBUTTONHlrOff(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck (myDegenerateModeIsOn);
pCmdUI->Enable (!myDegenerateModeIsOn);
}
void CViewer3dView::OnUpdateBUTTONHlrOn(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck (!myDegenerateModeIsOn);
pCmdUI->Enable (myDegenerateModeIsOn);
}
void CViewer3dView::OnUpdateBUTTONPanGlo(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck (myCurrentMode == CurAction3d_GlobalPanning);
pCmdUI->Enable (myCurrentMode != CurAction3d_GlobalPanning);
}
void CViewer3dView::OnUpdateBUTTONPan(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicPanning);
pCmdUI->Enable (myCurrentMode != CurAction3d_DynamicPanning );
}
void CViewer3dView::OnUpdateBUTTONZoomProg(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicZooming );
pCmdUI->Enable (myCurrentMode != CurAction3d_DynamicZooming);
}
void CViewer3dView::OnUpdateBUTTONZoomWin(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck (myCurrentMode == CurAction3d_WindowZooming);
pCmdUI->Enable (myCurrentMode != CurAction3d_WindowZooming);
}
void CViewer3dView::OnUpdateBUTTONRot(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck (myCurrentMode == CurAction3d_DynamicRotation);
pCmdUI->Enable (myCurrentMode != CurAction3d_DynamicRotation);
}
void CViewer3dView::DrawRectangle(const Standard_Integer MinX ,
const Standard_Integer MinY ,
const Standard_Integer MaxX ,
const Standard_Integer MaxY ,
const Standard_Boolean Draw ,
const LineStyle aLineStyle)
{
static int m_DrawMode;
if (!m_Pen && aLineStyle ==Solid )
{m_Pen = new CPen(PS_SOLID, 1, RGB(0,0,0)); m_DrawMode = R2_MERGEPENNOT;}
else if (!m_Pen && aLineStyle ==Dot )
{m_Pen = new CPen(PS_DOT, 1, RGB(0,0,0)); m_DrawMode = R2_XORPEN;}
else if (!m_Pen && aLineStyle == ShortDash)
{m_Pen = new CPen(PS_DASH, 1, RGB(255,0,0)); m_DrawMode = R2_XORPEN;}
else if (!m_Pen && aLineStyle == LongDash)
{m_Pen = new CPen(PS_DASH, 1, RGB(0,0,0)); m_DrawMode = R2_NOTXORPEN;}
else if (aLineStyle == Default)
{ m_Pen = NULL; m_DrawMode = R2_MERGEPENNOT;}
CPen* aOldPen;
CClientDC clientDC(this);
if (m_Pen) aOldPen = clientDC.SelectObject(m_Pen);
clientDC.SetROP2(m_DrawMode);
static Standard_Integer StoredMinX, StoredMaxX, StoredMinY, StoredMaxY;
static Standard_Boolean m_IsVisible;
if ( m_IsVisible && !Draw) // move or up : erase at the old position
{
clientDC.MoveTo(StoredMinX,StoredMinY);
clientDC.LineTo(StoredMinX,StoredMaxY);
clientDC.LineTo(StoredMaxX,StoredMaxY);
clientDC.LineTo(StoredMaxX,StoredMinY);
clientDC.LineTo(StoredMinX,StoredMinY);
m_IsVisible = false;
}
StoredMinX = min ( MinX, MaxX );
StoredMinY = min ( MinY, MaxY );
StoredMaxX = max ( MinX, MaxX );
StoredMaxY = max ( MinY, MaxY);
if (Draw) // move : draw
{
clientDC.MoveTo(StoredMinX,StoredMinY);
clientDC.LineTo(StoredMinX,StoredMaxY);
clientDC.LineTo(StoredMaxX,StoredMaxY);
clientDC.LineTo(StoredMaxX,StoredMinY);
clientDC.LineTo(StoredMinX,StoredMinY);
m_IsVisible = true;
}
if (m_Pen)
clientDC.SelectObject(aOldPen);
}
void CViewer3dView::OnModifyChangeBackground()
{
Standard_Real R1;
Standard_Real G1;
Standard_Real B1;
myView->BackgroundColor(Quantity_TOC_RGB,R1,G1,B1);
COLORREF m_clr ;
m_clr = RGB(R1*255,G1*255,B1*255);
CColorDialog dlgColor(m_clr);
if (dlgColor.DoModal() == IDOK)
{
m_clr = dlgColor.GetColor();
R1 = GetRValue(m_clr)/255.;
G1 = GetGValue(m_clr)/255.;
B1 = GetBValue(m_clr)/255.;
myView->SetBackgroundColor(Quantity_TOC_RGB,R1,G1,B1);
}
myView->Redraw();
}
void CViewer3dView::OnDirectionalLight()
{
// Directional light source creation
// Checking if the Active lights limit number is not reached
if( NbActiveLights>=myGraphicDriver->InquireLightLimit() )
{
char tmpStr[128];
sprintf_s(tmpStr, "You have reach the limit number of active lights (%d).\n Clear lights to create new ones.",
myGraphicDriver->InquireLightLimit());
MessageBox(tmpStr,"Light creation", MB_OK);
return;
}
UpdateData(TRUE);
((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick a first point");
GetDocument()->GetAISContext()->OpenLocalContext();
myCurrentMode = CurAction3d_BeginDirectionalLight;
TCollection_AsciiString Message("\
myCurrent_DirectionalLight = new V3d_DirectionalLight(myView->Viewer(), Xt, Yt, Zt, Xp, Yp, Zp);\n\
\n\
myView->SetLightOn(myCurrent_DirectionalLight);\n\
\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("V3d_DirectionalLight",Message);
}
void CViewer3dView::OnSpotLight()
{
// Spot light source creation
// Checking if the Active lights limit number is not reached
if( NbActiveLights>=myGraphicDriver->InquireLightLimit() )
{
char tmpStr[128];
sprintf_s(tmpStr, "You have reach the limit number of active lights (%d).\n Clear lights to create new ones.",
myGraphicDriver->InquireLightLimit());
MessageBox(tmpStr,"Light creation", MB_OK);
return;
}
GetDocument()->GetAISContext()->OpenLocalContext();
((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick the light position");
myCurrentMode = CurAction3d_BeginSpotLight;
TCollection_AsciiString Message("\
myCurrent_SpotLight = new V3d_SpotLight(myView->Viewer(), Xt, Yt, Zt, Xp, Yp, Zp,Quantity_NOC_RED);\n\
\n\
myView->SetLightOn(myCurrent_SpotLight);\n\
\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("V3d_SpotLight",Message);
}
void CViewer3dView::OnPositionalLight()
{
// Positional light source creation
// Checking if the Active lights limit number is not reached
if( NbActiveLights>=myGraphicDriver->InquireLightLimit() )
{
char tmpStr[128];
sprintf_s(tmpStr, "You have reach the limit number of active lights (%d).\n Clear lights to create new ones.",
myGraphicDriver->InquireLightLimit());
MessageBox(tmpStr,"Light creation", MB_OK);
return;
}
GetDocument()->GetAISContext()->OpenLocalContext();
myCurrent_PositionalLight=new V3d_PositionalLight(myView->Viewer(),0,0,0,Quantity_NOC_GREEN,1,0);
myView->SetLightOn(myCurrent_PositionalLight);
NbActiveLights++;
((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick the light position");
myCurrentMode = CurAction3d_BeginPositionalLight;
TCollection_AsciiString Message("\
myCurrent_PositionalLight=new V3d_PositionalLight(myView->Viewer(),Xp, Yp, Zp,Quantity_NOC_GREEN,1,0);\n\
\n\
myView->SetLightOn(myCurrent_PositionalLight) ;\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("V3d_PositionalLight",Message);
}
void CViewer3dView::OnAmbientLight()
{
// Ambiant light source creation
// Checking if the Active lights limit number is not reached
if( NbActiveLights>=myGraphicDriver->InquireLightLimit() )
{
char tmpStr[128];
sprintf_s(tmpStr, "You have reach the limit number of active lights (%d).\n Clear lights to create new ones.",
myGraphicDriver->InquireLightLimit());
MessageBox(tmpStr,"Light creation", MB_OK);
return;
}
GetDocument()->GetAISContext()->OpenLocalContext();
myCurrent_AmbientLight=new V3d_AmbientLight(myView->Viewer(), Quantity_NOC_GRAY);
myView->SetLightOn(myCurrent_AmbientLight) ;
NbActiveLights++;
GetDocument()->GetAISContext()->CloseLocalContext();
myView->UpdateLights();
TCollection_AsciiString Message("\
myCurrent_AmbientLight=new V3d_AmbientLight(myView->Viewer(), Quantity_NOC_GRAY);\n\
\n\
myView->SetLightOn(myCurrent_AmbientLight) ;\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("V3d_AmbientLight",Message);
}
void CViewer3dView::OnScale()
{
ScaleDlg Dlg(myView, this);
Dlg.DoModal();
myView->Redraw();
}
void CViewer3dView::OnZcueing()
{
ZCueingDlg Dlg(myView, GetDocument());
Dlg.DoModal();
myView->Redraw();
}
void CViewer3dView::OnZclipping()
{
ZClippingDlg Dlg(myView, GetDocument());
Dlg.DoModal();
myView->Redraw();
}
//V3d_View.hxx
void CViewer3dView::OnShadingmodel()
{
TCollection_AsciiString Message("\
myView->SetShadingModel(V3d_TypeOfShadingModel myTypeOfShadingModel);\n\
\n\
myCurrent_V3d_View->Update();\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetShadingModel",Message);
CShadingModelDlg Dlg(myView);
Dlg.DoModal();
myView->Redraw();
}
void CViewer3dView::OnAntialiasingonoff()
{
if(!myView->Antialiasing())
myView->SetAntialiasingOn();
else
myView->SetAntialiasingOff();
myView->Update();
TCollection_AsciiString Message("\
if(!myView->Antialiasing())\n\
myView->SetAntialiasingOn();\n\
else\n\
myView->SetAntialiasingOff();\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetAntialiasingOn/SetAntialiasingOff",Message);
}
void CViewer3dView::OnClearLights()
{
// Setting Off all viewer active lights
TColStd_ListOfTransient lights;
for(myView->Viewer()->InitActiveLights(); myView->Viewer()->MoreActiveLights(); myView->Viewer()->NextActiveLights())
{
lights.Append(myView->Viewer()->ActiveLight());
}
TColStd_ListIteratorOfListOfTransient itrLights(lights);
for (; itrLights.More(); itrLights.Next())
{
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());
myView->Viewer()->SetLightOff(light);
}
// Setting Off all view active lights
lights.Clear();
for(myView->InitActiveLights(); myView->MoreActiveLights(); myView->NextActiveLights())
{
lights.Append(myView->ActiveLight());
}
itrLights.Initialize(lights);
for (; itrLights.More(); itrLights.Next())
{
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());
myView->SetLightOff(light);
}
myView->Viewer()->SetDefaultLights();// Setting the default lights on
NbActiveLights = 2;// There are 2 default active lights
myView->Update();
TCollection_AsciiString Message("\
// Setting Off all viewer active lights\n\
TColStd_ListOfTransient lights;\n\
for(myView->Viewer()->InitActiveLights(); myView->Viewer()->MoreActiveLights(); myView->Viewer()->NextActiveLights())\n\
{\n\
lights.Append(myView->Viewer()->ActiveLight());\n\
}\n\
TColStd_ListIteratorOfListOfTransient itrLights(lights);\n\
for (; itrLights.More(); itrLights.Next())\n\
{\n\
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());\n\
myView->Viewer()->SetLightOff(light);\n\
}\n\
\n\
// Setting Off all view active lights\n\
lights.Clear();\n\
for(myView->InitActiveLights(); myView->MoreActiveLights(); myView->NextActiveLights())\n\
{\n\
lights.Append(myView->ActiveLight());\n\
}\n\
itrLights.Initialize(lights);\n\
for (; itrLights.More(); itrLights.Next())\n\
{\n\
Handle(V3d_Light) light = Handle(V3d_Light)::DownCast(itrLights.Value());\n\
myView->SetLightOff(light);\n\
}\n\
\n\
myView->Viewer()->SetDefaultLights();// Setting the default lights on\n\
");
// Update The Result Message Dialog
GetDocument()->UpdateResultMessageDlg("SetLightOff",Message);
}
void CViewer3dView::OnModelclipping()
{
if( myPlane.IsNull() )
{
//creates a plane defined : center of the box ( 50,50,50) and 1 direction
gp_Pln tmpPln(gp_Pnt(0,0,0),gp_Dir(1,0,0));
//getting the coefficients of the gp_Pln ( ax+by+cz+d = 0 )
Standard_Real A,B,C,D;
tmpPln.Coefficients(A,B,C,D);
//with these coefficients, creating a V3d_Plane
myPlane = new V3d_Plane(A,B,C,D);
// GetDocument()->GetViewer(),A,B,C,D);
//creates the Face
//NOTE : the face must be behind the clipping plane !!
tmpPln = gp_Pln(gp_Pnt(0.1,0,0),gp_Dir(1,0,0));
BRepBuilderAPI_MakeFace MakeFace(tmpPln, 200, -200, 410, -410);
TopoDS_Face S = MakeFace.Face();
//display the face
myShape = new AIS_Shape(S);
}
CModelClippingDlg Dlg(myView, myPlane, myShape, GetDocument());
Dlg.DoModal();
}
void CViewer3dView::OnOptionsTrihedronStaticTrihedron()
{
CTrihedronDlg Dlg(myView, GetDocument());
Dlg.DoModal();
}
void CViewer3dView::InitButtons()
{
myXmin=0;
myYmin=0;
myXmax=0;
myYmax=0;
myCurZoom=0;
myCurrentMode = CurAction3d_Nothing;
}
void CViewer3dView::Reset()
{
InitButtons();
myVisMode = VIS_SHADE;
if (!myView.IsNull())
{
RedrawVisMode();
myView->Reset();
}
}
void CViewer3dView::GetViewCenter(V3d_Coordinate& Xc, V3d_Coordinate& Yc)
{
myView->Center(Xc,Yc);
}
void CViewer3dView::SetViewCenter(V3d_Coordinate Xc, V3d_Coordinate Yc)
{
myView->SetCenter(Xc,Yc);
}
void CViewer3dView::GetViewEye(V3d_Coordinate& X, V3d_Coordinate& Y, V3d_Coordinate& Z)
{
myView->Eye(X,Y,Z);
}
void CViewer3dView::SetViewEye(V3d_Coordinate X, V3d_Coordinate Y, V3d_Coordinate Z)
{
myView->SetEye(X,Y,Z);
}
Quantity_Factor CViewer3dView::GetViewScale()
{
return myView->Scale();
}
void CViewer3dView::SetViewScale(Quantity_Factor Coef)
{
myView->SetScale(Coef);
}
void CViewer3dView::RedrawVisMode()
{
switch (myVisMode)
{
case VIS_WIREFRAME:
GetDocument()->GetAISContext()->SetDisplayMode(AIS_WireFrame);
myView->SetComputedMode (Standard_False);
break;
case VIS_SHADE:
GetDocument()->GetAISContext()->SetDisplayMode(AIS_Shaded);
myView->SetComputedMode (Standard_False);
break;
case VIS_HLR:
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
myView->SetComputedMode (Standard_True);
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
GetDocument()->GetAISContext()->SetDisplayMode(AIS_WireFrame);
break;
}
}