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

📄 slsdef.cpp

📁 快速原型制造分层切片源代码,适用于高温合金.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//SlsDef.cpp
//

#include "stdafx.h"
#include "SlsDef.h"

#include <io.h>
#include <conio.h>
#include <fstream.h>
////////////////////////////////////////////////////////////////
//define global variables

STLPointArray  tempPointArray;
STLEdgeArray   tempEdgeArray;
CErrorMsg globalErrorMessage;
planePointArray globalIntersectionArray;
////////////////////////////////////////////////////////////////
//define helper function
bool IsOnePoint(C2DRing& srcRing,int firstIndex,int secondIndex)
{
	return srcRing[firstIndex] == srcRing[secondIndex] ? TRUE:FALSE;
}

bool IsOneLine(C2DRing& srcRing, int firstIndex, int secondIndex, int thirdIndex)
{
	//三角形的面积 :s=|| p1p2 X p1p3 || / 2
	double s=fabs((srcRing[secondIndex].m_dX-srcRing[firstIndex].m_dX)*
		          (srcRing[thirdIndex].m_dY-srcRing[firstIndex].m_dY)-
				  (srcRing[secondIndex].m_dY-srcRing[firstIndex].m_dY)*
				  (srcRing[thirdIndex].m_dX-srcRing[firstIndex].m_dX))/2.0 ;
	
	//判断共线的条件 :面积小于某一阈值
    return s >= 1.0e-6 ? FALSE:TRUE ;
}

void ProcessRing(C2DRing& srcRing)   
{                                    
	INT counter=-1;
	INT firstIndex=-1;
	INT secondIndex=-1;
	INT thirdIndex=-1;

	//处理环中相邻两点距离非常小的情况
	for (INT i=0; i<srcRing.GetSize(); i++)
	{
		counter=srcRing.GetSize();
		if (counter < 2)
			break;
		
		//Select the ith point as a base point
		while(TRUE)
		{
			firstIndex=i % counter;
			secondIndex=(i+1) % counter;
			if(IsOnePoint(srcRing,firstIndex,secondIndex))
			{
				srcRing.RemoveAt(secondIndex);

				counter=srcRing.GetSize();
				if(counter < 2)
					break;
			}
			else
			{
				break;
			}
		}
	}
	
	//处理环中相邻三点共线或近似共线的情况
	for ( i=0; i<srcRing.GetSize(); i++)
	{
		counter=srcRing.GetSize();
		if (counter < 3)
			break;

		//Select the ith point as a base point
		while(TRUE)
		{
			firstIndex=i % counter;
			secondIndex=(i+1) % counter;
			thirdIndex=(i+2) % counter;
			if(IsOneLine(srcRing,firstIndex,secondIndex,thirdIndex))
			{
    			srcRing.RemoveAt(secondIndex);

				counter=srcRing.GetSize();
				if(counter < 3)
					break;
			}
			else
			{
				break;
			}
		}
	}
}

void SetMinMaxVal(double val, double& min, double& max)
{
	if(val <= min )	min=val;
	else if (val >= max) max=val;
}

int ComparePoint(const void* pFirstIndex,const void* pSecondIndex)
{
	return tempPointArray[*(int*)pFirstIndex].Compare(tempPointArray[*(int*)pSecondIndex]);
}

int CompareEdge(const void* pFirstIndex,const void* pSecondIndex)
{
	return tempEdgeArray[*(int*)pFirstIndex].Compare(tempEdgeArray[*(int*)pSecondIndex]);
}

int CompareIntersection(const void* pFirstIndex,const void* pSecondIndex)
{
	return globalIntersectionArray[*(int*)pFirstIndex].Compare(globalIntersectionArray[*(int*)pSecondIndex]);
}

bool ReadKeyword(istream& istream, const char* keyword)
{
	char buff[25];
	istream>>buff;
	if (_strnicmp(buff, keyword, sizeof(buff)))
	{
		globalErrorMessage.SetErrorMsg("STL文件中有错误, 是否停止执行应用程序?");

		if (globalErrorMessage.WaitForInstruction())
		{
			return FALSE;
		}
	}

	if (istream.bad()) 
	{
		globalErrorMessage.SetErrorMsg("打开STL文件出错!");
		globalErrorMessage.ShowErrorMsg();
		return FALSE;
	}

	return TRUE;
}

