//实体类
class CSTLSolid
{
public:
//constructor and destructor
CSTLSolid()
{
m_bInitialized=FALSE;
m_pIntersections=NULL;
}
~CSTLSolid(void) {delete []m_pIntersections;}
// Implementation
void WriteArchive(CArchive& archive);
int Initialize(const char* fileName); //Succeed if return zero, else return -1.
int CutSlice(double ,C2DContour&);
void Find_Min_Max_Value(CSTLPoint&, int );
// Attributes
STLPointArray m_points;
STLEdgeArray m_edges;
STLFaceArray m_faces;
BOOL m_bInitialized; //当前实体是否已经初始化
BOOL blReportFaceErr; //模型出现错误是否报告[报告/忽略]
STLIntersection* m_pIntersections; //记录切片所得到的交点
double m_xMin ,m_xMax ,m_yMin ,m_yMax ,m_zMin ,m_zMax;
double m_modeheight;
protected:
// Implementation
void InitIntersections(void); //初始化交点矩阵
public:
// 重新计算法向量<没有错误返回0><返回错误数目>
int ReCalNormal(void);
void RemoveAll(void);
};
int CSTLSolid::Initialize(const char* fileName)
{
/*********************Begin initialization**********************
***************************************************************/
LONG fileSize=0; //文件大小
ULONG totalFaces=0; //总面数
ULONG pointCounter=0; //点计数器
ULONG edgeCounter=0; //边计数器
ULONG faceCounter=0; //面计数器
/**********************Read STL file****************************
***************************************************************/
//Open as ASCII STL file
ifstream inputFile(fileName, ios::in | ios::_Nocreate);
if (inputFile.bad()) //损坏的文件
{
globalErrorMessage.SetErrorMsg("损坏的文件!");
globalErrorMessage.ShowErrorMsg();
inputFile.close();
return -1;
}
inputFile.seekg(0,ios::end);
if ( (fileSize=inputFile.tellg()) == -1L )//空文件
{
globalErrorMessage.SetErrorMsg("空文件错误!");
globalErrorMessage.ShowErrorMsg();
inputFile.close();
return -1;
}
inputFile.seekg(0,ios::beg);
//Check if "inputFile" is an ASCII file
//and search the occurrence of "facet".
LONG filePtr;
STLFILETYPE fileType=NONSTLFILE;
if (IsASCIISTLFile(inputFile, filePtr)) //判断文件格式为ASCII文件还是BINARY文件
{
inputFile.seekg(filePtr, ios::beg); //Rewind file pointer to ''facet"
// totalFaces=fileSize/250; //总面片数 <不适用于多种软件生成的ASCII文件>
fileType=ASCIISTLFILE; //标记为ASCII文件
}
else
{
inputFile.close();
inputFile.open(fileName, ios::in | ios::_Nocreate | ios::binary);
inputFile.seekg(80, ios::beg);
if (inputFile.bad()) //不可读文件
{
globalErrorMessage.SetErrorMsg("Binary STL不可读!");
globalErrorMessage.ShowErrorMsg();
inputFile.close();
return -1;
}
//取得总面片数
inputFile.read(( char* )(&totalFaces), sizeof (totalFaces));
if (inputFile.bad())
{
globalErrorMessage.SetErrorMsg("Binary STL不可读!");
globalErrorMessage.ShowErrorMsg();
inputFile.close();
return -1;
}
fileType=BINSTLFILE;
}
//Read STL file . Note: "inputFile" has been seeked to
//"facet" and "totalFaces" has already been setted .
CSTLPoint point;
CSTLFace face;
if (fileType==ASCIISTLFILE)
{
//Read ASCII STL File beginning at "facet" 读取ASCII文件
char buff[25];
//Set temporary array size
// tempPointArray.SetSize(totalFaces*3); //因为改为面片计数。此处修改
// m_faces.SetSize(totalFaces);
while(1)
{
inputFile>>buff;
//The file pointer reaches the "facet" or the file ends ?
if (_strnicmp(buff, "facet", strlen("facet"))!=0)
break;
//Read normal vector 读取法向量
if(!ReadKeyword(inputFile,"normal"))
return -1;
point.ReadSTLFile(inputFile,fileType);
face.m_vector_normal=point;
//Read three Points
if(!ReadKeyword(inputFile,"outer"))
return -1;
if(!ReadKeyword(inputFile,"loop"))
return -1;
for (INT i=0; i<3; i++)
{
if(!ReadKeyword(inputFile,"vertex"))
return -1;
point.ReadSTLFile(inputFile,fileType);
tempPointArray.Add(point); //由SetAt改为Add
face.m_points[i]=pointCounter;
Find_Min_Max_Value(point,pointCounter);
pointCounter++;
}
if(!ReadKeyword(inputFile,"endloop"))
return -1;
if(!ReadKeyword(inputFile,"endfacet"))
return -1;
m_faces.Add(face);
faceCounter++;
}
totalFaces = faceCounter;
//Verify the ASCII file ends with "endsolid".
if (_strnicmp(buff, "endsolid", sizeof(buff))!=0)
{
globalErrorMessage.SetErrorMsg("endsolid错误!");
globalErrorMessage.ShowErrorMsg();
return -1;
}
}
else
{
//Read BIN STL File 读取二进制文件
tempPointArray.SetSize(totalFaces*3);
m_faces.SetSize(totalFaces);
for (ULONG counter = 0; counter < totalFaces; counter++)
{
if (inputFile.eof()) //容错处理
{
if (counter + 1 != totalFaces)
{
globalErrorMessage.SetErrorMsg("实际读取面片不符!");
globalErrorMessage.ShowErrorMsg();
}
totalFaces=counter;
break;
};
//Read normal vector 读取法向量
point.ReadSTLFile(inputFile,fileType);
face.m_vector_normal=point;
//Read three Points 读取三个点
for (INT i=0; i<3; i++)
{
point.ReadSTLFile(inputFile,fileType);
tempPointArray.SetAt(pointCounter, point);
face.m_points[i]=pointCounter;
Find_Min_Max_Value(point,pointCounter);
pointCounter++;
}
m_faces.SetAt(faceCounter++, face);
//Read attribute word (must be ZERO)
WORD attribute;
inputFile.read(( char* )(&attribute), sizeof(attribute));
if (inputFile.bad())
{
globalErrorMessage.SetErrorMsg("STL文件bad错误!");
globalErrorMessage.ShowErrorMsg();
inputFile.close();
return -1;
}
// if (attribute != 0) //此规则不正确,面片备注不要求一定为零
// {
// globalErrorMessage.SetErrorMsg("STL文件attribute不为零!");
// globalErrorMessage.ShowErrorMsg();
// inputFile.close();
// return -1;
// }
}
}
m_modeheight = m_zMax - m_zMin;
//Close the input file
inputFile.close();
//Set array size to the actual size
tempPointArray.SetSize(pointCounter);
m_faces.SetSize(faceCounter);
/***********************排序 并 重新组织点***********************/
//1.点排序
/************************创建STL边信息****************************/
//2.边排序
//3.重组边结构
//4.重建 STL 边 和 STL 面关系
//5.Release memory allocation.
m_bInitialized=TRUE ;
/****************** End ***************************
***************************************************************/
return 0;
}