Added relaxation of pad overlap checking. Not GUI-settable yet.

- README, fpd.l, fpd.y: added directives "allow touch" and "allow overlap" to
  make overlap checking more permissive
- dump.c (dump_allow, dump): generate "allow" directive
- obj.h, obj.c (allow_overlap): added global variable for strictness of overlap
  checking
- overlap.h, overlap.c (overlap, ...), layer.h, layer.c (refine_layers):
  strictness of overlap checking is passed as an argument
- hole.c (check_through_hole), layer.h, layer.c (refine_copper), obj.c
  (instantiate): updated callers of "overlap" to provide "allow" argument



git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5974 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
werner 2010-08-09 04:16:37 +00:00
parent b2b3a46119
commit e6b2658a65
11 changed files with 153 additions and 42 deletions

28
README
View File

@ -106,7 +106,7 @@ The file has the following structure:
frame definitions
...
package name
unit
setup
objects
...
@ -124,6 +124,14 @@ from the previous vector to (2mm, 2mm), and then make a line connecting
the two points.
Setup
- - -
The setup section defines settings that affect the entire footprint.
It is optional and can contain a "unit" directive and an "allow"
directive.
Units
- - -
@ -154,6 +162,24 @@ When saving a footprint definition, the default unit is set to the
unit set in the GUI.
Allow
- - -
fped normally disallows overlapping pads. This restriction can be
relaxed with the "allow" directive.
allow touch
Allows pads touching but not having more than their border in common.
allow overlap
Do not check for overlaps at all.
If the "allow" directive is omitted, fped defaults to allowing
neigher overlap nor touch.
Vectors
- - - -

19
dump.c
View File

