学习日志2020.7.23 MFC显示OSG点云

在mfc上显示osg本地文件:
https://blog.csdn.net/weixin_30526593/article/details/97294251
将获取的livox点云模型写入osg文件:

bool result = osgDB::writeNodeFile(*root.get(), "my.osg");
if (!result)
osg::notify(osg::FATAL) << "Failed in osgDB::writeNodeFile()" << std::endl;

但是这个方法保存数据很慢。
获取主窗口句柄:AfxGetMainWnd()->m_hWnd。在类外无法获取。
把MFC_OSG.cpp里的void cOSG::InitSceneGraph(void)重写,将mRoot的初始化部分从读取本地文件替换成OSGShowPoint里的方法。

void cOSG::InitSceneGraph(void)
{
    // Init the main Root Node/Group
    mRoot  = new osg::Group;

    // Load the Model from the model name
    /*mModel = osgDB::readNodeFile(m_ModelName);
    if (!mModel) return;

    // Optimize the model
    osgUtil::Optimizer optimizer;
    optimizer.optimize(mModel.get());
    optimizer.reset();

    // Add the model to the scene
    mRoot->addChild(mModel.get());*/
	//ref_ptr<Group> root = new Group();
	ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
	{
		ref_ptr<osg::GraphicsContext::Traits> traits = new GraphicsContext::Traits;
		traits->x = 40;
		traits->y = 40;
		traits->width = 600;
		traits->height = 480;
		traits->windowDecoration = true;
		traits->doubleBuffer = true;
		traits->sharedContext = 0;
		ref_ptr<GraphicsContext> gc = GraphicsContext::createGraphicsContext(traits.get());
		gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		ref_ptr<Camera> camera = new Camera;
		camera->setGraphicsContext(gc.get());
		camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
		GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
		camera->setDrawBuffer(buffer);
		camera->setReadBuffer(buffer);
		// add this slave camera to the viewer, with a shift left of the projection matrix
		viewer->addSlave(camera.get());
	}
	//顶点数组
	ref_ptr<osg::Vec3Array> coords = new Vec3Array();
	ref_ptr<osg::Vec4Array> color = new Vec4Array();
	//读取文件
	char* filePath = "e:\\livox\\txtFiles\\2020-07-16_10-59-04.txt";
	FILE* pfData;
	errno_t err = fopen_s(&pfData, filePath, "r");
	//FILE* pfData = fopen(FileName, "r");
	int num = 0;//数据点数量
	if (pfData == NULL)
	{
		cout << "File does not exist!!!" << endl;
		return;
	}
	else
	{
		char strLine[100];
		while ((!feof(pfData)) && num<500000)
		{
			int fx = 0, fy = 0, fz = 0, fref = 0;
			fgets(strLine, 100, pfData);
			int DataIntegrity = 0;//点云数据完整
			char *ptr;
			char *p;
			char strs[] = " ";
			if (strcmp(strLine, strs) != 0)
			{
				ptr = strtok_s(strLine, ",", &p);
				if (ptr != NULL)
				{
					fx = atoi(ptr);
					ptr = strtok_s(NULL, ",", &p);
					DataIntegrity++;
				}
				if (ptr != NULL)
				{
					fy = atoi(ptr);
					ptr = strtok_s(NULL, ",", &p);
					DataIntegrity++;
				}
				if (ptr != NULL)
				{
					fz = atoi(ptr);
					ptr = strtok_s(NULL, ",", &p);
					DataIntegrity++;
				}
				if (ptr != NULL)
				{
					fref = atoi(ptr);
					ptr = strtok_s(NULL, ",", &p);
					DataIntegrity++;
				}
			}
			if (DataIntegrity == 4)
			{
				coords->push_back(osg::Vec3(fx, fy, fz));
				color->push_back(osg::Vec4(1.f, 0.f, 0.0f, 0.3f));
				num++;
			}
			DataIntegrity = 0;
		}
		fclose(pfData);
	}
	//创建几何体
	ref_ptr<Geometry> geometry = new Geometry();
	//设置顶点数组
	geometry->setVertexArray(coords.get());
	geometry->setColorArray(color.get());
	geometry->setColorBinding(Geometry::BIND_PER_VERTEX);
	Vec3Array *normals = new Vec3Array;
	normals->push_back(Vec3(0.0f, 1.0f, 0.0f));
	geometry->setNormalArray(normals);
	geometry->setNormalBinding(Geometry::BIND_OVERALL);
	geometry->addPrimitiveSet(new DrawArrays(PrimitiveSet::POINTS, 0, num)); //设置关联方式
	ref_ptr<Geode> geode = new Geode();
	geode->addDrawable(geometry.get());
	mRoot->addChild(geode.get());
}

开始采样的按钮的点击响应事件里,用MFC_OSG的方法显示点云:

CEdit* e1 = (CEdit*)GetDlgItem(editOSG);
	mOsg = new cOSG(e1->m_hWnd);
	mOsg->InitOSG("cow.osg");
	mThreadHandle = (HANDLE)_beginthread(&cOSG::Render, 0, mOsg);

新建MFC项目的时候为了精简,把所有可选项都取消勾选了。现在为对话框添加最大化最小化按钮。
对话框属性页-system menu设置为ture,然后把maximize box和minimize box设置为true。
把窗体内的控件也设置为随对话框大小而改变。
dlg头文件添加定义:

POINT Old;//存放对话框的宽和高。

dlg的cpp文件中初始化。在OnInitDialog函数内添加:

CRect rect;
GetClientRect(&rect); //取客户区大小   
Old.x = rect.right - rect.left;
Old.y = rect.bottom - rect.top;

类向导为MW_SIZE添加响应函数。内部添加代码:

// TODO:  在此处添加消息处理程序代码
if (nType == SIZE_RESTORED || nType == SIZE_MAXIMIZED)//窗体大小发生变动。处理程序
{
    float fsp[2];
    POINT Newp; //获取现在对话框的大小
    CRect recta;
    GetClientRect(&recta); //取客户区大小   
    Newp.x = recta.right - recta.left;
    Newp.y = recta.bottom - recta.top;
    fsp[0] = (float)Newp.x / Old.x;
    fsp[1] = (float)Newp.y / Old.y;
    CRect Rect;
    int woc;
    CPoint OldTLPoint, TLPoint; //左上角
    CPoint OldBRPoint, BRPoint; //右下角
    HWND hwndChild = ::GetWindow(m_hWnd, GW_CHILD); //列出所有控件   
    while (hwndChild)
    {
        woc = ::GetDlgCtrlID(hwndChild);//取得ID
        GetDlgItem(woc)->GetWindowRect(Rect);
        ScreenToClient(Rect);
        OldTLPoint = Rect.TopLeft();
        TLPoint.x = long(OldTLPoint.x*fsp[0]);
        TLPoint.y = long(OldTLPoint.y*fsp[1]);
        OldBRPoint = Rect.BottomRight();
        BRPoint.x = long(OldBRPoint.x *fsp[0]);
        BRPoint.y = long(OldBRPoint.y *fsp[1]); //高度不可读的控件(如:combBox),不要改变此值.
        Rect.SetRect(TLPoint, BRPoint);
        GetDlgItem(woc)->MoveWindow(Rect, TRUE);
        hwndChild = ::GetWindow(hwndChild, GW_HWNDNEXT);
    }
    Old = Newp;
}

参考:https://blog.csdn.net/why19940926/article/details/53946546

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值