#!/usr/bin/perl
#
# zstack.pl - Convert 2.5D paths into a stack with limited Z steps
#
# Written 2012 by Werner Almesberger
# Copyright 2012 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.
#


sub usage
{
	print STDERR "usage: $0 [-r] z-start z-maxstep [file ...]\n";
	print STDERR "  -r  reverse Z stacking. Also swaps X and Y.\n";
	exit(1);
}


sub issue
{
	local ($c, $z) = @_;
	my $t;

	#
	# The order here is a bit arbitrary. We sort to make the outcome
	# more predictable but it shouldn't really matter.
	#

	($t = $z{$c}) =~ s/\s+-?\d+(\.\d*)?$/ $z/mg;
	print $t;
}


if ($ARGV[0] eq "-r") {
	shift @ARGV;
	$reverse = 1;
}
&usage if $ARGV[0] =~ /^-[^0-9]/;

$z0 = shift @ARGV;
$zs = shift @ARGV;

$z0 =~ s/mm$//;
$zs =~ s/mm$//;

&usage unless $zs > 0;

while (<>) {
	if (/^\s*$/) {
		$z{$z} .= "$s\n";
		undef $s;
	}
	$z = $3 if /^-?\d+(\.\d*)?\s+-?\d+(\.\d*)?\s+(-?\d+(\.\d*)?)/;
	$s .= $_;
	$zmax = $z if $z > $zmax || !defined $zmax;
}
$z{$z} .= "$s\n";

if ($reverse) {
	for (keys %z) {
		($t{$zmax-$_} = $z{$_}) =~
		    s/^(-?\d+(\.\d*)?)\s+(-?\d+(\.\d*)?)\s+/$3 $1 /mg;
	}
	%z = %t;
}

$z = $z0;
for $c (sort { $b <=> $a } keys %z) {
	while ($z > $c+$zs) {
		$z -= $zs;
		&issue($c, $z);
	}
	$z = $c;
	&issue($c, $z);
}