#include /* struct stat */ #include /* malloc() */ #include /* fprintf() */ #include /* sqrt() */ #include "stl.h" /* load a STL file and return a pointer to the stl_t struct */ stl_t * stl_load(const char * filename) { struct stat s; if (stat(filename, &s)) { fprintf(stderr, "Couldn't stat '%s'\n", filename); return NULL; } if (s.st_size < sizeof(stl_t)) { fprintf(stderr, "Size of '%s' only %d bytes!\n", filename, s.st_size); return NULL; } FILE *fil; if ((fil = fopen(filename, "rb")) == NULL) { fprintf(stderr, "Couldn't open '%s'\n", filename); return NULL; } stl_t * stl = (stl_t *) malloc(s.st_size); fread(stl, 1, s.st_size, fil); fclose(fil); if (s.st_size < sizeof(stl_t) + sizeof(stl_face_t) * (stl_num_faces(stl)-1)) { fprintf(stderr, "Size of '%s' only %d bytes, but has %d faces!\n", filename, s.st_size, stl_num_faces(stl)); free(stl); return NULL; } return stl; } /* fill vector pointed to by normal with the normal of the face */ void stl_get_face_normal(stl_t * stl, int face, float * normal) { float e1[3]; float e2[3]; int i; for (i = 0; i < 3; i++) { e1[i] = stl_face(stl, face).vertices[1][i] - stl_face(stl, face).vertices[0][i]; e2[i] = stl_face(stl, face).vertices[2][i] - stl_face(stl, face).vertices[1][i]; } /* take the cross product of the first two edges */ normal[0] = e1[1] * e2[2] - e1[2] * e2[1]; normal[1] = e1[2] * e2[0] - e1[0] * e2[2]; normal[2] = e1[0] * e2[1] - e1[1] * e2[0]; /* then normalize */ double l; l = sqrt(normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2]); normal[0] /= l; normal[1] /= l; normal[2] /= l; }