/* * area-poly2d.c - Area fill (using libpoly2d) * * Written 2012, 2015 by Werner Almesberger * Copyright 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 #include "poly2d.h" #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; double r_tool = 0; struct p2d *polys; struct p2d *fill; for (path = paths; path; path = path->next) if (path->first && path->first->z == z) r_tool = path->r_tool; polys = paths_to_polys_z(paths, z, z); fill = p2d_area(polys, r_tool, 2*r_tool-overlap); p2d_free_all(polys); **res = polys_to_paths(fill, r_tool, z); while (**res) *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; unsigned n = 0, bad = 0; for (path = paths; path; path = path->next) { bad += !path_is_closed(path); n++; } if (bad) { fprintf(stderr, "%u/%u open paths\n", bad, n); exit(1); } 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; }