📄 stlreader.cpp
字号:
#include <Windows.h>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cmath>
#include <gl/GL.h>
#include "STLReader.h"
#define GET_NORMAL(i) \
sscanf(buf, "%s %s %s %s %s", buf_t, buf_t, buf_x, buf_y, buf_z); \
m_pTriangles[(i)].normal.x = ::EToD(buf_x); \
m_pTriangles[(i)].normal.y = ::EToD(buf_y); \
m_pTriangles[(i)].normal.z = ::EToD(buf_z);
#define GET_VERTEX(i) \
sscanf(buf, "%s %s %s %s", buf_t, buf_x, buf_y, buf_z); \
m_pTriangles[(i)].vertexs[0].x = ::EToD(buf_x); \
m_pTriangles[(i)].vertexs[0].y = ::EToD(buf_y); \
m_pTriangles[(i)].vertexs[0].z = ::EToD(buf_z); \
fgets(buf, BUFFER_SIZE, pModelFile); \
sscanf(buf, "%s %s %s %s", buf_t, buf_x, buf_y, buf_z); \
m_pTriangles[(i)].vertexs[1].x = ::EToD(buf_x); \
m_pTriangles[(i)].vertexs[1].y = ::EToD(buf_y); \
m_pTriangles[(i)].vertexs[1].z = ::EToD(buf_z); \
fgets(buf, BUFFER_SIZE, pModelFile); \
sscanf(buf, "%s %s %s %s", buf_t, buf_x, buf_y, buf_z); \
m_pTriangles[(i)].vertexs[2].x = ::EToD(buf_x); \
m_pTriangles[(i)].vertexs[2].y = ::EToD(buf_y); \
m_pTriangles[(i)].vertexs[2].z = ::EToD(buf_z);
double EToD(char *num)
{/*将科学计数法转换成double型*/
char d[BUFFER_SIZE];
char e[BUFFER_SIZE];
int i;
for (i = 0; i < BUFFER_SIZE && !(num[i] == 'e' || num[i] == 'E') && num[i] != '\0'; ++i)
{
d[i] = num[i];
}
if (num[i] == '\0')
{
return atof(num);
}
d[++i] = '\0';
strcpy_s(e, num+i);
//printf_s("%s\n", num);
//printf_s("%s : %f\n", d, atof(d));
//printf_s("%s : %d\n", e, atoi(e));
//printf_s("%f\n\n", atof(d)*pow(10.0, atoi(e)));
return atof(d)*pow(10.0, atoi(e));
}
CModel3D::CModel3D()
{
m_nTriangles = 0;
m_pTriangles = NULL;
m_bIsWired = true;
m_bIsShaded = false;
m_fColor[0] = 1.0;
m_fColor[1] = 1.0;
m_fColor[2] = 0.0;
m_fColor[3] = 1.0;
}
CModel3D::~CModel3D()
{
clearModel();
}
void CModel3D::clearModel()
{/*清除模型*/
if (m_pTriangles)
{
m_nTriangles = 0;
delete [] m_pTriangles;
m_pTriangles = NULL;
}
}
void CModel3D::doCount(FILE* pModelFile)
{/*统计STL文件中三角形数目*/
char buf[BUFFER_SIZE];
char buf_t[BUFFER_SIZE];
while(!feof(pModelFile))
{
fgets(buf, BUFFER_SIZE, pModelFile);
sscanf_s(buf, "%s", buf_t);
switch (buf_t[0])
{
case 'f':
++m_nTriangles;
break;
default:
break;
}
}
rewind(pModelFile);
}
void CModel3D::readData(FILE *pModelFile)
{/*根据统计结果分配空间,读入数据*/
char buf[BUFFER_SIZE];
char buf_t[BUFFER_SIZE];
char buf_x[BUFFER_SIZE];
char buf_y[BUFFER_SIZE];
char buf_z[BUFFER_SIZE];
unsigned i = 0;
m_pTriangles = new CTriangle[m_nTriangles+1];
while(!feof(pModelFile))
{
fgets(buf, BUFFER_SIZE, pModelFile);
sscanf_s(buf, "%s", buf_t);
// printf_s("%s\n", buf);
switch(buf_t[0])
{
case 'f':
++i;
GET_NORMAL(i)
break;
case 'v':
GET_VERTEX(i)
break;
case 's':
sscanf(buf, "%s %s", buf_t, m_strModelName);
break;
default:
break;
}
}
}
bool CModel3D::readFromSTL(char* fileName)
{/*读入STL文件时只需要调用此函数*/
/*打开文件*/
FILE* pModelFile = NULL;
fopen_s(&pModelFile, fileName, "r");
if (pModelFile == NULL)
{
fprintf_s(stderr, "File Open Error : file %s\n", fileName);
return false;
}
/*打开成功后复制文件名*/
strcpy_s(m_strFileName, fileName);
/*清除上一个模型*/
clearModel();
/*统计三角形数目*/
doCount(pModelFile);
/*读入数据*/
if (m_nTriangles)
{
readData(pModelFile);
computeBoundBox();
}
fclose(pModelFile);
return true;
}
void CModel3D::renderModel()
{/*显示模型*/
if (m_bIsWired && !m_bIsShaded)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDisable(GL_LIGHTING);
}
if (!m_bIsWired && m_bIsShaded)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_LIGHTING);
}
if (m_bIsWired && m_bIsShaded)
{
glPolygonOffset(1.0, 1.0);
glEnable(GL_LIGHTING);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
glColor3fv(m_fColor);
for (unsigned i = 1; i <= m_nTriangles; ++i)
{
glBegin(GL_POLYGON);
glNormal3d(m_pTriangles[i].normal.x, m_pTriangles[i].normal.y, m_pTriangles[i].normal.z);
glVertex3d(m_pTriangles[i].vertexs[0].x, m_pTriangles[i].vertexs[0].y, m_pTriangles[i].vertexs[0].z);
glVertex3d(m_pTriangles[i].vertexs[1].x, m_pTriangles[i].vertexs[1].y, m_pTriangles[i].vertexs[1].z);
glVertex3d(m_pTriangles[i].vertexs[2].x, m_pTriangles[i].vertexs[2].y, m_pTriangles[i].vertexs[2].z);
glEnd();
}
if (m_bIsWired && m_bIsShaded)
{
glDisable(GL_POLYGON_OFFSET_FILL);
glDisable(GL_LIGHTING);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(0.0, 1.0, 0.0);
for (unsigned i = 1; i <= m_nTriangles; ++i)
{
glBegin(GL_POLYGON);
glVertex3d(m_pTriangles[i].vertexs[0].x, m_pTriangles[i].vertexs[0].y, m_pTriangles[i].vertexs[0].z);
glVertex3d(m_pTriangles[i].vertexs[1].x, m_pTriangles[i].vertexs[1].y, m_pTriangles[i].vertexs[1].z);
glVertex3d(m_pTriangles[i].vertexs[2].x, m_pTriangles[i].vertexs[2].y, m_pTriangles[i].vertexs[2].z);
glEnd();
}
}
}
void CModel3D::showInfo()
{/*显示模型信息*/
printf_s("Model Name\t: %s\n", m_strModelName);
printf_s("Model File\t: %s\n", m_strFileName);
printf_s("Number of Triangles\t: %d\n", m_nTriangles);
printf_s("The Center of Model\t: %f,\t%f,\t%f\n", m_stCenter.x, m_stCenter.y, m_stCenter.z);
printf_s("The Range of X-axis\t: %f\t%f\n", m_stBox.min.x, m_stBox.max.x);
printf_s("The Range of Y-axis\t: %f\t%f\n", m_stBox.min.y, m_stBox.max.y);
printf_s("The Range of Z-axis\t: %f\t%f\n", m_stBox.min.z, m_stBox.max.z);
}
void CModel3D::computeBoundBox()
{/*计算包围盒*/
m_stBox.max.x = -1.7E+308;
m_stBox.max.y = -1.7E+308;
m_stBox.max.z = -1.7E+308;
m_stBox.min.x = 1.7E+308;
m_stBox.min.y = 1.7E+308;
m_stBox.min.z = 1.7E+308;
CPoint3D& max = m_stBox.max;
CPoint3D& min = m_stBox.min;
for (unsigned i = 1; i <= m_nTriangles; ++i)
{
for (int j = 0; j < 3; ++j)
{
if (m_pTriangles[i].vertexs[j].x > max.x)
{
max.x = m_pTriangles[i].vertexs[j].x;
}
if (m_pTriangles[i].vertexs[j].y > max.y)
{
max.y = m_pTriangles[i].vertexs[j].y;
}
if (m_pTriangles[i].vertexs[j].z > max.z)
{
max.z = m_pTriangles[i].vertexs[j].z;
}
if (m_pTriangles[i].vertexs[j].x < min.x)
{
min.x = m_pTriangles[i].vertexs[j].x;
}
if (m_pTriangles[i].vertexs[j].y < min.y)
{
min.y = m_pTriangles[i].vertexs[j].y;
}
if (m_pTriangles[i].vertexs[j].z < min.z)
{
min.z = m_pTriangles[i].vertexs[j].z;
}
}
}
m_stCenter.x = 0.5*(max.x+min.x);
m_stCenter.y = 0.5*(max.y+min.y);
m_stCenter.z = 0.5*(max.z+min.z);
m_dbDiagonal = sqrt(pow(max.x-min.x, 2) + pow(max.y-min.y, 2) + pow(max.z-min.z, 2));
}
void CModel3D::computeNormal()
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -