Open Cascade创建自己的MFC文档程序
项目初始设置
在Visual studio中创建一个单文档MFC项目(本例以MFCTest为名称):
在项目属性的VC++页面设置包含目录、库目录,在链接器的输入中添加OCC库目录下的所有.lib文件名称
添加头文件
在stdafx.h中添加:
#include <BRepTools.hxx> #include <Standard_DefineHandle.hxx> #include <DsgPrs_LengthPresentation.hxx> #include <GCPnts_TangentialDeflection.hxx> #include <Geom_Axis2Placement.hxx> #include <Geom_CartesianPoint.hxx> #include <Geom_Line.hxx> #include <Geom_Surface.hxx> #include <BRepAdaptor_Surface.hxx> #include <GeomAbs_CurveType.hxx> #include <GeomAdaptor_Curve.hxx> #include <GeomTools_Curve2dSet.hxx> #include <gp_Vec.hxx> #include <Graphic3d_NameOfMaterial.hxx> #include <MMgt_TShared.hxx> #include <OSD_Environment.hxx> #include <Precision.hxx> #include <Prs3d_IsoAspect.hxx> #include <Prs3d_LineAspect.hxx> #include <Prs3d_Projector.hxx> #include <Prs3d_Text.hxx> #include <Quantity_Factor.hxx> #include <Quantity_Length.hxx> #include <Quantity_NameOfColor.hxx> #include <Quantity_PhysicalQuantity.hxx> #include <Quantity_PlaneAngle.hxx> #include <Quantity_TypeOfColor.hxx> #include <SelectMgr_EntityOwner.hxx> #include <SelectMgr_SelectableObject.hxx> #include <SelectMgr_Selection.hxx> #include <SelectMgr_SelectionManager.hxx> #include <SelectMgr_ListOfFilter.hxx> #include <SelectMgr_Filter.hxx> #include <StdSelect_EdgeFilter.hxx> #include <StdSelect_ShapeTypeFilter.hxx> #include <Standard_Boolean.hxx> #include <Standard_CString.hxx> #include <Standard_ErrorHandler.hxx> #include <Standard_Integer.hxx> #include <Standard_IStream.hxx> #include <Standard_Macro.hxx> #include <Standard_NotImplemented.hxx> #include <Standard_OStream.hxx> #include <Standard_Real.hxx> #include <StdPrs_Curve.hxx> #include <StdPrs_Point.hxx> #include <StdPrs_PoleCurve.hxx> #include <TCollection_AsciiString.hxx> #include <TColgp_Array1OfPnt2d.hxx> #include <TColgp_HArray1OfPnt2d.hxx> #include <TCollection_AsciiString.hxx> #include <TColStd_HSequenceOfTransient.hxx> #include <TColStd_MapIteratorOfMapOfTransient.hxx> #include <TColStd_MapOfTransient.hxx> #include <TopExp_Explorer.hxx> #include <TopoDS.hxx> #include <TopoDS_Compound.hxx> #include <TopoDS_Shape.hxx> #include <TopoDS_Solid.hxx> #include <TopoDS_Vertex.hxx> #include <TopExp.hxx> #include <TopTools_HSequenceOfShape.hxx> #include <UnitsAPI.hxx> #include <V3d_View.hxx> #include <V3d_Viewer.hxx> #include <WNT_Window.hxx> #include <Prs3d_PointAspect.hxx> #include <AIS_Point.hxx> #include <AIS_InteractiveContext.hxx> #include <AIS_Shape.hxx> #include <BRep_Tool.hxx> #include <BRepAlgoAPI_Fuse.hxx> #include <BRepBuilderAPI_MakeEdge.hxx> #include <BRepBuilderAPI_MakeFace.hxx> #include <BRepBuilderAPI_MakeWire.hxx> #include <BRepBuilderAPI_MakeVertex.hxx> #include <BRepBuilderAPI_Transform.hxx> #include <BRepPrimAPI_MakeCone.hxx> #include <BRepPrimAPI_MakeRevol.hxx> #include <BRepFilletAPI_MakeFillet.hxx> #include <BRepBuilderAPI_Copy.hxx> #include <BRepBuilderAPI_MakePolygon.hxx> #include <BRepLib.hxx> #include <BRepOffsetAPI_MakeThickSolid.hxx> #include <BRepOffsetAPI_ThruSections.hxx> #include <BRepPrimAPI_MakeCylinder.hxx> #include <BRepPrimAPI_MakePrism.hxx> #include <BRepPrimAPI_MakeTorus.hxx> #include <BRepAlgoAPI_Section.hxx> #include <BRepPrimAPI_MakeSphere.hxx> #include <BRepFeat_SplitShape.hxx> #include <TColgp_HArray1OfPnt.hxx> #include <GeomAPI_Interpolate.hxx> #include <GC_MakeArcOfCircle.hxx> #include <GC_MakeSegment.hxx> #include <GC_MakeCircle.hxx> #include <GCE2d_MakeSegment.hxx> #include <gp.hxx> #include <gp_Ax1.hxx> #include <gp_Ax2.hxx> #include <gp_Ax2d.hxx> #include <gp_Dir.hxx> #include <gp_Dir2d.hxx> #include <gp_Pnt.hxx> #include <gp_Pnt2d.hxx> #include <gp_Trsf.hxx> #include <gp_Vec.hxx> #include <Geom_CylindricalSurface.hxx> #include <Geom_Plane.hxx> #include <Geom_Surface.hxx> #include <Geom_TrimmedCurve.hxx> #include <Geom2d_Ellipse.hxx> #include <Geom2d_TrimmedCurve.hxx> #include <TopExp_Explorer.hxx> #include <TopoDS.hxx> #include <TopoDS_Edge.hxx> #include <TopoDS_Face.hxx> #include <TopoDS_Wire.hxx> #include <TopoDS_Shape.hxx> #include <TopoDS_Compound.hxx> #include <GCPnts_AbscissaPoint.hxx> #include <BRepAdaptor_Curve.hxx> #include <GeomLib.hxx> #include <GeomConvert_CompCurveToBSplineCurve.hxx> #include <TopTools_ListOfShape.hxx> #include <TopTools_ListIteratorOfListOfShape.hxx> #include <TopTools_DataMapOfShapeInteger.hxx> #include <TopTools_DataMapOfShapeReal.hxx> #include <TopTools_IndexedDataMapOfShapeAddress.hxx> #include <V3d_PositionalLight.hxx> #include <V3d_DirectionalLight.hxx> #include <V3d_AmbientLight.hxx> #include <IGESControl_Controller.hxx> #include <IGESControl_Writer.hxx> #include <Interface_Static.hxx> #include <OpenGl_GraphicDriver.hxx> #include <Graphic3d_GraphicDriver.hxx>
添加代码
MFC文档分成三个结构:
Application: 项目名称.cpp 项目名称.h
Doc: 项目名称View.cpp 项目名称View.h
View: 项目名称Doc.cpp 项目名称Doc.h
在Application中 "项目名称.h" 文件中的类中加入代码:
protected: Handle(Graphic3d_GraphicDriver) m_GraphicDriver; public: Handle(Graphic3d_GraphicDriver) GetGraphicDriver(){return m_GraphicDriver;}
在对应的类的实现文件 "项目名称.cpp" 的类的构造函数中添加:
try { Handle(Aspect_DisplayConnection) aDisplayConnection; m_GraphicDriver = new OpenGl_GraphicDriver(aDisplayConnection); } catch (Standard_Failure) { AfxMessageBox(L"(Error Ocured in Initializing the Opencascade graphic variable.)"); }
接着处理Document Class在 "项目名称Doc.h" 中定义的类中添加:
public: Handle(V3d_Viewer) GetViewer(void) {return myViewer;} protected: Handle(AIS_InteractiveContext) myAISContext; Handle(V3d_Viewer) myViewer;
接着去实现文档 "项目名称Doc.cpp" 中类的"项目名称Doc::项目名称Doc()"构造函数中添加:
Handle(Graphic3d_GraphicDriver) theGraphicDriver = ((CMFCTestApp*)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);
在 "项目名称View.h" 中添加:
public: virtual void OnInitialUpdate(); protected: Handle(V3d_View) myView;
在 "项目名称View.cpp" 中重写OnInitialUpdate()函数:
void CmOCCTView::OnInitialUpdate() { myView = GetDocument()->GetViewer()->CreateView(); myView->SetShadingModel(V3d_GOURAUD); Handle(Graphic3d_GraphicDriver) theGraphicDriver = ((CMFCTestApp*)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();
选择x64平台编译生成即可看到界面:
注意:
在添加代码时会在new关键字处报错
将当前文件下的
#ifdef _DEBUG #define new DEBUG_NEW #endif
删去即可
2. 如果编译提醒缺少dll,请将opencascade的win64/vc14/bin目录以及所有第三方库的bin目录添加到系统环境变量Path,如此可以搜索到相应dll文件。或者将dll文件复制到exe文件目录下。
绘图
在mOCCTDoc.cpp和mOCCTDoc.h中写入DrawSphere代码:(需要在mOCCTDoc.cpp中include 头文件 #include “MFCTestView.h”)
//mMFCTestDoc.cpp: void CmOCCTDoc::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(); CmOCCTView *pView = (CmOCCTView *)pChild->GetActiveView(); pView->FitAll(); }
//mMFCTestDoc.h: void CmOCCTDoc::DrawSphere(double Radius);
在mOCCTView.h中加入一个类方法:
void FitAll() { if (!myView.IsNull()) myView->FitAll(); myView->ZFitAll(); };
接着在CMFCTestView::OnDraw中调用绘球函数:
pDoc->DrawSphere(6);
编译生成即可
鼠标拖拽
在 MFCTestView.cpp及MFCTestView.h中添加OnMouseMove函数:
//MFCTestView.h protected: afx_msg void OnMouseMove(UINT nFlags, CPoint point);
.cpp文件
// MFCTestView.cpp BEGIN_MESSAGE_MAP(CmOCCTView, CView) ... ON_WM_MOUSEMOVE() ... END_MESSAGE_MAP() ... void CmOCCTView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CView::OnMouseMove(nFlags, point); if(nFlags && MK_LBUTTON){ //myView->Rotate(point.x,point.y); myView->Rotation(point.x,point.y); } }
如此可实现鼠标左键的拖拽旋转
参考资料:
1.如何在自己的项目中使用OpenCascade7.3
2.How to Build an simple Opencascade Program using Visual C++