diff --git a/cameo/Makefile b/cameo/Makefile index 621cd9e..2e1c836 100644 --- a/cameo/Makefile +++ b/cameo/Makefile @@ -1,8 +1,8 @@ # # Makefile - Makefile of cameo # -# Written 2010, 2012, 2013 by Werner Almesberger -# Copyright 2010, 2012, 2013 by Werner Almesberger +# Written 2010, 2012, 2013, 2015 by Werner Almesberger +# Copyright 2010, 2012, 2013, 2015 by 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 @@ -16,7 +16,7 @@ SHELL=/bin/bash MAIN=cameo OBJS=cameo.o excellon.o area-poly2d.o gerber.o gnuplot.o ops.o path.o \ - poly2d.o shape.o stl.o lex.yy.o y.tab.o + connect.o poly2d.o shape.o stl.o lex.yy.o y.tab.o CFLAGS_WARN=-Wall -Wshadow -Wmissing-prototypes \ -Wmissing-declarations -Wno-format-zero-length diff --git a/cameo/connect.c b/cameo/connect.c new file mode 100644 index 0000000..4ef4b5b --- /dev/null +++ b/cameo/connect.c @@ -0,0 +1,76 @@ +/* + * connect.c - Connect paths + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + + +#include +#include + +#include "util.h" +#include "path.h" + + +static void path_reverse_inplace(struct path *path) +{ + struct point *points = NULL, *p, *next; + + path->last = path->first; + for (p = path->first; p; p = next) { + next = p->next; + p->next = points; + points = p; + } + path->first = points; +} + + +static int attr_eq(const struct path *a, const struct path *b) +{ + return a->r_tool == b->r_tool && a->outside == b->outside && + a->notch == b->notch; +} + + +struct path *path_connect(struct path *path) +{ + struct path **a, **b; + struct path *tmp; + +again: + for (a = &path; *a; a = &(*a)->next) + for (b = &(*a)->next; *b; b = &(*b)->next) { + if (!attr_eq(*a, *b)) + continue; + if (points_eq((*a)->last, (*b)->last)) + path_reverse_inplace(*b); + if (points_eq((*a)->last, (*b)->first)) { + (*a)->last->next = (*b)->first->next; + (*a)->last = (*b)->last; + free((*b)->first); + tmp = *b; + *b = tmp->next; + free(tmp); + goto again; + } + if (points_eq((*a)->first, (*b)->first)) + path_reverse_inplace(*b); + if (points_eq((*a)->first, (*b)->last)) { + (*b)->last->next = (*a)->first->next; + (*b)->last = (*a)->last; + free((*a)->first); + tmp = *a; + *a = tmp->next; + free(tmp); + goto again; + } + } + return path; +} diff --git a/cameo/path.c b/cameo/path.c index f73ead5..6edcc83 100644 --- a/cameo/path.c +++ b/cameo/path.c @@ -1,8 +1,8 @@ /* * path.c - 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 @@ -22,14 +22,6 @@ #include "path.h" -/* - * We allow for a bit of tolerance, to absorb the rounding errors KiCad - * produces with designs using a metric grid. - */ - -#define EPSILON_MM 0.006 /* 6 um */ - - static void free_points(struct point *points) { struct point *next; @@ -89,16 +81,6 @@ static struct point *clone_point(const struct point *p) } -static int points_eq(const struct point *a, const struct point *b) -{ - if (hypot(a->x-b->x, a->y-b->y) > EPSILON_MM) - return 0; - if (fabs(a->z-b->z) > EPSILON_MM) - return 0; - return 1; -} - - int path_is_closed(const struct path *path) { if (path->first == path->last) @@ -187,20 +169,6 @@ struct path *path_clone(const struct path *path) } -static void path_reverse_inplace(struct path *path) -{ - struct point *points = NULL, *p, *next; - - path->last = path->first; - for (p = path->first; p; p = next) { - next = p->next; - p->next = points; - points = p; - } - path->first = points; -} - - static struct point *offset_point(const struct point *a, const struct point *b, const struct point *c, double off, int left) { @@ -406,50 +374,6 @@ int path_is_inside(const struct path *a, const struct path *b) } -static int attr_eq(const struct path *a, const struct path *b) -{ - return a->r_tool == b->r_tool && a->outside == b->outside && - a->notch == b->notch; -} - - -struct path *path_connect(struct path *path) -{ - struct path **a, **b; - struct path *tmp; - -again: - for (a = &path; *a; a = &(*a)->next) - for (b = &(*a)->next; *b; b = &(*b)->next) { - if (!attr_eq(*a, *b)) - continue; - if (points_eq((*a)->last, (*b)->last)) - path_reverse_inplace(*b); - if (points_eq((*a)->last, (*b)->first)) { - (*a)->last->next = (*b)->first->next; - (*a)->last = (*b)->last; - free((*b)->first); - tmp = *b; - *b = tmp->next; - free(tmp); - goto again; - } - if (points_eq((*a)->first, (*b)->first)) - path_reverse_inplace(*b); - if (points_eq((*a)->first, (*b)->last)) { - (*b)->last->next = (*a)->first->next; - (*b)->last = (*a)->last; - free((*a)->first); - tmp = *a; - *a = tmp->next; - free(tmp); - goto again; - } - } - return path; -} - - void path_stats(const struct path *path) { int paths = 0, segs = 0; diff --git a/cameo/path.h b/cameo/path.h index 1344dad..ba66b4e 100644 --- a/cameo/path.h +++ b/cameo/path.h @@ -14,6 +14,8 @@ #ifndef PATH_H #define PATH_H +#include + struct point { double x, y, z; /* mm */ @@ -30,6 +32,24 @@ struct path { }; +/* + * We allow for a bit of tolerance, to absorb the rounding errors KiCad + * produces with designs using a metric grid. + */ + +#define EPSILON_MM 0.006 /* 6 um */ + + +static inline int points_eq(const struct point *a, const struct point *b) +{ + if (hypot(a->x-b->x, a->y-b->y) > EPSILON_MM) + return 0; + if (fabs(a->z-b->z) > EPSILON_MM) + return 0; + return 1; +} + + 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);