|
Implement the 3D view window in a Dialog with OpenCascade
【Preview】

【Motivation】
In my application about simulation on the Real Structure Elements in a construction, the calculation of some parameters is the mainly task which will be solved by the 3D graphic boolean method with Opencascade SDK. However, the white-box test unit should be established before the main module.
First, I think that the visual tools like the a dialog or a window will be helpful to check the boolean arithmetic in my application. Second, a window OCX or light-weight visual tool is mascara for the future.
【Design Item】
A window class “C3DWnd” is designed for disaplaying the Simulated Elements using in the main module. And a instance of the C3DWnd is aggregated in a Dialog class. Based the Idea of the Component, C3DWnd is nested in a DLL module which can be encapsulated as an OCX. On the other hand the “Dialog class” is nested in another module as an “exe file”.
【Code Background】
System: Window XP,sp1;
Compiler: Visual C++ 6.0,sp6;
SDK: Opencascade 5.1;
【Detail】
1、C3DWnd class
// 3DWnd.h : header file
//
#include <V3d_View.hxx>
#include <TPrsStd_AISViewer.hxx>
#include <Graphic3d_WNTGraphicDevice.hxx>
#include <AIS_InteractiveContext.hxx>
#include <WNT_Window.hxx>
#include <Handle_V3d_PositionalLight.hxx>
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#undef DLLIMPEXP
#ifdef _3DViewDLL_
#define DLLIMPEXP __declspec(dllexport)
#else
#define DLLIMPEXP
#endif
/////////////////////////////////////////////////////////////////////////////
// C3DWnd window
enum View3D_CurrentAction {
CurAction3d_Nothing,
CurAction3d_DynamicZooming,
CurAction3d_WindowZooming,
CurAction3d_DynamicPanning,
CurAction3d_GlobalPanning,
CurAction3d_DynamicRotation,
CurAction3d_BeginSpotLight,
CurAction3d_TargetSpotLight,
CurAction3d_EndSpotLight,
CurAction3d_BeginPositionalLight,
CurAction3d_BeginDirectionalLight,
CurAction3d_EndDirectionalLight
};
class __declspec(dllexport) C3DWnd : public CWnd
{
// Construction
public:
C3DWnd();
// Attributes
public:
enum LineStyle { Solid, Dot, ShortDash, LongDash, Default };
// Operations
public:
virtual void DrawRectangle (const Standard_Integer MinX ,
const Standard_Integer MinY ,
const Standard_Integer MaxX ,
const Standard_Integer MaxY ,
const Standard_Boolean Draw ,
const LineStyle aLineStyle = Default );
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(C3DWnd)
public:
//}}AFX_VIRTUAL
// Implementation
public:
void ShowFace(unsigned long nFaceID);
void ShowSolid(const int nID);
void DispplayText();
void DisplayAxis();
void Refresh();
void Clear();
void Right();
void Top();
void Left();
void Front();
void Bottom();
void Back();
void Axo();
void HideOff();
void HideOn();
void Rotate();
void PanGlobal();
void Pan();
void ZoomProg();
void ZoomWin();
void ZoolAll();
void ShowVolume();
virtual ~C3DWnd();
// Generated message map functions
protected:
//{{AFX_MSG(C3DWnd)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnPaint();
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
//画鼠标拉框用的笔:
CPen* m_pPen;
//3D视图指针:
Handle_V3d_View m_pView;
//视图容器类:
Handle_V3d_Viewer m_pViewer;
//window窗口框架:
Handle_WNT_Window m_pWNTWindow;
//选择图形和管理图形行为:
Handle_AIS_InteractiveContext m_pAISContext;
//初始化Windows NT Graphic Device:
Handle_Graphic3d_WNTGraphicDevice m_pGraphicDevice;
//位置灯光设置
Handle_V3d_PositionalLight m_pCurrent_PositionalLight;
//隐藏的标志:
Standard_Boolean m_DegenerateModeIsOn;
//当前的命令状态:
View3D_CurrentAction m_CurrentMode;
//当前缩放比例:
Quantity_Factor m_CurZoom;
//图像视图的宽度:
Standard_Real m_rWidth;
//图像视图的高度:
Standard_Real m_rHeight;
Standard_Integer m_Atx , m_Aty , m_Atz ;//
Standard_Integer m_Eyex , m_Eyey , m_Eyez ;//
};
/////////////////////////////////////////////////////////////////////////////
// 3DWnd.cpp : implementation file
//
#include "stdafx.h"
#include "3DWnd.h"
#include <AIS_ListOfInteractive.hxx>
#include <AIS_ListIteratorOfListOfInteractive.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <AIS_Trihedron.hxx>
#include <Geom_Axis2Placement.hxx>
#include "..\..\..\..\GCL7\Source\GeoCalc\ExportFunc.h"
#ifdef _DEBUG
//#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
gp_Pnt p1,p2,p3;
/////////////////////////////////////////////////////////////////////////////
// C3DWnd
Standard_Integer cXmin = 0;
Standard_Integer cYmin = 0;
Standard_Integer cXmax = 600;
Standard_Integer cYmax = 600;
Standard_Integer cZmin = 0;
Standard_Integer cZmax = 200;
Standard_Integer cZoomStep = 20;
#define ValZWMin 1
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;
}
C3DWnd::C3DWnd()
{
m_pView = NULL;
m_pViewer = NULL;
m_pAISContext = NULL;
m_pGraphicDevice = NULL;
m_pWNTWindow = NULL;
m_CurrentMode = CurAction3d_Nothing;
m_CurZoom = 0;
m_pPen = NULL;
m_DegenerateModeIsOn=Standard_True;
}
C3DWnd::~C3DWnd()
{
m_pView->Remove();
if (m_pPen != NULL)
delete m_pPen;
}
BEGIN_MESSAGE_MAP(C3DWnd, CWnd)
//{{AFX_MSG_MAP(C3DWnd)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_MOUSEWHEEL()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// C3DWnd message handlers
int C3DWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
// Creating View
try
{
m_pGraphicDevice = new Graphic3d_WNTGraphicDevice();
}
catch(Standard_Failure)
{
AfxMessageBox("Fatal Error During Graphic Initialisation");
};
m_pViewer = new V3d_Viewer(m_pGraphicDevice, (short *) (""));
m_pViewer->SetDefaultLights();
m_pViewer->SetLightOn();
// Create an interactive context based on the m_pViewer
m_pAISContext = new AIS_InteractiveContext(m_pViewer);
m_pView = m_pViewer->CreateView();
m_pView->SetDegenerateModeOn();
// store for restore state after rotation (witch is in Degenerated mode)
m_DegenerateModeIsOn = Standard_True;
// Creating new Window and attaching it to View
m_pWNTWindow = new WNT_Window(m_pGraphicDevice,GetSafeHwnd());
m_pView->SetWindow(m_pWNTWindow );
if (!m_pWNTWindow->IsMapped()) m_pWNTWindow ->Map();
DisplayAxis();
return 0;
}
void C3DWnd::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if (m_pView != NULL){
m_pView->MustBeResized();
m_pView->Size(m_rWidth, m_rHeight);
}
}
void C3DWnd::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect aRect;
GetWindowRect(aRect);
if(m_rWidth != aRect.Width() || m_rHeight != aRect.Height()) {
m_rWidth = aRect.Width();
m_rHeight = aRect.Height();
::PostMessage ( GetSafeHwnd () , WM_SIZE , SW_SHOW , m_rWidth + m_rHeight*65536 );
}
// TODO: Add your message handler code here
m_pView->Redraw();
// Do not call CWnd::OnPaint() for painting messages
}
void C3DWnd::ShowVolume()
{
Clear();
CArrLong arrID;
GetSolidsID(arrID);
for (int i = 0; i < arrID.GetSize(); i++){
TopoDS_Solid solid = GetSolidByID(arrID.GetAt(i));
Handle(AIS_Shape) ais = new AIS_Shape(solid);
m_pAISContext->SetColor(ais,Quantity_NOC_GREEN,Standard_False);
m_pAISContext->SetMaterial(ais,Graphic3d_NOM_GOLD,Standard_False);
m_pAISContext->SetDisplayMode(ais,1);
m_pAISContext->Display(ais,Standard_False);
}
GetFacesID(arrID);
for ( i = 0; i < arrID.GetSize(); i++){
TopoDS_Face Face ;
if (!GetFaceByID(arrID.GetAt(i), Face)) break;
Handle(AIS_Shape) ais = new AIS_Shape(Face);
m_pAISContext->SetColor(ais,Quantity_NOC_GRAY99,Standard_False);
m_pAISContext->SetMaterial(ais,Graphic3d_NOM_STONE,Standard_False);
m_pAISContext->SetDisplayMode(ais,1);
m_pAISContext->Display(ais,Standard_False);
}
m_pView->FitAll();
m_pView->ZFitAll();
/* TopoDS_Shape S = BRepPrimAPI_MakeWedge(600.,100.,80.,20.);
Handle(AIS_Shape) ais1 = new AIS_Shape(S);
m_pAISContext->SetColor(ais1,Quantity_NOC_GREEN,Standard_False);
m_pAISContext->SetMaterial(ais1,Graphic3d_NOM_PLASTIC,Standard_False);
m_pAISContext->Display(ais1,Standard_False);
|