📄 slsdef.cpp
字号:
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 + -