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