读stl模型的数据

//xlFileStream.h

#pragma once
#include <Windows.h>
#include <tchar.h>
//xlFileStream.h
struct FileHeader
{
	wchar_t			Author[32];				// 文件的创建人
	wchar_t			Company[32];			// 创建人的单位
	char			Version[34];			// GUID,表示版本

	unsigned int 	Count;					// 所含Node的数量

	char			Reserved[90];			// 保留字节
};

class FileStream
{
private:
	HANDLE		m_hFile;
	bool		m_bTmpFile;

	char* __Version__;

public:
	void Close( )
	{
		CloseHandle( m_hFile );
		m_hFile = NULL;
	}

	bool CreateFile( const wchar_t lpwszPathName[] )
	{
		if(m_bTmpFile)
			m_hFile = ::CreateFile(lpwszPathName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
		else
			m_hFile = ::CreateFile(lpwszPathName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

		if(m_hFile == INVALID_HANDLE_VALUE)
		{
			m_hFile = NULL;
			return false;
		}
		return true;
	}

	bool OpenFile( const wchar_t  lpwszPathName[] )
	{
		if(m_bTmpFile)
			m_hFile = ::CreateFile(lpwszPathName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
		else
			m_hFile = ::CreateFile(lpwszPathName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

		if(m_hFile == INVALID_HANDLE_VALUE)
		{
			m_hFile = NULL;
			return false;
		}
		return true;
	}

	BOOL Read( void* pv, ULONG cb, LPOVERLAPPED lpOverlapped = NULL)
	{
		ULONG pcbRead;
		BOOL bRet = ReadFile(m_hFile, pv, cb, &pcbRead, lpOverlapped);
		if(!bRet)
			return false;
		if(cb != pcbRead)
			return false;
		else
			return true;
	}

	BOOL Write( void const* pv, ULONG cb, LPOVERLAPPED lpOverlapped = NULL)
	{
		ULONG pcbWritten;
		BOOL bRet = WriteFile(m_hFile, pv, cb, &pcbWritten, lpOverlapped);
		if(!bRet)
			return false;
		if(cb != pcbWritten)
			return false;
		else
			return true;
	}

	bool WriteHeader(unsigned int Count, wchar_t Author[] = NULL, wchar_t Company[] = NULL)
	{
		FileHeader header;
		if(Author != NULL)
			wcscpy_s(header.Author, wcslen(Author) + 1, Author);
		if(Company != NULL)
			wcscpy_s(header.Company, wcslen(Company) + 1, Company);
		strcpy_s(header.Version, 34, __Version__);
		header.Count = Count;

		BOOL bRet = Write(&header, sizeof(FileHeader));
		if(!bRet)
			return false;
		return true;
	}

	bool ReadHeader(unsigned int& Count, wchar_t Author[] = NULL, wchar_t Company[] = NULL)
	{
		FileHeader header;
		if(Read(&header, sizeof(FileHeader)))
		{
			if(Author != NULL)
				wcscpy_s(Author, wcslen(header.Author) + 1, header.Author);
			if(Company != NULL)
				wcscpy_s(Company, wcslen(header.Company) + 1, header.Company);
			Count = header.Count;

			if(strncmp(__Version__, header.Version, 32) != 0)
				false;
		}

		return true;
	}

public:
	FileStream( bool bTmpFile = false )  : m_hFile(0), m_bTmpFile(bTmpFile)
	{
		__Version__ = "691287C840924b6aB3C98F8C278FF967";
	}

	~FileStream( void )
	{
		CloseHandle( m_hFile );
	}
};


xlSortPoints.h

// xlSortPoints.h
// 用于完成空间点的最小堆算法,具体的

#pragma once

#include <math.h>
#include <float.h>

#include <vector>
#include <map>
using namespace std;

namespace SortPoint
{
	struct tagIndex { int i; int j; int k; };

	inline bool operator < (const tagIndex& ind1, const tagIndex& ind2)
	{
		if(ind1.i < ind2.i) return true;
		else if(ind1.i > ind2.i) return false;
		else if(ind1.j < ind2.j) return true;
		else if(ind1.j > ind2.j) return false;
		else if(ind1.k < ind2.k) return true;
		else return false;
	}

	inline bool operator > (const tagIndex& ind1, const tagIndex& ind2)
	{
		if(ind1.i > ind2.i) return true;
		else if(ind1.i < ind2.i) return false;
		else if(ind1.j > ind2.j) return true;
		else if(ind1.j < ind2.j) return false;
		else if(ind1.k > ind2.k) return true;
		else return false;
	}

	inline bool operator == (const tagIndex& ind1, const tagIndex& ind2)
	{
		if(ind1 < ind2) return false;
		else if(ind1 > ind2) return false;
		else return true;
	}

	template<typename Real>
	class CSortPoints
	{
	private:
		map<tagIndex, vector<int>> m_mapSortedPoints;
		Real	m_fOrg[3];
		Real	m_fUnit;
		Real	m_fMinDist;

		inline void GetIndex(const Real point[3], tagIndex& ind)
		{
			ind.i = int((point[0] - m_fOrg[0]) / m_fUnit);
			ind.j = int((point[1] - m_fOrg[1]) / m_fUnit);
			ind.k = int((point[2] - m_fOrg[2]) / m_fUnit);
		}

	public:
		inline int insert_point(Real pt[3], vector<Real>& points)
		{
			size_t i;
			int index;
			tagIndex ind, tmp;
			GetIndex(pt, ind);

			map<tagIndex, vector<int>>::iterator iter;
			for(tmp.i = ind.i - 1; tmp.i < ind.i + 2; tmp.i++)
			{
				for(tmp.j = ind.j - 1; tmp.j < ind.j + 2; tmp.j++)
				{
					for(tmp.k = ind.k - 1; tmp.k < ind.k + 2; tmp.k++)
					{
						iter = m_mapSortedPoints.find(tmp);
						if(iter != m_mapSortedPoints.end())
						{
							vector<int>& bucket = m_mapSortedPoints[tmp];
							for(i = 0; i < bucket.size(); i++)
							{
								index = bucket[i] * 3;
								if( (fabs(points[index + 0] - pt[0]) < m_fMinDist) && 
									(fabs(points[index + 1] - pt[1]) < m_fMinDist) && 
									(fabs(points[index + 2] - pt[2]) < m_fMinDist) )
								{
									return bucket[i];
								}
							}
						}
					}
				}
			}

			int ret = points.size() / 3;

			points.push_back(pt[0]);
			points.push_back(pt[1]);
			points.push_back(pt[2]);

			m_mapSortedPoints[ind].push_back(ret);

			return ret;
		}

		inline int NearestPoint(const vector<Real>& points, Real pt[])
		{
			tagIndex ind, tmp;
			GetIndex(pt, ind);

			size_t i;
			Real min = FLT_MAX;
			int ret = -1, index;

			map<tagIndex, vector<int>>::iterator iter;
			for(tmp.i = ind.i - 1; tmp.i < ind.i + 2; tmp.i++)
			{
				for(tmp.j = ind.j - 1; tmp.j < ind.j + 2; tmp.j++)
				{
					for(tmp.k = ind.k - 1; tmp.k < ind.k + 2; tmp.k++)
					{
						iter = m_mapSortedPoints.find(tmp);
						if(iter != m_mapSortedPoints.end())
						{
							vector<int>& bucket = m_mapSortedPoints[tmp];
							for(i = 0; i < bucket.size(); i++)
							{
								index = bucket[i] * 3;
								Real dist = pow(points[index + 0] - pt[0], 2) + pow(points[index + 1] - pt[1], 2) +
									pow(points[index + 2] - pt[2], 2);
								if(dist < min)
								{
									min = dist;
									ret = index;
								}
							}
						}
					}
				}
			}
			return ret / 3;
		}

		inline int NearestPoint(const vector<Real>& points, Real x, Real y, Real z)
		{
			Real pt[] = { x, y, z };
			return NearestPoint(points, pt);
		}

		inline int NearestPoint(const vector<Real>& points, const Real* pt)
		{
			Real p[] = { pt[0], pt[1], pt[2] };
			return NearestPoint(points, p);
		}

		Real GaussUnit(const vector<Real>& points)
		{
			Real range[6] = {
				DBL_MAX, -DBL_MAX,
				DBL_MAX, -DBL_MAX,
				DBL_MAX, -DBL_MAX,
			};

			unsigned int i, ptsize = points.size() / 3;

			for(i = 0; i < ptsize; i++)
			{
				const Real& x = points[i * 3 + 0];
				const Real& y = points[i * 3 + 1];
				const Real& z = points[i * 3 + 2];

				if(x < range[0]) range[0] = x;
				if(x > range[1]) range[1] = x;

				if(y < range[2]) range[2] = y;
				if(y > range[3]) range[3] = y;

				if(z < range[4]) range[4] = z;
				if(z > range[5]) range[5] = z;
			}

			return 2 * pow((range[1] - range[0]) * (range[3] - range[2]) * (range[5] - range[4]) / ptsize, 1/3.0);
		}

		inline void init(Real org[3], Real unit)
		{
			m_fOrg[0] = org[0]; m_fOrg[1] = org[1]; m_fOrg[2] = org[2];
			m_fUnit = unit;
		}

		inline void init(const vector<Real>& points, Real org[3], Real unit)
		{
			m_fOrg[0] = org[0]; m_fOrg[1] = org[1]; m_fOrg[2] = org[2];
			m_fUnit = unit;

			tagIndex ind;
			unsigned int size = points.size() / 3;
			for(unsigned int i = 0; i < size; i++)
			{
				GetIndex(&(points[i * 3]), ind);

				m_mapSortedPoints[ind].push_back(i);
			}
		}

		inline void init(const vector<Real>& points)
		{
			m_fOrg[0] = points[0]; m_fOrg[1] = points[1]; m_fOrg[2] = points[2];
			m_fUnit = GaussUnit(points);

			tagIndex ind;
			unsigned int size = points.size() / 3;
			for(unsigned int i = 0; i < size; i++)
			{
				GetIndex(&(points[i * 3]), ind);

				m_mapSortedPoints[ind].push_back(i);
			}
		}

		inline void clear()
		{
			m_mapSortedPoints.clear();
		}

		CSortPoints(Real min_dist = 1.0e-6f) : m_fMinDist(min_dist)
		{
		}

		~CSortPoints()
		{
		}
	};

}

stl.cpp

inline float GetUnit(float x[3], float y[3], float z[3])
{
	float ret[3];
	ret[0] = fabs(x[0] - y[0]) > fabs(x[1] - y[1]) ? fabs(x[0] - y[0]) : fabs(x[1] - y[1]);
	if (fabs(x[2] - y[2]) > ret[0]) ret[0] = fabs(x[2] - y[2]);

	ret[1] = fabs(x[0] - z[0]) > fabs(x[1] - z[1]) ? fabs(x[0] - z[0]) : fabs(x[1] - z[1]);
	if (fabs(x[2] - z[2]) > ret[1]) ret[1] = fabs(x[2] - z[2]);

	ret[2] = fabs(z[0] - y[0]) > fabs(z[1] - y[1]) ? fabs(z[0] - y[0]) : fabs(z[1] - y[1]);
	if (fabs(z[2] - y[2]) > ret[2]) ret[2] = fabs(z[2] - y[2]);

	if (ret[0] > ret[1]) ret[0] = ret[1];
	if (ret[0] > ret[2]) ret[0] = ret[2];
	return ret[0];
}

inline bool ReadSTL(const wchar_t* wszPath, vector<float>& points, vector<float>& normals, vector<__int32>& triangles)
{
	ifstream infile(wszPath);
	if (!infile)
		return false;

	float org[3], unit;
	float n[3]; float x[3]; float y[3]; float z[3];
	char unusered[2];

	int ix, iy, iz;

	SortPoint::CSortPoints<float> sorted_points;

	char string[256] = "";

	infile >> string;	//read "solid"
	if (_strnicmp(string, "solid", 5) != 0)		// 二进制
	{
		infile.close();

		FileStream fStream;
		if (!fStream.OpenFile(wszPath))
			return false;

		char info[90];
		int size;

		fStream.Read(info, sizeof(char) * 80);
		fStream.Read(&size, sizeof(int));

		for (int i = 0; i < size; i++)
		{
			fStream.Read(n, sizeof(float) * 3);
			fStream.Read(x, sizeof(float) * 3);
			fStream.Read(y, sizeof(float) * 3);
			fStream.Read(z, sizeof(float) * 3);
			fStream.Read(unusered, sizeof(char) * 2);

			if (points.size() == 0)
			{
				unit = GetUnit(x, y, z);
				org[0] = x[0]; org[1] = x[1]; org[2] = x[2];

				sorted_points.init(org, unit);
			}

			normals.push_back(n[0]); normals.push_back(n[1]); normals.push_back(n[2]);

			ix = sorted_points.insert_point(x, points);
			iy = sorted_points.insert_point(y, points);
			iz = sorted_points.insert_point(z, points);

			if (ix != iy && iy != iz && ix != iz)
				triangles.push_back(ix); triangles.push_back(iy); triangles.push_back(iz);
		}
		return true;
	}
	else		// 文本
	{
		while (_strnicmp(string, "facet", 5) != 0)	// 读到facet为止
			infile >> string;

		do
		{
			infile >> string;	//read "normal"
			infile >> n[0] >> n[1] >> n[2];

			infile >> string;	//read "outer"
			infile >> string;	//read "loop"

			infile >> string;	//read "vertex"
			infile >> x[0] >> x[1] >> x[2];

			infile >> string;	//read "vertex"
			infile >> y[0] >> y[1] >> y[2];

			infile >> string;	//read "vertex"
			infile >> z[0] >> z[1] >> z[2];

			if (points.size() == 0)
			{
				unit = GetUnit(x, y, z);
				org[0] = x[0]; org[1] = x[1]; org[2] = x[2];

				sorted_points.init(org, unit);
			}

			normals.push_back(n[0]); normals.push_back(n[1]); normals.push_back(n[2]);

			ix = sorted_points.insert_point(x, points);
			iy = sorted_points.insert_point(y, points);
			iz = sorted_points.insert_point(z, points);

			triangles.push_back(ix); triangles.push_back(iy); triangles.push_back(iz);

			infile >> string;	// read "endloop"
			infile >> string;	// read "endfacet"
			infile >> string;	// read "facet" or "endsolid"
			if (_strnicmp(string, "endsolid", 8) == 0)
			{
				infile >> string;
				if (_strnicmp(string, "solid", 8) == 0)
					infile >> string;
				else
					break;
			}
		} while (_strnicmp(string, "facet", 5) == 0);

		infile.close();
		return true;
	}

	return false;
}

inline bool WriteSTL(const wchar_t* wszPath, vector<float>& points, bool bBinary)
{
	if (!bBinary)
	{
		ofstream file(wszPath);
		if (!file)
			return false;

		file << "Solid" << endl;
		for (size_t i = 0; i < points.size(); i += 12)
		{
			file << "  Facet Normal " << points[i + 0] << " " << points[i + 1] << " " << points[i + 2] << endl;
			file << "    Outer Loop" << endl;
			file << "      Vertex   " << points[i + 3] << " " << points[i + 4] << " " << points[i + 5] << endl;
			file << "      Vertex   " << points[i + 6] << " " << points[i + 7] << " " << points[i + 8] << endl;
			file << "      Vertex   " << points[i + 9] << " " << points[i + 10] << " " << points[i + 11] << endl;
			file << "    Endloop" << endl;
			file << "  Endfacet" << endl;
		}
		file << "Endsolid" << endl;
		file.close();
	}
	else
	{
		//iostream fStream;
		FileStream fStream;
		if (!fStream.CreateFile(wszPath))
			return false;

		char info[90];
		int size = points.size() / 12;

		fStream.Write(info, sizeof(char) * 80);
		fStream.Write(&size, sizeof(int));

		for (int i = 0; i < size; i++)
		{
			fStream.Write(&(points[i * 12]), sizeof(float) * 12);
			char reserved[2];
			fStream.Write(reserved, sizeof(char) * 2);
		}
	}

	return true;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值