//實體類
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;
}