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

📄 slsdef.cpp

📁 快速原型制造分层切片源代码,适用于高温合金.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
const CSTLPoint& CSTLPoint::operator=(const CSTLPoint& srcPoint)
{
	m_dX=srcPoint.m_dX;
	m_dY=srcPoint.m_dY;
	m_dZ=srcPoint.m_dZ;
	return *this ;
}
///////////////////////////////////////////////////////////////////
//Implementation of STL edge class

CSTLEdge::CSTLEdge(const CSTLEdge& srcEdge)
{
	m_points[0]=srcEdge.m_points[0];
	m_points[1]=srcEdge.m_points[1];
	m_faces[0]=srcEdge.m_faces[0];
	m_faces[1]=srcEdge.m_faces[1];
}

int CSTLEdge::Compare(const CSTLEdge& secondEdge)
{
	int difference;
	if(abs(m_points[0]-secondEdge.m_points[0]) >= 1.0e-6)
		difference=m_points[0]-secondEdge.m_points[0];
	else if(abs(m_points[1]-secondEdge.m_points[1]) >= 1.0e-6)
		 	 difference=m_points[1]-secondEdge.m_points[1];
		 else
		     difference=0;

    return difference > 0 ? 1 : (difference < 0 ? -1 : 0);
}

const CSTLEdge& CSTLEdge::operator=(const CSTLEdge& srcEdge)
{
	m_points[0]=srcEdge.m_points[0];
	m_points[1]=srcEdge.m_points[1];
	m_faces[0]=srcEdge.m_faces[0];
	m_faces[1]=srcEdge.m_faces[1];
	return *this ;
}
/////////////////////////////////////////////////////////////////
//Implementation of STL face class

CSTLFace::CSTLFace(const CSTLFace& srcFace)
{
	m_vector=srcFace.m_vector;

	m_points[0]=srcFace.m_points[0];
	m_points[1]=srcFace.m_points[1];
	m_points[2]=srcFace.m_points[2];

	m_edges[0]=srcFace.m_edges[0];
	m_edges[1]=srcFace.m_edges[1];
	m_edges[2]=srcFace.m_edges[2];
}

const CSTLFace& CSTLFace::operator=(const CSTLFace& srcFace)
{
	m_vector=srcFace.m_vector;

	m_points[0]=srcFace.m_points[0];
	m_points[1]=srcFace.m_points[1];
	m_points[2]=srcFace.m_points[2];

	m_edges[0]=srcFace.m_edges[0];
	m_edges[1]=srcFace.m_edges[1];
	m_edges[2]=srcFace.m_edges[2];
	
	return *this ;
}
////////////////////////////////////////////////////////////////
//Implementation of STL solid class

