⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stlreader.cpp

📁 关于stl模型的加载
💻 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 + -