From e69fa2413369d45e2c55d25b844d7ac61d2fec6d Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Tue, 12 Jun 2012 12:32:08 -0300 Subject: [PATCH] cameo/: new commands "remove" and "keep" for path filtering (untested) --- cameo/README | 10 ++++++++++ cameo/lang.l | 4 +++- cameo/lang.y | 21 +++++++++++++++++++-- cameo/ops.c | 38 ++++++++++++++++++++++++++++++++++++++ cameo/ops.h | 2 ++ cameo/path.c | 21 ++++++++++++++++++++- cameo/path.h | 5 +++-- 7 files changed, 95 insertions(+), 6 deletions(-) diff --git a/cameo/README b/cameo/README index 7567c8e..4bbe16b 100644 --- a/cameo/README +++ b/cameo/README @@ -82,6 +82,16 @@ Note that "mm" and "mil" only affect dimensions in the command file and have no effect on the interpretation of toolpath files. +Filtering: + + remove + keep + +"remove" removes all paths that have at least one vertex inside the +specified rectangle. "keep" keeps only paths that have all vertices +in the rectangle. + + Horizontal adjustments: align diff --git a/cameo/lang.l b/cameo/lang.l index 9c64ff8..eb7ccbc 100644 --- a/cameo/lang.l +++ b/cameo/lang.l @@ -40,15 +40,17 @@ NUM -?[0-9]+\.?[0-9]* align { BEGIN(DIGIT); return TOK_ALIGN; } +area return TOK_AREA; array return TOK_ARRAY; clear return TOK_CLEAR; drill return TOK_DRILL; empty return TOK_EMPTY; -area return TOK_AREA; +keep return TOK_KEEP; mill return TOK_MILL; offset return TOK_OFFSET; optimize return TOK_OPTIMIZE; remainder return TOK_REMAINDER; +remore return TOK_REMOVE; reset return TOK_RESET; reverse return TOK_REVERSE; rotate return TOK_ROTATE; diff --git a/cameo/lang.y b/cameo/lang.y index d7c7536..e3c9c00 100644 --- a/cameo/lang.y +++ b/cameo/lang.y @@ -187,8 +187,9 @@ static struct path **classify(struct path **anchor, struct path *path) }; -%token TOK_ALIGN TOK_ARRAY TOK_CLEAR TOK_DRILL TOK_EMPTY TOK_AREA -%token TOK_MILL TOK_OFFSET TOK_OPTIMIZE TOK_REMAINDER TOK_RESET +%token TOK_ALIGN TOK_AREA TOK_ARRAY TOK_CLEAR TOK_DRILL TOK_EMPTY +%token TOK_KEEP TOK_MILL TOK_OFFSET TOK_OPTIMIZE TOK_REMAINDER +%token TOK_REMOVE TOK_RESET %token TOK_REVERSE TOK_ROTATE TOK_STATS TOK_TRANSLATE TOK_Z %token TOK_APPEND TOK_GERBER TOK_GNUPLOT TOK_EXCELLON TOK_WRITE %token TOK_DOG TOK_INSIDE TOK_ANY @@ -366,6 +367,22 @@ command: if (paths) yyerror("path list is not empty"); } + | TOK_KEEP dimen dimen dimen dimen + { + struct path *tmp; + + tmp = select_paths(paths, $2, $3, $4, $5, 1); + clear_paths(); + paths = tmp; + } + | TOK_REMOVE dimen dimen dimen dimen + { + struct path *tmp; + + tmp = select_paths(paths, $2, $3, $4, $5, 0); + clear_paths(); + paths = tmp; + } ; opt_filename: diff --git a/cameo/ops.c b/cameo/ops.c index 545647a..6457125 100644 --- a/cameo/ops.c +++ b/cameo/ops.c @@ -153,3 +153,41 @@ struct path *reverse_paths(const struct path *paths) } return res; } + + +static int select_path(const struct path *path, double xa, double ya, + double xb, double yb, int inside) +{ + const struct point *p; + + for (p = path->first; p; p = p->next) { + if (p->x >= xa && p->x <= xb && p->y >= ya && p->y <= yb) { + if (!inside) + return 0; + } else { + if (inside) + return 0; + } + } + return 1; +} + + +struct path *select_paths(const struct path *paths, double xa, double ya, + double xb, double yb, int inside) +{ + struct path *res = NULL, **last = &res; + + if (xa > xb) + return select_paths(paths, xb, ya, xa, yb, inside); + if (ya > yb) + return select_paths(paths, xa, yb, xb, ya, inside); + while (paths) { + if (select_path(paths, xa, ya, xb, yb, inside)) { + *last = path_clone(paths); + last = &(*last)->next; + } + paths = paths->next; + } + return res; +} diff --git a/cameo/ops.h b/cameo/ops.h index f1e381b..5c83882 100644 --- a/cameo/ops.h +++ b/cameo/ops.h @@ -23,5 +23,7 @@ struct path *try_drill(struct path *path, double d_min, double d_max); struct path *try_mill(struct path *path, double diam, double step, int any); struct path *optimize_paths(struct path *paths); struct path *reverse_paths(const struct path *paths); +struct path *select_paths(const struct path *paths, double xa, double ya, + double xb, double yb, int inside); #endif /* !OPS_H */ diff --git a/cameo/path.c b/cameo/path.c index dfdb92f..c2a4707 100644 --- a/cameo/path.c +++ b/cameo/path.c @@ -75,7 +75,7 @@ static struct path *path_from(const struct path *old) } -static struct point *clone_point(struct point *p) +static struct point *clone_point(const struct point *p) { struct point *n; @@ -156,6 +156,25 @@ struct path *path_reverse(const struct path *path) } +struct path *path_clone(const struct path *path) +{ + struct path *new; + const struct point *p; + struct point *n; + + new = path_from(path); + for (p = path->first; p; p = p->next) { + n = clone_point(p); + if (new->first) + new->last->next = n; + else + new->first = n; + new->last = n; + } + return new; +} + + static void path_reverse_inplace(struct path *path) { struct point *points = NULL, *p, *next; diff --git a/cameo/path.h b/cameo/path.h index d419a46..bbf3097 100644 --- a/cameo/path.h +++ b/cameo/path.h @@ -1,8 +1,8 @@ /* * path.h - Toolpath operations * - * Written 2010-2011 by Werner Almesberger - * Copyright 2010-2011 Werner Almesberger + * Written 2010-2012 by Werner Almesberger + * Copyright 2010-2012 Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,6 +33,7 @@ struct path { struct path *path_new(double r_tool, const char *id); void path_add(struct path *path, double x, double y, double z); struct path *path_reverse(const struct path *path); +struct path *path_clone(const struct path *path); int path_tool_is_left(const struct path *path); struct path *path_offset(const struct path *path, int left, int notch); const struct path *path_find_leftmost(const struct path *path);