如何获取这个PLY里的模型
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何获取这个PLY里的模型相关的知识,希望对你有一定的参考价值。
参考技术A Ply文件由MeshLab导出生成,格式可能和其他软件导出的有出入。本来想把模型文件贴上来,但是找了一下好像不能上传,希望着可留言。
这里贴一下模型文件的开头部分。
-------------------------------------------------------
ply
format ascii 1.0
comment VCGLIB generated
element vertex 6479
property float x
property float y
property float z
property float nx
property float ny
property float nz
property int flags
property uchar red
property uchar green
property uchar blue
property uchar alpha
element face 12954
property list uchar int vertex_indices
property int flags
end_header
0.0363526 0.0894518 0.0166275 -2.58589 -5.26492 -2.22414 0 175 160 84 255
0.0389934 0.088225 0.0166275 -2.52566 -5.33 -2.15753 0 170 156 88 255
0.0389934 0.0894518 0.0138336 -2.41584 -5.1918 -2.5521 0 146 145 86 255
0.0340731 0.0894518 0.0200012 -2.865 -5.39322 -1.43764 0 174 151 78 255
0.0356197 0.0886338 0.0200012 -2.74755 -5.42387 -1.53245 0 168 145 74 255
0.0356197 0.0894518 0.0175829 -2.64306 -5.36739 -1.90754 0 171 156 75 255
......
-------------------------------------------------------
PlyLoader.h
#ifndef PLYREADER_H_
#define PLYREADER_H_
#include <GL/glut.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include <vector>
#include <iostream>
using namespace std;
struct SModelData
vector <float> vecFaceTriangles; // = face * 9
vector <float> vecFaceTriangleColors; // = face * 9
vector <float> vecNormals; // = face * 9
int iTotalConnectedTriangles;
;
class CPLYLoader
public:
CPLYLoader();
int LoadModel(char *filename);
void Draw();
private:
float* mp_vertexXYZ;
float* mp_vertexNorm;
float* mp_vertexRGB;
int m_totalConnectedQuads;
int m_totalConnectedPoints;
int m_totalFaces;
SModelData m_ModelData;
;
#endif本回答被提问者和网友采纳
二进制格式 PLY 模型文件的读取与渲染
PLY 文件头部信息:
ply
format binary_little_endian 1.0
comment VCGLIB generated
element vertex 13469
property float x
property float y
property float z
property float nx
property float ny
property float nz
property uchar red
property uchar green
property uchar blue
property uchar alpha
element face 26934
property list uchar int vertex_indices
end_header
完整可运行的 C++ 代码(基于 GLUT)
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <cstdlib>
using namespace std;
const int TRANSFORM_NONE = 0;
const int TRANSFORM_ROTATE = 1;
const int TRANSFORM_SCALE = 2;
const int TRANSFORM_TRANSLATE = 3;
static int press_x, press_y;
const int LIGHT_NUM = 3;
int current_light = 0;
static float x_angle = 0.0;
static float y_angle = 0.0;
static float scale_size = 1;
static float x_dist = 0.0;
static float y_dist = 0.0;
static int obj_mode = 0;
static int xform_mode = 0;
static int proj_mode = 0;
// 存储定点信息
struct Vertex
{
double x, y, z;
double r, g, b, a;
double nx, ny, nz;
};
// 存储与表面相关的顶点
struct Face
{
int v1, v2, v3;
};
vector<Vertex> vertices;
vector<Face> faces;
// 加载 PLY 文件;此处为了方便硬编码有关格式;格式参考:http://paulbourke.net/dataformats/ply/
bool load_ply()
{
char fname[] = "data.ply";
FILE* f = fopen(fname, "rb");
if (f == NULL)
{
cout << "file " << fname << " does not exist" << endl;
return false;
}
int counter = 0;
while (counter < 17)
{
char c;
fread((void*)(&c), sizeof(c), 1, f);
if (c == '
') {
counter++;
}
}
int vertex_num = 13469;
int face_num = 26934;
for (int i = 0; i < vertex_num; i++) {
float x, y, z;
fread((void*)(&x), 4, 1, f);
fread((void*)(&y), 4, 1, f);
fread((void*)(&z), 4, 1, f);
float nx, ny, nz;
fread((void*)(&nx), 4, 1, f);
fread((void*)(&ny), 4, 1, f);
fread((void*)(&nz), 4, 1, f);
unsigned char r, g, b, a;
fread((void*)(&r), 1, 1, f);
fread((void*)(&g), 1, 1, f);
fread((void*)(&b), 1, 1, f);
fread((void*)(&a), 1, 1, f);
Vertex vertex;
vertex.x = x / 1000;
vertex.y = y / 1000;
vertex.z = z / 1000;
vertex.nx = nx;
vertex.ny = ny;
vertex.nz = nz;
vertex.r = r;
vertex.g = g;
vertex.b = b;
vertex.a = a;
vertices.push_back(vertex);
}
for (int i = 0; i < face_num; i++) {
unsigned char n;
int v1, v2, v3;
fread((unsigned char*)(&n), 1, 1, f);
fread((void*)(&v1), 4, 1, f);
fread((void*)(&v2), 4, 1, f);
fread((void*)(&v3), 4, 1, f);
Face face;
face.v1 = v1;
face.v2 = v2;
face.v3 = v3;
faces.push_back(face);
}
fclose(f);
return true;
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glutPostRedisplay();
}
void display(void)
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glShadeModel(GL_SMOOTH);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);
// 设置光源
GLfloat light_position[] = { 0.0, 0.0, 1.0, 1.0 };
GLfloat light_direction[] = { 0.0, 0.0, -1.0 };
GLfloat white_color[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat red_color[] = { 1.0, 0.0, 0.0, 1.0 };
GLfloat green_color[] = { 0.0, 1.0, 0.0, 1.0 };
GLfloat blue_color[] = { 0.0, 0.0, 1.0, 1.0 };
GLfloat exponent[] = { 10.0f };
GLfloat cutoff[] = { 20.0f };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
switch (current_light)
{
case 1:
cutoff[0] = 45;
exponent[0] = 20;
glLightfv(GL_LIGHT0, GL_SPOT_EXPONENT, exponent);
glLightfv(GL_LIGHT0, GL_SPOT_CUTOFF, cutoff);
glLightfv(GL_LIGHT0, GL_SPECULAR, white_color);
break;
case 2:
glLightfv(GL_LIGHT0, GL_SPECULAR, green_color);
glLightfv(GL_LIGHT0, GL_DIFFUSE, green_color);
glLightfv(GL_LIGHT0, GL_AMBIENT, green_color);
glLightfv(GL_LIGHT0, GL_SPOT_EXPONENT, exponent);
glLightfv(GL_LIGHT0, GL_SPOT_CUTOFF, cutoff);
glLightfv(GL_LIGHT0, GL_SPECULAR, white_color);
break;
default:
exponent[0] = 0;
cutoff[0] = 180;
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_direction);
glLightfv(GL_LIGHT0, GL_SPOT_EXPONENT, exponent);
glLightfv(GL_LIGHT0, GL_SPOT_CUTOFF, cutoff);
glLightfv(GL_LIGHT0, GL_SPECULAR, white_color);
glLightfv(GL_LIGHT0, GL_DIFFUSE, white_color);
glLightfv(GL_LIGHT0, GL_AMBIENT, white_color);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0);
break;
}
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glTranslatef(x_dist, -y_dist, 0);
glRotatef(x_angle, 0, 1, 0);
glRotatef(y_angle, 1, 0, 0);
glScalef(scale_size, scale_size, scale_size);
glEnable(GL_LIGHTING);
for (int i = 0; i < (int)faces.size(); i++)
{
Face f = faces[i];
Vertex v1 = vertices[f.v1];
Vertex v2 = vertices[f.v2];
Vertex v3 = vertices[f.v3];
glBegin(GL_TRIANGLES);
glColor3f(1, 0, 0);
glNormal3f(v1.nx, v1.ny, v1.nz);
glVertex3f(v1.x, v1.y, v1.z);
glNormal3f(v2.nx, v2.ny, v2.nz);
glVertex3f(v2.x, v2.y, v2.z);
glNormal3f(v3.nx, v3.ny, v3.nz);
glVertex3f(v3.x, v3.y, v3.z);
glEnd();
}
glutSwapBuffers();
}
void mouse(int button, int state, int x, int y)
{
if (state == GLUT_DOWN)
{
press_x = x; press_y = y;
if (button == GLUT_LEFT_BUTTON)
xform_mode = TRANSFORM_ROTATE;
else if (button == GLUT_MIDDLE_BUTTON)
xform_mode = TRANSFORM_TRANSLATE;
else if (button == GLUT_RIGHT_BUTTON)
xform_mode = TRANSFORM_SCALE;
}
else if (state == GLUT_UP)
{
xform_mode = TRANSFORM_NONE;
}
}
void mouseMotion(int x, int y)
{
if (xform_mode == TRANSFORM_ROTATE)
{
x_angle += (x - press_x) / 5.0;
if (x_angle > 180)
x_angle -= 360;
else if (x_angle < -180)
x_angle += 360;
press_x = x;
y_angle += (y - press_y) / 5.0;
if (y_angle > 180)
y_angle -= 360;
else if (y_angle < -180)
y_angle += 360;
press_y = y;
}
else if (xform_mode == TRANSFORM_SCALE)
{
float old_size = scale_size;
scale_size *= (1 + (y - press_y) / 60.0);
if (scale_size < 0)
scale_size = old_size;
press_y = y;
}
else if (xform_mode == TRANSFORM_TRANSLATE)
{
x_dist += (x - press_x) / 50.0;
press_x = x;
y_dist += (y - press_y) / 50.0;
press_y = y;
}
// force the redraw function
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'l':
current_light++;
current_light %= LIGHT_NUM;
cout << "Change light source:" << current_light << endl;
break;
case 'd':
x_dist += 0.05;
break;
case 'a':
x_dist -= 0.05;
break;
case 's':
y_dist += 0.05;
break;
case 'w':
y_dist -= 0.05;
break;
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
cout << "Help:
1. Press W A S D to move model.
2. Press L to change light source.
3. Drag mouse's left button to rotate model.
4. Drag mouse's right button to move model." << endl;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(600, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("Team Project");
if (!load_ply())
{
cerr << "Load ply file failed!" << endl;
return -1;
}
glClearColor(0.0, 0.0, 0.0, 0.0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(mouseMotion);
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutMainLoop();
return 1;
}
以上是关于如何获取这个PLY里的模型的主要内容,如果未能解决你的问题,请参考以下文章
php 如何通过session id获取session里的数据?