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