#!/usr/bin/perl # convert GERBER file and aperture table to Fig # Andrew Daviel TRIUMF Feb 2002 advax@triumf.ca unless ($ARGV[1]) { &usage ; exit ; } open (IN,$ARGV[0]) or die ; while (){ tr/\r//d ; chomp ; #D10 R 0.05 CNTL.APR #D19 ROUNDED 60.000 60.000 0.000 FLASH #D20 RECTANGULAR 60.000 60.000 0.000 FLASH #D21 ROUNDED 200.000 200.000 0.000 FLASH tr/ / /s ; ($n,$t,$s,$s2,$z,$c) = split(/ /) ; if (length($t) > 1) { $s /= 1000 ; $s2 /= 1000 ; } $size{$n} = $s ; $size2{$n} = $s2 ; if ($t eq 'RECTANGULAR' && $s == $s2) { $t = 'S' ; } # square if ($t eq 'ROUNDED' && $s == $s2 && $c eq 'LINE') { $t = 'D' ; } # draw if ($t eq 'ROUNDED' && $s == $s2) { $t = 'R' ; } # round if ($t eq 'S') { $size2{$n} = $s ; } $type{$n} = $t ; print "$n $t $s $s2\n" ; } close (IN) ; # big grid 1" = 1200 pt, 0.5" 600, 0.25 300 , 0.125 150, 0.0625 75 # metric 1cm = 900 5mm 450 ... 45 # type text = 4 # justification 0 left 1 center 2 right # colour 0 black 4 red 1 blue # type justif colour depth ? font size angle flags zz x y text # print "4 $just $colour $depth 0 $fn $pt $angle $flags 210 750 $x $y $_\\001\n" ; # type poly = 2 # type x styl x fgcol bgcol depth x fil angle x cap x x fwdarw backarw npts # 2 1 0 1 4 7 50 0 -1 0.000 0 0 -1 0 0 3 # line width 1 0.012" $fg = 4 ; $bg = 4 ; $angle = 0.0 ; $date = localtime() ; # circle rad # 1 x sty wid fg bg dep x fil angle x x X Y R R X Y # 1 3 0 4 0 7 50 0 -1 0.000 1 0.0000 825 1350 618 618 825 1350 1425 1200 # 1 3 0 4 0 7 50 0 -1 0.000 1 0.0000 825 1350 618 618 825 1350 1425 1200 # fil #1 3 0 4 0 -1 50 0 4 0.000 1 0.0000 1575 2250 586 586 1575 2250 2161 2250 #1 3 0 4 0 -1 50 0 4 0.000 1 0.0000 1575 2250 586 586 1575 2250 2161 2250 # 100% fill #1 3 0 4 0 -1 50 0 20 0.000 1 0.0000 1575 2250 586 586 1575 2250 2161 2250 # 50% fill #1 3 0 4 0 -1 50 0 10 0.000 1 0.0000 1575 2250 586 586 1575 2250 2161 225 # pattern fill #1 3 0 4 0 7 50 0 44 0.000 1 0.0000 1875 2025 636 636 1875 2025 2511 2025 # gap angle #1 3 3 4 0 7 50 0 41 7.500 1 0.2269 1875 2025 636 636 1875 2025 2511 2025 #1 3 3 4 0 7 50 0 41 7.500 1 0.2269 1875 2025 636 636 1875 2025 2511 2025 # circle dia #1 4 0 4 0 7 50 0 -1 0.000 1 0.0000 1725 1537 457 457 1350 1800 2100 1275 # ellipse radii # x x x wid x x dep x x x x X y xr yr # 1 1 0 4 0 7 50 0 -1 0.000 1 0.0000 1050 1575 825 300 1050 1575 1875 1275 # 1 1 0 4 0 7 50 0 -1 0.000 1 0.0000 1050 1575 825 300 1050 1575 1875 1275 # ellipse dia #x x x x x x dep x x x x x X Y XR YR #1 2 0 4 0 7 50 0 -1 0.000 1 0.0000 2175 1837 675 263 1500 2100 2850 1575 #1 2 0 4 0 7 50 0 -1 0.000 1 0.0000 2175 1837 675 263 1500 2100 2850 1575 # box # wid dep #2 2 0 4 0 7 50 0 -1 0.000 0 0 -1 0 0 5 # X1 Y1 X2 Y1 X2 Y2 X1 Y2 X1 Y1 # 1500 2250 2625 2250 2625 1725 1500 1725 1500 2250 #c Gerber Meaning HP meaning #c D01 aperture open PD pen down #c D02 aperture close PU pen up #c D03 flash CI draw circle #c Pnn select aperture SPnn select pen #c Cnnn select aperture - calculate circle size for CI #c G54 initialize IN initialize #c M02 end of file SP0,NR park pen, deselect plotter $depth = 50 ; $width = 1 ; $lw2 = 10/2 ; # half linewidth if ($ARGV[3]) { $depth = $ARGV[3] ; if ($depth <20) { $fg = $bg = $depth ; } } open (OUT,">$ARGV[2]") ; print OUT<) ; unless (/^G54\*/) { print "$ARGV[1] not a Gerber file; missing G54*" ; } while () { tr/ \r\n//d ; #print OUT "# $_\n" ; #D10* #X00190Y00100D02*D03* #D21* #X-00050Y00400D02* #M02* #P3* #X01505Y01583D01* #X01577Y01655D01* #C50* #D03* #Y4600D02* $pixel = 1200 ; if (/^D03\*/) { if (@line) { &doline ; } print "flash $type\n" ; if ($type eq 'R') { print OUT "1 3 0 1 0 0 $depth 0 20 0.000 1 0.0000 $x $y $radius $radius $x $y 0 0\n" ; } elsif ($type eq 'S' || $type eq 'RECTANGULAR') { print "flash $radius2 x $radius\n" ; $x1 = $x - $radius2 ; $x2 = $x + $radius2 ; $y1 = $y - $radius ; $y2 = $y + $radius ; print OUT "2 2 0 1 0 0 $depth 0 20 0.000 0 0 -1 0 0 5\n" ; print OUT "\t$x1 $y1 $x2 $y1 $x2 $y2 $x1 $y2 $x1 $y1\n" ; } else { print "error flash type $type\n" ; } } elsif (/^(D[\d]+)\*/) { if (@line) { &doline ; } print "aperture $1 size $size{$1} x $size2{$1} type $type{$1}\n" ; $radius = int($size{$1}*$pixel/2 + 0.5) - $lw2 ; $radius2 = int($size2{$1}*$pixel/2 + 0.5) - $lw2 ; unless ($radius2) { $radius2 = $radius ; } $diam = int($size{$1}*$pixel+ 0.5) ; $type = $type{$1} ; $width = int($diam/12+0.5) ; if ($width < 1) { $width = 1 ; } } elsif (/^(P[\d]+)\*/) { if (@line) { &doline ; } print "pen $1\n" ; } elsif (/^M02\*/) { if (@line) { &doline ; } print "End\n" ; } elsif (/^(C[\d]+)\*/) { if (@line) { &doline ; } print "circle$1\n" ; } elsif (/^X(-*[\d]+)Y(-*[\d]+)D01\*/) { $x = int($2*$pixel/1000+0.5) ; $y = int($1*$pixel/1000+0.5) ; print "x $1 y $2 draw $x $y\n" ; push (@line,"$x $y") ; } elsif (/^X(-*[\d]+)D01\*/) { $y = int($1*$pixel/1000+0.5) ; print "x $1 draw $x $y\n" ; push (@line,"$x $y") ; } elsif (/^Y(-*[\d]+)D01\*/) { $x = int($1*$pixel/1000+0.5) ; print "y $1 draw $x $y\n" ; push (@line,"$x $y") ; } elsif (/^X(-*[\d]+)Y(-*[\d]+)D02\*/) { if (@line) { &doline ; } $x = int($2*$pixel/1000+0.5) ; $y = int($1*$pixel/1000+0.5) ; print "x $1 y $2 move $x $y\n" ; push (@line,"$x $y") ; } elsif (/^Y(-*[\d]+)D02\*/) { if (@line) { &doline ; } $x = int($1*$pixel/1000+0.5) ; print " y $1 move $x $y\n" ; push (@line,"$x $y") ; } elsif (/^X(-*[\d]+)D02\*/) { if (@line) { &doline ; } $y = int($1*$pixel/1000+0.5) ; print "x $1 move $x $y\n" ; push (@line,"$x $y") ; } else { if (@line) { &doline ; } if ($_) { print "error $_\n" ; } } } sub doline { my $npts = @line ; my $line ; if ($npts > 1) { unless ($type eq 'D') { print "error draw $type\n" ; } print OUT "2 1 0 $width $fg $bg $depth 0 -1 $angle 0 1 -1 0 0 $npts\n" ; foreach $line (@line) { print OUT "\t$line\n" ; } } undef(@line) ; } sub usage { print STDERR< (default 50) The aperture table is required Round flash are translated to filled circles, square flash to filled boxes and lines to round-end polylines. EOT }