#!/usr/bin/perl -w

# Use:
#   - support X/Y dist 0.5mm

use strict;

our $shape = <<'END';
xyyZZYYXYxxyzYYZXzzxyXXYXXXZxxxyyXXZyyyzXXzz
zxxYYXXZXzzxyXXYZyyzxZZXZZZYzzzxxZZYxxxyZZyy
yzzXXZZYZyyzxZZXYxxyzYYZYYYXyyyzzYYXzzzxYYxx
END
# simple version (unknotted, [0,1,2]^3):
# YxxyzYYZXzzxyXXYZyyzxZZX
#
# New and less symmetric one that also fits in the 2x2x2 box:
# YXXyzzYxYXZZxzyxYzyyZXZx
# (email 8.9.2022)

sub o { print @_ or die $!; }

o <<'END';
// -*- autogenerated, do not edit -*-

module Trace() {
END

my @p = qw(0 0 0);

$"=',';

while ($shape =~ s/^\s*(\w)//) {
    my $ix = index('xyz', (lc $1));
    my $sign = $1 =~ /[A-Z]/ ? +1 : -1;
    my @q = @p;
    $q[$ix] += $sign;
    o "    TraceEdge([@p],[@q]);\n";
    @p = @q;
}

die @p unless "@p" eq '0,0,0';

o "}\n\n";

while (<DATA>) { o $_ }

__DATA__

thick = 6;
edgeu = 10;
//edgeu = 15;

// calculated

octa_long = thick;
octa_short = octa_long / (1 + sqrt(2));

module OctaThing() {
    hull(){
	for (r = [[0,0,0], [90,0,0], [0,90,0]]) {
	    rotate(r)
		cube([ octa_short,octa_short, octa_long ], center=true);
	}
    }
}

module TraceEdge(p,q) {
    hull(){
        for (x=[p,q]) {
            translate(x * edgeu)
                OctaThing();
        }
    }
}

rotate([0,0,45])
  rotate([0,90,0])
  Trace();

	
