X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=commitid.scad.pl;h=f19082c50ede34da7dc49f5cd2c648388d60343e;hb=ebfe6ab1e6d15fa695d8eade7ae74dbee3c2ff99;hp=62ae5105e07259a2a0a2ec25ad2f69f8aec8b0a0;hpb=e483e7b4218e5d2501dadd948c101299ed91248e;p=reprap-play.git diff --git a/commitid.scad.pl b/commitid.scad.pl deleted file mode 100755 index 62ae510..0000000 --- a/commitid.scad.pl +++ /dev/null @@ -1,917 +0,0 @@ -#!/usr/bin/perl -w - -# commitid.scad.pl - a program for annotating solid models with commit info -# Copyright (C)2016 Ian Jackson. See below. There is NO WARRANTY. - - -# USAGE -# ===== -# -# .../commitid.scad.pl [OPTION...] [STRING...] >commitid.scad.new \ -# && mv -f commitid.scad.new commitid.scad -# -# Run without arguments, commitid.scad.pl will output an openscad file -# which contains 2D and 3D models of the current git commit count and -# commit object id (commit hash), useful for identifying printed -# parts. -# -# See below for details. You probably want these two sections, as a -# quick starting point: -# General form of provided openscad modules -# Autoscaling modules -# -# We can also generate models of short mainly-numeric strings -# specified on the command line. -# -# -# Options: -# -# --git Generate git commit indications, as shown below -# (this is the default if no strings are requested with -t). -# Ie, produce the `Autoscaling modules' and `Specific layouts'. -# -# --git=objid -# Generate git commit indication based on commit object only -# (ie avoid counting commits). Ie, do not generate `Small' -# and `Full' layouts (and never select them for `Best'). -# -# -i Do not generate `+' dirty indication if git-untracked files -# are present (ie, missing .gitignore entries). The `*' -# dirty tree indication (for modified files) cannot be disabled. -# -# [-t[LAYOUT]] TEXT -# Generate a layout LAYOUT containing TEXT. TEXT can -# contain newlines (a final newline usually undesirable, as -# it will generate a blank line). If LAYOUT is not specified, -# generates Arg0, Arg1, Arg2, etc., for successive such -# TEXTs. The permissible character set in is TEXT is: -# space 0-9 a-f + * -# -# -# OPENSCAD INTERFACE -# ================== -# -# Dynamic variables for configuration -# ----------------------------------- -# -# We honour the following variables to control various scaling factors: -# -# default value notes -# $Commitid_pixelsz 0.8 \ multiplied together -# $Commitid_scale 1.0 / -# $Commitid_depth pixelsz/2 \ multiplied together -# $Commitid_depth_scale 1.0 / -# $Commitid_max_best_scale 2.0 limits XY scaling in *Best* -# -# FYI the font is nominally 3x5 pixels, with 1-pixel inter-line and -# inter-character gaps. (It's not strictly speaking a 3x5 bitmap -# font, size it contains partial pixels and diagonals.) -# -# -# Non-`module'-specific functions -# ------------------------------- -# -# We provide the following functions (which depend on the config -# variables, but not on anything else) and compute useful values: -# -# function Commitid_pixelsz() Actual size of each nominal pixel -# function Commitid_depth() Depth to use (the amount characters -# should be raised or sunken) -# -# General form of provided openscad modules -# ----------------------------------------- -# -# module Commitid_MODULE_2D(...) Collection of polygons forming characters -# module Commitid_MODULE(...) The above, extruded up and down in Z -# module Commitid_MODULE_M_2D(...) Mirror writing -# module Commitid_MODULE_M(...) 3D mirror writing -# function Commitid_MODULE_sz() A 2-vector giving the X,Y size -# -# Except for *Best* modules, the XY origin is in the bottom left -# corner without any margin. Likewise Commitid_MODULE_sz does not -# include any margin. -# -# For 3D versions, the model is 2*depth deep and the XY plane bisects -# the model. This means it's convenient to either add or subtract from -# a workpiece whose face is in the XY plane. -# -# The _M versions are provided to avoid doing inconvenient translation -# and rotation to get the flipped version in the right place. -# -# -# Autoscaling modules -# ------------------- -# -# These modules take a specification of the available XY space, and -# select and generate a suitable specific identification layout: -# -# module Commitid_BestCount_2D (max_sz, margin=Commitid_pixelsz()) -# module Commitid_BestCount (max_sz, margin=Commitid_pixelsz()) -# module Commitid_BestCount_M_2D(max_sz, margin=Commitid_pixelsz()) -# module Commitid_BestCount_M (max_sz, margin=Commitid_pixelsz()) -# module Commitid_BestObjid_2D (max_sz, margin=Commitid_pixelsz()) -# module Commitid_BestObjid (max_sz, margin=Commitid_pixelsz()) -# module Commitid_BestObjid_M_2D(max_sz, margin=Commitid_pixelsz()) -# module Commitid_BestObjid_M (max_sz, margin=Commitid_pixelsz()) -# -# max_sz should be [x,y]. -# -# BestCount includes (as much as it can of) the git commit count, -# ie the result of -# git rev-list --first-parent --count HEAD -# (and it may include some of the git revision ID too). -# -# BestObjid includes as much as it can of the git commit object hash, -# and never includes any of the count. -# -# All of these will autoscale and autorotate the selected model, and -# will include an internal margin of the specified size (by default, -# one pixel around each edge). If no margin is needed, pass margin=0. -# -# There are no `function Commitid_Best*_sz'. If they existed they -# would simply return max_sz. -# -# -# Output format -# ------------- -# -# In general the output, although it may be over multiple lines, -# is always in this order -# git commit object id (hash) -# dirty indicator -# git commit count -# -# Not all layouts have all these parts. The commit object id may -# sometimes be split over multiple lines, but the count will not be. -# If both commit id and commit count appear they will be separated -# by (at least) a newline, or a dirty indicator, or a space. -# -# The commit id is truncated to fit, from the right. -# -# The commit count is truncated from the _left_, leaving the least -# significant decimal digits. -# -# The dirty indicator can be -# -# * meaning the working tree contains differences from HEAD -# -# + meaning the working tree contains untracked files -# (ie files you have failed to `git add' and also failed -# to add to gitignore). (But see the -i option.) -# -# -# Specific layouts -# ---------------- -# -# If you want to control the exact layout (and make space for it in -# your design), you can use these: -# -# module Commitid_LAYOUT_2D() -# module Commitid_LAYOUT() -# module Commitid_LAYOUT_M_2D() -# module Commitid_LAYOUT_M() -# function Commitid_LAYOUT_sz() -# -# Here LAYOUT is one of the following (giving for example, `module -# Commitid_Full8_2D'). In the examples, we will assume that the tree -# is dirty, the commit count is 123456, and the commit object id -# starts abcdeffedbcaabcdef... In the examples `_' shows where a -# space would be printed. -# -# Small2 Small3 ... Small9 Small10 Small12 Small14 Small16 -# A single line containing as much of the count will fit, eg: -# Small5 3456* -# Small8 _*123456 -# The objectid is included if more than one character of of it -# will fit without makign the output ambiguous: -# Small9 ab*123456 -# -# Small2S Small4S ... Small16S -# Small3T Small9T Small12T -# Same as Small but split into two lines (S) -# or three lines (T). Eg: -# Small4S *4 Small6T _* -# 56 34 -# 56 -# Git2 Git3 ... Git9 Git10 Git12 Git14 Git16 -# Git4S Git6S ... Git16S -# Git6T Git9T Git12T -# Just the commit object hash, in one, two (S) or three (T) -# lines. E.g.: -# Git5 abcd* -# -# Full4 Full6 ... Full20: -# The commit object hash plus the commit count, on -# separate lines, eg: -# Full12 abcdef Full16 abcdeffe -# *23456 _*123456 -# -# Full6T Full9T ... Full30T -# As Full but the commit object id is split over two lines -# producing a 3-line layout, eg: -# Full9T abc Full21T abcdeff -# de* edbcaa* -# 456 _123456 -# -# Other LAYOUTs -# ------------- -# -# FontDemo -# -# A demonstration of the built-in 18-character font -# -# Arg0 Arg1, ... -# -# Strings passed on command line (without -t, or bare -t, -# rather than with -tLAYOUT). -# -# LAYOUT -# -# Generated by passing -tLAYOUT on the command line. -# - - -# COPYRIGHT, LICENCE AND LACK-OF-WARRANTY INFORMATION -# =================================================== -# -# This program is Free Software and a Free Cultural Work. -# -# 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 3 of the License, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Alternatively, at your option: -# -# This work is licensed under the Creative Commons -# Attribution-ShareAlike 4.0 International License. -# -# There is NO WARRANTY. - - -use strict; - -$SIG{__WARN__} = sub { die @_; }; - -our $debug=0; - -if (@ARGV && $ARGV[0] =~ m/^-(D+)$/) { - $debug = length $1; - shift @ARGV; -} - -sub p { print @_ or die $!; } - -sub p_debug { print STDERR @_ if $debug; } - -p <<'END'; -// *** AUTOGENERATED - DO NOT EDIT *** // -function Commitid_pixelsz() = - ($Commitid_pixelsz ? $Commitid_pixelsz : 0.8) * - ($Commitid_scale ? $Commitid_scale : 1.0); -function Commitid_depth() = - ($Commitid_depth ? $Commitid_depth : Commitid_pixelsz()/2) * - ($Commitid_depth_scale ? $Commitid_depth_scale : 1.0); -function Commitid__scale() = - Commitid_pixelsz() / 0.2; -END - -sub chrmodname ($) { - my ($chr) = @_; - my $chrx = sprintf '%#x', ord $chr; - return "Commitid__chr_$chrx"; -} - -our $gtm_demo_i = -1; -our $gtm_demo_j; -our @gtm_demo_o; - -sub gentextmodule_demo_start_batch () { - $gtm_demo_j = 0; - $gtm_demo_i++; -} - -sub argl_formal (@) { join ', ', @_; } -sub argl_actual (@) { join ',', map { m/=/ ? $` : $_ } @_; } - -sub gen3dmodule ($@) { - my ($modb,$size,@argl) = (@_); - $size ||= "${modb}_sz()"; - p "module ${modb}_M_2D(".argl_formal(@argl)."){\n"; - p " translate([${size}[0],0])\n"; - p " mirror([1,0,0])\n"; - p " ${modb}_2D(".argl_actual(@argl).");\n"; - p "};\n"; - foreach my $mir ('','_M') { - my $mm = "${modb}${mir}"; - p "module ${mm}(".argl_formal(@argl)."){\n"; - p " d=Commitid_depth();\n"; - p " translate([0,0,-d]) linear_extrude(height=d*2)\n"; - p " ${mm}_2D(".argl_actual(@argl).");\n"; - p "}\n"; - } -} - -sub gentextmodule ($@) { - my ($form, @lines) = @_; - my $modb = "Commitid_$form"; - p "module ${modb}_2D(){\n"; - p " // |$_|\n" foreach @lines; - p " scale(Commitid__scale()){\n"; - my $y = @lines; - my $cols = 1; - foreach my $line (@lines) { - $y--; - my $x = 0; - foreach my $chr (split //, $line) { - p sprintf " translate([%d * 0.8, %d * 1.2]) %s();\n", - $x, $y, chrmodname $chr - if $chr =~ m/\S/; - $x++; - } - $cols = $x if $x > $cols; - } - p " }\n"; - p "}\n"; - gen3dmodule($modb,''); - - p sprintf "function %s_sz() = Commitid__scale() * 0.1 * [ %d, %d ];\n", - $modb, 2 * ($cols * 4 - 1), 2 * (@lines * 6 - 1); - - push @gtm_demo_o, <commitid-DEBUG-simplify-$chr.ps"; - print S "%!\n"; - print S "(Courier-Bold) findfont 15 scalefont setfont\n"; - - $prcount=0; -} - -sub debug_simplify_done () { - return unless $debug; - print S "showpage\n"; - close S or die $!; -} - -sub debug_simplify_pr ($$$) { - my ($chr,$polys,$why) = @_; - - return unless $debug; - - print STDERR "PR $chr $why\n"; - my $ct_x = 10000 * ($prcount % 6); - my $ct_y = 18000 * int($prcount / 6); - printf S "0 setgray\n"; - printf S "%d %d moveto\n", map {$_/100 + 10} $ct_x,$ct_y; - printf S "(%s) show\n", $why; - my $pr_recur; - - $pr_recur = sub { - my ($tpolys, @levels) = @_; - return unless @$tpolys; - foreach my $i (0..$#$tpolys) { - printf STDERR "P@levels %02d :", $i; - my $pinfo = $tpolys->[$i]; - my $p = $pinfo->{E}; - printf STDERR "@$p\n"; - my $lw = 5 - 4*($i / ($#$tpolys || 1)); - my $pp = sub { - my $spec = $p->[$_[0]]; - $spec =~ m/^\d{5}/; - sprintf "%d %d",map { $_/100 } - 1000 + $ct_x + $&, - 5000 + $ct_y + $'; - }; - printf S "%s setrgbcolor\n", (@levels==0 ? '0 0 0' : - @levels==1 ? '0 0 1' - : '1 1 0'); - foreach my $eai (0..$#$p) { - my $ebi = ($eai + 1) % @$p; - printf S <($eai), $pp->($ebi); - %f setlinewidth - %s moveto - %s lineto - stroke -END - } - $pr_recur->($pinfo->{Holes}, @levels, $i); - } - }; - $pr_recur->($polys,0); - - $prcount++; -} - -sub simplify ($$) { - my ($chr,$polys) = @_; - use Data::Dumper; - - return unless @$polys; - - my $count=0; - my $pr = sub { }; - - if ($debug) { - debug_simplify_begin($chr); - } - - $pr->("start"); - - AGAIN: while(1) { - my %edges; - my $found_hole; - - foreach my $pi (0..$#$polys) { - my $p = $polys->[$pi]{E}; - foreach my $ei (0..$#$p) { - my $e = $p->[$ei].$p->[($ei+1) % @$p]; - die if $edges{$e}; - $edges{$e} = [ $p, $pi, $ei ]; - } - } - p_debug "AGAIN $count\n"; - my $merge = sub { - my ($pa, $pai, $eai, $pb, $pbi, $ebi) = @_; - p_debug "# merging $pai:$eai.. $pbi:$ebi..\n"; - splice @$pa, $eai, 1, - ((@$pb)[$ebi+1..$#$pb], (@$pb)[0..$ebi-1]); - @$pb = ( ); - }; - foreach my $pai (0..$#$polys) { - my $painfo = $polys->[$pai]; - my $pa = $painfo->{E}; - foreach my $eai (0..$#$pa) { - my $ear = $pa->[ ($eai+1) % @$pa ].$pa->[$eai]; - my $ebi = $edges{$ear}; - next unless $ebi; - my ($pb,$pbi); - ($pb, $pbi, $ebi) = @$ebi; - # $pai:($eai+1)..$eai and $pbi:$ebi..($ebi+1) are identical - # so we want to remove them. - if ($pai==$pbi) { - # we're making a hole! we make an assumption: - # holes have fewer line segments than the - # outlines. This is almost always true because of - # the way we construct our figures. - if (($ebi - $eai + @$pa) % @$pa > @$pa/2) { - # We arrange that $eai..$ebi is the hole - ($ebi,$eai) = ($eai,$ebi); - } - p_debug "HOLE $eai $ebi\n"; - # we want to make the smallest hole, to avoid - # making a hole that itself needs simplifying - my $holesz = ($ebi - $eai + @$pa) % @$pa; - $found_hole = [ $pa,$pai,$eai, $ebi, $holesz ] - unless $found_hole && $found_hole->[4] < $holesz; - } else { - $merge->($pa,$pai,$eai,$pb,$pbi,$ebi); - debug_simplify_pr($chr,$polys,"after $count"); - next AGAIN; - } - } - # we process hole joining last, so that the whole of the - # edge of the hole must be part of the same polygon - if ($found_hole) { - p_debug "HOLE DOING @$found_hole\n"; - my ($pa,$pai,$eai,$ebi) = @$found_hole; - # simplify the indexing - @$pa = ((@$pa)[$eai..$#$pa], (@$pa)[0..$eai-1]); - $ebi -= $eai; $ebi += @$pa; $ebi %= @$pa; - $eai = 0; - push @{ $painfo->{Holes} }, { - E => [ (@$pa)[$eai+1..$ebi-1] ], - Holes => [ ], - }; - splice @$pa, $eai, $ebi-$eai+1; - debug_simplify_pr($chr,$polys,"hole $count"); - next AGAIN; - } - } - last; - } - - debug_simplify_done(); -} - -sub p_edgelist ($$$) { - my ($points,$vecs,$p) = @_; - my @vec; - foreach my $pt (@$p) { - $pt =~ s{\d{5}}{$&,}; - $pt =~ s{\b\d}{$&.}g; - push @$points, "[$pt]"; - push @vec, $#$points; - } - push @$vecs, \@vec; -} - -sub parsefont () { - my %cellmap; - for (;;) { - $_ = // die; - last if %cellmap && !m/\S/; - next unless m/\S/; - chomp; - s{^(.) }{}; - $cellmap{$1} = $_; - } - my %chrpolys; - # $chrs{$chr}[$poly] = $poly - # $poly->{E} = [ "012345012345", ... ] - # $poly->{Holes} = $poly2 - while () { - next unless m/\S/; - chomp; - my @chrs = split / /, $_; - !~ m/\S/ or die; - foreach my $row (reverse 0..4) { - $_ = ; - chomp; - s{^}{ }; - $_ .= ' ' x 8; - m{\S/\S} and die; - s{/(?=\s)}{L}g; - s{/(?=\S)}{r}g; - s{\\(?=\s)}{l}g; - s{\\(?=\S)}{R}g; - p "// $_\n"; - foreach my $chr (@chrs) { - s{^ }{} or die "$chr $_ ?"; - foreach my $col (0..2) { - my @verts; - if (s{^ }{}) { - } elsif (s{^\S}{}) { - my $f = $cellmap{$&}; - die unless $f; - $f =~ s/\b\d/ sprintf '%05d', $col*2000 + $&*1000 /ge; - $f =~ s/\d\b/ sprintf '%05d', $row*2000 + $&*1000 /ge; - push @{ $chrpolys{$chr} }, { E => [ split / /, $f ] }; - } else { - die "$_ ?"; - } - } - } - die "$_ ?" if m{\S}; - } - } - - my $demo = ''; - my $democols = 6; - foreach my $chr (sort keys %chrpolys) { - - my $polys = $chrpolys{$chr}; - $_->{Holes} = [] foreach @$polys; - - simplify($chr,$polys); - - my $mod = chrmodname $chr; - p "module $mod () {\n"; - foreach my $poly (@$polys) { - p " polygon("; - my $holes = $poly->{Holes}; - my (@points, @vecs); - p_edgelist(\@points, \@vecs, $poly->{E}); - foreach my $hole (@$holes) { - p_edgelist(\@points, \@vecs, $hole->{E}); - } - p "points=[".(join ",",@points)."],"; - if (@$holes) { - p ",paths=[".(join ",", - map { "[".(join ",",@$_)."]" } - @vecs)."],"; - } - p "convexity=4);\n"; - } - p "}\n"; - $demo .= $chr; - } - @demo = reverse $demo =~ m{.{1,$democols}}go; -} - -parsefont(); - -our $do_git; # contains may chars 'c' (count) and/or 'o' (object) -our $do_git_untracked = 1; -our $argcounter; - -our @forms; -our %included; # 0 = not at all; 1 = truncated; 2 = full - -sub rjustt ($$$;$) { - # right justify and truncate (ie, pad and truncate at left) - # always includes prefix - # sets $included{$what} - my ($sz, $what, $whole, $prefix) = @_; - $prefix //= ''; - my $lw = length $whole; - my $spare = $sz - $lw - (length $prefix); - $included{$what}= 1 + ($spare > 0); - return - ($spare > 0 ? (' ' x $spare) : ''). - $prefix. - substr($whole, ($spare < 0 ? -$spare : 0)); -} - -sub ljustt ($$$;$) { - my ($sz, $what, $whole, $suffix) = @_; - $suffix //= ''; - $sz -= length $suffix; - $included{$what} = 1 + ($sz >= length $whole); - return sprintf "%-${sz}.${sz}s%s", $whole, $suffix; -} - -sub genform_prep() { - $included{$_}=0 foreach qw(Objid Count); -} - -sub genform ($@) { - my ($form, @lines) = @_; - gentextmodule($form, @lines); - my $f = { - Form => $form, - Chars => (length join '', @lines), - Lines => (scalar @lines), - Ambiguous => ($form =~ m/Full/ && !grep { m/\W/ } @lines), - Included => { %included }, - }; - push @forms, $f; -} - -sub genform_q ($$$) { - my ($form, $s, $lines) = @_; - $gtm_demo_j++; - my $l = length $s; - return if $l % $lines; - my $e = $l/$lines; - return if $e < 2; - $gtm_demo_j--; - genform($form, $s =~ m/.{$e}/g); -} - -sub genform_plusq ($$) { - my ($form, $s) = @_; - genform($form, $s); - genform_q("${form}S", $s, 2); - genform_q("${form}T", $s, 3); -} - -our @gcmd; - -sub gitrun_start () { - open F, "-|", @gcmd or die "$gcmd[0]: start: $!"; -} - -sub gitrun_done (;$) { - my ($errok) = @_; - $?=0; $!=0; - return if close F; - return if $errok; - die $! if $!; - die "@gcmd failed ($?)\n"; -} - -sub gitoutput (@) { - (@gcmd) = (qw(git), @_); - gitrun_start; - $_ = ; - gitrun_done; - defined or die "@gcmd produced no output"; - chomp or die "@gcmd produced no final newline"; - $_; -} - -sub do_git () { - return unless $do_git; - - @gcmd = qw(git status --porcelain); - push @gcmd, qw(--untracked=no) unless $do_git_untracked; - - my $git_dirty = ''; - gitrun_start; - while () { - if (m/^\?\?/ && $do_git_untracked) { - $git_dirty = '+'; - next; - } - $git_dirty = '*'; - last; - } - gitrun_done($git_dirty eq '*'); - - my $git_count; - my $git_object; - - if ($do_git =~ m/c/) { - $git_count = gitoutput qw(rev-list --first-parent --count HEAD); - } - if ($do_git =~ m/o/) { - $git_object = gitoutput qw(rev-parse HEAD); - } - print STDERR join ' ', map { $_ // '?' } - "-- commitid", $git_object, $git_dirty, $git_count, "--\n"; - - foreach my $sz (2..10, qw(12 14 16)) { - gentextmodule_demo_start_batch(); - - if (defined($git_count)) { - genform_prep(); - my $smallstr = rjustt($sz, 'Count', $git_count, $git_dirty); - my $forgitobj = $sz - length($git_count) - 1; - if (defined($git_object) && $forgitobj >= 2) { - $smallstr = ljustt($forgitobj, 'Objid', $git_object). - ($git_dirty || ' '). - $git_count; - } - genform_plusq("Small$sz", $smallstr); - } - - genform_prep(); - genform_plusq("Git$sz", ljustt($sz, 'Objid', $git_object, $git_dirty)) - if defined $git_object; - - if (defined $git_count && defined $git_object && $sz<=10) { - genform_prep(); - genform("Full".($sz*2), - ljustt($sz, 'Objid', $git_object), - rjustt($sz, 'Count', $git_count, $git_dirty)); - - genform_prep(); - my $e = $sz; - genform("Full".($e*3)."T", - ljustt($e*2, 'Objid', $git_object, $git_dirty) - =~ m/.{$e}/g, - rjustt($e, 'Count', $git_count)); - } - } -} - -sub do_some_best ($$) { - my ($bestwhat, $formre) = @_; - my $modname = "Best$bestwhat"; - my $fullmodname = "Commitid_${modname}_2D"; - my @argl = qw(max_sz margin=Commitid_pixelsz()); - p "module $fullmodname(".argl_formal(@argl).") {\n"; - my $mbs = '$Commitid_max_best_scale'; - p " sc_max = $mbs ? $mbs : 2;\n"; - p " sz = max_sz - 2*[margin,margin];\n"; - my @do; - foreach my $f ( - sort { - $b->{Included}{$bestwhat} <=> $a->{Included}{$bestwhat} or - $b->{Chars} <=> $a->{Chars} or - $a->{Lines} <=> $b->{Chars} - } - grep { - $_->{Form} =~ m/$formre/ && - !$_->{Ambiguous} - } - @forms - ) { - my $form = $f->{Form}; - p " sz_$form = Commitid_${form}_sz();\n"; - foreach my $rot (qw(0 1)) { - my $id = "${form}_r${rot}"; - p " sc_$id = min(sc_max"; - foreach my $xy (qw(0 1)) { - p ",sz[$xy]/sz_$form","[",(($xy xor $rot)+0),"]"; - } - p ");\n"; - push @do, " if (sc_$id >= 1.0"; - push @do, " && sc_$id >= sc_${form}_r1" if !$rot; - push @do, ") {\n"; - push @do, " translate([margin,margin]) scale(sc_$id)\n"; - push @do, " rotate(90) translate([0,-sz_$form"."[1]])\n" if $rot; - push @do, " Commitid_${form}_2D();\n"; - push @do, " } else"; - } - } - push @do, < 00 20 22 02 11 -< 00 20 11 22 02 - -0 1 2 3 4 5 6 7 8 9 - -/#\ r /#\ ##\ # # ### /#/ ### /#\ /#\ -# # /# # # # # # # # # # # # -# # # /#/ ##< \## ##\ ##\ // >#< \## -# # # # # # # # # # # # # -\#/ /#\ ### ##/ # ##/ \#/ # \#/ ##/ - -a b c d e f - - # # /## - # /## # /#\ # -/## ##\ # /## #r# ### -# # # # # # # #/ # -\## ##/ \## \## \#/ # - -+ * - - # # - # \#/ -### ### - # /#\ - # # diff --git a/commitid.scad.pl b/commitid.scad.pl new file mode 120000 index 0000000..f19082c --- /dev/null +++ b/commitid.scad.pl @@ -0,0 +1 @@ +diziet-utils/commitid.scad.pl \ No newline at end of file