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

📄 slsdef.cpp

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

void C2DContour::ScanPathPerLayer(SCANPATH& path, double angle)
{
	INT totalPoints=-1;
	INT totalLoops=GetSize();

	path.polygons.SetSize(0);
	path.polylines.SetSize(0);

	GroupingFunc(); //对轮廓中的环按包容关系分组

	//1. 外形轮廓扫描路径设计
	for(int counter=0; counter < totalLoops; counter++)
		path.polygons.Add(ElementAt(counter));

	//2. 实体内部扫描路径设计
	if(fabs(angle) > 1.0e-6)
	{
		for( counter=0; counter < totalLoops; counter++)
		{
			Origin_Circling_Rotation(ElementAt(counter), angle);
			ElementAt(counter).Find_Min_Max_Value();
		}
	}

	for( counter=0; counter < totalLoops; counter++)
	{
		C2DRing ring=GetAt(counter);

		if(!ring.m_bOutermostLoop) 
			continue;

		C2DPoint featurePoint; //特征点
		featurePoint.m_dX=ring.m_xMin - 0.1;
		featurePoint.m_dY=ring.m_yMax;

		planePointArray tempIntersectionArray;
		planePointArray sortedIntersectionArray;

		sortedIntersectionArray.SetSize(0);
		while(featurePoint.m_dY >= ring.m_yMin)
		{
			globalIntersectionArray.SetSize(0);

			//扫描线与最外层环求交
			GetIntersections(ring, tempIntersectionArray, featurePoint);

			totalPoints=tempIntersectionArray.GetSize();
			for(INT i=0; i < totalPoints; i++)
				globalIntersectionArray.Add(tempIntersectionArray.GetAt(i));

			//扫描线与同组的内层环求交
			for(i=0; i < totalLoops; i++)  
			{
				if(i == counter || ElementAt(i).m_GroupNum != ring.m_GroupNum)
					continue;

				GetIntersections(ElementAt(i), tempIntersectionArray, featurePoint);

				totalPoints=tempIntersectionArray.GetSize();
				for(INT j=0; j < totalPoints; j++)
					globalIntersectionArray.Add(tempIntersectionArray.GetAt(j));

			}
			
			//将交点排序
			totalPoints=globalIntersectionArray.GetSize();
			if(totalPoints < 2)
			{
				featurePoint.m_dY -= m_ScanWidth; //扫描线下移m_ScanWidth
				continue;
			}

			INT* pointIndexes= new INT[totalPoints];
			if (pointIndexes==NULL)
			{
				globalErrorMessage.SetErrorMsg("分配内存失败!");
				globalErrorMessage.ShowErrorMsg();
				return ;
			}
	
			for (i = 0; i < totalPoints; i ++) 
				 pointIndexes[i]=i;

			qsort(pointIndexes,totalPoints, sizeof(INT),CompareIntersection);
			
			for (i = 0; i < totalPoints; i ++)
			{
				if(i == 0)
				{
					globalIntersectionArray[pointIndexes[i]].m_bStartPoint=TRUE;
				}
				else
				{
					if(i == (totalPoints-1))
						 globalIntersectionArray[pointIndexes[i]].m_bEndPoint=TRUE;
				}

			    sortedIntersectionArray.Add(globalIntersectionArray[pointIndexes[i]]);
			}
			
			delete[] pointIndexes;

			featurePoint.m_dY -= m_ScanWidth; //扫描线下移m_ScanWidth
		}

		if(fabs(angle) > 1.0e-6)
			Origin_Circling_Rotation(sortedIntersectionArray, -angle);

		//求实体内部扫描路径
		INT counter=-1;
		C2DLine lineSegment;
		C2DPoint intersection;
		scanLine scanLine;
		scanLineArray scanLines;
		scanLines.SetSize(0);
		totalPoints=sortedIntersectionArray.GetSize();
		for (INT i = 0; i < totalPoints ; i ++)
		{
			intersection=sortedIntersectionArray.GetAt(i);
			if(intersection.m_bStartPoint)
			{
				counter=0;
				scanLine.m_uCount=0;
				scanLine.m_lineSegArray.SetSize(0);
				while(!intersection.m_bEndPoint)
				{
					if((i+counter) >= (totalPoints-1))	//滤除非法交点
						break;

					if(counter%2 == 0)
					{
						lineSegment.m_startPoint=sortedIntersectionArray.GetAt(i+counter);
						lineSegment.m_endPoint=sortedIntersectionArray.GetAt(i+(counter+1));
						scanLine.m_lineSegArray.Add(lineSegment);
						scanLine.m_uCount += 1;
					}

					counter++;
					intersection=sortedIntersectionArray.GetAt(i+counter);
				}

				scanLines.Add(scanLine);
			}

		}
		
		//绕过实体内部空腔,减少空行程
		bool condition;

		planeLineArray lineSegArray;
		lineSegArray.SetSize(0);

		INT totalScanLines=scanLines.GetSize();
		INT firstIndex=0, secondIndex=0, thirdIndex=0;

		while(firstIndex < totalScanLines)
		{
			for(secondIndex=firstIndex+1; secondIndex < totalScanLines; secondIndex++)
			{
				if(scanLines[firstIndex].m_uCount != scanLines[secondIndex].m_uCount)
				{
					if((secondIndex+1) >= totalScanLines)
					{
							condition=TRUE;
							scanLines.RemoveAt(secondIndex);	//滤除有错扫描线
							totalScanLines=scanLines.GetSize();
					}
					else
					{
						if(scanLines[firstIndex].m_uCount == 
							scanLines[secondIndex+1].m_uCount)
						{
							scanLines.RemoveAt(secondIndex);	//滤除有错扫描线
							totalScanLines=scanLines.GetSize();

							condition=FALSE;
						}
						else
						{
							condition=TRUE;
						}
					}
				}
				else
				{
					condition=FALSE;
				}

				if(condition)
					break;

			}

			for(UINT k=0; k < scanLines[firstIndex].m_uCount; k++)
			{
				thirdIndex=firstIndex;
				while(thirdIndex < secondIndex)
				{
					lineSegArray.Add(scanLines[thirdIndex].m_lineSegArray[k]);
					thirdIndex += 1;
				}
			}

			firstIndex = secondIndex;
		}

		for(i=0; i < lineSegArray.GetSize(); i++)
		{
			if(i%2)
			{
				lineSegment.m_startPoint=lineSegArray[i].m_endPoint;
				lineSegment.m_endPoint=lineSegArray[i].m_startPoint;
			}
			else
			{
				lineSegment.m_startPoint=lineSegArray[i].m_startPoint;
				lineSegment.m_endPoint=lineSegArray[i].m_endPoint;
			}

			path.polylines.Add(lineSegment);
		
		} //处理完一组环

	} //处理完所有环
}

