#!/usr/bin/perl # # dxf2gp - Convert simple DXF to Gnuplot # # Written 2011 by Werner Almesberger # Copyright 2011 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. # # # Currently, only the directives LINE, CIRCLE, and ARC are supported. # Adjacent line segments are not merged. Arcs and circles are translated # to (multi-segment) lines. # # The main purpose of this script is currently to convert the M1 case # design: # http://projects.qi-hardware.com/index.php/p/m1/source/tree/master/cad/protocase_v7_laser.dxf # $S_SCAN = 0; # wait for LINE, CIRCLE, or ARC $S_ByLayer = 1; # next is ByLayer $S_INDEX = 2; # next is index $S_DATA = 3; # next is indexed data $S_MARKER = 4; # next is subclass marker sub line { print "$_[10] $_[20]\n$_[11] $_[21]\n\n"; } sub circle { local ($x, $y, $r) = ($_[10], $_[20], $_[40]); for (my $i = 0; $i != 100; $i++) { local $v = 3.14159265*2/100*$i; print $x+$r*sin($v), " ", $y+$r*cos($v), "\n"; } print $x, " ", $y+$r, "\n\n"; } sub arc { local ($x, $y, $r) = ($_[10], $_[20], $_[40]); local ($a0, $a1) = ($_[50], $_[51]); $a1 += 360 if $a1 < $a0; for (my $a = $a0; $a <= $a1; $a += 2) { local $v = 3.14159265/180*$a; print $x+$r*cos($v), " ", $y+$r*sin($v), "\n"; } print "\n"; } $s = $S_SCAN; while (<>) { if ($s == $S_SCAN) { if (/^LINE\b/) { *fn = *line; } elsif (/^CIRCLE/) { *fn = *circle; } elsif (/^ARC/) { *fn = *arc; } else { next; } $s = $S_ByLayer; next; } elsif ($s == $S_ByLayer) { if (/^ByLayer/) { $s = $S_INDEX; } next; } elsif ($s == $S_INDEX) { if ($_ == 0) { &fn(@a); @a = (); $s = $S_SCAN; } elsif ($_ == 100) { $s = $S_MARKER; } else { $index = $_; $s = $S_DATA; } } elsif ($s == $S_DATA) { $a[$index] = $_+0; $s = $S_INDEX; } elsif ($s == $S_MARKER) { $s = $S_INDEX; } else { die; } }