Coin3D单文档点云显示程序

1、创建工程

启动VC6.0,创建新的工程,File | New | Projects | MFC AppWizard (exe)。假设工程名为"SDIshow3D"。对向导使用默认配置,可以创建单文档或多文档程序。

2、为SoWin和Coin添加代码

打开SDIshow3D.cpp文件。

1)       包含头文件:

#include <Inventor/Win/SoWin.h>

2)       编辑函数CSDIshow3DApp::InitInstance(),在第一行中添加:

SoWin::init("");

上述用于初始化SoWin和Coin库,在使用这些函数库之前必须被调用。

打开SDIshow3DView.h文件。

1)       在预编译头之后(#ifdef/#pragma once/#endif sequence)添加包含文件:

#include <Inventor/Win/SoWin.h>

#include<Inventor/Win/viewers/SoWinExaminerViewer.h>

2)       添加公共数据成员:

SoWinExaminerViewer * viewer;

ExaminerViewer用于渲染场景,且用于交互显示(旋转,选择部分场景等)

打开文件SDIshow3DView.cpp

1)       修改构造函数如下:

CSDIshow3DView::CMFCViewerView()

{

  viewer = NULL;

}

2)       修改析构函数如下:

CSDIshow3DView::CMFCViewerView()

{

  if (viewer != NULL)

    delete viewer;

}

3)       修改方法CSDIshow3DView::OnDraw(CDC*pDC) 如下:

void CSDIshow3DView::OnDraw(CDC* pDC)

{

       CSDIshow3DDoc* pDoc =GetDocument();

       ASSERT_VALID(pDoc);

       if (viewer == NULL)

         {

              viewer = newSoWinExaminerViewer( m_hWnd );

              viewer->setDecoration(FALSE);

              }

              SoSeparator*root = GetDocument()->GetScene(); //与文档类的Getscene()联系起来

              viewer->setSceneGraph(root);//设置场景图的顶部节点为root

 

              WINDOWPLACEMENTp;  //包含关于屏幕上窗口的位置的信息。

              memset(&p,0, sizeof(p));

              p.length =sizeof(WINDOWPLACEMENT);

              p.showCmd =SW_SHOWMAXIMIZED;

              SetWindowPlacement(&p);

}

这会将ExaminerViewer嵌入到CSDIshow3DView窗口中。

打开文件SDIshow3DDoc.h

1)       添加包含文件:

#include <Inventor/Win/SoWin.h>

#include <Inventor/Win/viewers/SoWinExaminerViewer.h>

#include <Inventor/nodes/SoSeparator.h>

#include <Inventor/nodes/SoMaterial.h>

#include <Inventor/nodes/SoCoordinate3.h>

#include <Inventor/nodes/SoDrawStyle.h>

#include <Inventor/nodes/SoPointSet.h>

#include <Inventor/SbBox.h>

#include <Inventor/SbVec3f.h>

#include <Inventor/nodes/SoTriangleStripSet.h>

#include <Inventor/nodes/SoNormal.h>

#include <Inventor/nodes/SoNormalBinding.h>

#include <Inventor/nodes/SoCube.h>

#include <Inventor/nodes/SoTransform.h>

#include <Inventor/nodes/SoLightModel.h>

#include <Inventor/nodes/SoSphere.h>

 

#include <vector>

#include <math.h>

 

using namespace std ;

2)       添加类:

class SoSeparator;  //通知编译器,将使用SoSeparator类。

class Point 

{    

public:

       int pt_ID;

       float X;

       float Y;

       float Z;

};

3)       添加方法:

public:

       voidCreateCoordinates();

       int Read_PtsFile(char*filename);

       SoSeparator *GetScene();

4)       添加数据成员:

private:

       vector<float>X,Y,Z;

       vector<Point>  m_Points;  //原始点坐标

       SoSeparator * m_pScene;

public:   

       SbVec3f * coord;

       bool m_PtsRead;

       SoSeparator * root;       //场景图的最高结点

打开文件SDIshow3DDoc.cpp

1)       为读取点云菜单添加消息响应函数

void CSDIshow3DDoc::OnReadPoints()

