cameo/: new command "purge" to remove corners that add little or on area

Such corners are typically artefacts that can upset later processing stages.
This commit is contained in:
Werner Almesberger 2015-09-28 18:13:02 -03:00
parent 445d8f7205
commit 346899c34c
5 changed files with 108 additions and 6 deletions

View File

@ -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 [<length>]
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:

View File

@ -51,6 +51,7 @@ NUM -?[0-9]+\.?[0-9]*
<INITIAL>offset return TOK_OFFSET;
<INITIAL>optimize return TOK_OPTIMIZE;
<INITIAL>outside return TOK_OUTSIDE;
<INITIAL>purge return TOK_PURGE;
<INITIAL>remainder return TOK_REMAINDER;
<INITIAL>remore return TOK_REMOVE;
<INITIAL>reset return TOK_RESET;

View File

@ -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 <str> STRING
%type <str> opt_filename
%type <num> dimen number x_size y_size
%type <num> dimen number opt_dimen x_size y_size
%type <flag> opt_any
%type <oopt> offset_options offset_option
%type <axis> 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
{

View File

@ -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 <stddef.h>
#include <stdbool.h>
#include <math.h>
#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;
}

View File

@ -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 */