@ -569,6 +569,23 @@ static void dump_unit(FILE *file)
}
static void dump_allow(FILE *file)
{
switch (allow_overlap) {
case ao_none:
break;
case ao_touch:
fprintf(file, "allow touch\n");
break;
case ao_any:
fprintf(file, "allow overlap\n");
break;
default:
abort();
}
}
static void reverse_frames(FILE *file, struct frame *last)
{
if (last) {
@ -589,6 +606,8 @@ int dump(FILE *file)
reverse_frames(file, frames->next);
fprintf(file, "package \"%s\"\n", pkg_name);
dump_unit(file);
dump_allow(file);
fprintf(file, "\n");
dump_frame(file, frames, "");
fflush(file);

6
fpd.l
View File

@ -61,6 +61,8 @@ void scan_values(const char *s)
/* keywords are only accepted at the beginning of a line */
%s NOKEYWORD
/* ALLOW is followed by special keywords (we could use NOKEYWORD as well) */
%s ALLOW
NUM [0-9]+\.?[0-9]*
SP [\t ]*
@ -123,6 +125,10 @@ SP [\t ]*
<INITIAL>"unit" { BEGIN(NOKEYWORD);
return TOK_UNIT; }
<INITIAL>"allow" BEGIN(ALLOW);
<ALLOW>"overlap" return TOK_ALLOW_OVERLAP;
<ALLOW>"touch" return TOK_ALLOW_TOUCH;
<INITIAL>"%del" { BEGIN(NOKEYWORD);
return TOK_DBG_DEL; }
<INITIAL>"%move" { BEGIN(NOKEYWORD);

27
fpd.y
View File

@ -459,6 +459,7 @@ static int dbg_meas(const char *name)
%token TOK_NEXT TOK_NEXT_INVERTED TOK_MAX TOK_MAX_INVERTED
%token TOK_DBG_DEL TOK_DBG_MOVE TOK_DBG_FRAME TOK_DBG_PRINT
%token TOK_DBG_DUMP TOK_DBG_EXIT TOK_DBG_TSORT TOK_DBG_MEAS
%token TOK_ALLOW_OVERLAP TOK_ALLOW_TOUCH
%token <num> NUMBER
%token <str> STRING
@ -508,8 +509,8 @@ all:
;
fpd:
frame_defs part_name opt_unit opt_frame_items opt_measurements
| frame_defs unit opt_frame_items opt_measurements
frame_defs part_name opt_setup opt_frame_items opt_measurements
| frame_defs setup opt_frame_items opt_measurements
| frame_defs frame_items opt_measurements
| frame_defs opt_measurements
;
@ -532,8 +533,15 @@ part_name:
}
;
opt_unit:
| unit
opt_setup:
| setup
;
setup:
unit
| allow
| unit allow
| allow unit
;
unit:
@ -552,6 +560,17 @@ unit:
}
;
allow:
TOK_ALLOW_TOUCH
{
allow_overlap = ao_touch;
}
| TOK_ALLOW_OVERLAP
{
allow_overlap = ao_any;
}
;
frame_defs:
| frame_defs frame_def
;

2
hole.c
View File

@ -19,7 +19,7 @@
static int check_through_hole(struct inst *pad, struct inst *hole)
{
if (!overlap(pad, hole))
if (!overlap(pad, hole, ao_none))
return 1;
if (!inside(hole, pad)) {
fail("hole (line %d) not completely inside "

11
layer.c
View File

@ -113,7 +113,8 @@ static int refine_overlapping(struct inst *copper, struct inst *other)
}
static int refine_copper(const struct pkg *pkg_copper, struct inst *copper)
static int refine_copper(const struct pkg *pkg_copper, struct inst *copper,
enum allow_overlap allow)
{
const struct pkg *pkg;
struct inst *other;
@ -126,7 +127,7 @@ static int refine_copper(const struct pkg *pkg_copper, struct inst *copper)
continue;
for (other = pkg->insts[ip_pad_copper]; other;
other = other->next)
if (copper != other && overlap(copper, other)) {
if (copper != other && overlap(copper, other, allow)) {
fail("overlapping copper pads "
"(\"%s\" line %d, \"%s\" line %d)",
copper->u.pad.name, copper->obj->lineno,
@ -136,7 +137,7 @@ static int refine_copper(const struct pkg *pkg_copper, struct inst *copper)
}
for (other = pkg->insts[ip_pad_special]; other;
other = other->next)
if (overlap(copper, other))
if (overlap(copper, other, ao_none))
if (!refine_overlapping(copper, other))
return 0;
}
@ -155,7 +156,7 @@ static void mirror_layers(layer_type *layers)
}
int refine_layers(void)
int refine_layers(enum allow_overlap allow)
{
const struct pkg *pkg;
struct inst *copper;
@ -163,7 +164,7 @@ int refine_layers(void)
for (pkg = pkgs; pkg; pkg = pkg->next)
for (copper = pkg->insts[ip_pad_copper]; copper;
copper = copper->next) {
if (!refine_copper(pkg, copper))
if (!refine_copper(pkg, copper, allow))
return 0;
if (copper->u.pad.hole)
mirror_layers(&copper->u.pad.layers);

View File

@ -15,6 +15,8 @@
#include <stdint.h>
#include "overlap.h"
typedef uint32_t layer_type;
@ -75,6 +77,6 @@ enum pad_type layers_to_pad_type(layer_type layers);
layer_type mech_hole_layers(void);
int refine_layers(void);
int refine_layers(enum allow_overlap allow);
#endif /* !LAYER_H */

4
obj.c
View File

@ -22,6 +22,7 @@
#include "meas.h"
#include "inst.h"
#include "hole.h"
#include "overlap.h"
#include "layer.h"
#include "delete.h"
#include "obj.h"
@ -37,6 +38,7 @@ char *pkg_name = NULL;
struct frame *frames = NULL;
struct frame *active_frame = NULL;
void *instantiation_error = NULL;
enum allow_overlap allow_overlap = ao_none;
static struct bitset *frame_set; /* frames visited in "call chain" */
@ -498,7 +500,7 @@ int instantiate(void)
if (ok)
ok = link_holes();
if (ok)
ok = refine_layers();
ok = refine_layers(allow_overlap);
if (ok)
ok = instantiate_meas(n_frames);
if (ok)

2
obj.h
View File

@ -20,6 +20,7 @@
#include "expr.h"
#include "coord.h"
#include "meas.h"
#include "overlap.h"
#include "layer.h"
@ -242,6 +243,7 @@ extern char *pkg_name; /* anonymous common package first */
extern struct frame *frames; /* root frame first */
extern struct frame *active_frame;
extern void *instantiation_error;
extern enum allow_overlap allow_overlap;
struct inst;

View File

@ -71,15 +71,23 @@ struct shape {
static int circle_circle_overlap(struct coord c1, unit_type r1,
struct coord c2, unit_type r2)
struct coord c2, unit_type r2, enum allow_overlap allow)
{
if (allow == ao_touch)
return dist_point(c1, c2) < r1+r2;
return dist_point(c1, c2) <= r1+r2;
}
static int circle_rect_overlap(struct coord c, unit_type r,
struct coord min, struct coord max)
struct coord min, struct coord max, enum allow_overlap allow)
{
if (allow == ao_touch) {
if (c.x <= min.x-r || c.x >= max.x+r)
return 0;
if (c.y <= min.y-r || c.y >= max.y+r)
return 0;
}
if (c.x < min.x-r || c.x > max.x+r)
return 0;
if (c.y < min.y-r || c.y > max.y+r)
@ -89,8 +97,14 @@ static int circle_rect_overlap(struct coord c, unit_type r,
static int rect_rect_overlap(struct coord min1, struct coord max1,
struct coord min2, struct coord max2)
struct coord min2, struct coord max2, enum allow_overlap allow)
{
if (allow == ao_touch) {
if (max1.x <= min2.x || max2.x <= min1.x)
return 0;
if (max1.y <= min2.y || max2.y <= min1.y)
return 0;
}
if (max1.x < min2.x || max2.x < min1.x)
return 0;
if (max1.y < min2.y || max2.y < min1.y)
@ -99,15 +113,18 @@ static int rect_rect_overlap(struct coord min1, struct coord max1,
}
static int shapes_overlap(const struct shape *a, const struct shape *b)
static int shapes_overlap(const struct shape *a, const struct shape *b,
enum allow_overlap allow)
{
if (a->circle && !b->circle)
return shapes_overlap(b, a);
return shapes_overlap(b, a, allow);
if (a->circle) /* b must be circle, too */
return circle_circle_overlap(a->center, a->r, b->center, b->r);
return circle_circle_overlap(a->center, a->r, b->center, b->r,
allow);
if (b->circle) /* a must be rect */
return circle_rect_overlap(b->center, b->r, a->min, a->max);
return rect_rect_overlap(a->min, a->max, b->min, b->max);
return circle_rect_overlap(b->center, b->r, a->min, a->max,
allow);
return rect_rect_overlap(a->min, a->max, b->min, b->max, allow);
}
@ -115,11 +132,11 @@ static int shapes_overlap(const struct shape *a, const struct shape *b)
static int test_overlap(const struct inst *a, const struct inst *b,
const struct shape *other);
const struct shape *other, enum allow_overlap allow);
static int do_circle(const struct inst *next, const struct shape *other,
unit_type x, unit_type y, unit_type r)
unit_type x, unit_type y, unit_type r, enum allow_overlap allow)
{
struct shape shape = {
.circle = 1,
@ -131,13 +148,14 @@ static int do_circle(const struct inst *next, const struct shape *other,
};
if (next)
return test_overlap(next, NULL, &shape);
return shapes_overlap(other, &shape);
return test_overlap(next, NULL, &shape, allow);
return shapes_overlap(other, &shape, allow);
}
static int do_rect(const struct inst *next, const struct shape *other,
unit_type x, unit_type y, unit_type w, unit_type h)
unit_type x, unit_type y, unit_type w, unit_type h,
enum allow_overlap allow)
{
struct shape shape = {
.circle = 0,
@ -152,13 +170,13 @@ static int do_rect(const struct inst *next, const struct shape *other,
};
if (next)
return test_overlap(next, NULL, &shape);
return shapes_overlap(other, &shape);
return test_overlap(next, NULL, &shape, allow);
return shapes_overlap(other, &shape, allow);
}
static int test_overlap(const struct inst *a, const struct inst *b,
const struct shape *other)
const struct shape *other, enum allow_overlap allow)
{
struct coord min, max;
unit_type h, w, r;
@ -183,23 +201,26 @@ static int test_overlap(const struct inst *a, const struct inst *b,
w = max.x-min.x;
if (!rounded)
return do_rect(b, other, min.x, min.y, w, h);
return do_rect(b, other, min.x, min.y, w, h, allow);
if (h > w) {
r = w/2;
return do_circle(b, other, min.x+r, max.y-r, r) ||
do_rect(b, other, min.x, min.y+r, w, h-2*r) ||
do_circle(b, other, min.x+r, min.y+r, r);
return do_circle(b, other, min.x+r, max.y-r, r, allow) ||
do_rect(b, other, min.x, min.y+r, w, h-2*r, allow) ||
do_circle(b, other, min.x+r, min.y+r, r, allow);
} else {
r = h/2;
return do_circle(b, other, min.x+r, min.y+r, r) ||
do_rect(b, other, min.x+r, min.y, w-2*r, h) ||
do_circle(b, other, max.x-r, min.y+r, r);
return do_circle(b, other, min.x+r, min.y+r, r, allow) ||
do_rect(b, other, min.x+r, min.y, w-2*r, h, allow) ||
do_circle(b, other, max.x-r, min.y+r, r, allow);
}
}
int overlap(const struct inst *a, const struct inst *b)
int overlap(const struct inst *a, const struct inst *b,
enum allow_overlap allow)
{
return test_overlap(a, b, NULL);
if (allow == ao_any)
return 0;
return test_overlap(a, b, NULL, allow);
}

View File

@ -1,8 +1,8 @@
/*
* overlap.h - Test for overlaps
*
* Written 2009 by Werner Almesberger
* Copyright 2009 by Werner Almesberger
* Written 2009, 2010 by Werner Almesberger
* Copyright 2009, 2010 by 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
@ -13,7 +13,19 @@
#ifndef OVERLAP_H
#define OVERLAP_H
#include "inst.h"
enum allow_overlap {
ao_none,
ao_touch,
ao_any,
};
/*
* Avoid inst.h -> layer.h -> overlay.h -> inst.h loop
*/
struct inst;
/*
@ -27,6 +39,7 @@ int inside(const struct inst *a, const struct inst *b);
* "overlap" returns 1 if "a" and "b" have at least one point in common.
*/
int overlap(const struct inst *a, const struct inst *b);
int overlap(const struct inst *a, const struct inst *b,
enum allow_overlap allow);
#endif /* !OVERLAP_H */