【发布时间】:2022-10-12 21:24:15
【问题描述】:
这是我的第二个解析二进制 STL 文件的项目。我遇到了几年前遇到的同样问题,我的 STL 文件的表示最终丢失了几个三角形。我已经尝试读取超过 STL 标题中指示的三角形数量,以查看是否有比指示更多的三角形,但我最终得到相同的缺失三角形。
我相信这是 STL 或我阅读它的方式的问题,而不是我的可视化问题,因为我之前在一个项目中遇到过相同的问题,该项目基本上只是使用与 C 几乎相同的代码读取 STL下面的代码。
Gomboc STL missing triangles after being run through my slicing project code
//RETURNED POINTER MUST BE FREE'D
struct tri* readSTL(char* filename, int* numTriangles) {
FILE* fp;
char wordIn = '\0';
fp = fopen(filename, "r");
//READ 80 BYTE HEADER
for (int i = 0; i < 80; i++) {
fread(&wordIn, sizeof(char), 1, fp);
}
//READ 4 BYTE NUMBER OF TRIANGLES
fread(numTriangles, sizeof(char), 4, fp);
//READ ALL TRIANGLES
struct tri* triangles = calloc(*numTriangles, sizeof(struct tri));
for (int i = 0; i < *numTriangles; i++) {
//READ NORMAL VECTOR
fread(&(triangles[i].normal.X), sizeof(char), 4, fp);
fread(&(triangles[i].normal.Y), sizeof(char), 4, fp);
fread(&(triangles[i].normal.Z), sizeof(char), 4, fp);
//READ X
fread(&(triangles[i].p1.X), sizeof(char), 4, fp);
fread(&(triangles[i].p1.Y), sizeof(char), 4, fp);
fread(&(triangles[i].p1.Z), sizeof(char), 4, fp);
//READ Y
fread(&(triangles[i].p2.X), sizeof(char), 4, fp);
fread(&(triangles[i].p2.Y), sizeof(char), 4, fp);
fread(&(triangles[i].p2.Z), sizeof(char), 4, fp);
//READ Z
fread(&(triangles[i].p3.X), sizeof(char), 4, fp);
fread(&(triangles[i].p3.Y), sizeof(char), 4, fp);
fread(&(triangles[i].p3.Z), sizeof(char), 4, fp);
//READ THROW-AWAY
int throwaway;
fread(&throwaway, sizeof(char), 2, fp);
printf("FILE NORMAL: %f, %f, %f\n", triangles[i].normal.X,
triangles[i].normal.Y, triangles[i].normal.Z);
struct point Normal = computeNormal(triangles[i]);
printf("Computed NORMAL: %f, %f, %f\n\n", Normal.X, Normal.Y, Normal.Z);
}
fclose(fp);
return triangles;
}
关于 STL 数据结构,我是否遗漏了一些可以解释这一点的东西?这个问题似乎出现在我阅读的超过 100 个三角形的任何 STL 中。解析由 12 个三角形组成的 6 面立方体看起来很完美。
编辑 1此代码目前仅设置为读取 BINARY STL 文件,这就是它要读取的全部内容。
编辑 2我现在的主要理论是,在大多数导出到 STL 的软件中,缺少三角形是标准的,如果三角形是由它周围的三角形定义的,那么它就不会被添加。奇怪的是,这些未指定的三角形是如何确定的,因为它们在物体上没有视觉或对称图案,也没有丢失的三角形出现在可以从周围三角形合理推断的每个位置。
【问题讨论】:
-
如果“STL 文件”是二进制文件(而不是文本文件),那么您需要在binary 模式。如果它是一个文本文件,那么您不能使用
fread,因为它会将内容作为原始二进制数据读取。 -
@Someprogrammerdude 我目前只阅读二进制 STL。我将更新问题以指定这一点。以现在的代码方式读取二进制 STL 会有任何潜在问题吗?
-
那么你打开文件文本模式,这意味着在某些系统上可能会自动翻译某些“字符”(字节)。最值得注意的是,在 Windows 上,序列
0x0d 0x0a将仅被转换为0x0a(\r\n被转换为\n)。 -
顺便说一句,拥有一个合适的minimal reproducible example 会很不错。请花一些时间阅读the help pages,阅读SO tour,阅读How to Ask,以及this question checklist。还学习如何edit您的问题以改进它们。
-
@SteveSummit 是的,但它读取时不解释字节(除了可能的翻译)。将“文本”读入
int通常没有意义,以及将int值的二进制数据读入字符数组(尽管这可能有时有点道理,尽管它仍然不是“字符串”)。
标签: c slicers stl-format triangle 3d-printing