fped/: added gnuplot output for line/rect/circle with -g (experimental)

This commit is contained in:
Werner Almesberger 2011-09-04 20:35:34 -03:00
parent 6ca5c22ea4
commit e5d8fd87c3
6 changed files with 255 additions and 5 deletions

View File

@ -15,7 +15,7 @@ PREFIX ?= /usr/local
UPLOAD = www-data@downloads.qi-hardware.com:werner/fped/
OBJS = fped.o expr.o coord.o obj.o delete.o inst.o util.o error.o \
unparse.o file.o dump.o kicad.o postscript.o meas.o \
unparse.o file.o dump.o kicad.o postscript.o gnuplot.o meas.o \
layer.o overlap.o hole.o tsort.o bitset.o \
cpp.o lex.yy.o y.tab.o \
gui.o gui_util.o gui_style.o gui_inst.o gui_status.o gui_canvas.o \

16
file.c
View File

@ -20,6 +20,7 @@
#include "dump.h"
#include "kicad.h"
#include "postscript.h"
#include "gnuplot.h"
#include "util.h"
#include "file.h"
#include "fped.h"
@ -197,3 +198,18 @@ void write_ps_fullpage(const char *one)
{
do_write_ps(postscript_fullpage, one);
}
void write_gnuplot(const char *one)
{
char *name;
if (save_file_name) {
name = set_extension(save_file_name, "gp");
save_to(name, gnuplot, one);
free(name);
} else {
if (!gnuplot(stdout, one))
perror("stdout");
}
}

1
file.h
View File

@ -32,5 +32,6 @@ void save_fpd(void);
void write_kicad(void);
void write_ps(const char *one);
void write_ps_fullpage(const char *one);
void write_gnuplot(const char *one);
#endif /* !FILE_H */

20
fped.c
View File