void C2DContour::GroupingFunc(void)
{
	C2DRing ring;
	UINT groupNum=1; //环的分组号
	INT totalLoops=GetSize();

	//搜索最外层环
	for(INT i=0; i < totalLoops; i++)
	{
		ring=GetAt(i);

		if(!ring.m_bOuterLoop)
		{
			ElementAt(i).m_bOutermostLoop=FALSE;
			continue;
		}

		for(INT j=0; j < totalLoops; j++)
		{
			if(j == i)
				continue;

			if(DoesFirstRingContainSecondRing(ElementAt(j), ring))
			{
				ElementAt(i).m_bOutermostLoop=FALSE;
				break;
			}
		}

		if(j >= totalLoops)
		{
			ElementAt(i).m_GroupNum=groupNum++;
			ElementAt(i).m_bOutermostLoop=TRUE;
		}
	}

	//从最外层环开始,将所有环按包容关系分组
	for(i=0; i < totalLoops; i++)
	{
		ring=GetAt(i);

		if(!ring.m_bOutermostLoop) 
			continue;

		//搜索被第i条环包容的多边形
		for(INT j=0; j < totalLoops; j++)  
		{
			if(j == i)
				continue;

			if(DoesFirstRingContainSecondRing(ring, ElementAt(j)))
			{
				ElementAt(j).m_GroupNum=ring.m_GroupNum; 
			}
		}
	}
}

