Only the first patch "might" be ready for committing. Can someone check
if the change I made to this for loop's bounds is correct, or if the
array needs to be bigger?
(Bug spotted by a more watchful and pedantic gcc)
Also, I've been prodding some stuff with polygons. I noticed rendering
benchmarks spent a lot of time in the no holes polygon dicer. Since I
pan around my board a fair bit, it seemed that caching the diced results
would yield a speedup in real-world usage, not just the repeated redraw
benchmark. So.. I added a cache. Its probably still got a few bugs,
patch is dirty, but it helps improve rendering speed once things have
been cached.
Tonight - I thought I'd have a poke at polygons. I think the patch works
- although context in the drawing patch requires the previous crufty
one. (Ok - I might still need to check the export HIDs, fix up on-screen
visualisation / export visualisation.)
I've changed things such that polygons can take the "CLEARLINE" flag,
("j" on the keyboard bindings), to change if a polygon clears other
polygons or not. In the case where it clears, filled rendering is
disabled, it just renders an outline, and that polygon plows holes in
any other it touches.
This is useful for defining keepout regions, and may also be handy for
some other ideas I have cooking with relation to better polygon
support.
I HATE the fact everything but the big chunk disspears.. I'm working on
allowing all pieces to be left after clipping, including correct
connectivity checking. (The "FULLPOLY" flag doesn't help there).
I'm thinking I will then follow this up with a separate island removal
step - which _may_ be based on laying down some special keepout poly
(flagged as auto-generated) in the areas matching the polygons which
aren't connected.
Just ideas, but comments are welcome - esp. from people who've read the
attached patches, and spotted the flaws in them ;)
Best wishes,
--
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!)
>From 08ccaed2c2f57532f7809a2ba32619b060ce26f2 Mon Sep 17 00:00:00 2001
From: Peter Clifton <[EMAIL PROTECTED]>
Date: Thu, 2 Oct 2008 04:26:50 +0100
Subject: [PATCH] Fix array index out of bounds over layer groups
---
src/move.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/move.c b/src/move.c
index 2e9eb1f..003c2e0 100644
--- a/src/move.c
+++ b/src/move.c
@@ -1027,7 +1027,7 @@ MoveLayer (int old_index, int new_index)
move_all_thermals(old_index, new_index);
- for (g = 0; g < MAX_LAYER + 1; g++)
+ for (g = 0; g < MAX_LAYER; g++)
PCB->LayerGroups.Number[g] = 0;
for (l = 0; l < max_layer + 2; l++)
{
--
1.5.6.3
>From 82cf5186e45efea28952da09c703460b2009ecc2 Mon Sep 17 00:00:00 2001
From: Peter Clifton <[EMAIL PROTECTED]>
Date: Thu, 2 Oct 2008 04:26:50 +0100
Subject: [PATCH] Add cache for "noholes", diced versions of polygons
---
src/create.c | 2 +
src/draw.c | 24 +++++++++++++---
src/global.h | 2 +
src/mymem.c | 2 +
src/polygon.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
src/polygon.h | 3 +-
6 files changed, 104 insertions(+), 14 deletions(-)
diff --git a/src/create.c b/src/create.c
index 5df8ceb..bbfd52f 100644
--- a/src/create.c
+++ b/src/create.c
@@ -603,6 +603,8 @@ CreateNewPolygon (LayerTypePtr Layer, FlagType Flags)
polygon->Flags = Flags;
polygon->ID = ID++;
polygon->Clipped = NULL;
+ polygon->NoHoles = NULL;
+ polygon->NoHolesValid = 0;
return (polygon);
}
diff --git a/src/draw.c b/src/draw.c
index 0f08ea6..38daf9a 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -2171,8 +2171,23 @@ DrawPlainPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon)
if (!Gathering)
PolygonHoles (clip_box, Layer, Polygon, thin_callback);
}
- else if (Polygon->Clipped)
+ else //if (Polygon->NoHoles)//(Polygon->Clipped)
{
+ if (!Polygon->NoHolesValid)
+ {
+ ComputeNoHoles (Polygon);
+ }
+
+ if (Polygon->NoHoles)
+ {
+ PolygonType poly;
+ poly.Clipped = Polygon->NoHoles;
+ do {
+ DrawPolygonLowLevel (&poly);
+ poly.Clipped = poly.Clipped->f;
+ } while (poly.Clipped != Polygon->NoHoles);
+ }
+#if 0
NoHolesPolygonDicer (Polygon, DrawPolygonLowLevel, clip_box);
/* draw other parts of the polygon if fullpoly flag is set */
if (TEST_FLAG (FULLPOLYFLAG, Polygon))
@@ -2185,6 +2200,7 @@ DrawPlainPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon)
NoHolesPolygonDicer (&poly, DrawPolygonLowLevel, clip_box);
}
}
+#endif
}
/* if the gui has the dicer flag set then it won't draw missing poly outlines */
if (TEST_FLAG (CHECKPLANESFLAG, PCB) && Polygon->Clipped && !Gathering
@@ -2207,10 +2223,7 @@ DrawPlainPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon)
}
gui->set_line_width (Output.fgGC, 1);
for (i = 0; i < n - 1; i++)
- {
- gui->draw_line (Output.fgGC, x[i], y[i], x[i + 1], y[i + 1]);
- /* gui->fill_circle (Output.bgGC, x[i], y[i], 10); */
- }
+ gui->draw_line (Output.fgGC, x[i], y[i], x[i + 1], y[i + 1]);
gui->draw_line (Output.fgGC, x[n - 1], y[n - 1], x[0], y[0]);
free (x);
free (y);
@@ -2218,6 +2231,7 @@ DrawPlainPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon)
}
}
+
/* ---------------------------------------------------------------------------
* draws an element
*/
diff --git a/src/global.h b/src/global.h
index cc39bbc..7763c80 100644
--- a/src/global.h
+++ b/src/global.h
@@ -204,6 +204,8 @@ typedef struct /* holds information about a polygon */
Cardinal PointN, /* number of points in polygon */
PointMax; /* max number from malloc() */
POLYAREA *Clipped; /* the clipped region of this polygon */
+ POLYAREA *NoHoles; /* the polygon broken into hole-less regions */
+ int NoHolesValid; /* Is the NoHoles polygon up to date? */
PointTypePtr Points; /* data */
} PolygonType, *PolygonTypePtr;
diff --git a/src/mymem.c b/src/mymem.c
index 57eca2d..ffa4dad 100644
--- a/src/mymem.c
+++ b/src/mymem.c
@@ -727,6 +727,8 @@ FreePolygonMemory (PolygonTypePtr Polygon)
MYFREE (Polygon->Points);
if (Polygon->Clipped)
poly_Free (&Polygon->Clipped);
+ if (Polygon->NoHoles)
+ poly_Free (&Polygon->NoHoles);
memset (Polygon, 0, sizeof (PolygonType));
}
}
diff --git a/src/polygon.c b/src/polygon.c
index 3086be6..ecf11f4 100644
--- a/src/polygon.c
+++ b/src/polygon.c
@@ -77,6 +77,53 @@ static double circleVerticies[] = {
0.98480775301221, 0.17364817766693,
};
+static void
+add_noholes_polyarea (PolygonType *noholes_poly, void *user_data)
+{
+ PolygonType *poly = user_data;
+ PLINE *pline;//, last;
+ POLYAREA *new_area;
+
+ new_area = malloc (sizeof (POLYAREA) * 1);
+
+ /* Allocate a new PLINE, COPY the PLINE from the passed polygon */
+ poly_CopyContour (&pline, noholes_poly->Clipped->contours);
+ new_area->contours = pline;
+
+ /* Link the new POLYAREA into the NoHoles circularaly linked list */
+
+ if (poly->NoHoles)
+ {
+ new_area->f = poly->NoHoles;
+ new_area->b = poly->NoHoles->b;
+ poly->NoHoles->b->f = new_area;
+ poly->NoHoles->b = new_area;
+ }
+ else
+ {
+ new_area->f = new_area;
+ new_area->b = new_area;
+ }
+
+ poly->NoHoles = new_area;
+
+}
+
+void
+ComputeNoHoles (PolygonType *poly)
+{
+ /* TODO: IS THIS RIGHT? */
+ if (poly->NoHoles)
+ {
+ poly_Free (&poly->NoHoles);
+ }
+ poly->NoHoles = NULL;
+ if (poly->Clipped)
+ NoHolesPolygonDicer (poly, add_noholes_polyarea, poly, NULL);
+ else
+ printf ("Compute_noholes caught poly->Clipped = NULL\n");
+ poly->NoHolesValid = 1;
+}
static POLYAREA *
biggest (POLYAREA * p)
@@ -111,7 +158,7 @@ biggest (POLYAREA * p)
big = n->contours->area;
}
}
- while ((n = n->f) != p);
+ while ((n = n->f) != p); /* TODO: Decipher this line ... is it pointless? Is it just "n=p"? */
assert (top);
if (top == p)
return p;
@@ -185,6 +232,8 @@ ClipOriginal (PolygonType * poly)
fprintf (stderr, "Error while clipping PBO_ISECT: %d\n", r);
poly_Free (&result);
poly->Clipped = NULL;
+ if (poly->NoHoles) printf ("Just leaked in ClipOriginal\n");
+ poly->NoHoles = NULL;
return 0;
}
poly->Clipped = biggest (result);
@@ -558,6 +607,8 @@ Subtract (POLYAREA * np1, PolygonType * p, Boolean fnp)
fprintf (stderr, "Error while clipping PBO_SUB: %d\n", x);
poly_Free (&merged);
p->Clipped = NULL;
+ if (p->NoHoles) printf ("Just leaked in Subtract\n");
+ p->NoHoles = NULL;
return -1;
}
p->Clipped = biggest (merged);
@@ -835,6 +886,7 @@ clearPoly (DataTypePtr Data, LayerTypePtr Layer, PolygonType * polygon,
if (info.solder || group == Group (Data, max_layer + COMPONENT_LAYER))
r += r_search (Data->pad_tree, ®ion, NULL, pad_sub_callback, &info);
}
+ polygon->NoHolesValid = 0;
return r;
}
@@ -851,6 +903,8 @@ Unsubtract (POLYAREA * np1, PolygonType * p)
fprintf (stderr, "Error while clipping PBO_UNITE: %d\n", x);
poly_Free (&merged);
p->Clipped = NULL;
+ if (p->NoHoles) printf ("Just leaked in Unsubtract\n");
+ p->NoHoles = NULL;
return 0;
}
p->Clipped = biggest (merged);
@@ -957,11 +1011,18 @@ InitClip (DataTypePtr Data, LayerTypePtr layer, PolygonType * p)
if (p->Clipped)
poly_Free (&p->Clipped);
p->Clipped = original_poly (p);
+ if (p->NoHoles)
+ {
+ poly_Free (&p->NoHoles);
+ }
+ p->NoHoles = NULL;
if (!p->Clipped)
return 0;
assert (poly_Valid (p->Clipped));
if (TEST_FLAG (CLEARPOLYFLAG, p))
clearPoly (Data, layer, p, NULL, 0);
+ else
+ p->NoHolesValid = 0;
return 1;
}
@@ -1215,18 +1276,23 @@ subtract_plow (DataTypePtr Data, LayerTypePtr Layer, PolygonTypePtr Polygon,
case PIN_TYPE:
case VIA_TYPE:
SubtractPin (Data, (PinTypePtr) ptr2, Layer, Polygon);
+ Polygon->NoHolesValid = 0;
return 1;
case LINE_TYPE:
SubtractLine ((LineTypePtr) ptr2, Polygon);
+ Polygon->NoHolesValid = 0;
return 1;
case ARC_TYPE:
SubtractArc ((ArcTypePtr) ptr2, Polygon);
+ Polygon->NoHolesValid = 0;
return 1;
case PAD_TYPE:
SubtractPad ((PadTypePtr) ptr2, Polygon);
+ Polygon->NoHolesValid = 0;
return 1;
case TEXT_TYPE:
SubtractText ((TextTypePtr) ptr2, Polygon);
+ Polygon->NoHolesValid = 0;
return 1;
}
return 0;
@@ -1423,7 +1489,7 @@ IsRectangleInPolygon (LocationType X1, LocationType Y1, LocationType X2,
}
static void
-r_NoHolesPolygonDicer (PLINE * p, void (*emit) (PolygonTypePtr))
+r_NoHolesPolygonDicer (PLINE * p, void (*emit) (PolygonTypePtr, void *), void *user_data)
{
POLYAREA *pa;
@@ -1441,6 +1507,7 @@ r_NoHolesPolygonDicer (PLINE * p, void (*emit) (PolygonTypePtr))
poly.BoundingBox.Y2 = p->ymax;
poly.PointN = poly.PointMax = 4;
poly.Clipped = pa;
+ poly.NoHoles = NULL;
poly.Points = pts;
pts[0].X = pts[0].X2 = p->xmin;
pts[0].Y = pts[0].Y2 = p->ymin;
@@ -1451,7 +1518,7 @@ r_NoHolesPolygonDicer (PLINE * p, void (*emit) (PolygonTypePtr))
pts[3].X = pts[3].X2 = p->xmin;
pts[3].Y = pts[3].Y2 = p->ymax;
poly.Flags = MakeFlags (CLEARPOLYFLAG);
- emit (&poly);
+ emit (&poly, user_data);
poly_Free (&pa);
return;
}
@@ -1471,7 +1538,7 @@ r_NoHolesPolygonDicer (PLINE * p, void (*emit) (PolygonTypePtr))
do
{
PLINE *pl = x->contours;
- r_NoHolesPolygonDicer (pl, emit);
+ r_NoHolesPolygonDicer (pl, emit, user_data);
y = x->f;
/* the pline was already freed by its use int he recursive dicer */
free (x);
@@ -1485,7 +1552,7 @@ r_NoHolesPolygonDicer (PLINE * p, void (*emit) (PolygonTypePtr))
do
{
PLINE *pl = x->contours;
- r_NoHolesPolygonDicer (pl, emit);
+ r_NoHolesPolygonDicer (pl, emit, user_data);
y = x->f;
free (x);
}
@@ -1495,8 +1562,8 @@ r_NoHolesPolygonDicer (PLINE * p, void (*emit) (PolygonTypePtr))
}
void
-NoHolesPolygonDicer (PolygonTypePtr p, void (*emit) (PolygonTypePtr),
- const BoxType * clip)
+NoHolesPolygonDicer (PolygonTypePtr p, void (*emit) (PolygonTypePtr, void *),
+ void *user_data, const BoxType * clip)
{
POLYAREA *save, *ans;
@@ -1521,7 +1588,7 @@ NoHolesPolygonDicer (PolygonTypePtr p, void (*emit) (PolygonTypePtr),
do
{
POLYAREA *prev;
- r_NoHolesPolygonDicer (save->contours, emit);
+ r_NoHolesPolygonDicer (save->contours, emit, user_data);
/* go to next poly (could be one because of clip) */
prev = save;
save = prev->f;
@@ -1554,6 +1621,8 @@ MorphPolygon (LayerTypePtr layer, PolygonTypePtr poly)
* we do this dirty work.
*/
poly->Clipped = NULL;
+ if (poly->NoHoles) printf ("Just leaked in MorpyPolygon\n");
+ poly->NoHoles = NULL;
flags = poly->Flags;
RemovePolygon (layer, poly);
inhibit = True;
diff --git a/src/polygon.h b/src/polygon.h
index 721ba95..2c78e94 100644
--- a/src/polygon.h
+++ b/src/polygon.h
@@ -43,6 +43,7 @@ int PolygonHoles (const BoxType * range, LayerTypePtr, PolygonTypePtr,
int (*callback) (PLINE *, LayerTypePtr, PolygonTypePtr));
int PlowsPolygon (DataType *, int, void *, void *,
int (*callback) (DataTypePtr, LayerTypePtr, PolygonTypePtr, int, void *, void *));
+void ComputeNoHoles (PolygonType *poly);
POLYAREA * ContourToPoly (PLINE *);
POLYAREA * RectPoly (LocationType x1, LocationType x2, LocationType y1, LocationType y2);
POLYAREA * CirclePoly(LocationType x, LocationType y, BDimension radius);
@@ -61,5 +62,5 @@ Boolean IsRectangleInPolygon (LocationType, LocationType, LocationType,
LocationType, PolygonTypePtr);
Boolean isects (POLYAREA *, PolygonTypePtr, Boolean);
Boolean MorphPolygon (LayerTypePtr, PolygonTypePtr);
-void NoHolesPolygonDicer (PolygonTypePtr p, void (*emit) (PolygonTypePtr), const BoxType *clip);
+void NoHolesPolygonDicer (PolygonTypePtr p, void (*emit) (PolygonTypePtr, void *), void *user_data, const BoxType *clip);
#endif
--
1.5.6.3
>From 9a1c41897b9ef66e075e049bb695c597a377923d Mon Sep 17 00:00:00 2001
From: Peter Clifton <[EMAIL PROTECTED]>
Date: Thu, 2 Oct 2008 04:26:56 +0100
Subject: [PATCH] Allow polygons with CLEARLINEFLAG set to cut out other polygons
Gives the possibility to mask out regions which are to be free of
polygon fill.
---
src/buffer.c | 2 +
src/change.c | 57 +++++++++++++++++++++++++++++++++++++++++++++--
src/change.h | 2 +-
src/draw.c | 7 +++--
src/move.c | 4 +++
src/polygon.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
6 files changed, 129 insertions(+), 11 deletions(-)
diff --git a/src/buffer.c b/src/buffer.c
index 89c8a3a..c8a35f1 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -364,6 +364,7 @@ MovePolygonToBuffer (LayerTypePtr Layer, PolygonTypePtr Polygon)
LayerTypePtr lay;
PolygonTypePtr polygon;
+ RestoreToPolygon (Source, POLYGON_TYPE, Layer, Polygon);
r_delete_entry (Layer->polygon_tree, (BoxTypePtr) Polygon);
lay = &Dest->Layer[GetLayerNumber (Source, Layer)];
polygon = GetPolygonMemory (lay);
@@ -377,6 +378,7 @@ MovePolygonToBuffer (LayerTypePtr Layer, PolygonTypePtr Polygon)
if (!lay->polygon_tree)
lay->polygon_tree = r_create_tree (NULL, 0, 0);
r_insert_entry (lay->polygon_tree, (BoxTypePtr) polygon, 0);
+ ClearFromPolygon (Source, POLYGON_TYPE, Layer, Polygon);
return (polygon);
}
diff --git a/src/change.c b/src/change.c
index 0599ee4..92ba535 100644
--- a/src/change.c
+++ b/src/change.c
@@ -123,6 +123,9 @@ static void *ChangeTextJoin (LayerTypePtr, TextTypePtr);
static void *SetTextJoin (LayerTypePtr, TextTypePtr);
static void *ClrTextJoin (LayerTypePtr, TextTypePtr);
static void *ChangePolyClear (LayerTypePtr, PolygonTypePtr);
+static void *ChangePolyJoin (LayerTypePtr, PolygonTypePtr);
+static void *SetPolyJoin (LayerTypePtr, PolygonTypePtr);
+static void *ClrPolyJoin (LayerTypePtr, PolygonTypePtr);
/* ---------------------------------------------------------------------------
* some local identifiers
@@ -217,7 +220,7 @@ static ObjectFunctionType ChangeSquareFunctions = {
static ObjectFunctionType ChangeJoinFunctions = {
ChangeLineJoin,
ChangeTextJoin,
- NULL,
+ ChangePolyJoin,
NULL,
NULL,
NULL,
@@ -277,7 +280,7 @@ static ObjectFunctionType SetSquareFunctions = {
static ObjectFunctionType SetJoinFunctions = {
SetLineJoin,
SetTextJoin,
- NULL,
+ SetPolyJoin,
NULL,
NULL,
NULL,
@@ -319,7 +322,7 @@ static ObjectFunctionType ClrSquareFunctions = {
static ObjectFunctionType ClrJoinFunctions = {
ClrLineJoin,
ClrTextJoin,
- NULL,
+ ClrPolyJoin,
NULL,
NULL,
NULL,
@@ -1191,6 +1194,31 @@ ChangeTextJoin (LayerTypePtr Layer, TextTypePtr Text)
}
/* ---------------------------------------------------------------------------
+ * changes the clearance flag of a polygon
+ */
+static void *
+ChangePolyJoin (LayerTypePtr Layer, PolygonTypePtr poly)
+{
+ if (TEST_FLAG (LOCKFLAG, poly))
+ return (NULL);
+ ErasePolygon (poly);
+ if (TEST_FLAG(CLEARLINEFLAG, poly))
+ {
+ AddObjectToClearPolyUndoList (POLYGON_TYPE, Layer, poly, poly, False);
+ RestoreToPolygon (PCB->Data, POLYGON_TYPE, Layer, poly);
+ }
+ AddObjectToFlagUndoList (LINE_TYPE, Layer, poly, poly);
+ TOGGLE_FLAG (CLEARLINEFLAG, poly);
+ if (TEST_FLAG(CLEARLINEFLAG, poly))
+ {
+ AddObjectToClearPolyUndoList (POLYGON_TYPE, Layer, poly, poly, True);
+ ClearFromPolygon (PCB->Data, POLYGON_TYPE, Layer, poly);
+ }
+ DrawPolygon (Layer, poly, 0);
+ return (poly);
+}
+
+/* ---------------------------------------------------------------------------
* sets the clearance flag of a text
*/
static void *
@@ -1202,6 +1230,17 @@ SetTextJoin (LayerTypePtr Layer, TextTypePtr Text)
}
/* ---------------------------------------------------------------------------
+ * sets the clearance flag of a polygon
+ */
+static void *
+SetPolyJoin (LayerTypePtr Layer, PolygonTypePtr poly)
+{
+ if (TEST_FLAG (LOCKFLAG, poly) || TEST_FLAG (CLEARLINEFLAG, poly))
+ return (NULL);
+ return ChangePolyJoin (Layer, poly);
+}
+
+/* ---------------------------------------------------------------------------
* clears the clearance flag of a text
*/
static void *
@@ -1213,6 +1252,17 @@ ClrTextJoin (LayerTypePtr Layer, TextTypePtr Text)
}
/* ---------------------------------------------------------------------------
+ * clears the clearance flag of a polygon
+ */
+static void *
+ClrPolyJoin (LayerTypePtr Layer, PolygonTypePtr poly)
+{
+ if (TEST_FLAG (LOCKFLAG, poly) || !TEST_FLAG (CLEARLINEFLAG, poly))
+ return (NULL);
+ return ChangePolyJoin (Layer, poly);
+}
+
+/* ---------------------------------------------------------------------------
* changes the square flag of all pins on an element
*/
static void *
@@ -1699,6 +1749,7 @@ ChangeSelectedJoin (int types)
change = SelectedOperation (&ChangeJoinFunctions, False, types);
if (change)
{
+ printf ("Hello\n");
Draw ();
IncrementUndoSerialNumber ();
}
diff --git a/src/change.h b/src/change.h
index 7f43fba..1be41aa 100644
--- a/src/change.h
+++ b/src/change.h
@@ -56,7 +56,7 @@
(ELEMENT_TYPE | PIN_TYPE | VIA_TYPE)
#define CHANGEJOIN_TYPES \
- (ARC_TYPE | LINE_TYPE | TEXT_TYPE)
+ (ARC_TYPE | LINE_TYPE | TEXT_TYPE | POLYGON_TYPE)
#define CHANGETHERMAL_TYPES \
(PIN_TYPE | VIA_TYPE)
diff --git a/src/draw.c b/src/draw.c
index 38daf9a..e0b9660 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -1752,8 +1752,9 @@ DrawPolygonLowLevel (PolygonTypePtr Polygon)
x[i] = v->point[0];
y[i++] = v->point[1];
}
- if (TEST_FLAG (THINDRAWFLAG, PCB)
- || TEST_FLAG (THINDRAWPOLYFLAG, PCB))
+ if (TEST_FLAG (THINDRAWFLAG, PCB) ||
+ TEST_FLAG (THINDRAWPOLYFLAG, PCB) ||
+ TEST_FLAG (CLEARLINEFLAG, Polygon))
{
gui->set_line_width (Output.fgGC, 1);
for (i = 0; i < n - 1; i++)
@@ -2180,7 +2181,7 @@ DrawPlainPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon)
if (Polygon->NoHoles)
{
- PolygonType poly;
+ PolygonType poly = *Polygon;
poly.Clipped = Polygon->NoHoles;
do {
DrawPolygonLowLevel (&poly);
diff --git a/src/move.c b/src/move.c
index 003c2e0..aebfc30 100644
--- a/src/move.c
+++ b/src/move.c
@@ -355,10 +355,12 @@ MovePolygon (LayerTypePtr Layer, PolygonTypePtr Polygon)
{
ErasePolygon (Polygon);
}
+ RestoreToPolygon (PCB->Data, POLYGON_TYPE, Layer, Polygon);
r_delete_entry (Layer->polygon_tree, (BoxType *) Polygon);
MovePolygonLowLevel (Polygon, DeltaX, DeltaY);
r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0);
InitClip (PCB->Data, Layer, Polygon);
+ ClearFromPolygon (PCB->Data, POLYGON_TYPE, Layer, Polygon);
if (Layer->On)
{
DrawPolygon (Layer, Polygon, 0);
@@ -418,12 +420,14 @@ MovePolygonPoint (LayerTypePtr Layer, PolygonTypePtr Polygon,
{
ErasePolygon (Polygon);
}
+ RestoreToPolygon (PCB->Data, POLYGON_TYPE, Layer, Polygon);
r_delete_entry (Layer->polygon_tree, (BoxType *) Polygon);
MOVE (Point->X, Point->Y, DeltaX, DeltaY);
SetPolygonBoundingBox (Polygon);
r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0);
RemoveExcessPolygonPoints (Layer, Polygon);
InitClip (PCB->Data, Layer, Polygon);
+ ClearFromPolygon (PCB->Data, POLYGON_TYPE, Layer, Polygon);
if (Layer->On)
{
DrawPolygon (Layer, Polygon, 0);
diff --git a/src/polygon.c b/src/polygon.c
index ecf11f4..0d3c895 100644
--- a/src/polygon.c
+++ b/src/polygon.c
@@ -733,6 +733,20 @@ SubtractPad (PadType * pad, PolygonType * p)
return Subtract (np, p, True);
}
+static int
+SubtractPolygon (PolygonType * poly, PolygonType * p)
+{
+ POLYAREA *np;
+
+ /* Don't subtract from ourselves! */
+ if (poly == p || !TEST_FLAG (CLEARLINEFLAG, poly))
+ return 0;
+
+ np = original_poly (poly);
+
+ return Subtract (np, p, True);
+}
+
struct cpInfo
{
const BoxType *other;
@@ -834,6 +848,24 @@ text_sub_callback (const BoxType * b, void *cl)
}
static int
+poly_sub_callback (const BoxType * b, void *cl)
+{
+ PolygonTypePtr poly = (PolygonTypePtr) b;
+ struct cpInfo *info = (struct cpInfo *) cl;
+ PolygonTypePtr polygon;
+
+ /* don't subtract the object that was put back! */
+ if (b == info->other)
+ return 0;
+ if (!TEST_FLAG (CLEARLINEFLAG, poly))
+ return 0;
+ polygon = info->polygon;
+ if (SubtractPolygon (poly, polygon) < 0)
+ longjmp (info->env, 1);
+ return 1;
+}
+
+static int
Group (DataTypePtr Data, Cardinal layer)
{
Cardinal i, j;
@@ -881,6 +913,8 @@ clearPoly (DataTypePtr Data, LayerTypePtr Layer, PolygonType * polygon,
r_search (layer->arc_tree, ®ion, NULL, arc_sub_callback, &info);
r +=
r_search (layer->text_tree, ®ion, NULL, text_sub_callback, &info);
+ r +=
+ r_search (layer->polygon_tree, ®ion, NULL, poly_sub_callback, &info);
}
END_LOOP;
if (info.solder || group == Group (Data, max_layer + COMPONENT_LAYER))
@@ -1001,6 +1035,26 @@ UnsubtractPad (PadType * pad, LayerType * l, PolygonType * p)
return 1;
}
+static int
+UnsubtractPolygon (PolygonType * poly, LayerType * l, PolygonType * p)
+{
+ POLYAREA *np;
+
+ /* Don't subtract from ourselves! */
+ if (poly == p || !TEST_FLAG (CLEARLINEFLAG, poly))
+ return 0;
+
+ /* overlap a bit to prevent notches from rounding errors */
+ np = BoxPolyBloated (&poly->BoundingBox, UNSUBTRACT_BLOAT);
+
+ if (!np)
+ return 0;
+ if (!Unsubtract (np, p))
+ return 0;
+ clearPoly (PCB->Data, l, p, (const BoxType *) poly, 2 * UNSUBTRACT_BLOAT);
+ return 1;
+}
+
static Boolean inhibit = False;
int
@@ -1290,6 +1344,10 @@ subtract_plow (DataTypePtr Data, LayerTypePtr Layer, PolygonTypePtr Polygon,
SubtractPad ((PadTypePtr) ptr2, Polygon);
Polygon->NoHolesValid = 0;
return 1;
+ case POLYGON_TYPE:
+ SubtractPolygon ((PolygonTypePtr) ptr2, Polygon);
+ Polygon->NoHolesValid = 0;
+ return 1;
case TEXT_TYPE:
SubtractText ((TextTypePtr) ptr2, Polygon);
Polygon->NoHolesValid = 0;
@@ -1317,6 +1375,9 @@ add_plow (DataTypePtr Data, LayerTypePtr Layer, PolygonTypePtr Polygon,
case PAD_TYPE:
UnsubtractPad ((PadTypePtr) ptr2, Layer, Polygon);
return 1;
+ case POLYGON_TYPE:
+ UnsubtractPolygon ((PolygonTypePtr) ptr2, Layer, Polygon);
+ return 1;
case TEXT_TYPE:
UnsubtractText ((TextTypePtr) ptr2, Layer, Polygon);
return 1;
@@ -1380,6 +1441,7 @@ PlowsPolygon (DataType * Data, int type, void *ptr1, void *ptr2,
case LINE_TYPE:
case ARC_TYPE:
case TEXT_TYPE:
+ case POLYGON_TYPE:
/* the cast works equally well for lines and arcs */
if (!TEST_FLAG (CLEARLINEFLAG, (LineTypePtr) ptr2))
return 0;
@@ -1433,8 +1495,7 @@ RestoreToPolygon (DataType * Data, int type, void *ptr1, void *ptr2)
{
if (type == POLYGON_TYPE)
InitClip (PCB->Data, (LayerTypePtr) ptr1, (PolygonTypePtr) ptr2);
- else
- PlowsPolygon (Data, type, ptr1, ptr2, add_plow);
+ PlowsPolygon (Data, type, ptr1, ptr2, add_plow);
}
void
@@ -1442,8 +1503,7 @@ ClearFromPolygon (DataType * Data, int type, void *ptr1, void *ptr2)
{
if (type == POLYGON_TYPE)
InitClip (PCB->Data, (LayerTypePtr) ptr1, (PolygonTypePtr) ptr2);
- else
- PlowsPolygon (Data, type, ptr1, ptr2, subtract_plow);
+ PlowsPolygon (Data, type, ptr1, ptr2, subtract_plow);
}
Boolean
--
1.5.6.3
_______________________________________________
geda-dev mailing list
[email protected]
http://www.seul.org/cgi-bin/mailman/listinfo/geda-dev