diff --git a/cameo/README b/cameo/README index ed4d516..db1e8ee 100644 --- a/cameo/README +++ b/cameo/README @@ -252,6 +252,13 @@ Try to reduce the movements made between paths by reordering the paths. Note that this disturbs the order generated by "offset" and should thus not be used on paths that are to be executed in a specific sequence. + purge [] + +Remove all corners where the area of the corresponding parallelogram is +inferior to the square of the length parameter. This is particularly +useful for removing artefacts that cold upset later processing steps. +If the length omitted, a default of 1 um is used. + Statistics: diff --git a/cameo/lang.l b/cameo/lang.l index dac599a..5773bf8 100644 --- a/cameo/lang.l +++ b/cameo/lang.l @@ -51,6 +51,7 @@ NUM -?[0-9]+\.?[0-9]* offset return TOK_OFFSET; optimize return TOK_OPTIMIZE; outside return TOK_OUTSIDE; +purge return TOK_PURGE; remainder return TOK_REMAINDER; remore return TOK_REMOVE; reset return TOK_RESET; diff --git a/cameo/lang.y b/cameo/lang.y index 80834c4..0b6bc5c 100644 --- a/cameo/lang.y +++ b/cameo/lang.y @@ -230,7 +230,7 @@ static struct path **classify(struct path **anchor, struct path *path) %token TOK_ALIGN TOK_AREA TOK_ARRAY TOK_CLEAR TOK_DRILL TOK_EMPTY %token TOK_FLIP TOK_KEEP TOK_MILL TOK_OFFSET TOK_OPTIMIZE -%token TOK_OUTSIDE TOK_REMAINDER +%token TOK_OUTSIDE TOK_PURGE TOK_REMAINDER %token TOK_REMOVE TOK_RESET %token TOK_REVERSE TOK_ROTATE TOK_STATS TOK_STL TOK_TRANSLATE %token TOK_X TOK_Y TOK_Z @@ -242,7 +242,7 @@ static struct path **classify(struct path **anchor, struct path *path) %token STRING %type opt_filename -%type dimen number x_size y_size +%type dimen number opt_dimen x_size y_size %type opt_any %type offset_options offset_option %type axis @@ -457,6 +457,14 @@ command: clear_paths(); paths = tmp; } + | TOK_PURGE opt_dimen + { + struct path *tmp; + + tmp = purge_paths(paths, $2); + clear_paths(); + paths = tmp; + } ; opt_filename: @@ -488,6 +496,16 @@ dimen: } ; +opt_dimen: + { + $$ = 0; + } + | dimen + { + $$ = $1; + } + ; + x_size: dimen { diff --git a/cameo/ops.c b/cameo/ops.c index 1c24e91..7350fd4 100644 --- a/cameo/ops.c +++ b/cameo/ops.c @@ -1,8 +1,8 @@ /* * ops.c - Higher-level toolpath operations * - * Written 2010-2013 by Werner Almesberger - * Copyright 2010-2013 Werner Almesberger + * Written 2010-2013, 2015 by Werner Almesberger + * Copyright 2010-2013, 2105 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 @@ -12,6 +12,7 @@ #include +#include #include #include "path.h" @@ -193,3 +194,74 @@ struct path *select_paths(const struct path *paths, double xa, double ya, } return res; } + + +static double cross_area(double ax, double ay, double az, double bx, double by, + double bz) +{ + double x, y, z; + + x = ay * bz - by * az; + y = az * bx - ax * bz; + z = ax * by - ay * bx; + return hypot(hypot(x, y), z); +} + + +struct path *purge_paths(const struct path *paths, double len) +{ + const struct path *path; + struct path *p = NULL, **anchor = &p, *new; + struct point *a, *b, *c; + struct point *end; + double area, t; + bool closed; + + if (!len) + len = EPSILON_PURGE; + area = len * len; + for (path = paths; path; path = path->next) { + if (!path->first) + continue; + closed = path_is_closed(path); + if (closed) { + end = path->first; + while (end->next != path->last) + end = end->next; + } else { + end = path->last; + } + a = end; + b = path->first; + c = b->next; + if (!c) + continue; + new = path_from(path); + while (1) { + t = cross_area(a->x - b->x, a->y - b->y, a->z - b->z, + c->x - b->x, c->y - b->y, c->z - b->z); + if (t >= area) { + path_add(new, b->x, b->y, b->z); + a = b; + } + b = c; + if (closed) { + c = c == end ? path->first : c->next; + } else { + c = c->next; + } + if (b == path->first || !c) + break; + } + if (new->first) { + if (closed) + path_add(new, new->first->x, new->first->y, + new->first->z); + *anchor = new; + anchor = &new->next; + } else { + path_free(new); + } + } + return p; +} diff --git a/cameo/ops.h b/cameo/ops.h index 5c83882..883d53f 100644 --- a/cameo/ops.h +++ b/cameo/ops.h @@ -1,8 +1,8 @@ /* * ops.h - Higher-level toolpath operations * - * Written 2010-2012 by Werner Almesberger - * Copyright 2010-2012 Werner Almesberger + * Written 2010-2012, 2015 by Werner Almesberger + * Copyright 2010-2012, 2015 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 @@ -17,6 +17,9 @@ #include "path.h" +#define EPSILON_PURGE 1e-3 + + struct path *tool_comp_paths(const struct path *paths, int dog_bone, int all_inside); struct path *try_drill(struct path *path, double d_min, double d_max); @@ -25,5 +28,6 @@ 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); +struct path *purge_paths(const struct path *paths, double len); #endif /* !OPS_H */