#!/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;
	}
}