{

       // TODO: Add yourcommand handler code here

       CString szFilter ="(*.pts;*.txt;*.iv)|*.pts;*.txt;*.iv||";       //过滤显示该类文件

       CFileDialog dlg(TRUE,"", "", NULL, szFilter, NULL);

       if(dlg.DoModal() ==IDOK)

       {

              CString str;

              str =dlg.GetPathName();

              char * p;

              p =str.GetBuffer(0);      //获取str字符串的指针

        int nump =Read_PtsFile(p); //调用Read_PtsFile函数,返回读取到的点的个数  

              //str.Format("文件读取完毕,共计点%d个",nump);

              //MessageBox(NULL,str,"三维坐标读取",0);

              UpdateAllViews(NULL);

              return;

       }

       else

       {

              return;

       }

}

2)       添加函数,用于读取点云文件:

int CSDIshow3DDoc::Read_PtsFile(char *filename)

{

       FILE * f = fopen(filename,"r");

       float num;

       int sum = 0;

       while (!feof(f))                           //读取点坐标,如果文件不为空则继续读

       {    

              fscanf(f,"%f",&num);          //将文件指针f指向的文件以浮点型格式保存到num中

              sum++;                                      //每次从文件中读取一个数则sum加1

              if (sum%3 == 1)                  //将坐标分别存入XYZ矢量中

              {

                     X.push_back(num);              //在矢量X尾部插入数字num

              }

              if (sum%3 == 2)

              {

                     Y.push_back(num);

              }

              if (sum%3 == 0)

              {

                     Z.push_back(num);

              }           

       }

    fclose(f);

       m_PtsRead = true;

       CreateCoordinates();             //调用该函数创建点的坐标

    return X.size() - 1;               //返回点的个数

}

3)       添加函数,用于创建点云对于的3D坐标

void CSDIshow3DDoc::CreateCoordinates()//将XYZ矢量中的值保存到3D点中

{

       int num_p = X.size() -1;

       coord = newSbVec3f[num_p];    

       for (int i = 0; i<num_p; i++)

       {

              coord[i].setValue(X[i],Y[i],Z[i]);

              float x,y,z;

              coord[i].getValue(x,y,z);

              Point temp;

              temp.pt_ID = i;

              temp.X = x;

              temp.Y = y;

              temp.Z = z;

              m_Points.push_back(temp);

       }

}

4)       将点云添加到场景中

SoSeparator * CSDIshow3DDoc::GetScene()

{

       if (m_PtsRead)

       {

              if (m_pScene !=NULL)

              {

                     m_pScene->unref();

              }

             

              m_pScene = newSoSeparator;     

              m_pScene->ref();

              SoLightModel *lightmodel = new SoLightModel;            

              lightmodel->model= SoLightModel::BASE_COLOR;    //关闭默认光源           

              m_pScene->addChild(lightmodel);

             

              SoCoordinate3 *coord3 = new SoCoordinate3;         

              coord3->point.setValues(0,X.size()-1, coord);

              m_pScene->addChild(coord3);

 

              SoMaterial *mat_p = new SoMaterial;       

              mat_p->diffuseColor.setValue(0,1,0);               

              m_pScene->addChild(mat_p);

             

              SoDrawStyle *drawstyle = new SoDrawStyle;          

              drawstyle->pointSize= 1.5;         

              drawstyle->style= SoDrawStyle::LINES;

              m_pScene->addChild(drawstyle);

             

              SoPointSet *pointset = new SoPointSet;

              m_pScene->addChild(pointset);

 

              SoSeparator *temp = new SoSeparator;

              SoMaterial * mat= new SoMaterial;

              mat->diffuseColor.setValue(1,1,0);

              temp->addChild(mat);                

           m_pScene->addChild(temp);

 

              SoSeparator *instructsep = new SoSeparator;     //加载操作指令说明

       m_pScene->addChild(instructsep);

 

              SoMaterial *myMaterial = new SoMaterial;

              instructsep->addChild(myMaterial);

              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[] = {

                     "Instructionsfor the MFCViewer tutorial",

                     "",

                     "Leftmouse button = rotate",

                     "Middlemouse button = move",

                     "CTRL+ middle mouse button = zoom",

                     "Rightmouse button = options"

                     };

              instructions->string.setValues(0,sizeof(str) / sizeof(char *), str);

              instructions->justification= SoText2::LEFT;

              instructsep->addChild(instructions);

       }

       return m_pScene;

}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值