void CSTLSolid::WriteArchive(CArchive& archive)
{
	WORD word = 0;
	char STLFileHead[80] = "perfectZ STL solid file";
	archive.Write(( void* )( STLFileHead ), 80);

	int faceNum = m_faces.GetSize();
	archive.Write(( void* )( &faceNum ), sizeof(faceNum));

	for(int i=0; i < faceNum; i++)
	{
		m_faces[i].m_vector.WriteArchive(archive);
				
		for(int j=0; j<3; j++)
		{
			m_points[m_faces[i].m_points[j]].WriteArchive(archive);
		}
		
		//属性字
		archive.Write(( void* )( &word ), sizeof(word));		
	}
}

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("打开STL文件出错!");
		globalErrorMessage.ShowErrorMsg();
		inputFile.close();
		return -1;
	}

	if ( (fileSize=_filelength(inputFile.fd())) == -1L )
	{
		globalErrorMessage.SetErrorMsg("STL文件中有错误!");
		globalErrorMessage.ShowErrorMsg();
		inputFile.close();
		return -1;
	}
    ////////////////////////////////////////////////////////////////
	//Check if "inputFile" is an ASCII file
	//and search the occurrence of "facet".

	LONG filePtr;
	STLFILETYPE fileType=NONSTLFILE;
	
	if (IsASCIISTLFile(inputFile, filePtr)) 
	{
		inputFile.seekg(filePtr, ios::beg); //Rewind file pointer to ''facet"
		totalFaces=fileSize/250;
		fileType=ASCIISTLFILE;
	}
	else
	{
		inputFile.close();
		inputFile.open(fileName, ios::in | ios::nocreate | ios::binary);
		inputFile.seekg(80, ios::beg);

		if (inputFile.bad()) 
		{
			globalErrorMessage.SetErrorMsg("STL文件中有错误!");
			globalErrorMessage.ShowErrorMsg();
			inputFile.close();
			return -1;
		}

		//Get total faces 
	    inputFile.read(( char* )(&totalFaces), sizeof (totalFaces));

		if (inputFile.bad())
		{
			globalErrorMessage.SetErrorMsg("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"
	
		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=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.SetAtGrow(pointCounter,point);
				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.SetAtGrow(faceCounter++, face);
				
		}			
			
	    ////////////////////////////////////////////////////////////
		//Verify the ASCII file ends with "endsolid".

		if (_strnicmp(buff, "endsolid", sizeof(buff))!=0)
		{
			globalErrorMessage.SetErrorMsg("STL文件中有错误!");
			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())
			{
				totalFaces=counter; 
				break;
			};
				
			//Read normal vector
			point.ReadSTLFile(inputFile,fileType);
			face.m_vector=point;

			//Read three Points
			for (INT i=0; i<3; i++)
			{
   				point.ReadSTLFile(inputFile,fileType);
				tempPointArray.SetAtGrow(pointCounter, point);
				face.m_points[i]=pointCounter;
				Find_Min_Max_Value(point,pointCounter);
				pointCounter++;
			}			

			m_faces.SetAtGrow(faceCounter++, face);

			//Read attribute word (must be ZERO)
			WORD attribute;
			inputFile.read(( char* )(&attribute), sizeof(attribute));

			if (inputFile.bad())
			{
				globalErrorMessage.SetErrorMsg("STL文件中有错误!");
				globalErrorMessage.ShowErrorMsg();
				inputFile.close();
				return -1;
			}
			
			if (attribute != 0) 
			{
				globalErrorMessage.SetErrorMsg("STL文件中有错误!");
				globalErrorMessage.ShowErrorMsg();
				inputFile.close();
				return -1;
			}
					
		}
	}

	//Close the input file
	inputFile.close();
    ////////////////////////////////////////////////////////////////
	//Set array size to the actual size

	tempPointArray.SetSize(pointCounter);
	m_faces.SetSize(faceCounter);
    /******************Sort and reorganize points*******************
    ***************************************************************/

	INT* pointIndexes=NULL;
	INT* organizedPointIndexes=NULL;
	INT  organizedPointCounter=-1;
    ////////////////////////////////////////////////////////////////
	//1.Sort points

	pointIndexes= new INT[pointCounter];
	if (pointIndexes==NULL)
	{
		globalErrorMessage.SetErrorMsg("内存分配失败!");
		globalErrorMessage.ShowErrorMsg();
		return -1;
	}
	
	for (ULONG counter =0; counter < pointCounter; counter ++) 
		pointIndexes[counter]=counter;

	qsort(pointIndexes,pointCounter, sizeof(INT),ComparePoint);
    ////////////////////////////////////////////////////////////////
	//2.Reorganize points

	organizedPointIndexes= new INT[pointCounter];
	if (organizedPointIndexes == NULL)
	{
		globalErrorMessage.SetErrorMsg("内存分配失败!");
		globalErrorMessage.ShowErrorMsg();
		return -1;
	}
	
	m_points.SetSize(faceCounter/2);
	for (counter=0; counter < pointCounter; counter++)
	{
		////////////////////////////////////////////////////////////
		////Delete repeated points
		if ( counter==0 || tempPointArray[pointIndexes[counter]].Compare(tempPointArray[pointIndexes[counter-1]]) )
			m_points.SetAtGrow(++organizedPointCounter,tempPointArray[pointIndexes[counter]]);

		organizedPointIndexes[pointIndexes[counter]]=organizedPointCounter;
	}
	
	organizedPointCounter++;
	m_points.SetSize(organizedPointCounter);
    ////////////////////////////////////////////////////////////////
	//3.Rebuild the relationship between STL points and STL faces.

	for (counter=0; counter<faceCounter; counter++)
		for (INT i=0; i<3; i++)
			m_faces[counter].m_points[i]=organizedPointIndexes[m_faces[counter].m_points[i]];

    ////////////////////////////////////////////////////////////////
	//4.Release memory allocation.

	delete [] pointIndexes;
	delete [] organizedPointIndexes;
    /****************Create STL edge information*******************
    ***************************************************************/

	INT* edgeIndexes=NULL;
	INT* organizedEdgeIndexes=NULL;
	INT organizedEdgeCounter=-1;
    ////////////////////////////////////////////////////////////////
	//1.Creat temporary edge array

	INT firstPointIndex;
	INT secondPointIndex; 

	tempEdgeArray.SetSize(faceCounter*3);

	for (counter=0; counter<faceCounter; counter++)
		for (INT i=0; i<3; i++)
		{
			firstPointIndex=m_faces[counter].m_points[i];
			secondPointIndex=m_faces[counter].m_points[(i+1)%3];
			if (firstPointIndex > secondPointIndex) 
			{
				tempEdgeArray[edgeCounter].m_points[0]=secondPointIndex;
				tempEdgeArray[edgeCounter].m_points[1]=firstPointIndex;
			}
			else
			{
				tempEdgeArray[edgeCounter].m_points[0]=firstPointIndex;
				tempEdgeArray[edgeCounter].m_points[1]=secondPointIndex;
			}
			
			edgeCounter++;
		}
    ////////////////////////////////////////////////////////////////
	//2.Sort edges			

	edgeIndexes=new INT[edgeCounter];
	if (edgeIndexes == NULL )
	{
		globalErrorMessage.SetErrorMsg("内存分配失败!");
		globalErrorMessage.ShowErrorMsg();
		return -1;
	}

	for (counter=0; counter<edgeCounter; counter++) 
		edgeIndexes[counter]=counter;
		
	qsort(edgeIndexes,edgeCounter, sizeof(INT),CompareEdge);
    ////////////////////////////////////////////////////////////////
	//3.Reorganize edges

	organizedEdgeIndexes= new INT[edgeCounter];
	if (organizedEdgeIndexes == NULL )
	{
		globalErrorMessage.SetErrorMsg("内存分配失败!");
		globalErrorMessage.ShowErrorMsg();
		return -1;
	}

	m_edges.SetSize(faceCounter*3/2);

	for (counter=0; counter<edgeCounter; counter++)
	{
		////////////////////////////////////////////////////////////
		////Delete repeated edges
		if ( counter==0 || tempEdgeArray[edgeIndexes[counter]].Compare(tempEdgeArray[edgeIndexes[counter-1]]) )
		{
			m_edges.SetAtGrow(++organizedEdgeCounter,tempEdgeArray[edgeIndexes[counter]]);
			m_edges[organizedEdgeCounter].m_faces[0]=-1;
			m_edges[organizedEdgeCounter].m_faces[1]=-1;
		}

		organizedEdgeIndexes[edgeIndexes[counter]]=organizedEdgeCounter;
	}

	organizedEdgeCounter++;	
	m_edges.SetSize(organizedEdgeCounter);
   ////////////////////////////////////////////////////////////////
   //4.Rebuild the relationship between STL edges and STL faces.
	
	INT edgeIndex=-1;
	INT tempEdgeIndex=0;
	INT* edgeDealtTime=new INT[organizedEdgeCounter];  //记录同一条边被处理的次数
	if (edgeDealtTime == NULL)
	{
		globalErrorMessage.SetErrorMsg("内存分配失败!");
		globalErrorMessage.ShowErrorMsg();
		return -1;
	}

	for ( INT i =0; i < organizedEdgeCounter; i++) 
		edgeDealtTime[i]=0;

	for (counter=0; counter < faceCounter; counter++)
		for (i=0; i<3; i++)
		{
			edgeIndex=organizedEdgeIndexes[tempEdgeIndex++];
			m_faces[counter].m_edges[i]=edgeIndex;

			if (edgeDealtTime[edgeIndex] < 2 )
			{
				m_edges[edgeIndex].m_faces[edgeDealtTime[edgeIndex]++]=counter;
			}
			else 
			{
				globalErrorMessage.SetErrorMsg("STL文件出错!");
				globalErrorMessage.ShowErrorMsg();
				delete[] edgeIndexes;
				delete[] organizedEdgeIndexes;
				delete[] edgeDealtTime;
				return -1;
			}
		}
	////////////////////////////////////////////////////////////////
	//5.Release memory allocation.

	delete[] edgeIndexes;
	delete[] organizedEdgeIndexes;
	delete[] edgeDealtTime;
	////////////////////////////////////////////////////////////////

	m_bInitialized=TRUE ;
    /******************End initialization***************************
    ***************************************************************/
	
	return 0;
}

