/* * 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; }