#!/usr/bin/perl # -*- perl -*- # Copyright 2002 DJ Delorie # Distributed under the terms of the GNU General Public License $grid = 25; $padcl = 10; $trackcl = 10; $viacl = 10; $viasize = 25; $trackwidth = 10; $pcb = shift; $track = shift; if ($pcb) { open(STDIN, $pcb) || die("$pcb: $!"); } if ($track) { open(STDOUT, ">$track") || die("$track: $!"); } $li = $pi = $di = 0; $maxlayer = 0; $minlayer = 999; while () { if (/PCB\((.*) (\d+) (\d+)\)/) { $board_width = $2; $board_height = $3; } if (/Pin\((.*)\)/) { ($x,$y,$diam,$drill,$name,$num,$flags) = split(' ', $1); $pins[$pi]->{x} = $x; $pins[$pi]->{y} = $y; $pins[$pi]->{d} = $diam; $pins[$pi]->{tw} = $diam / 4; $pi++; } if (/Pad\((.*)\)/) { ($x1,$y1,$x2,$y2,$width,$name,$num,$flags) = split(' ', $1); $x = ($x1+$x2)/2; $y = ($y1+$y2)/2; $pins[$pi]->{x} = $x; $pins[$pi]->{y} = $y; if ($x1 == $x2) { $pins[$pi]->{w} = $width; $pins[$pi]->{h} = &abs($y1-$y2); } else { $pins[$pi]->{h} = $width; $pins[$pi]->{w} = &abs($x1-$x2); } $pins[$pi]->{tw} = $width / 4; $renumber{"$x1 $y1"} = "$x $y"; $renumber{"$x2 $y2"} = "$x $y"; $pi++; } if (/Layer\((\d+) "(.*)"\)/) { $ln = $2; $current_layer = $1; $minlayer = $1 if $minlayer > $1; $maxlayer = $1 if $maxlayer < $1; if ($ln =~ /^(vcc|gnd)$/i) { $route_on{$current_layer} = -2; } elsif ($ln =~ /^(solder|component)$/) { $route_on{$current_layer} = 0; } else { $route_on{$current_layer} = -1; } if ($ln eq "component") { $component_layer = $current_layer; } if ($ln eq "solder") { $solder_layer = $current_layer; } } if (/\sLine\((.*)\)/) { ($x1,$y1,$x2,$y2,$width,$flags) = split(' ', $1); if ($renumber{"$x1 $y1"}) { ($x1, $y1) = split(' ', $renumber{"$x1 $y1"}); } if ($renumber{"$x2 $y2"}) { ($x2, $y2) = split(' ', $renumber{"$x2 $y2"}); } $lines[$li]->{x1} = $x1; $lines[$li]->{y1} = $y1; $lines[$li]->{x2} = $x2; $lines[$li]->{y2} = $y2; $lines[$li]->{l} = $current_layer; $li++; $route_on{$current_layer} = 0; &connect($x1, $y1, $x2, $y2); } } sub connect { my ($x1,$y1,$x2,$y2) = @_; if ($net{"$x1 $y1"} && $net{"$x2 $y2"}) { $old = $net{"$x2 $y2"}; $new = $net{"$x1 $y1"}; while (($k,$v) = each %net) { if ($v == $old) { $net{$k} = $new; } } } elsif ($net{"$x1 $y1"}) { $net{"$x2 $y2"} = $net{"$x1 $y1"}; } elsif ($net{"$x2 $y2"}) { $net{"$x1 $y1"} = $net{"$x2 $y2"}; } else { $route_no ++; $net{"$x1 $y1"} = $net{"$x2 $y2"} = $route_no; } } for $n (keys %net) { $route_nos{$net{$n}} = 1; } for $n (keys %route_nos) { $nroutes++; } print "j 0 0 $board_width $board_height $minlayer $maxlayer $nroutes $grid"; print " $padcl $trackcl $viacl 0 $viasize n 0 $trackwidth 0 0 0 0\n"; print "k\n"; print "m 0\n"; for ($l=$minlayer; $l<=$maxlayer; $l++) { $route_on{$l} = -1 unless defined $route_on{$l}; $on = $route_on{$l}; print "l $l $on\n"; } for ($i=0; $i<$pi; $i++) { $x = $pins[$i]->{x}; $y = $pins[$i]->{y}; $r = $net{"$x $y"}; if ($r) { $pads_in_route{$r} ++; $tw = $pins[$i]->{tw}; if ($route_width{$r} == 0 || $route_width{$r} > $tw) { $route_width{$r} = $tw; } } else { &emit_pad('u', $i, 0); } } sub emit_pad { my ($type, $i, $qq) = @_; my ($x, $y, $d, $r, $l, $w, $b); $x = $pins[$i]->{x}; $y = $pins[$i]->{y}; $d = $pins[$i]->{d}; $r = $net{"$x $y"}; $r = 0 unless $r; if ($d > 0) { print "$type $r $x $y $minlayer $maxlayer $qq 1 $qq 1 0 0 0 0 0 0\n"; print "q c 0 $d 0 $minlayer $maxlayer\n"; } else { $l = $component_layer; $w = $pins[$i]->{w}; $b = $pins[$i]->{h}; print "$type $r $x $y $l $l $qq 1 $qq 1 0 0 0 0 0 0\n"; if ($w > $b) { print "q r 0 $w $b $l $l\n"; } else { print "q r 90 $b $w $l $l\n"; } } } for $w (values %route_width) { $route_widths{$w} = 1; } for $w (sort { $a <=> $b } keys %route_widths) { for $n (sort keys %route_nos) { next unless $route_width{$n} == $w; $tw = $route_width{$n}; $tw = 40 if $tw > 40; $tw = $trackwidth if $tw < $trackwidth; $tw = 5*int(($tw+4.999)/5); $tw = $trackwidth; print "r $n $pads_in_route{$n} 0 0 0 $tw 0 0\n"; $qq = 0; for ($i=0; $i<$pi; $i++) { $x = $pins[$i]->{x}; $y = $pins[$i]->{y}; $r = $net{"$x $y"}; if ($r == $n) { $qq++; emit_pad('p', $i, $qq); } } } } sub abs { my($a) = @_; if ($a < 0) { return -$a; } return $a; }