From 1c11f4d2011b1c5d698f777a5ed0b24c0f02df21 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Tue, 8 May 2012 00:52:47 -0300 Subject: [PATCH] cameo/: use libpoly2d for area fills --- cameo/Makefile | 9 +++-- cameo/area-poly2d.c | 90 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 cameo/area-poly2d.c diff --git a/cameo/Makefile b/cameo/Makefile index 790ae0e..0c079f4 100644 --- a/cameo/Makefile +++ b/cameo/Makefile @@ -15,7 +15,7 @@ PREFIX ?= /usr/local SHELL=/bin/bash MAIN=cameo -OBJS=cameo.o excellon.o area.o gerber.o gnuplot.o ops.o path.o shape.o \ +OBJS=cameo.o excellon.o area-poly2d.o gerber.o gnuplot.o ops.o path.o shape.o \ lex.yy.o y.tab.o CFLAGS_WARN=-Wall -Wshadow -Wmissing-prototypes \ @@ -28,9 +28,10 @@ SLOPPY = -Wno-unused -Wno-implicit-function-declaration # -Wno-missing-prototypes -Wno-missing-declarations # -CFLAGS=$(CFLAGS_WARN) -g -LDFLAGS= -LDLIBS=-lm -lfl +CFLAGS=$(CFLAGS_WARN) -g -I../poly2d +LDFLAGS=-L../poly2d +LDLIBS=-lpoly2d -lCGAL -lCGAL_Core -lboost_thread \ + -lstdc++ -lmpfr -lgmp -lm -lfl YACC = bison -y YYFLAGS = -v diff --git a/cameo/area-poly2d.c b/cameo/area-poly2d.c new file mode 100644 index 0000000..d123937 --- /dev/null +++ b/cameo/area-poly2d.c @@ -0,0 +1,90 @@ +/* + * area-poly2d.c - Area fill (using libpoly2d) + * + * Written 2012 by Werner Almesberger + * Copyright 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include + +#include + +#include "path.h" +#include "area.h" + + +static void fill_path(const struct path *paths, double z, double overlap, + struct path ***res) +{ + const struct path *path; + const struct point *p; + double r_tool; + struct p2d *polys = NULL, *poly, *last = NULL; + struct p2d *fill; + const struct v2d *v; + + for (path = paths; path; path = path->next) { + if (path->first->z != z) + continue; + if (!path->first || !path->first->next) + continue; + r_tool = path->r_tool; + + poly = p2d_new(); + if (last) + last->next = poly; + else + polys = poly; + last = poly; + for (p = path->first; p && p->next; p = p->next) + p2d_append(poly, v2d_new(p->x, p->y)); + p2d_close(poly); + } + + fill = p2d_area(polys, r_tool, 2*r_tool-overlap); + p2d_free_all(polys); + + for (poly = fill; poly; poly = poly->next) { + **res = path_new(r_tool, ""); + v = poly->v; + while (v) { + path_add(**res, v->x, v->y, z); + v = v->next; + if (v == poly->v) + break; + } + if (v) + path_add(**res, v->x, v->y, z); + *res = &(**res)->next; + } + p2d_free_all(fill); +} + + +struct path *area(const struct path *paths, double overlap) +{ + double z = HUGE_VAL, best_z; + const struct path *path; + struct path *res = NULL, **last = &res; + + while (1) { + best_z = -HUGE_VAL; + for (path = paths; path; path = path->next) { + if (path->first->z >= z) + continue; + if (best_z >= path->first->z) + continue; + best_z = path->first->z; + } + if (best_z == -HUGE_VAL) + break; + fill_path(paths, best_z, overlap, &last); + z = best_z; + } + return res; +}