BOOL IsASCIISTLFile(ifstream& ifstream, long& filePtr) 
{
	char buff[100];
	for (int i=0; i<250; i++)
	{
		if (ifstream.eof()) break;

		filePtr=ifstream.tellg();
		ifstream.getline(buff, sizeof(buff));
		strcat(buff,"\0");
		if (ifstream.bad()) 
		{
			globalErrorMessage.SetErrorMsg("打开STL文件出错!");
			globalErrorMessage.ShowErrorMsg();
			return FALSE;
		}

		if (strstr(_strupr(buff), "FACET") != NULL)
			return TRUE;
	}

	return FALSE;
}
//////////////////////////////////////////////////////////////////
//CErrorMsg	class

void CErrorMsg::ShowErrorMsg(void)
{
	AfxMessageBox(m_pErrorMsg, MB_OK | MB_ICONSTOP);
}

bool CErrorMsg::WaitForInstruction(void)
{
	if(AfxMessageBox(m_pErrorMsg, MB_YESNO | MB_ICONSTOP) == IDYES)
		return TRUE;
	else
		return FALSE;
}

void CErrorMsg::SetErrorMsg(char* pErrorMsg)
{
	m_pErrorMsg = pErrorMsg;
}
//////////////////////////////////////////////////////////////////
//2D point class

C2DPoint::C2DPoint(double srcX,double srcY)
{
	m_dX=srcX;
	m_dY=srcY;
}

C2DPoint::C2DPoint(const C2DPoint& srcPoint)
{
	m_dX=srcPoint.m_dX;
	m_dY=srcPoint.m_dY;
	m_bStartPoint=srcPoint.m_bStartPoint;
	m_bEndPoint=srcPoint.m_bEndPoint;
}

