通过调用pcl相关库及函数,将pcd、obj、las、ply格式3D文件统一转换成ply点云格式文件进行存储及显示,调用OpenGL相关函数进行三维显示及鼠标、键盘的简单操作。

1、transform.h(建立一个抽象类Modelloader,由三个子类分别继承,使其读取转换不同的3D文件)

#include <iostream>
#include <cstdlib>
#include<string>
#include <liblas/liblas.hpp>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/io/ply_io.h>
#include<pcl/PCLPointCloud2.h>
#include <pcl/io/obj_io.h>using namespace pcl;
using namespace pcl::io;
using namespace std;class ModelLoader {public:string filename;string savefilename;ModelLoader(string filename="", string savefilename="") {this->filename = filename;this->savefilename = savefilename;}virtual void  TO_PLY(){}~ModelLoader() {this->filename = "";}};class LasLoader:public ModelLoader {public:LasLoader(string filename="",string savefilename="") :ModelLoader(filename,savefilename) {}void TO_PLY();};
class PCDLoader :public ModelLoader {public:PCDLoader(string filename = "", string savefilename = "") :ModelLoader(filename, savefilename) {}void TO_PLY();};
class OBJLoader :public ModelLoader {
public:OBJLoader(string filename = "", string savefilename = "") :ModelLoader(filename, savefilename) {}void TO_PLY();
};

2、LAS_to_PLY.cpp

#include "transform.h"
void LasLoader::TO_PLY()
{std::ifstream ifs; ifs.open(this->filename, ios::in | ios::binary);liblas::ReaderFactory f;liblas::Reader reader = f.CreateWithStream(ifs);unsigned long int nbPoints = reader.GetHeader().GetPointRecordsCount();pcl::PointCloud<pcl::PointXYZRGB> cloud;cloud.width = nbPoints;cloud.height = 1;cloud.is_dense = false;cloud.points.resize(cloud.width * cloud.height);int i = 0;uint16_t r1, g1, b1;int r2, g2, b2;uint32_t rgb;while (reader.ReadNextPoint()){cloud.points[i].x = (reader.GetPoint().GetX());cloud.points[i].y = (reader.GetPoint().GetY());cloud.points[i].z = (reader.GetPoint().GetZ());r1 = (reader.GetPoint().GetColor().GetRed());g1 = (reader.GetPoint().GetColor().GetGreen());b1 = (reader.GetPoint().GetColor().GetBlue());r2 = ceil(((float)r1 / 65536) * (float)256);g2 = ceil(((float)g1 / 65536) * (float)256);b2 = ceil(((float)b1 / 65536) * (float)256);rgb = ((int)r2) << 16 | ((int)g2) << 8 | ((int)b2);cloud.points[i].rgb = *reinterpret_cast<float*>(&rgb);i++;}pcl::io::savePLYFileASCII(this->savefilename, cloud);
}

3、OBJ_to_PLY.cpp

#include "transform.h"int OBJtoPLYconvertor(string& input_filename, string& output_filename)
{pcl::PCLPointCloud2 cloud;if (loadOBJFile(input_filename, cloud) < 0){cout << "Error: cannot load the PCD file!!!" << endl;return -1;}PLYWriter  writer;writer.writeASCII(output_filename, cloud, Eigen::Vector4f::Zero(), Eigen::Quaternionf::Identity(), 40, true);return 0;}void OBJLoader::TO_PLY()
{OBJtoPLYconvertor(this->filename, this->savefilename);}

4、PCD_to_PLY.cpp

#include "transform.h"int PCDtoPLYconvertor(string& input_filename, string& output_filename)
{pcl::PCLPointCloud2 cloud;if (loadPCDFile(input_filename, cloud) < 0){cout << "Error: cannot load the PCD file!!!" << endl;return -1;}PLYWriter  writer;writer.writeASCII(output_filename, cloud, Eigen::Vector4f::Zero(), Eigen::Quaternionf::Identity(), 20, true);return 0;}void PCDLoader::TO_PLY()
{PCDtoPLYconvertor(this->filename, this->savefilename);}

5、PLYloader.h(将文件格式转换为ply后统一由一个plyloader类读取ps:提前声明了一些参数。)

#define PLYREADER_H_#include <GL/glut.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include <vector>
#include <Windows.h>
#include <cmath>using namespace std;static int mousetate = 0;//鼠标当前的状态
static int mousestate1 = 0;
static int mousestate2 = 0;
static GLfloat Oldx = 0.0; // 点击之前的位置
static GLfloat Oldy = 0.0;static float xRotate = 0.0f;
static float yRotate = 0.0f;
static float scale = 1;
static float timesx = 0.0f;
static float timesy = 0.0f;static float cx = 0.0f;
static float cy = 0.0f;
static float cz = 0.0f;void OnMouse(int button, int state, int x, int y);
void onMouseMove(int x, int y);
void mySpecial(int key, int x, int y);class CPLYLoader
{
public:CPLYLoader();int LoadModel(char* filename);void Draw();private:GLfloat* mp_vertexXYZ;int m_totalConnectedPoints;};

6、PLYloader.cpp

#include "PLYLoader.h"
#include <iostream>CPLYLoader::CPLYLoader()
{this->m_totalConnectedPoints = 0;}int CPLYLoader::LoadModel(char* filename)
{printf("Loading %s...\n", filename);char* pch = strstr(filename, ".ply");if (pch != NULL){FILE* file = fopen(filename, "r");if (!file){printf("load PLY file %s failed\n", filename);return false;}fseek(file, 0, SEEK_END);long fileSize = ftell(file);try{mp_vertexXYZ = (GLfloat*)malloc(ftell(file));//mp_vertexNorm = (float*)malloc(ftell(file));//mp_vertexRGB = (float*)malloc(ftell(file));}catch (char*){return -1;}if (mp_vertexXYZ == NULL) return -1;fseek(file, 0, SEEK_SET);if (file){int i = 0;int temp = 0;int quads_index = 0;int triangle_index = 0;int normal_index = 0;int colorIndex = 0;char buffer[1000];fgets(buffer, 300, file);while (strncmp("element vertex", buffer, strlen("element vertex")) != 0){fgets(buffer, 300, file);}strcpy(buffer, buffer + strlen("element vertex"));sscanf(buffer, "%i", &this->m_totalConnectedPoints);cout << this->m_totalConnectedPoints << endl;fseek(file, 0, SEEK_SET);while (strncmp("end_header", buffer, strlen("end_header")) != 0){fgets(buffer, 300, file);    }i = 0;for (int iterator = 0; iterator < this->m_totalConnectedPoints; iterator++){char tmp[1];fgets(buffer, 300, file);sscanf(buffer, "%f %f %f ", &mp_vertexXYZ[i], &mp_vertexXYZ[i + 1], &mp_vertexXYZ[i + 2]);i += 3;}i = 0;fclose(file);printf("%s Loaded!\n", filename);}else{printf("File can't be opened\n");}}else{printf("File does not have a .PLY extension. ");}return 0;
}void CPLYLoader::Draw()
{glEnableClientState(GL_VERTEX_ARRAY);glColor3f(0.0f, 0.0f, 0.0f);glVertexPointer(3, GL_FLOAT, 0, mp_vertexXYZ);glDrawArrays(GL_POINTS, 0, this->m_totalConnectedPoints);glDisableClientState(GL_VERTEX_ARRAY);}

7、main.cpp

#include "transform.h"
#include <stdio.h>
#include "PLYloader.h"int width = 640;
int height = 480;
static bool sign = false;
static string p,t;
static char  ptr[100]; void OnMouse(int button, int state, int x, int y)
{if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {cout << "LEFT_DOWN" << endl;mousetate = 1;}elsemousetate = 0;if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN){mousestate1 = 1;}elsemousestate1 = 0;if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN){mousestate2 = 1;}elsemousestate2 = 0;if (state == GLUT_UP && button == 3) {cout << "WHEEL_UP" << endl;scale += 0.02;}else if (state == GLUT_UP && button == 4){cout << "WHEEL_DOWN" << endl;scale -= 0.02;}glutPostRedisplay();
}
void onMouseMove(int x, int y) {timesx = timesy = 0;if (mousetate) {yRotate += (x - Oldx) * 0.4f;}if (mousestate1){xRotate += (y - Oldy) * 0.4f;}Oldx = x;Oldy = y;if (mousestate2){timesx = x;timesy = y;}glutPostRedisplay();}
void mySpecial(int key, int x, int y) {switch (key) {//cx = cy = cz = 0;case GLUT_KEY_F1://按F1主视图xRotate = 0;yRotate = 0;timesx = timesy = 0;break;case GLUT_KEY_F2:xRotate = 92.001;yRotate = 0;timesx = timesy = 0;break;case GLUT_KEY_F3:xRotate = 0;yRotate = 270.4;timesx = timesy = 0;break;default:break;}glutPostRedisplay();
}CPLYLoader plyLoader;
void Initialize()
{glClearColor(1.0, 1.0, 1.0, 0.0);glEnable(GL_DEPTH);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(65, 1, 1, 50);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(12, 12, 20, 0, 0, 0, 0, 1, 0);}void Reshape(int w, int h)
{width = w;height = h;glViewport(0, 0, width, height);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(45.0, (double)width / (double)height, 1.0, 1000.0);
}
void Display()
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//gluLookAt(0.0f, 0.0f, 0.0f, cx, cy, cz,0,0,0);glViewport(0, 0, width, height);glMatrixMode(GL_PROJECTION);glLoadIdentity();glMatrixMode(GL_MODELVIEW);glLoadIdentity();glRotatef(yRotate, 0, 1,0 );glRotatef(xRotate, 1, 0, 0);glTranslatef(timesx*0.001f, -timesy*0.001f, 0.0f);cout << "沿x轴旋转" << xRotate << "沿y轴旋转" << yRotate << endl;glScalef(scale, scale, scale);plyLoader.Draw();glutSwapBuffers();}
int main(int argc, char** argv)
{ModelLoader* model;cout << "输入要处理的文件路径!" << endl;cin >> p;char str[100];p.copy(str, p.size(), 0);char* q = str;if (strstr(q, "las")){cout << "输入要存储的文件路径" << endl;cin >> t;model = new LasLoader(p,t);model->TO_PLY();}else if (strstr(q, "pcd")){cout << "输入要存储的文件路径" << endl;cin >> t;model = new PCDLoader(p,t);model->TO_PLY();}else if (strstr(q, "obj")){cout << "输入要存储的文件路径" << endl;cin >> t;model = new OBJLoader(p,t);model->TO_PLY();}else if (strstr(q, "ply")){model = new ModelLoader();model->savefilename = p;}else {cout << "该文件类型暂不能处理!" << endl;}strcpy(ptr, model->savefilename.c_str());plyLoader.LoadModel(ptr);glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowSize(600, 800);glutInitWindowPosition(100, 100);glutCreateWindow("F1、F2、F3分别进行模型三视图展示,鼠标左右键拖住旋转,鼠标滑轮放缩,鼠标中键拖住平移。");Initialize();glutMouseFunc(OnMouse);glutMotionFunc(onMouseMove);glutSpecialFunc(mySpecial);glutDisplayFunc(Display);glutReshapeFunc(Reshape);glutMainLoop();return 0;}

该代码为笔者c++实习时所写,逻辑格式问题较多,如有疑问请联系笔者,

该代码借鉴网络上部分代码,如有侵权,请联系删除。

c++实习项目3D模型显示系统相关推荐

  1. 英雄联盟(LOL)3d模型显示

    英雄联盟(LOL)3d模型显示. 参考资料:http://code.google.com/p/lolblender/wiki/fileFormats 注:由于版本升级,lol模型的骨骼文件的文件格式发 ...

  2. Unity中将3D模型显示在UI上或者显示在UI前面

    标题 Unity中将3D模型显示在UI上或者显示在UI前面 一.将3D模型显示在UI上-使用RawImage和Render Texture组合实现效果 1.创建一个RawImage控件 2.创建一个R ...

  3. 实现3D模型显示在UI层上面

    在网上搜了很多发现都实现不了我要的结果,故而只能自己做了.方法很简单 因为我的游戏是2D游戏,于是我用了两个正交摄像机(orthigraphic) 第一个摄像机,用来照射UI,第二个摄像机用来照射模型 ...

  4. 基于阿里云实现3D模型显示(WebAR项目)

    基于阿里云实现webar中3D模型的展示 WebAR介绍 demo 网页端html 阿里云服务器配置 WebAR介绍 这个项目是帮朋友做的毕设-原本是四月份就打算写这篇文章的,但是由于各种原因推到了六 ...

  5. Min3D测试-在Android里面载入MMD模型-快速3D模型显示测试-By黑月君

    快速在Android里面实现3D人物显示 一直在研究Android上实现女仆美豆酱(个人助理)的研究,在制作完毕短信和电话提醒功能后,希望可以实现3D人物的快速显示 至少可以独立显示模型及其动作,主要 ...

  6. 记:四周实习项目--XX医院门诊系统

    职位:项目组长 接到的任务是:XX医院门诊系统,采用B/S设计 记得看到任务书的时候第一反应是有点蛋疼,据我所知,医院(我去过的)全是C/S设计的. 主要是就医疗行业来说,业务流程比较繁忙与复杂,处理 ...

  7. UNITY把3D模型显示在UI层级上的思路

    一般UI是处理于显示最高层级的, 因此这里的做法是 使用镜子效果,做镜子可使用renderTexture 然后启用一个摄像机对renderTexture进行数据填充, 然后在ui上使用Raw Imag ...

  8. Sundot实习项目——高考志愿填报系统

    数据库表设计 原则:按照前端展示的形式设计数据库表 1.用户表 name tele address choose year score ranking password email – – – – i ...

  9. Unity中如何通过UI显示3D模型解决方案?

    需求:实现将3D模型显示在2DUI上面,实现王者荣耀英雄商城之中英雄展示功能,3D模型可以旋转,添加特效等正常3D功能. 使用RenderTexture和RawImage做相机映射 使用ScreenS ...

最新文章

  1. Linux vmstat命令详细解读
  2. 【Android】MTK Android 源码开发环境搭建
  3. 自定义Django的admin界面
  4. HotSpot增量Java垃圾收集器
  5. AI 与 5G 时代,实时互联网的下一个风口是什么?
  6. hanlp提取文本关键词的使用方法记录
  7. 配置主机间信任的一个简单办法
  8. linux下往外ping不通-出现ping: unknown host www.baidu.com
  9. 在MFC中获取窗口\视图句柄 &获取当前活动的CView .
  10. 2014-2015年开发的机器人仿真测试平台
  11. 为了面试能通过,我要看完这75道面试题(下)
  12. 微信小程序加入(长按识别)群聊(群二维码)
  13. 获取webservice(wsdl)数据包
  14. 微信小程序原生tabBar基础模板
  15. 银行的存款利率是怎么计算的?
  16. 国内企业云盘哪个好用?
  17. 一图读懂 Unix 时间日期例程相互关系
  18. 香蕉最好别和这些东西一起吃!90%的人根本不知道
  19. 未雨绸缪,迎接运维新时代—— Tech Neo第十六期技术沙龙
  20. C4(1) 三字棋代码实现

热门文章

  1. 关于Z变换及其物理含义
  2. 找工作如何避免培训机构骗局
  3. Unity接入原生Android穿山甲广告
  4. 【java】intellij idea 搭建 maven环境
  5. DOS微信多开高级版
  6. 必备软件——视频播放
  7. java面试题连接集锦
  8. 计算机处理器性能天梯,2021最新版电脑处理器性能天梯图:你的CPU排第几?
  9. 学习Linux你要是不知道这些,那你可能真的都算不上入门!
  10. 309专供 之 桑葚图