OCC-7.6.0 + MFC单文档应用 入门教程
磨刀不误砍柴工,如果你对MFC没任何基础,请先读这篇MFC的入门基础,它会降低你对这篇文章的恐惧感
开发环境说明
win7+ opencascade-7.6.0+vs2019 最终成果如下:
先来个餐前甜点
opencasecade-7.6.0安装完成后,进入opencasecade-7.6.0目录,如下
不知道如何安装,请点击这里有完整教程 各目录的功能如下所示:
adm目录:包含编译OCCT的相关工程;
adm/cmake目录:包含使用CMake构建OCCT的相关处理脚本;
adm/msvc目录:包含window平台 Visual C++ 2010, 2012, 2013, 2015, 2017 and 2019等版本的32/64平台solutinon文件;
data目录: 包含用于OCCT功能测试的CAD文件
doc目录:包含OCCT的html和pdf格式帮助文档;
dox目录:包含了基于MarkDown文件格式的文本文档;
inc目录:OCCT头文件依赖;
samples目录:OCCT示例项目;
src目录:OCCT源码目录;
tests目录:包含测试脚本文件
tools目录:包含Inspector工具的源码.
win64/vc10目录:包含window平台预编译的可执行程序和lib库;
gendoc.bat: 将occt的Markdown格式文件编译为html格式
inspector.bat occinspector工具运行环境
msvc.bat: visual studio编译工程和运行环境
draw.bat: draw工具运行环境
我们可以进行测试一下,运行draw.bat 出现两个窗口如下图
一个是cmd命令窗口,一个 Draw窗口 在cmd命令窗口输入
pload DEFAULT
axo
继续输入命令
box b -10 -10 -10 10 10 10
fit
开始创建MFC项目
step.1 创建项目
step.2 开发环境配置
设置为x64位,如下图
设置项目的包含目录 和库目录 包含目录在OpenCASCADE-7.6.0-vc14-64/opencascade-7.6.0/inc 将完整路径添加到 包含目录 库目录在OpenCASCADE-7.6.0-vc14-64\opencascade-7.6.0\win64\vc14\lib 将完整路径添加到库目录 如下图
然后在连接器,找到输入的 附加依赖项 ,设置附加依赖项
添加如下lib文件名
TKBin.lib;
TKBinL.lib;
TKBinTObj.lib;
TKBinXCAF.lib;
TKBO.lib;
TKBool.lib;
TKBRep.lib;
TKCAF.lib;
TKCDF.lib;
TKD3DHost.lib;
TKD3DHostTest.lib;
TKDCAF.lib;
TKDFBrowser.lib;
TKDraw.lib;
TKernel.lib;
TKFeat.lib;
TKFillet.lib;
TKG2d.lib;
TKG3d.lib;
TKGeomAlgo.lib;
TKGeomBase.lib;
TKHLR.lib;
TKIGES.lib;
TKIVtk.lib;
TKIVtkDraw.lib;
TKLCAF.lib;
TKMath.lib;
TKMesh.lib;
TKMeshVS.lib;
TKMessageModel.lib;
TKMessageView.lib;
TKOffset.lib;
TKOpenGl.lib;
TKOpenGles.lib;
TKOpenGlesTest.lib;
TKOpenGlTest.lib;
TKPrim.lib;
TKQADraw.lib;
TKRWMesh.lib;
TKService.lib;
TKShapeView.lib;
TKShHealing.lib;
TKStd.lib;
TKStdL.lib;
TKSTEP.lib;
TKSTEP209.lib;
TKSTEPAttr.lib;
TKSTEPBase.lib;
TKSTL.lib;
TKTInspector.lib;
TKTInspectorAPI.lib;
TKTObj.lib;
TKTObjDRAW.lib;
TKToolsDraw.lib;
TKTopAlgo.lib;
TKTopTest.lib;
TKTreeModel.lib;
TKV3d.lib;
TKVCAF.lib;
TKView.lib;
TKViewerTest.lib;
TKVInspector.lib;
TKVRML.lib;
TKXCAF.lib;
TKXDEDRAW.lib;
TKXDEIGES.lib;
TKXDESTEP.lib;
TKXMesh.lib;
TKXml.lib;
TKXmlL.lib;
TKXmlTObj.lib;
TKXmlXCAF.lib;
TKXSBase.lib;
TKXSDRAW.lib;
打开OpenCASCADE-7.6.0-vc14-64\opencascade-7.6.0\win64\vc14\lib 目录,在该目录下打开cmd ,执行dir /b>libName.txt ,打开该文件,即可得到上面的所有依赖名,复制后粘贴到附加依赖项
添加头文件stdafx.h ,但是好像并没有stdafx.h 的头文件,我们可以把occt的相关头文件放在pch.h 中
VS2017开始,stdafx.h改名叫pch.h了
step.3 pch.h头文件
#pragma warning( disable : 4244 )
#include <Standard_ShortReal.hxx>
#pragma warning( default : 4244 )
#include <Standard.hxx>
#include <Aspect_DisplayConnection.hxx>
#include <AIS_InteractiveContext.hxx>
#include <AIS_Shape.hxx>
#include <AIS_Point.hxx>
#include <V3d_Viewer.hxx>
#include <V3d_View.hxx>
#include <OpenGl_GraphicDriver.hxx>
#include <WNT_Window.hxx>
#include <Standard_ErrorHandler.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
step.4 OCCmfc.h及OCCmfc.cpp
接着在OCCmfc.h 的文件类中,添加如下代码
protected:
Handle(Graphic3d_GraphicDriver) m_GraphicDriver;
public:
Handle(Graphic3d_GraphicDriver) GetGraphicDriver() { return m_GraphicDriver; }
ps: 这里的OCCmfc 为项目名,注意自己创建的项目名
在OCCmfc.cpp 中的构造函数COCCmfcApp::COCCmfcApp() noexcept 中,添加如下代码
try {
Handle(Aspect_DisplayConnection) aDisplayConnection;
m_GraphicDriver = new OpenGl_GraphicDriver(aDisplayConnection);
}
catch (Standard_Failure) {
AfxMessageBox(L"(Error Ocured in Initializing the Opencascade graphic variable.)");
}
注意,如果出现new报错,则需要文件头部的如下代码注释
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
step.5 OCCmfcDoc.h及OCCmfcDoc.cpp
然后在OCCmfcDoc.h 中的类中添加如下声明
public:
Handle(V3d_Viewer) GetViewer(void) { return myViewer; }
protected:
Handle(AIS_InteractiveContext) myAISContext;
Handle(V3d_Viewer) myViewer;
在OCCmfcDoc.cpp 中的构造函数``中添加如下代码
COCCmfcDoc::COCCmfcDoc() noexcept
{
Handle(Graphic3d_GraphicDriver) theGraphicDriver = ((COCCmfcApp*)AfxGetApp())->GetGraphicDriver();
myViewer = new V3d_Viewer(theGraphicDriver);
myViewer->SetDefaultLights();
myViewer->SetLightOn();
myAISContext = new AIS_InteractiveContext(myViewer);
myAISContext->SetDisplayMode(AIS_Shaded, true);
myAISContext->SetAutomaticHilight(Standard_False);
}
step.6 OCCmfcView.h及OCCmfcView.cpp
最后在OCCmfcView.h 中添加如下声明
public:
virtual void OnInitialUpdate();
protected:
Handle(V3d_View) myView;
在OCCmfcView.cpp 中重写OnInitialUpdate 函数,如下所示:
void COCCmfcView::OnInitialUpdate() {
myView = GetDocument()->GetViewer()->CreateView();
myView->SetShadingModel(V3d_GOURAUD);
Handle(Graphic3d_GraphicDriver) theGraphicDriver = ((COCCmfcApp*)AfxGetApp())->GetGraphicDriver();
Aspect_Handle aWindowHandle = (Aspect_Handle)GetSafeHwnd();
Handle(WNT_Window) aWntWindow = new WNT_Window(GetSafeHwnd());
myView->SetWindow(aWntWindow);
if (!aWntWindow->IsMapped()) {
aWntWindow->Map();
}
Standard_Integer w = 100;
Standard_Integer h = 100;
aWntWindow->Size(w, h);
::PostMessage(GetSafeHwnd(), WM_SIZE, SIZE_RESTORED, w + h * 65536);
myView->FitAll();
myView->ZBufferTriedronSetup(Quantity_NOC_RED, Quantity_NOC_GREEN, Quantity_NOC_BLUE1, 0.8, 0.05, 12);
myView->TriedronDisplay(Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.2, V3d_ZBUFFER);
}
并在OnDraw() 函数中,添加如下代码
myView->MustBeResized();
myView->Update();
F5 运行,得到如下结果,可以看到左下角的坐标系
开始绘制图形
step.7 OCCmfcDoc.h及OCCmfcDoc.cpp
首先在OCCmfcDoc.h 中声明如下方法
void CmOCCTDoc::DrawSphere(double Radius);
在OCCmfcDoc.cpp 中定义该方法
#include "OCCmfcView.h"
void COCCmfcDoc::DrawSphere(double Radius)
{
BRepPrimAPI_MakeSphere mkSphere(Radius);
TopoDS_Shape Sphere = mkSphere.Shape();
Handle(AIS_Shape) myAISSphere = new AIS_Shape(Sphere);
myAISContext->Display(myAISSphere, Standard_False);
CMDIFrameWnd* pFrame = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
CMDIChildWnd* pChild = (CMDIChildWnd*)pFrame->GetActiveFrame();
COCCmfcView* pView = (COCCmfcView*)pChild->GetActiveView();
pView->FitAll();
}
step.8 OCCmfcView.h及OCCmfcView.cpp
在OCCmfcView.h 中声明FitAll() 方法
public:
void FitAll();
并在OCCmfcView.cpp 中定义
void COCCmfcView::FitAll()
{
if (!myView.IsNull())
myView->FitAll();
myView->ZFitAll();
}
接在,在COCCmfcView::OnDraw() 函数中,添加绘制球的方法,如下代码
pDoc->DrawSphere(6);
F5 运行,即可得到如下图
添加鼠标监听事件,实现鼠标拖拽旋转
step.9 OCCmfcView.h及OCCmfcView.cpp
首先在OCCmfcView.h 中添加声明
protected:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
在OCCmfcView.cpp 中,添加监听事件并设置消息映射
BEGIN_MESSAGE_MAP(COCCmfcView, CView)
...
ON_WM_MOUSEMOVE()
...
END_MESSAGE_MAP()
...
void COCCmfcView::OnMouseMove(UINT nFlags, CPoint point)
{
CView::OnMouseMove(nFlags, point);
if (nFlags && MK_LBUTTON) {
myView->Rotation(point.x, point.y);
}
}
完成!
|