getoptified and made fov parameter
This commit is contained in:
parent
060a4d472d
commit
c7504c0541
17
camera.c
17
camera.c
@ -21,14 +21,16 @@ camera_t *
|
|||||||
camera_new(
|
camera_new(
|
||||||
v3_t eye,
|
v3_t eye,
|
||||||
v3_t lookat,
|
v3_t lookat,
|
||||||
v3_t up
|
v3_t up,
|
||||||
|
float fov,
|
||||||
|
float scale
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
camera_t * c = calloc(1, sizeof(*c));
|
camera_t * c = calloc(1, sizeof(*c));
|
||||||
if (!c)
|
if (!c)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
camera_setup(c, eye, lookat, up);
|
camera_setup(c, eye, lookat, up, fov, scale);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +40,9 @@ camera_setup(
|
|||||||
camera_t * const c,
|
camera_t * const c,
|
||||||
v3_t eye,
|
v3_t eye,
|
||||||
v3_t lookat,
|
v3_t lookat,
|
||||||
v3_t up
|
v3_t up,
|
||||||
|
float fov,
|
||||||
|
float scale
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// compute the basis for the camera
|
// compute the basis for the camera
|
||||||
@ -82,7 +86,6 @@ camera_setup(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// now compute the perspective projection matrix
|
// now compute the perspective projection matrix
|
||||||
float fov = 60;
|
|
||||||
float s = 1.0 / tan(fov * M_PI / 180 / 2);
|
float s = 1.0 / tan(fov * M_PI / 180 / 2);
|
||||||
c->near = 1.0;
|
c->near = 1.0;
|
||||||
c->far = 200;
|
c->far = 200;
|
||||||
@ -149,9 +152,9 @@ camera_project(
|
|||||||
|
|
||||||
// Transform to screen coordinate frame,
|
// Transform to screen coordinate frame,
|
||||||
// and return it to the caller
|
// and return it to the caller
|
||||||
v_out->p[0] = p[0] * 100;
|
v_out->p[0] = p[0];
|
||||||
v_out->p[1] = p[1] * 100;
|
v_out->p[1] = p[1];
|
||||||
v_out->p[2] = p[2] * 100;
|
v_out->p[2] = p[2];
|
||||||
|
|
||||||
// what if p->p[4] == 0?
|
// what if p->p[4] == 0?
|
||||||
// pz < 0 == The point is behind us; do not display?
|
// pz < 0 == The point is behind us; do not display?
|
||||||
|
8
camera.h
8
camera.h
@ -8,7 +8,9 @@ extern camera_t *
|
|||||||
camera_new(
|
camera_new(
|
||||||
v3_t eye,
|
v3_t eye,
|
||||||
v3_t lookat,
|
v3_t lookat,
|
||||||
v3_t up
|
v3_t up,
|
||||||
|
float fov,
|
||||||
|
float scale
|
||||||
);
|
);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
@ -16,7 +18,9 @@ camera_setup(
|
|||||||
camera_t * const c,
|
camera_t * const c,
|
||||||
v3_t eye,
|
v3_t eye,
|
||||||
v3_t lookat,
|
v3_t lookat,
|
||||||
v3_t up
|
v3_t up,
|
||||||
|
float fov,
|
||||||
|
float scale
|
||||||
);
|
);
|
||||||
|
|
||||||
/** Transform a XYZ point into a screen point.
|
/** Transform a XYZ point into a screen point.
|
||||||
|
142
hiddenwire.c
142
hiddenwire.c
@ -10,14 +10,50 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <getopt.h>
|
||||||
#include "v3.h"
|
#include "v3.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
|
||||||
|
|
||||||
|
static const char usage[] =
|
||||||
|
"Usage: hiddenwire [options] file.stl > file.svg\n"
|
||||||
|
"\n"
|
||||||
|
"Options:\n"
|
||||||
|
" -h | -? | --help Help\n"
|
||||||
|
" -v | --verbose Enable debugging output\n"
|
||||||
|
" -c | --camera x,y,z Camera position\n"
|
||||||
|
" -l | --lookat x,y,z Target\n"
|
||||||
|
" -u | --up x,y,z Up vector\n"
|
||||||
|
" -F | --fov deg Field-of-view angle\n"
|
||||||
|
" -s | --scale s Scale factor\n"
|
||||||
|
" -p | --prune s Prune lines shorter than s\n"
|
||||||
|
" --no-backface Disable backface culling\n"
|
||||||
|
" --no-coplanar Disable coplanar merging\n"
|
||||||
|
" --no-hiddenwire Disable hidden wire frame removal\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
static const struct option long_options[] = {
|
||||||
|
{ "help", 0, NULL, 'h' },
|
||||||
|
{ "verbose", 0, NULL, 'v' },
|
||||||
|
{ "no-backface", 0, NULL, 'B' },
|
||||||
|
{ "no-coplanar", 0, NULL, 'C' },
|
||||||
|
{ "no-hiddenwire", 0, NULL, 'H' },
|
||||||
|
{ "camera", 1, NULL, 'c' },
|
||||||
|
{ "lookat", 1, NULL, 'l' },
|
||||||
|
{ "up", 1, NULL, 'u' },
|
||||||
|
{ "scale", 1, NULL, 's' },
|
||||||
|
{ "prune", 1, NULL, 'p' },
|
||||||
|
{ "fov", 1, NULL, 'F' },
|
||||||
|
{ NULL, 0, NULL, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
#define M_PI 3.1415926535897932384
|
#define M_PI 3.1415926535897932384
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int debug = 1;
|
static int debug = 0;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -637,28 +673,96 @@ return;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int v3_parse(v3_t * out, const char * str)
|
||||||
|
{
|
||||||
|
int rc = sscanf(str, "%f,%f,%f",
|
||||||
|
&out->p[0],
|
||||||
|
&out->p[1],
|
||||||
|
&out->p[2]
|
||||||
|
);
|
||||||
|
if (rc != 3)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(
|
int main(
|
||||||
int argc,
|
int argc,
|
||||||
char ** argv
|
char ** argv
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
if (argc <= 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s", usage);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int opt;
|
||||||
|
int do_backface = 1;
|
||||||
|
int do_coplanar = 1;
|
||||||
|
int do_hidden = 1;
|
||||||
|
v3_t eye = { { 100, 0, 0 } };
|
||||||
|
v3_t lookat = { { 0, 0, 0 } };
|
||||||
|
v3_t up = { { 0, 0, 1 } };
|
||||||
|
float scale = 1;
|
||||||
|
float fov = 45;
|
||||||
|
float prune = 0.1;
|
||||||
|
|
||||||
|
while((opt = getopt_long(argc, argv ,"h?vBCHc:l:s:u:p:F:", long_options, NULL)) != -1)
|
||||||
|
{
|
||||||
|
switch(opt)
|
||||||
|
{
|
||||||
|
case 'h' : case '?':
|
||||||
|
printf("%s", usage);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "%s", usage);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
case 'v': debug++; break;
|
||||||
|
|
||||||
|
case 'B': do_backface = 0; break;
|
||||||
|
case 'C': do_coplanar = 0; break;
|
||||||
|
case 'H': do_hidden = 0; break;
|
||||||
|
|
||||||
|
case 'p': prune = atof(optarg); break;
|
||||||
|
case 's': scale = atof(optarg); break;
|
||||||
|
case 'F': fov = atof(optarg); break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
if (v3_parse(&eye, optarg) < 0)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
if (v3_parse(&lookat, optarg) < 0)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
if (v3_parse(&up, optarg) < 0)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: sanity check fov, scale, etc
|
||||||
|
|
||||||
const size_t max_len = 32 << 20;
|
const size_t max_len = 32 << 20;
|
||||||
uint8_t * const buf = calloc(max_len, 1);
|
uint8_t * const buf = calloc(max_len, 1);
|
||||||
|
size_t offset = 0;
|
||||||
|
|
||||||
int filter_level = argc > 4 ? atoi(argv[4]) : 1;
|
while(1)
|
||||||
|
{
|
||||||
ssize_t rc = read(0, buf, max_len);
|
ssize_t rc = read(0, buf+offset, max_len - offset);
|
||||||
if (rc == -1)
|
if (rc == -1)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
if (rc == 0)
|
||||||
|
break;
|
||||||
|
offset += rc;
|
||||||
|
}
|
||||||
|
|
||||||
const stl_header_t * const hdr = (const void*) buf;
|
const stl_header_t * const hdr = (const void*) buf;
|
||||||
const stl_face_t * const stl_faces = (const void*)(hdr+1);
|
const stl_face_t * const stl_faces = (const void*)(hdr+1);
|
||||||
const int num_triangles = hdr->num_triangles;
|
const int num_triangles = hdr->num_triangles;
|
||||||
|
|
||||||
int backface = filter_level & 1;
|
|
||||||
int hidden = filter_level & 2;
|
|
||||||
int coplanar = filter_level & 4;
|
|
||||||
float coplanar_eps = 0.001;
|
float coplanar_eps = 0.001;
|
||||||
|
|
||||||
if(debug)
|
if(debug)
|
||||||
@ -668,16 +772,12 @@ int main(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// looking at (0,0,0)
|
const camera_t * const cam = camera_new(eye, lookat, up, fov, scale);
|
||||||
v3_t eye = { { -100, 40, 50 } };
|
|
||||||
v3_t lookat = { { 0, 0, 0 } };
|
|
||||||
v3_t up = { { 0, -1, 0 } };
|
|
||||||
const camera_t * const cam = camera_new(eye, lookat, up);
|
|
||||||
|
|
||||||
printf("<svg xmlns=\"http://www.w3.org/2000/svg\">\n");
|
printf("<svg xmlns=\"http://www.w3.org/2000/svg\">\n");
|
||||||
|
|
||||||
float off_x = 500;
|
float off_x = 0;
|
||||||
float off_y = 500;
|
float off_y = 0;
|
||||||
printf("<g transform=\"translate(%f %f)\">\n", off_x, off_y);
|
printf("<g transform=\"translate(%f %f)\">\n", off_x, off_y);
|
||||||
|
|
||||||
int rejected = 0;
|
int rejected = 0;
|
||||||
@ -696,16 +796,16 @@ int main(
|
|||||||
v3_t s[3];
|
v3_t s[3];
|
||||||
|
|
||||||
for(int j = 0 ; j < 3 ; j++)
|
for(int j = 0 ; j < 3 ; j++)
|
||||||
{
|
|
||||||
camera_project(cam, &stl->p[j], &s[j]);
|
camera_project(cam, &stl->p[j], &s[j]);
|
||||||
}
|
|
||||||
|
|
||||||
if(0)fprintf(stderr, "%.3f,%.3f,%.3f -> %.0f,%.0f\n",
|
if(debug >= 2)
|
||||||
|
fprintf(stderr, "%.3f,%.3f,%.3f -> %.1f,%.1f,%.1f\n",
|
||||||
stl->p[0].p[0],
|
stl->p[0].p[0],
|
||||||
stl->p[0].p[1],
|
stl->p[0].p[1],
|
||||||
stl->p[0].p[2],
|
stl->p[0].p[2],
|
||||||
s[0].p[0],
|
s[0].p[0],
|
||||||
s[0].p[1]
|
s[0].p[1],
|
||||||
|
s[0].p[2]
|
||||||
);
|
);
|
||||||
|
|
||||||
tri_t * const tri = tri_new(s, stl->p);
|
tri_t * const tri = tri_new(s, stl->p);
|
||||||
@ -717,7 +817,7 @@ if(0)fprintf(stderr, "%.3f,%.3f,%.3f -> %.0f,%.0f\n",
|
|||||||
// do a back-face cull to determine if this triangle
|
// do a back-face cull to determine if this triangle
|
||||||
// is not facing us. we have to determine the orientation
|
// is not facing us. we have to determine the orientation
|
||||||
// from the winding of the new projection
|
// from the winding of the new projection
|
||||||
if (backface && tri->normal.p[2] <= 0)
|
if (do_backface && tri->normal.p[2] <= 0)
|
||||||
goto reject;
|
goto reject;
|
||||||
|
|
||||||
retained++;
|
retained++;
|
||||||
@ -742,7 +842,7 @@ reject:
|
|||||||
{
|
{
|
||||||
unsigned matches = 0;
|
unsigned matches = 0;
|
||||||
|
|
||||||
if(coplanar)
|
if(do_coplanar)
|
||||||
for(tri_t * t2 = zlist ; t2 ; t2 = t2->next)
|
for(tri_t * t2 = zlist ; t2 ; t2 = t2->next)
|
||||||
{
|
{
|
||||||
if (t == t2)
|
if (t == t2)
|
||||||
@ -776,7 +876,7 @@ reject:
|
|||||||
// we now have a z-sorted list of triangles
|
// we now have a z-sorted list of triangles
|
||||||
rejected = 0;
|
rejected = 0;
|
||||||
|
|
||||||
if(hidden)
|
if(do_hidden)
|
||||||
{
|
{
|
||||||
// work on each segment, intersecting it with all of the triangles
|
// work on each segment, intersecting it with all of the triangles
|
||||||
int processed = 0;
|
int processed = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user