void C2DContour::GetIntersections(const C2DRing& ring, planePointArray& pointArray, const C2DPoint& scanLinePos)
{
	pointArray.SetSize(0);
	
	INT count=ring.GetSize();
	INT firstIndex, secondIndex, thirdIndex;

	//建立边数组
	planeLineArray edgeArray;
	edgeArray.SetSize(0);
	for(INT i=0; i < count; i++)
	{
		C2DLine edge;
		firstIndex=i;
		secondIndex=(i+1)%count;
		edge.m_startPoint=ring[firstIndex];
		edge.m_endPoint=ring[secondIndex];
		edge.m_bDealt=FALSE;
		edgeArray.Add(edge);
	}

	//取平行X轴且向右的射线为扫描线, 求环与扫描线的交点
	C2DPoint intersection; 
	for(i=0; i < count; i++)
	{
		if(edgeArray[i].m_bDealt)
			continue;

		edgeArray[i].m_bDealt=TRUE;

		double dx, dy, dxVal1, dxVal2, dyVal1, dyVal2, dyVal3, dyVal4, multVal;
		dxVal1=edgeArray[i].m_startPoint.m_dX-scanLinePos.m_dX;
		dxVal2=edgeArray[i].m_endPoint.m_dX-scanLinePos.m_dX;
		dyVal1=edgeArray[i].m_startPoint.m_dY-scanLinePos.m_dY;
		dyVal2=edgeArray[i].m_endPoint.m_dY-scanLinePos.m_dY;

		if(fabs(dyVal1) < 1.0e-6)
			dyVal1 = 0.0;

		if(fabs(dyVal2) < 1.0e-6)
			dyVal2 = 0.0;

		multVal=dyVal1*dyVal2;

		if((dxVal1 < 0) && (dxVal2 < 0)) //起点和终点均位于扫描线左侧(无交点)
			continue;                                    

		if(multVal <= 0) //起点和终点位于扫描线异侧或在扫描线上
		{
			if((fabs(dyVal1) >= 1.0e-6) && (fabs(dyVal2) >= 1.0e-6)) //扫描线不经过多边形顶点
			{
				dx=edgeArray[i].m_endPoint.m_dX-edgeArray[i].m_startPoint.m_dX;
				dy=edgeArray[i].m_endPoint.m_dY-edgeArray[i].m_startPoint.m_dY;

				intersection.m_dX=edgeArray[i].m_startPoint.m_dX+(scanLinePos.m_dY-
					              edgeArray[i].m_startPoint.m_dY)*dx/dy;
				intersection.m_dY=scanLinePos.m_dY;

			    if(intersection.m_dX > scanLinePos.m_dX) //判断交点的有效性
					pointArray.Add(intersection);
			}
			else //扫描线经过多边形顶点
			{
				if(i == 0)
				{
					firstIndex=count-1;
				}
				else
				{
					firstIndex=i-1;
				}

				secondIndex=(i+1)%count;

				C2DLine prevEdge, nextEdge;
				prevEdge=edgeArray[firstIndex];  //取前一条边
				nextEdge=edgeArray[secondIndex]; //取下一条边

				//当前边在扫描线上
				if((fabs(dyVal1) < 1.0e-6) && (fabs(dyVal2) < 1.0e-6))
				{
					dyVal3=prevEdge.m_startPoint.m_dY-scanLinePos.m_dY;
					dyVal4=nextEdge.m_endPoint.m_dY-scanLinePos.m_dY;
					if(dyVal3*dyVal4 < 0)
					{
				        edgeArray[firstIndex].m_bDealt=TRUE;
				        edgeArray[secondIndex].m_bDealt=TRUE;
						pointArray.Add(edgeArray[i].m_startPoint);
					}
					else 
					{
				        edgeArray[firstIndex].m_bDealt=TRUE;
				        edgeArray[secondIndex].m_bDealt=TRUE;
					}

					continue;
				}
				
				//当前边的起点在扫描线上,而终点在扫描线外
				if((fabs(dyVal1) < 1.0e-6) && (fabs(dyVal2) >= 1.0e-6))
				{
					dyVal3=prevEdge.m_startPoint.m_dY-scanLinePos.m_dY;
					if(fabs(dyVal3) < 1.0e-6) //前一条边也在扫描线上
					{
						if(firstIndex == 0) //取再前一条边  
						{
							thirdIndex=count-1;
						}
						else
						{
							thirdIndex=firstIndex-1;
						}

						dyVal3=edgeArray[thirdIndex].m_startPoint.m_dY-scanLinePos.m_dY;
						dyVal4=edgeArray[i].m_endPoint.m_dY-scanLinePos.m_dY;
						if(dyVal3*dyVal4 < 0)
						{
							edgeArray[firstIndex].m_bDealt=TRUE;
							edgeArray[thirdIndex].m_bDealt=TRUE; 
							pointArray.Add(prevEdge.m_startPoint);
						}
						else
						{
							edgeArray[firstIndex].m_bDealt=TRUE;
							edgeArray[thirdIndex].m_bDealt=TRUE;
						}
					}
					else //前一条边不在扫描线上
					{
						dyVal4=edgeArray[i].m_endPoint.m_dY-scanLinePos.m_dY;
						if(dyVal3*dyVal4 < 0)
						{
							edgeArray[firstIndex].m_bDealt=TRUE;
							pointArray.Add(edgeArray[i].m_startPoint);
						}
						else
						{
							edgeArray[firstIndex].m_bDealt=TRUE;
						}
					}

					continue;
				}

    			//当前边的起点在扫描线外,而终点在扫描线上
				if((fabs(dyVal1) >= 1.0e-6) && (fabs(dyVal2) < 1.0e-6))
				{

					dyVal3=nextEdge.m_endPoint.m_dY-scanLinePos.m_dY;
					if(fabs(dyVal3) < 1.0e-6) //下一条边也在扫描线上
					{
						thirdIndex=(secondIndex+1)%count; //取再下一条边

						dyVal3=edgeArray[thirdIndex].m_endPoint.m_dY-scanLinePos.m_dY;
						dyVal4=edgeArray[i].m_startPoint.m_dY-scanLinePos.m_dY;
						if(dyVal3*dyVal4 < 0)
						{
							edgeArray[secondIndex].m_bDealt=TRUE;
							edgeArray[thirdIndex].m_bDealt=TRUE;
							pointArray.Add(edgeArray[i].m_endPoint);
						}
						else
						{
							edgeArray[secondIndex].m_bDealt=TRUE;
							edgeArray[thirdIndex].m_bDealt=TRUE;
						}
					}
					else //下一条边不在扫描线上
					{
						dyVal4=edgeArray[i].m_startPoint.m_dY-scanLinePos.m_dY;
						if(dyVal3*dyVal4 < 0)
						{
							edgeArray[secondIndex].m_bDealt=TRUE;
							pointArray.Add(edgeArray[i].m_endPoint);
						}
						else
						{
							edgeArray[secondIndex].m_bDealt=TRUE;
						}
					}

				}
			}
		}

	} //处理完一条边

} //处理完所有边

