slicer/slicer.c: rewrite - we now consider all non-horizontal facets

This commit is contained in:
Werner Almesberger 2015-01-15 02:00:05 -03:00
parent 02d2b28097
commit 005dcc308c
1 changed files with 59 additions and 75 deletions

View File

@ -20,22 +20,19 @@
#include "slice.h"
struct line {
float ax, ay;
float bx, by;
float cz;
struct line *next;
struct facet {
struct v a, b, c;
struct facet *next;
};
struct z {
float z;
bool present;
struct line *lines;
};
static GTree *tree;
static struct facet *facets = NULL;
/* ----- Bounding box ------------------------------------------------------ */
@ -73,44 +70,23 @@ static inline bool eq(float a, float b)
}
static struct z *get_z(float z)
{
struct z *base;
base = g_tree_lookup(tree, &z);
if (base)
return base;
base = alloc_type(struct z);
base->z = z;
base->present = 0;
base->lines = NULL;
g_tree_insert(tree, &base->z, base);
return base;
}
static void mark_z(float z)
{
struct z *base;
struct z *e;
base = get_z(z);
base->present = 1;
e = g_tree_lookup(tree, &z);
if (e)
return;
e = alloc_type(struct z);
e->z = z;
g_tree_insert(tree, &e->z, e);
}
static void add(const struct v *a, const struct v *b, const struct v *c)
{
float cross;
struct z *z;
struct line *line;
if (eq(a->x, b->x) && eq(a->y, b->y)) {
fprintf(stderr, "zero point\n");
return;
}
if (c->z < a->z)
return;
struct facet *f;
cross = (b->x - a->x) * (c->y - a->y) - (b->y - a->y) * (c->x - a->x);
if (!eq(cross, 0)) {
@ -122,16 +98,14 @@ fprintf(stderr, "zero point\n");
bbox(a->x, a->y);
bbox(b->x, b->y);
bbox(c->x, c->y);
z = get_z(a->z);
line = alloc_type(struct line);
line->ax = a->x;
line->ay = a->y;
line->bx = b->x;
line->by = b->y;
line->cz = c->z;
line->next = z->lines;
z->lines = line;
f = alloc_type(struct facet);
f->a = *a;
f->b = *b;
f->c = *c;
f->next = facets;
facets = f;
}
@ -139,16 +113,12 @@ void slice(struct v f[3])
{
bool ab = eq(f[0].z, f[1].z);
bool bc = eq(f[1].z, f[2].z);
bool ac = eq(f[0].z, f[2].z);
if (ab && bc)
if (ab && bc) {
mark_z(f[0].z);
else if (ab)
add(f + 0, f + 1, f + 2);
else if (bc)
add(f + 1, f + 2, f + 0);
else if (ac)
add(f + 0, f + 2, f + 1);
return;
}
add(f + 0, f + 1, f + 2);
}
@ -170,9 +140,6 @@ static gboolean check_z(gpointer key, gpointer value, gpointer data)
float d;
int n, i;
if (!z->present)
return 0;
if (ctx->first) {
ctx->first = 0;
ctx->z0 = z->z;
@ -212,31 +179,51 @@ void slice_intermediate(float z_step)
/* ----- Dumping ----------------------------------------------------------- */
static gboolean dump_layer(gpointer key, gpointer value, gpointer data)
static bool cut(const struct v *a, const struct v *b, float z, struct v *res)
{
const struct z *z0 = data;
const struct z *z1 = value;
const struct line *line;
float dx, dy, dz;
float f;
if (z0->z > z1->z)
if (a->z > b->z)
return cut(b, a, z, res);
if (eq(a->z, b->z))
return 0;
if (!z1->present)
if (a->z > z || b->z < z || eq(b->z, z))
return 0;
for (line = z0->lines; line; line = line->next)
if (line->cz > z1->z)
printf("%f %f %f\n%f %f %f\n\n\n",
line->ax, line->ay, z1->z,
line->bx, line->by, z1->z);
return 0;
dx = b->x - a->x;
dy = b->y - a->y;
dz = b->z - a->z;
f = (z - a->z) / dz;
res->x = f * dx + a->x;
res->y = f * dy + a->y;
res->z = z;
return 1;
}
static gboolean dump_range(gpointer key, gpointer value, gpointer data)
static gboolean dump_layer(gpointer key, gpointer value, gpointer data)
{
const struct z *z = value;
const struct facet *f;
struct v p1, p2;
if (z->present)
g_tree_foreach(tree, dump_layer, value);
for (f = facets; f; f = f->next) {
if (cut(&f->a, &f->b, z->z, &p1)) {
if (!cut(&f->a, &f->c, z->z, &p2) &&
!cut(&f->b, &f->c, z->z, &p2))
continue;
} else if (!cut(&f->a, &f->c, z->z, &p1) ||
!cut(&f->b, &f->c, z->z, &p2)) {
continue;
}
printf("%f %f %f\n%f %f %f\n\n\n",
p1.x, p1.y, z->z, p2.x, p2.y, z->z);
}
return 0;
}
@ -246,9 +233,6 @@ static gboolean dump_box(gpointer key, gpointer value, gpointer data)
const struct z *z = value;
float box = *(float *) data;
if (!z->present)
return 0;
printf("%f %f %f\n%f %f %f\n%f %f %f\n%f %f %f\n%f %f %f\n\n\n",
min_x - box, min_y - box, z->z,
max_x + box, min_y - box, z->z,
@ -262,7 +246,7 @@ static gboolean dump_box(gpointer key, gpointer value, gpointer data)
void slice_dump(float box)
{
g_tree_foreach(tree, dump_range, NULL);
g_tree_foreach(tree, dump_layer, NULL);
if (box && !first)
g_tree_foreach(tree, dump_box, &box);
}