STL 格式解析--文本以及二进制格式

时间:2021-05-13 19:48:16

主入口
判断文件是否有效
以及文件为文本或二进制

read(const char *chFile)
{
bool bRet = false;
FILE* fStl = fopen(chFile, "r");
if (fStl == nullptr)
{
return bRet;
}
unsigned long long nNumWhiteSpace = 0;
unsigned char nWhiteSpace;
if (fread(&nWhiteSpace, 1, 1, fStl) != 1)
{
fclose(fStl);
return bRet;
}

while(isspace(nWhiteSpace))
{
nNumWhiteSpace++;
if (fread(&nWhiteSpace, 1, 1, fStl) != 1)
{
fclose(fStl);
return bRet;
}
}
fseek(fStl, nNumWhiteSpace, SEEK_SET);

char chBuffer[6];
if (fread(chBuffer, 5, 1, fStl) != 1)
{
fclose(fStl);
return bRet;
}
fclose(fStl);

chBuffer[5] = '\0';

std::vector<SC_TRIANGLE> m_vecEmpty;
m_vecEmpty.resize(0);
m_vecTriangle.swap(m_vecEmpty);
m_vecTriangle.clear();

if (stringcasecompare(chBuffer, "solid") == 0)
{
bool bLoadSuccess = readVertexTXT(chFile);
if (!bLoadSuccess)
return bRet;

if (m_vecTriangle.size() < 1)
{
bRet = readVertexBinary(chFile);
return bRet;
}
return true;
}

bRet = readVertexBinary(chFile);
return bRet;
}

读取文本格式

    FILE *fStl;
int nRes = fopen_s(&fStl, chFile, "r");
if (0 != nRes)
{
return false;
}

char chGet[1024] = { '\0' };


while (!feof(fStl))
{
fgets(chGet, 1024, fStl);
if (sscanf_s(chGet, " vertex %f %f %f", &pointGet.x, &pointGet.y, &pointGet.z) == 3)
{
n++;
switch(n)
{
case 1:
pt1 = pointGet;
break;
case 2:
pt2 = pointGet;
break;
case 3:
pt3 = pointGet;
break;
}
}
}

fclose(fStl);

读取二进制格式

{
FILE *fStl = nullptr;
int nRes = fopen_s(&fStl, chFile, "rb");
if (0 != nRes)
{
return false;
}

fseek(fStl, 0L, SEEK_END);
long long file_size = ftell(fStl);
rewind(fStl);
size_t face_count = (file_size - 80 - sizeof(uint32_t)) / 50;

char buffer[80];
// Skip the header
if (fread(buffer, 80, 1, fStl) != 1)
{
fclose(fStl);
return false;
}

uint32_t nReportedFaceCount;
// Read the face count. We'll use it as a sort of redundancy code to check for file corruption.
if (fread(&nReportedFaceCount, sizeof(uint32_t), 1, fStl) != 1)
{
fclose(fStl);
return false;
}
if (nReportedFaceCount != face_count)
{
//std::to_string(nReportedFaceCount).c_str(), std::to_string(face_count).c_str());
}

//For each face read:
//float(x,y,z) = normal, float(X,Y,Z)*3 = vertexes, uint16_t = flags
// Every Face is 50 Bytes: Normal(3*float), Vertices(9*float), 2 Bytes Spacer
//mesh->faces.reserve(face_count);
//mesh->vertices.reserve(face_count);

for (unsigned int i = 0; i < face_count; i++)
{
if (fread(buffer, 50, 1, fStl) != 1)
{
fclose(fStl);
return false;
}

float *v= ((float*)buffer)+3;
triangle.pt1.x = v[0];
triangle.pt1.y = v[1];
triangle.pt1.z = v[2];

triangle.pt2.x = v[3];
triangle.pt2.y = v[4];
triangle.pt2.z = v[5];

triangle.pt3.x = v[6];
triangle.pt3.y = v[7];
triangle.pt3.z = v[8];

//Point3 v0 = matrix.apply(FPoint3(v[0], v[1], v[2]));
//Point3 v1 = matrix.apply(FPoint3(v[3], v[4], v[5]));
//Point3 v2 = matrix.apply(FPoint3(v[6], v[7], v[8]));
//mesh->addFace(v0, v1, v2);

m_vecTriangle.push_back(triangle);
}
fclose(fStl);

return true;
}