STL文件序列化读取

//实体类
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;
}


展开阅读全文

没有更多推荐了,返回首页