void CSTLSolid::Find_Min_Max_Value(CSTLPoint& srcPoint, int counter)
{
	if (counter==0)
	{
		m_xMin=m_xMax=srcPoint.m_dX;
		m_yMin=m_yMax=srcPoint.m_dY;
		m_zMin=m_zMax=srcPoint.m_dZ;
	}
	else
	{
		SetMinMaxVal(srcPoint.m_dX,m_xMin,m_xMax);
		SetMinMaxVal(srcPoint.m_dY,m_yMin,m_yMax);
		SetMinMaxVal(srcPoint.m_dZ,m_zMin,m_zMax);
	}
}

void CSTLSolid::InitIntersections(void)
{
	ASSERT(m_bInitialized);
	ASSERT(m_pIntersections == NULL);
	m_pIntersections=new STLIntersection[m_edges.GetSize()];
	if (m_pIntersections == NULL) 
	{
		globalErrorMessage.SetErrorMsg("内存分配失败!");
		globalErrorMessage.ShowErrorMsg();
	}
}

int CSTLSolid::CutSlice(double height, C2DContour& contour)
{
	//求交点
	contour.SetSize(0);
	if ((height < m_zMin) || (height > m_zMax) )
		return 0;

	BOOL* dealtFlags=new BOOL[m_points.GetSize()];
	for(int i=0; i<m_points.GetSize(); i++)
	{
		if (fabs(m_points[i].m_dZ-height) <= 1.0e-6) 
		{
			dealtFlags[i]=TRUE;
			m_points[i].m_dZ += 0.01;
		}
		else 
		{
			dealtFlags[i]=FALSE;
		}
	}

	if (m_pIntersections == NULL) 
		InitIntersections();

	INT firstIndex=-1;
	INT SecondIndex=-1;
	double startHeight=0.0; 
	double endHeight=0.0;
	double multVal=0.0;

	for (i=0; i < m_edges.GetSize(); i++)
	{
		firstIndex=m_edges[i].m_points[0];
		SecondIndex=m_edges[i].m_points[1];
		startHeight=m_points[firstIndex].m_dZ;
		endHeight=m_points[SecondIndex].m_dZ;
		multVal=(height-startHeight)*(height-endHeight);
		
		if (((m_edges[i].m_faces[0]==-1) || (m_edges[i].m_faces[1]==-1))	//if the edge has less then two faces
			|| multVal > 0 )			//if the edge has no intersection
		{
			m_pIntersections[i].m_status=NOINTERSECTION;
		}
		else 
		{
			double Kzox=(m_points[SecondIndex].m_dX-m_points[firstIndex].m_dX)
				        /(endHeight-startHeight);
			double Kyoz=(m_points[SecondIndex].m_dY-m_points[firstIndex].m_dY)
				        /(endHeight-startHeight);

			m_pIntersections[i].m_status=TOBEDEALT;

			m_pIntersections[i].m_intersection.m_dX
				=Kzox * (height-startHeight)+m_points[firstIndex].m_dX;                    
			m_pIntersections[i].m_intersection.m_dY
				=Kyoz * (height-startHeight)+m_points[firstIndex].m_dY;

		}
	}

	//提取边界环
	C2DRing ring;
	for (i=0; i < m_edges.GetSize(); i++)
	{
		if (m_pIntersections[i].m_status == TOBEDEALT)
		{
			ring.SetSize(0);

			// + order trip
			int nextEdgeIndex=i;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -