#!/usr/bin/perl -w # # usage: # ./distort-stl OUTPUT DISTORTION [PARAMS...] ... # # DISTORTIONs: # # project-cylinder RADIUS # projects the X-Z plane onto the cylinder of # radius RADIUS with axis [0, 0, t] # origin becomes [0, -RADIUS, 0] # other planes of the input are projected onto smaller # or larger cylinders accordingly # probably a bad idea if # object has any Y > RADIUS # object has any |X| > tau / RADIUS # technically, treats input as if it were # polar-rectangular coords: # Z' = Z; R' = Y + RADIUS; theta' = X / RADIUS # and then converts back into cartesian use strict; use autodie; sub shift_arg () { die unless @ARGV; scalar shift @ARGV; } sub pointmap_distortion { my ($x,$y,$z) = @_; my $radius = shift_arg; my $r = $y + $radius; my $theta = $x / $radius; return ($r * cos($theta), $r * sin($theta), $z); } if (@ARGV && $ARGV[0] =~ m/^-/) { die "no options supported\n"; } my $admesh_pipe = '--write-ascii-stl 3<&0 4>&1 >/dev/null /dev/fd/4 /dev/fd/3'; open I, "admesh $admesh_pipe |"; open O, "| admesh --normal-values $admesh_pipe"; our @saved_argv = @ARGV; while () { if (s/^\s+vertex\s+//) { my $lhs = $&; s/\s+$//; my @xyz = split /\s+/, $_; while (@ARGV) { my $op = shift_arg; @xyz = &{ $::{"pointmap_$op"} }( @xyz ); } @xyz = map { sprintf "%.18g", $_ } @xyz; $_ = "$lhs@xyz\n"; } print O; } , if 0; # suppresses Name "main::I" used only once close I; close O;