On Wed, 2011-05-11 at 11:43 +0100, Peter Clifton wrote:
I've attached it here in case it helps you get started.
(Now attached!)
--
Peter Clifton
Electrical Engineering Division,
Engineering Department,
University of Cambridge,
9, JJ Thomson Avenue,
Cambridge
CB3 0FA
Tel: +44 (0)7729 980173 - (No signal in the lab!)
Tel: +44 (0)1223 748328 - (Shared lab phone, ask for me)
/* PolyCombine plug-in for PCB
Copyright (C) 2010 Peter Clifton pc...@cam.ac.uk
Licensed under the terms of the GNU General Public License, version 2.
Compile like this:
gcc -I$HOME/pcbsrc/git/src -I$HOME/pcbsrc/git -O2 -shared polycombine.c -o polycombine.so
The resulting polycombine.so goes in $HOME/.pcb/plugins/polycombine.so.
Usage: PolyCombine()
The selected polygons are combined together according to the ordering of their points.
*/
#include stdio.h
#include math.h
#include global.h
#include data.h
#include macro.h
#include create.h
#include remove.h
#include hid.h
#include error.h
#include rtree.h
#include polygon.h
#include polyarea.h
#include assert.h
#include strflags.h
#include find.h
#include misc.h
#include draw.h
static POLYAREA *
original_poly (PolygonType * p, bool *forward)
{
PLINE *contour = NULL;
POLYAREA *np = NULL;
Cardinal n;
Vector v;
int hole = 0;
*forward = true;
if ((np = poly_Create ()) == NULL)
return NULL;
/* first make initial polygon contour */
for (n = 0; n p-PointN; n++)
{
/* No current contour? Make a new one starting at point */
/* (or) Add point to existing contour */
v[0] = p-Points[n].X;
v[1] = p-Points[n].Y;
if (contour == NULL)
{
if ((contour = poly_NewContour (v)) == NULL)
return NULL;
}
else
{
poly_InclVertex (contour-head.prev, poly_CreateNode (v));
}
/* Is current point last in contour? If so process it. */
if (n == p-PointN - 1 ||
(hole p-HoleIndexN n == p-HoleIndex[hole] - 1))
{
poly_PreContour (contour, TRUE);
/* Log the direction in which the outer contour was specified */
if (hole == 0)
*forward = (contour-Flags.orient == PLF_DIR);
/* make sure it is a positive contour (outer) or negative (hole) */
if (contour-Flags.orient != (hole ? PLF_INV : PLF_DIR))
poly_InvContour (contour);
assert (contour-Flags.orient == (hole ? PLF_INV : PLF_DIR));
poly_InclContour (np, contour);
contour = NULL;
assert (poly_Valid (np));
hole++;
}
}
return np;
}
typedef struct poly_tree poly_tree;
struct poly_tree {
PolygonType *polygon;
bool forward;
POLYAREA *polyarea;
poly_tree *parent;
poly_tree *child;
poly_tree *prev;
poly_tree *next;
};
/* __
* ___|_ P6 | +P1 +P6
* | P1| || |
* | _ |_|| -P2 -P4 -P5
* | |P2 ||P5 | | |
* | | [] ||| | +P3
* | | P3 ||
* | |_||
* | |
* | ___|
* | |P4 | |
* | |___| |
* | |
* |_|
*
* As we encounter each polygon, it gets a record. We need to check
* whether it contains any of the polygons existing in our tree. If
* it does, it will become the parent of them. (Check breadth first).
*
* When processing, work top down (breadth first), although if the
* contours can be assumed not to overlap, we can drill down in this
* order: P1, P2, P3, P4, P5, P6.
*/
static bool
PolygonContainsPolygon (POLYAREA *outer, POLYAREA *inner)
{
// int contours_isect;
/* Should check outer contours don't intersect? */
// contours_isect = Touching (outer, inner);
/* Cheat and assume simple single contour polygons for now */
// return contours_isect ?
// 0 : poly_ContourInContour (outer-contours, inner-contours);
return poly_ContourInContour (outer-contours, inner-contours);
}
static poly_tree *
insert_node_recursive (poly_tree *start_point, poly_tree *to_insert)
{
poly_tree *cur_node, *next = NULL;
// bool to_insert_isects_cur_node; /* Intersection */
bool to_insert_contains_cur_node; /* Containment */
bool cur_node_contains_to_insert; /* Containment */
bool placed_to_insert = false;
poly_tree *return_root = start_point;
if (start_point == NULL)
{
// printf (start_point is NULL, so returning to_insert\n);
//to_insert-parent = !!; UNDEFINED
return to_insert;
}
/* Investigate the start point and its peers first */
for (cur_node = start_point; cur_node != NULL; cur_node = next)
{
next = cur_node-next;
// to_insert_isects_cur_node = IsPolygonInPolygon (to_insert-polygon, cur_node-polygon);
to_insert_contains_cur_node =