stl/stl.c
josh 47911edec3 stl: computing normals in the stl module by cross product now
git-svn-id: svn://anubis/misc/stl@7 bd8a9e45-a331-0410-811e-c64571078777
2007-06-03 03:23:32 +00:00

70 lines
1.7 KiB
C

#include <sys/stat.h> /* struct stat */
#include <stdlib.h> /* malloc() */
#include <stdio.h> /* fprintf() */
#include <math.h> /* 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;
}