如何在MFC程序中使用Open Inventor

2024-05-08 10:18
文章标签 使用 程序 mfc open inventor

本文主要是介绍如何在MFC程序中使用Open Inventor,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

如何在MFC程序中使用Open Inventor
本文将介绍如何在MFC程序中使用Open Inventor(以下简称OIV)开发库。文中将使用VC 2003作为开发环境,使用SIM公司( www.coin3d.org)公司提供的Coin3D OIV作为Open Inventor开发库。关于OIV在Visual C++中的设置,请阅读网站 “Open Inventor-Coin3D开发环境” 中的内容。
1.创建工程
首先启动VC 2003,使用MFC Wizards创建一个MDI 应用程序(本文只讨论MDI类型的应用程序,但SDI或Dialog程序只需要稍微做一些修改,也是同样可以使用OIV的)。我们假定MDI应用程序的名称叫做“MFCViewer”。
       2.增加Coin和SoWin代码
1.         打开MFCViewer.cpp文件,在文件开始部分增加下列头文件:
    #include <Inventor/Win/SoWin.h>  

编辑CMFCViewerApp::InitInstance(),在函数中增加上:                    
             SoWin::init("");
这行代码将初始化SoWin和Coin库,必须在调用任何Coin或SoWin函数之前调用这行代码。
2.         打开MFCViewerView.h文件,增加下列头文件列表(增加到预编译头文件-#ifdef/#pragma once/#endif 序列之后)
              #include <Inventor/Win/SoWin.h>
              #include <Inventor/Win/viewers/SoWinExaminerViewer.h>
增加一个公共数据成员变量
SoWinExaminerViewer * viewer;
SoWinExaminerViewer主要用于渲染我们的场景,以可以和显示的内容做交互式操作(像旋转物体,选择部分场景等)
 
3.         打开MFCViewerView.cpp文件,修改构造函数:
CMFCViewerView::CMFCViewerView()
{
         viewer = NULL;
}
修改析构函数:
        CMFCViewerView::CMFCViewerView()
        {
             if (viewer != NULL)
                  delete viewer;
        }
3.创建场景
我们希望当用户创建了一个新文档后(点击菜单File | New),新创建的窗口中会有一个OIV场景。
1.         打开MFCViewerDoc.h文件,在CMFCViewerDoc类定义之上增加下列代码:
class SoSeparator;
这行代码主要是告诉编译器,我们要使用一个叫做SoSeparator的类。
2.         向CMFCViewerDoc类增加一个公共数据成员变量:
SoSeparator *root;
这是我们场景的根节点。
3.         打开MFCViewerDoc.cpp文件,增加下列头文件:
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/SoTranslation.h>
#include <Inventor/nodes/SoText2.h>
这些都是我们准备在场景中使用的节点,因此需要首先包含它们的头文件。
4.         修改函数OnNewDocument()     
BOOL CMFCViewerDoc::OnNewDocument()
{
 if (!CDocument::OnNewDocument())
    return FALSE;
 
 root = new SoSeparator;
 root->ref();
 SoMaterial *myMaterial;
 root->addChild(myMaterial = new SoMaterial);
 myMaterial->diffuseColor.setValue(1.0, 0.0, 0.0);
 root->addChild(new SoCone);
 
 SoSeparator * instructsep = new SoSeparator;
 root->addChild(instructsep);
 
 instructsep->addChild(myMaterial = new SoMaterial);
 myMaterial->diffuseColor.setValue(0.5, 1.0, 1.0);
 
 SoTranslation * instructtrans = new SoTranslation;
 instructtrans->translation = SbVec3f(-2.0f, 1.3f, 2.0f);
 instructsep->addChild(instructtrans);
 
 SoText2 * instructions = new SoText2;
 const char * str[] = {
    "Instructions for the MFCViewer tutorial",
    "",
    "Left mouse button = rotate",
    "Middle mouse button = move",
    "CTRL + middle mouse button = zoom",
    "Right mouse button = options"
    };
 instructions->string.setValues(0, sizeof(str) / sizeof(char *), str);
 instructions->justification = SoText2::LEFT;
 instructsep->addChild(instructions);
 
 return TRUE;
} 
我们通过向根节点增加子节点来建立场景。请记住,OIV会自己删除所有的场景对象,因此这里不需要程序员记住这些对象的指针,在以后的时候删除它们。(事实上如果这样做将会发生内存错误)。OIV是通过一种叫做引用计数的技术来实现这个功能的。
5.         修改构造和析构函数,增加上下列代码:
CMFCViewerDoc::CMFCViewerDoc()
{
 root = NULL;
}
 
CMFCViewerDoc::~CMFCViewerDoc()
{
 if (root)
    root->unref();
}
                   调用 root->unref(),告诉OIV,我们已经不再使用根节点对象了。所以OIV将会自动删除根节点。
6.         打开MFCViewerView.cpp文件,增加上下列代码:
#include <Inventor/nodes/SoSeparator.h>
修改函数CMFCViewerView::OnDraw(CDC* pDC):
void CMFCViewerView::OnDraw(CDC* pDC)
                           {
 CMFCViewerDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 if (viewer == NULL)
 {
    viewer = new SoWinExaminerViewer( m_hWnd );
    viewer->setDecoration(FALSE);
 
    SoSeparator *root = GetDocument()->root;
    viewer->setSceneGraph(root);
 }
}
      上面的代码将WinExaminerViewer嵌入到CMFCViewerView窗口中,其中WinExaminerViewer四周的 Toolbar(即Decoration)是不显示的。
编译并执行此应用程序
www.openinventor.cn
openinventor@gmail.com
openinventor@126.com

这篇关于如何在MFC程序中使用Open Inventor的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/970049

相关文章

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

C 语言中enum枚举的定义和使用小结

《C语言中enum枚举的定义和使用小结》在C语言里,enum(枚举)是一种用户自定义的数据类型,它能够让你创建一组具名的整数常量,下面我会从定义、使用、特性等方面详细介绍enum,感兴趣的朋友一起看... 目录1、引言2、基本定义3、定义枚举变量4、自定义枚举常量的值5、枚举与switch语句结合使用6、枚

使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)

