Root/
| 1 | /* |
| 2 | * area-poly2d.c - Area fill (using libpoly2d) |
| 3 | * |
| 4 | * Written 2012, 2015 by Werner Almesberger |
| 5 | * Copyright 2012, 2015 Werner Almesberger |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | */ |
| 12 | |
| 13 | #include <stdlib.h> |
| 14 | #include <stdio.h> |
| 15 | #include <math.h> |
| 16 | |
| 17 | #include "poly2d.h" |
| 18 | |
| 19 | #include "path.h" |
| 20 | #include "area.h" |
| 21 | |
| 22 | |
| 23 | static void fill_path(const struct path *paths, double z, double overlap, |
| 24 | struct path ***res) |
| 25 | { |
| 26 | const struct path *path; |
| 27 | double r_tool = 0; |
| 28 | struct p2d *polys; |
| 29 | struct p2d *fill; |
| 30 | |
| 31 | for (path = paths; path; path = path->next) |
| 32 | if (path->first && path->first->z == z) |
| 33 | r_tool = path->r_tool; |
| 34 | |
| 35 | polys = paths_to_polys_z(paths, z, z); |
| 36 | |
| 37 | fill = p2d_area(polys, r_tool, 2*r_tool-overlap); |
| 38 | p2d_free_all(polys); |
| 39 | |
| 40 | **res = polys_to_paths(fill, r_tool, z); |
| 41 | while (**res) |
| 42 | *res = &(**res)->next; |
| 43 | p2d_free_all(fill); |
| 44 | } |
| 45 | |
| 46 | |
| 47 | struct path *area(const struct path *paths, double overlap) |
| 48 | { |
| 49 | double z = HUGE_VAL, best_z; |
| 50 | const struct path *path; |
| 51 | struct path *res = NULL, **last = &res; |
| 52 | unsigned n = 0, bad = 0; |
| 53 | |
| 54 | for (path = paths; path; path = path->next) { |
| 55 | bad += !path_is_closed(path); |
| 56 | n++; |
| 57 | } |
| 58 | if (bad) { |
| 59 | fprintf(stderr, "%u/%u open paths\n", bad, n); |
| 60 | exit(1); |
| 61 | } |
| 62 | while (1) { |
| 63 | best_z = -HUGE_VAL; |
| 64 | for (path = paths; path; path = path->next) { |
| 65 | if (path->first->z >= z) |
| 66 | continue; |
| 67 | if (best_z >= path->first->z) |
| 68 | continue; |
| 69 | best_z = path->first->z; |
| 70 | } |
| 71 | if (best_z == -HUGE_VAL) |
| 72 | break; |
| 73 | fill_path(paths, best_z, overlap, &last); |
| 74 | z = best_z; |
| 75 | } |
| 76 | return res; |
| 77 | } |
| 78 |
Branches:
master
