From 005dcc308ce0219a4acc607807f1d361746b7435 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Thu, 15 Jan 2015 02:00:05 -0300 Subject: [PATCH] slicer/slicer.c: rewrite - we now consider all non-horizontal facets --- slicer/slice.c | 134 ++++++++++++++++++++++--------------------------- 1 file changed, 59 insertions(+), 75 deletions(-) diff --git a/slicer/slice.c b/slicer/slice.c index cb6ddff..cf4c04e 100644 --- a/slicer/slice.c +++ b/slicer/slice.c @@ -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); }