void C2DContour::Origin_Circling_Rotation(planePointArray& pointArray, double angle)
{
	if(fabs(angle) <= 1.0e-6)
		return;

	INT totalPoints=pointArray.GetSize();
	planePointArray	tempPointArray;
	tempPointArray.SetSize(totalPoints);

	for(INT i=0; i< totalPoints; i++)
	{
		if(pointArray[i].m_bStartPoint)
			tempPointArray[i].m_bStartPoint=TRUE;
		else if(pointArray[i].m_bEndPoint)
				 tempPointArray[i].m_bEndPoint=TRUE;

		tempPointArray[i].m_dX=pointArray[i].m_dX*cos(angle)-pointArray[i].m_dY*sin(angle);
		tempPointArray[i].m_dY=pointArray[i].m_dX*sin(angle)+pointArray[i].m_dY*cos(angle);
	}

	pointArray.SetSize(0);
	pointArray.Copy(tempPointArray);
	tempPointArray.SetSize(0);
}

bool C2DContour::DoesFirstRingContainSecondRing(const C2DRing& firstRing, const C2DRing& secondRing)
{
	if((firstRing.m_xMin < secondRing.m_xMin)&& 
	   (firstRing.m_xMax > secondRing.m_xMax)&&
	   (firstRing.m_yMin < secondRing.m_yMin)&&
	   (firstRing.m_yMax > secondRing.m_yMax) )
	{
		return TRUE; 
	}
	else
	{
		return FALSE; 	
	}
}
///////////////////////////////////////////////////////////////////
//Implementation of STL point class

CSTLPoint::CSTLPoint(double srcX,double srcY,double srcZ)
{
	m_dX=srcX;
	m_dY=srcY;
	m_dZ=srcZ;
}

CSTLPoint::CSTLPoint(const CSTLPoint& srcPoint)
{
	m_dX=srcPoint.m_dX;
	m_dY=srcPoint.m_dY;
	m_dZ=srcPoint.m_dZ;
}

void CSTLPoint::ReadSTLFile(istream& istream, STLFILETYPE stlFileType)
{
	if (stlFileType == ASCIISTLFILE)
	{
		istream>>m_dX>>m_dY>>m_dZ;
	}
	else
	{
		ASSERT(stlFileType == BINSTLFILE);
		float tempVal;
        istream.read(( char* )( &tempVal ), sizeof (tempVal));
		m_dX=( double )(tempVal);
        istream.read(( char* )( &tempVal ), sizeof (tempVal));
		m_dY=( double )(tempVal);
        istream.read(( char* )( &tempVal ), sizeof (tempVal));
		m_dZ=( double )(tempVal);
	}

	if (istream.bad()) 
	{
		globalErrorMessage.SetErrorMsg("STL文件中有错误!");
		globalErrorMessage.ShowErrorMsg();
	}
}

void CSTLPoint::WriteArchive(CArchive& archive)
{
	float tempVal=(float)m_dX;
	archive.Write(( void* )( &tempVal ), sizeof(tempVal));
	tempVal=(float)m_dY;
	archive.Write(( void* )( &tempVal ), sizeof(tempVal));
	tempVal=(float)m_dZ;
	archive.Write(( void* )( &tempVal ), sizeof(tempVal));
}

int CSTLPoint::Compare(const CSTLPoint& secondPoint)
{
	double difference;
	if(fabs(m_dZ-secondPoint.m_dZ) >= 1.0e-6)
		difference=m_dZ-secondPoint.m_dZ;
	else 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);
}

⌨️ 快捷键说明

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