From d77b4c8570de09de27faad35e5411e7e483cf004 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Mon, 1 Nov 2010 18:50:24 -0300 Subject: [PATCH] Added override (in gnuplot file) for inside/outside path detection. - cameo/cameo.c (process_paths): explain the inside/outside path detection heuristics - cameo/path.h (struct path), cameo/path.c (path_new): added attribute "outside" to explicitly mark paths as outside edges - cameo/path.c (path_from): new function to make a path that takes the attributes of another path - cameo/path.c (path_reverse, path_offset): use path_from instead of path_new - cameo/gnuplot.c (gnuplot_read, gnuplot_do_write): read and write the #%outside hint --- cameo/cameo.c | 16 +++++++++++++++- cameo/gnuplot.c | 8 ++++++++ cameo/path.c | 15 +++++++++++++-- cameo/path.h | 1 + 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/cameo/cameo.c b/cameo/cameo.c index 02fc4ed..2fef161 100644 --- a/cameo/cameo.c +++ b/cameo/cameo.c @@ -37,10 +37,24 @@ static void process_paths(struct path *paths) { struct path *leftmost, *path; + /* + * We don't have an algorithm (yet) that can detect which paths are + * inside other paths. Therefore, we fake it by looking for the path + * that contains lowest x coordinate. This ought to be the outer + * boundary of the piece. + * + * Note that this heuristic falls apart when a job consists of + * multiple pieces. In this case, the #%outside hint can be used to + * explicitly tell cameo to treat the path as an outside edge. + */ + leftmost = path_find_leftmost(paths); for (path = paths; path; path = path->next) - if (path != leftmost) + if (path != leftmost && !path->outside) process_path(path, 1); + for (path = paths; path; path = path->next) + if (path != leftmost && path->outside) + process_path(path, 0); process_path(leftmost, 0); } diff --git a/cameo/gnuplot.c b/cameo/gnuplot.c index 2194f75..239b803 100644 --- a/cameo/gnuplot.c +++ b/cameo/gnuplot.c @@ -13,6 +13,7 @@ #include #include +#include #include "path.h" #include "gnuplot.h" @@ -25,6 +26,7 @@ struct path *gnuplot_read(const char *name, double r_tool_default) char buf[1024]; double x, y, z, tmp; double r_tool = r_tool_default; + int outside = 0; int n; struct path *paths = NULL, *path = NULL; struct path **lnk = &paths; @@ -39,6 +41,8 @@ struct path *gnuplot_read(const char *name, double r_tool_default) lineno++; if (sscanf(buf, "#%%r_tool=%lf\n", &tmp) == 1) r_tool = tmp; + if (!strcmp(buf, "#%outside\n")) + outside = 1; if (*buf == '#') continue; n = sscanf(buf, "%lf %lf %lf\n", &x, &y, &z); @@ -46,6 +50,7 @@ struct path *gnuplot_read(const char *name, double r_tool_default) case -1: path = NULL; r_tool = r_tool_default; + outside = 0; continue; case 2: z = 0; @@ -60,6 +65,7 @@ struct path *gnuplot_read(const char *name, double r_tool_default) if (!path) { path = path_new(r_tool); + path->outside = outside; *lnk = path; lnk = &path->next; } @@ -81,6 +87,8 @@ static int gnuplot_do_write(FILE *file, const struct path *paths) return 0; if (fprintf(file, "#%%r_tool=%f\n", path->r_tool) < 0) return 0; + if (path->outside && fprintf(file, "#%%outside\n") < 0) + return 0; for (p = path->first; p; p = p->next) if (fprintf(file, "%f %f %f\n", p->x, p->y, p->z) < 0) return 0; diff --git a/cameo/path.c b/cameo/path.c index 13d4930..6df4689 100644 --- a/cameo/path.c +++ b/cameo/path.c @@ -45,12 +45,23 @@ struct path *path_new(double r_tool) path = alloc_type(struct path); path->r_tool = r_tool; + path->outside = 0; path->first = path->last = NULL; path->next = NULL; return path; } +static struct path *path_from(const struct path *old) +{ + struct path *new; + + new = path_new(old->r_tool); + new->outside = old->outside; + return new; +} + + static struct point *clone_point(struct point *p) { struct point *n; @@ -113,7 +124,7 @@ struct path *path_reverse(const struct path *path) const struct point *p; struct point *n; - new = path_new(path->r_tool); + new = path_from(path); for (p = path->first; p; p = p->next) { n = alloc_type(struct point); n->x = p->x; @@ -275,7 +286,7 @@ struct path *path_offset(const struct path *path, int left, int notch) int dog; assert(path_is_closed(path)); - new = path_new(path->r_tool); + new = path_from(path); prev = path->first; for (p = path->first->next; p; p = p->next) { next = p->next ? p->next : path->first->next; diff --git a/cameo/path.h b/cameo/path.h index d84e12f..3f1b3ed 100644 --- a/cameo/path.h +++ b/cameo/path.h @@ -23,6 +23,7 @@ struct point { struct path { struct point *first, *last; double r_tool; /* mm */ + int outside; /* non-zero to mark path as an outside edge */ struct path *next; };