@ -69,15 +69,17 @@ static void usage(const char *name)
fprintf(stderr,
"usage: %s [batch_mode] [cpp_option ...] [in_file [out_file]]\n\n"
"Batch mode options:\n"
" -g [-1 package]\n"
" write gnuplot output, then exit\n"
" -k write KiCad output, then exit\n"
" -p write Postscript output, then exit\n"
" -P [-s scale] [-1 package]\n"
" write Postscript output (full page), then exit\n"
" -1 name output only the specified package\n"
" -s scale scale factor for -P (default: auto-scale)\n"
" -T test mode. Load file, then exit\n"
" -T -T test mode. Load file, dump to stdout, then exit\n\n"
"Common options:\n"
" -1 name output only the specified package\n"
" -s scale scale factor for -P (default: auto-scale)\n"
" cpp_option -Idir, -Dname[=value], or -Uname\n"
, name);
exit(1);
@ -91,6 +93,7 @@ int main(int argc, char **argv)
batch_kicad,
batch_ps,
batch_ps_fullpage,
batch_gnuplot,
batch_test
} batch = batch_none;
char *name = *argv;
@ -104,11 +107,16 @@ int main(int argc, char **argv)
const char *one = NULL;
int c;
while ((c = getopt(argc, argv, "1:kps:D:I:PTU:")) != EOF)
while ((c = getopt(argc, argv, "1:gkps:D:I:PTU:")) != EOF)
switch (c) {
case '1':
one = optarg;
break;
case 'g':
if (batch)
usage(*argv);
batch = batch_gnuplot;
break;
case 'k':
if (batch)
usage(*argv);
@ -146,7 +154,8 @@ int main(int argc, char **argv)
usage(name);
}
if (one && batch != batch_ps && batch != batch_ps_fullpage)
if (one && batch != batch_ps && batch != batch_ps_fullpage &&
batch != batch_gnuplot)
usage(name);
if (!batch) {
@ -200,6 +209,9 @@ int main(int argc, char **argv)
case batch_ps_fullpage:
write_ps_fullpage(one);
break;
case batch_gnuplot:
write_gnuplot(one);
break;
case batch_test:
dump(stdout, NULL);
break;

199
gnuplot.c Normal file
View File

@ -0,0 +1,199 @@
/*
* gnuplot.c - Dump objects in gnuplot 2D format
*
* Written 2011 by Werner Almesberger
* Copyright 2011 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "coord.h"
#include "inst.h"
#include "gnuplot.h"
#define ARC_STEP 0.1 /* @@@ make configurable */
static void recurse_id(FILE *file, const struct inst *inst)
{
if (inst->obj->frame->name) {
recurse_id(file, inst->outer);
fprintf(file, "/%s", inst->obj->frame->name);
}
}
static void identify(FILE *file, const struct inst *inst)
{
fprintf(file, "#%%id=");
recurse_id(file, inst);
fprintf(file, "\n");
}
static void gnuplot_line(FILE *file, const struct inst *inst)
{
double xa, ya, xb, yb;
xa = units_to_mm(inst->base.x);
ya = units_to_mm(inst->base.y);
xb = units_to_mm(inst->u.rect.end.x);
yb = units_to_mm(inst->u.rect.end.y);
identify(file, inst);
fprintf(file, "#%%r=%f\n%f %f\n%f %f\n\n",
units_to_mm(inst->u.rect.width), xa, ya, xb, yb);
}
static void gnuplot_rect(FILE *file, const struct inst *inst)
{
double xa, ya, xb, yb;
xa = units_to_mm(inst->base.x);
ya = units_to_mm(inst->base.y);
xb = units_to_mm(inst->u.rect.end.x);
yb = units_to_mm(inst->u.rect.end.y);
identify(file, inst);
fprintf(file, "#%%r=%f\n", units_to_mm(inst->u.rect.width));
fprintf(file, "%f %f\n", xa, ya);
fprintf(file, "%f %f\n", xa, yb);
fprintf(file, "%f %f\n", xb, yb);
fprintf(file, "%f %f\n", xb, ya);
fprintf(file, "%f %f\n\n", xa, ya);
}
static void gnuplot_circ(FILE *file, const struct inst *inst)
{
double cx, cy, r;
double a;
int n, i;
cx = units_to_mm(inst->base.x);
cy = units_to_mm(inst->base.y);
r = units_to_mm(inst->u.arc.r);
identify(file, inst);
fprintf(file, "#%%r=%f\n", units_to_mm(inst->u.arc.width));
n = ceil(2*r*M_PI/ARC_STEP);
if (n < 2)
n = 2;
for (i = 0; i <= n; i++) {
a = 2*M_PI/n*i;
fprintf(file, "%f %f\n", cx+r*sin(a), cy+r*cos(a));
}
fprintf(file, "\n");
}
static void gnuplot_arc(FILE *file, const struct inst *inst)
{
abort();
#if 0
struct coord p;
double a;
/*
* The documentation says:
* Xstart, Ystart, Xend, Yend, Angle, Width, Layer
*
* But it's really:
* Xcenter, Ycenter, Xend, Yend, ...
*/
p = rotate_r(inst->base, inst->u.arc.r, inst->u.arc.a2);
a = inst->u.arc.a2-inst->u.arc.a1;
while (a <= 0)
a += 360;
while (a > 360)
a -= 360;
fprintf(file, "DA %d %d %d %d %d %d %d\n",
units_to_kicad(inst->base.x),
-units_to_kicad(inst->base.y),
units_to_kicad(p.x),
-units_to_kicad(p.y),
(int) (a*10.0),
units_to_kicad(inst->u.arc.width),
layer_silk_top);
#endif
}
static void gnuplot_inst(FILE *file, enum inst_prio prio,
const struct inst *inst)
{
switch (prio) {
case ip_pad_copper:
case ip_pad_special:
/* complain ? */
break;
case ip_hole:
/* complain ? */
break;
case ip_line:
gnuplot_line(file, inst);
break;
case ip_rect:
gnuplot_rect(file, inst);
break;
case ip_circ:
gnuplot_circ(file, inst);
break;
case ip_arc:
gnuplot_arc(file, inst);
break;
default:
/*
* Don't try to export vectors, frame references, or
* measurements.
*/
break;
}
}
static void gnuplot_package(FILE *file, const struct pkg *pkg)
{
enum inst_prio prio;
const struct inst *inst;
/*
* Package name
*/
fprintf(file, "# %s\n", pkg->name);
FOR_INST_PRIOS_UP(prio) {
for (inst = pkgs->insts[prio]; inst; inst = inst->next)
gnuplot_inst(file, prio, inst);
for (inst = pkg->insts[prio]; inst; inst = inst->next)
gnuplot_inst(file, prio, inst);
}
fprintf(file, "\n");
}
int gnuplot(FILE *file, const char *one)
{
const struct pkg *pkg;
for (pkg = pkgs; pkg; pkg = pkg->next)
if (pkg->name)
if (!one || !strcmp(pkg->name, one))
gnuplot_package(file, pkg);
fflush(file);
return !ferror(file);
}

22
gnuplot.h Normal file
View File

@ -0,0 +1,22 @@
/*
* gnuplot.h - Dump objects in gnuplot 2D format
*
* Written 2011 by Werner Almesberger
* Copyright 2011 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef GNUPLOT_H
#define GNUPLOT_H
#include <stdio.h>
int gnuplot(FILE *file, const char *one);
#endif /* !GNUPLOT_H */