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