《使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)》PPT是一种高效的信息展示工具,广泛应用于教育、商务和设计等多个领域,PPT文档中常常包含丰富的图片内容,这些图片不仅提升了... 目录一、引言二、环境与工具三、python 提取PPT背景图片3.1 提取幻灯片背景图片3.2 提取

使用Python实现图像LBP特征提取的操作方法

《使用Python实现图像LBP特征提取的操作方法》LBP特征叫做局部二值模式,常用于纹理特征提取,并在纹理分类中具有较强的区分能力,本文给大家介绍了如何使用Python实现图像LBP特征提取的操作方... 目录一、LBP特征介绍二、LBP特征描述三、一些改进版本的LBP1.圆形LBP算子2.旋转不变的LB

Maven的使用和配置国内源的保姆级教程

《Maven的使用和配置国内源的保姆级教程》Maven是⼀个项目管理工具,基于POM(ProjectObjectModel,项目对象模型)的概念,Maven可以通过一小段描述信息来管理项目的构建,报告... 目录1. 什么是Maven?2.创建⼀个Maven项目3.Maven 核心功能4.使用Maven H

Python中__init__方法使用的深度解析

《Python中__init__方法使用的深度解析》在Python的面向对象编程(OOP)体系中,__init__方法如同建造房屋时的奠基仪式——它定义了对象诞生时的初始状态,下面我们就来深入了解下_... 目录一、__init__的基因图谱二、初始化过程的魔法时刻继承链中的初始化顺序self参数的奥秘默认

将Java程序打包成EXE文件的实现方式

《将Java程序打包成EXE文件的实现方式》:本文主要介绍将Java程序打包成EXE文件的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录如何将Java程序编程打包成EXE文件1.准备Java程序2.生成JAR包3.选择并安装打包工具4.配置Launch4

SpringBoot使用GZIP压缩反回数据问题

《SpringBoot使用GZIP压缩反回数据问题》:本文主要介绍SpringBoot使用GZIP压缩反回数据问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot使用GZIP压缩反回数据1、初识gzip2、gzip是什么,可以干什么?3、Spr

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

Spring Boot 集成 Quartz并使用Cron 表达式实现定时任务

《SpringBoot集成Quartz并使用Cron表达式实现定时任务》本篇文章介绍了如何在SpringBoot中集成Quartz进行定时任务调度,并通过Cron表达式控制任务... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启动 Sprin