int C2DPoint::Compare(const C2DPoint& secondPoint)
{
	double difference;
	if(fabs(m_dY-secondPoint.m_dY) >= 1.0e-6)
	   difference=m_dY-secondPoint.m_dY;
	else if(fabs(m_dX-secondPoint.m_dX) >= 1.0e-6)	
			difference=m_dX-secondPoint.m_dX;
		 else
		    difference=0;

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

bool C2DPoint::WriteIntoOutputFile(ostream& ostream, OUTPUTFILETYPE fileType)
{
	if (fileType == ASCIIOUTPUTFILE)
	{
		ostream<<m_dX<<" "<<m_dY<<"\n";
	}
	else
	{
		ASSERT(fileType == BINOUTPUTFILE);
		float tempVal;
		tempVal=( float )m_dX;
        ostream.write(( char* )( &tempVal ), sizeof (tempVal));
		tempVal=( float )m_dY;
        ostream.write(( char* )( &tempVal ), sizeof (tempVal));
	}

	if (ostream.bad())
	{
		globalErrorMessage.SetErrorMsg("输出数据文件时出错!");
		globalErrorMessage.ShowErrorMsg();
		return FALSE;
	}
	else
	{
		return TRUE;
	}
}

BOOL C2DPoint::operator ==(const C2DPoint& secondPoint)
{
	double distance=sqrt(pow((m_dX-secondPoint.m_dX),2)+
						 pow((m_dY-secondPoint.m_dY),2));
    return distance >= 1.0e-6 ? FALSE:TRUE ;
}

const C2DPoint& C2DPoint::operator=(const C2DPoint& srcPoint)
{
	m_dX=srcPoint.m_dX;
	m_dY=srcPoint.m_dY;
	m_bStartPoint=srcPoint.m_bStartPoint;
	m_bEndPoint=srcPoint.m_bEndPoint;
	return *this ;
}
////////////////////////////////////////////////////////////
//2D line structure

bool C2DLine::WriteIntoOutputFile(ostream& ostream, OUTPUTFILETYPE fileType)
{
	if (fileType == ASCIIOUTPUTFILE)
	{	
		if(!m_startPoint.WriteIntoOutputFile(ostream, ASCIIOUTPUTFILE))
			return FALSE;
		if(!m_endPoint.WriteIntoOutputFile(ostream, ASCIIOUTPUTFILE))
			return FALSE;
	}
	else
	{
		ASSERT(fileType == BINOUTPUTFILE);
		if(!m_startPoint.WriteIntoOutputFile(ostream, BINOUTPUTFILE))
			return FALSE;
		if(!m_endPoint.WriteIntoOutputFile(ostream, BINOUTPUTFILE))
			return FALSE;
	}

	if (ostream.bad())
	{
		globalErrorMessage.SetErrorMsg("输出数据文件时出错!");
		globalErrorMessage.ShowErrorMsg();
		return FALSE;
	}
	else
	{
		return TRUE;
	}
}
//////////////////////////////////////////////////////////////////
//2D ring class

C2DRing::C2DRing(const C2DRing& srcRing)
{
	SetSize(0);
	Copy(srcRing);
	m_xMin=srcRing.m_xMin;
	m_xMax=srcRing.m_xMax;
	m_yMin=srcRing.m_yMin;
    m_yMax=srcRing.m_yMax;
	m_GroupNum=srcRing.m_GroupNum;
	m_bDealt=srcRing.m_bDealt;
	m_bOuterLoop=srcRing.m_bOuterLoop;
	m_bOutermostLoop=srcRing.m_bOutermostLoop;
}

void C2DRing::Find_Min_Max_Value(void)
{
	for(INT i=0; i < GetSize(); i++)
	{	
		C2DPoint point=GetAt(i);

		if( i == 0 )
		{
			m_xMin=m_xMax=point.m_dX;
			m_yMin=m_yMax=point.m_dY;
		}
		else
		{
			if(point.m_dX <= m_xMin)
				m_xMin=point.m_dX;
			else if(point.m_dX >= m_xMax)
					m_xMax=point.m_dX;

			if(point.m_dY <= m_yMin)
				m_yMin=point.m_dY;
			else if(point.m_dY >= m_yMax)
					m_yMax=point.m_dY;
		}
	}
}

bool C2DRing::WriteIntoOutputFile(ostream& ostream, OUTPUTFILETYPE fileType)
{
	int totalVertex=GetSize();
    int totalPoints=totalVertex+1;

	if (fileType == ASCIIOUTPUTFILE)
	{
		ostream<<"total_point\t"<<totalPoints<<"\n";
		for(int i=0; i <= totalVertex; i++)
		{
			C2DPoint pt=GetAt(i%totalVertex);
			if(!pt.WriteIntoOutputFile(ostream, ASCIIOUTPUTFILE))
				return FALSE;
		}
	}
	else
	{
		ASSERT(fileType == BINOUTPUTFILE);
		ostream.write(( char* )(&totalPoints), sizeof (totalPoints));
		for(int i=0; i <= totalVertex; i++)
		{
			C2DPoint pt=GetAt(i%totalVertex);
			if(!pt.WriteIntoOutputFile(ostream, BINOUTPUTFILE))
				return FALSE;
		}
	}

	if (ostream.bad())
	{
		globalErrorMessage.SetErrorMsg("输出数据文件时出错!");
		globalErrorMessage.ShowErrorMsg();
		return FALSE;
	}
	else
	{
		return TRUE;
	}
}

const C2DRing& C2DRing::operator= (const C2DRing& srcRing)
{
	SetSize(0);
	Copy(srcRing);
	m_xMin=srcRing.m_xMin;
	m_xMax=srcRing.m_xMax;
	m_yMin=srcRing.m_yMin;
    m_yMax=srcRing.m_yMax;
	m_GroupNum=srcRing.m_GroupNum;
	m_bDealt=srcRing.m_bDealt;
	m_bOuterLoop=srcRing.m_bOuterLoop;
	m_bOutermostLoop=srcRing.m_bOutermostLoop;
	return *this;
}
////////////////////////////////////////////////////////////////
//scan path structure
 
bool tagScanPath::WriteIntoOutputFile(ostream& ostream, OUTPUTFILETYPE fileType)
{
	int count=-1;

	if (fileType == ASCIIOUTPUTFILE)
	{
		count=polygons.GetSize();
		ostream<<"total_ring\t"<<count<<"\n";
		for(int i=0; i < polygons.GetSize(); i++)
		{
			ostream<<"begin_ring\n";

			if(!polygons[i].WriteIntoOutputFile(ostream, ASCIIOUTPUTFILE))
				return FALSE;

			ostream<<"end_ring\n";
		}

		count=polylines.GetSize();
		ostream<<"begin_pline\n";
		ostream<<"total_seg\t"<<count<<"\n";
		for(i=0; i < polylines.GetSize(); i++)
		{
			if(!polylines[i].WriteIntoOutputFile(ostream, ASCIIOUTPUTFILE))
				return FALSE;
		}
		ostream<<"end_pline\n";
	}
	else
	{
		ASSERT(fileType == BINOUTPUTFILE);
		
		count=polygons.GetSize();
        ostream.write(( char* )(&count), sizeof (count));

		for(int i=0; i < count; i++)
		{
			if(!polygons[i].WriteIntoOutputFile(ostream, BINOUTPUTFILE))
				return FALSE;
		}

		count=polylines.GetSize();
        ostream.write(( char* )(&count), sizeof (count));

		for(i=0; i < count; i++)
		{
			if(!polylines[i].WriteIntoOutputFile(ostream, BINOUTPUTFILE))
				return FALSE;
		}
	}

	if (ostream.bad())
	{
		globalErrorMessage.SetErrorMsg("输出数据文件时出错!");
		globalErrorMessage.ShowErrorMsg();
		return FALSE;
	}
	else
	{
		return TRUE;
	}
}
//////////////////////////////////////////////////////////////////
//2D contour class

C2DContour::C2DContour(const C2DContour& srcContour)
{
	SetSize(0);
	Copy(srcContour);
	m_xMin=srcContour.m_xMin;
	m_xMax=srcContour.m_xMax;
	m_yMin=srcContour.m_yMin;
	m_yMax=srcContour.m_yMax;
	m_ScanWidth=srcContour.m_ScanWidth;
}

const C2DContour& C2DContour::operator= (const C2DContour& srcContour)
{
	SetSize(0);
	Copy(srcContour);
	m_xMin=srcContour.m_xMin;
	m_xMax=srcContour.m_xMax;
	m_yMin=srcContour.m_yMin;
	m_yMax=srcContour.m_yMax;
	m_ScanWidth=srcContour.m_ScanWidth;
	return *this ;
}

void C2DContour::Find_Min_Max_Value(void)
{
	for(INT i=0; i < GetSize(); i++)
	{	
		C2DRing ring=GetAt(i);

		if( i == 0 )
		{
			m_xMin=ring.m_xMin;
			m_xMax=ring.m_xMax;
			m_yMin=ring.m_yMin;
			m_yMax=ring.m_yMax;
		}
		else
		{
			if(ring.m_xMin <= m_xMin)
				m_xMin=ring.m_xMin;
			else if(ring.m_xMax >= m_xMax)
					m_xMax=ring.m_xMax;

			if(ring.m_yMin <= m_yMin)
				m_yMin=ring.m_yMin;
			else if(ring.m_yMax >= m_yMax)
					m_yMax=ring.m_yMax;
		}
	}
}

void C2DContour::JudgeOuterLoops(void)
{
	C2DRing ring;
	INT totalLoops=GetSize();
	INT totalPoints=-1;
	INT IntersectionCounter=-1;  //记录交点个数
	
	//搜索与平面轮廓包容矩形相交的外层环
	for(INT i=0; i < totalLoops; i++)
	{
		ring=GetAt(i);
		totalPoints=ring.GetSize(); 

		for(INT j=0; j < totalPoints; j++)
		{
			if( fabs(m_xMin-ring[j].m_dX) < 1.0e-6 ||
				fabs(m_xMax-ring[j].m_dX) < 1.0e-6 ||
				fabs(m_yMin-ring[j].m_dY) < 1.0e-6 ||
				fabs(m_yMax-ring[j].m_dY) < 1.0e-6  )
			{
				ElementAt(i).m_bOuterLoop=TRUE; 
				break;
			}
		}
	}

	//处理其它外层环以及所有内层环
	for(i=0; i < totalLoops; i++)
	{
		ring=GetAt(i);

		if(!ring.m_bOuterLoop) 
		{
			IntersectionCounter=0;

			C2DPoint featurePoint; //扫描线的起点
			featurePoint.m_dX=ring.m_xMax;
			featurePoint.m_dY=ring.m_yMax;
			totalPoints=ring.GetSize(); 

			//设置扫描线的起点
			for(INT j=0; j < totalPoints; j++)
			{
				if(fabs(ring[j].m_dX-ring.m_xMax) < 1.0e-6)
				{
				    featurePoint.m_dY=ring[j].m_dY;
					break;
				}
			}
		
			//遍历所有包容第i条环的多边形
			for(INT k=0; k < totalLoops; k++)  
			{
				
				if(k == i)
					continue ;

			    if(DoesFirstRingContainSecondRing(ElementAt(k), ring))
				{ 
					planePointArray pointArray;
					GetIntersections(ElementAt(k), pointArray, featurePoint);
					IntersectionCounter+=pointArray.GetSize();
				} 

			}	//处理完所有多边形
	    	
			// 判断第i条环是否为外环
			if((IntersectionCounter % 2 )==0)
			    ElementAt(i).m_bOuterLoop=TRUE;
		} // 处理完第i条环
		
	} // 处理完所有环

}

⌨️ 快捷键说明

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