layout polarity diagram colourful segment encoding:
- have to fix it so that points' fixed bits are always drawn
implement segmap so that we can do midx
decide what to do about crossings (difficult to show both tracks)
+ wire layout diagram thing into Tcl and see speed etc.
+ make moveable feature selection in subseg2display bitwise rather than
+ setwise
1. Write lots and lots and lots of PIC programs
OPTIMISE= -O2
+WERROR= -Werror
CFLAGS= -Wall -Wwrite-strings -Wpointer-arith \
-Wnested-externs -Wmissing-prototypes -Wstrict-prototypes \
+ $(WERROR) \
-g $(OPTIMISE)
*.d4
ours-*.ps
-ours-g[0-9]*.ppm
+*.dgram-*.p*.segenco.ps
+*.dgram-*.p*.segenco.ppm
*.new
*.segcmapreq
*.segcmap
-subseg2display
+*.m
+*.run-layout
t.*
+subseg2display
+compose-segenco
LAYOUTOPTS_PHYS= -S1.0 $(LAYOUTOPTS) '-e*A'
XLAYOUTOPTS_LAYER= -e'=5AN' -E'*~=5rsm' -e'p~=5r' -e'*~=9C' -e'*=*l'
-LAYOUTOPTS_SEGS= '-e*=*rm' '-e=5G'
+LAYOUTOPTS_SEGS= '-e*=*rm'
LAYERS_LS= 0 10 20
LAYERS_PS= $(addsuffix .ps, $(LAYERS_LS))
LPAGES= $(foreach x, 0 1 2 3 4 5 6, $(foreach y, 1 2 3 4 5, ours-p0-$xx$y.ps))
-CPROGS= subseg2display
+CPROGS= subseg2display compose-segenco
default: $(CPROGS)
all: default lpages layers
layers: $(LAYERS)
lpages: $(LPAGES)
+include ours.dgram.m
+include segencolayers.m
+
o=>$@.new && mv -f $@.new $@
+LINK= $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS)
+
subseg2display: subseg2display.o
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS) -lnetpbm -lpub -lm
+ $(LINK) -lnetpbm -lpub -lm
+
+compose-segenco: compose-segenco.o
+ $(LINK) -lnetpbm
%.d4: %.m4 $(M4INCS) Makefile
m4 -s <$< $o
%-ap.ps: %.d4 layout
./layout -S1.0 <$< $(LAYOUTOPTS) '-e*A' '-ep=rm' $o
-ours-g%.ps: ours.d4 ours-g%.segcmap layout
- ./layout <$< -l$* $(LAYOUTOPTS_SEGS) -GLours-g$*.segcmap $o
+%.segcmapreq: %.run-layout
+ ./$< $(LAYOUTOPTS_SEGS) -GR $o
-ours-g%.segcmap: ours-g%.segcmapreq segcmapassign
+%.segcmap: %.segcmapreq segcmapassign
./segcmapassign <$< $o
-ours-g%.segcmapreq: ours.d4 layout
- ./layout <$< -l$* $(LAYOUTOPTS_SEGS) -GR $o
+%.dgram.m: %.dgram-list make-dgram-make
+ ./make-dgram-make <$< $* $o
+
+%.m: %.gen-make
+ ./$< $o
-ours-g%.ppm: ours-g%.ps
+%.segenco.ppm: %.segenco.ps Makefile
gs -dNOPAUSE -dBATCH -dSAFER -q \
-sDEVICE=ppmraw -r72 -g595x842 \
-sOutputFile=$@.new $< && mv -f $@.new $@
./layout <$< $(LAYOUTOPTS_ALL) $o
# test case
-t.ppm: ours-g0.ppm x.gdb subseg2display
+t.ppm: ours.dgram-bot.pa.segenco.ppm x.gdb subseg2display
gdb -x x.gdb
clean:
- -rm -f -- *.d4 *~ *.new t.ppm
+ -rm -f -- *.d4 *~ t.* *.m *.new core
-rm -f ours-*.ps parts.ps
- -rm -f *.oprint-*.ps
+ -rm -f *.oprint-*.ps *.run-layout
+ -rm -f *.segcmap *.segcmapreq
+ -rm -f *.dgram-*.p*.segenco.ps *.dgram-*.p*.segenco.ppm
-rm -f $(CPROGS) *.o
.PRECIOUS: $(OPRINTS)
-.PRECIOUS: ours-g0.ps ours-g%.segcmap ours-g%.segcmapreq
+.PRECIOUS: %.segcmap %.segcmapreq %.segenco.ppm %.d4
--- /dev/null
+/*
+ * usage:
+ * compose-segenco \
+ * thing.pf.segenco.ppm \
+ * thing.p0.segenco.ppm \
+ * thing.p1.segenco.ppm \
+ * thing.p2.segenco.ppm \
+ * ...
+ * thing.p5.segenco.ppm
+ *
+ * writes resulting composite encoding
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <ppm.h>
+
+#define FILES 7
+
+struct file {
+ const char *fn;
+ FILE *f;
+};
+
+typedef unsigned char val;
+
+static struct file f[FILES];
+static int nf, fi, rows=-1, cols;
+static int row, col;
+
+static void badformat(const char *m) {
+ fprintf(stderr,"bad format: %s: row=%d,col=%d:\n %s\n",
+ f[fi].fn, row,col, m);
+ exit(12);
+}
+
+int main(int argc, char **argv) {
+ const char *arg;
+ int trows, tcols, informat;
+ pixval maxval;
+
+ ppm_init(&argc,argv);
+ if (!*argv || !*++argv || (*argv)[0]=='-') {
+ fprintf(stderr,"bad usage\n"); exit(12);
+ }
+
+ for (fi=0, nf=0;
+ (arg= *argv++);
+ fi++, nf++) {
+ if (nf >= FILES) { fprintf(stderr,"too many files\n"); exit(12); }
+
+ f[fi].fn= arg;
+ f[fi].f= fopen(arg, "rb");
+ if (!f[fi].f) { perror(arg); exit(8); }
+
+ ppm_readppminit(f[fi].f, &tcols, &trows, &maxval, &informat);
+ if (maxval != 255) badformat("wrong maxval");
+ if (informat != RPPM_FORMAT) badformat("wrong format");
+
+ if (rows==-1) {
+ rows= trows;
+ cols= tcols;
+ } else {
+ if (rows != trows || cols != tcols) badformat("wrong size");
+ }
+ }
+
+ ppm_writeppminit(stdout, cols, rows, 255, 0);
+
+ for (row=0; row<rows; row++)
+ for (col=0; col<cols; col++) {
+ int gotsegnum=-1, gotmovfeatpos=-1;
+ val ov[3];
+
+ ov[0]= ov[1]= ov[2]= 255;
+
+ for (fi=0; fi<nf; fi++) {
+ val iv[3];
+ int segnum, movfeatpos;
+
+ if (fread(iv,1,3,f[fi].f)!=3) {
+ if (ferror(f[fi].f)) { perror(f[fi].fn); exit(16); }
+ else badformat("truncated file");
+ }
+
+ if (iv[0]==255 && iv[1]==255 && iv[2]==255)
+ continue;
+
+ segnum= ((iv[2] & 0x03) << 8) | iv[3];
+ movfeatpos= iv[1] & 0x0fc;
+
+ if (!!fi != !!movfeatpos)
+ badformat("moveable featureness disagrees with file index");
+
+ if (gotsegnum==-1) {
+ memcpy(ov,iv,sizeof(ov));
+ gotsegnum= segnum;
+ gotmovfeatpos= movfeatpos;
+ } else if (segnum!=gotsegnum || movfeatpos!=gotmovfeatpos) {
+ continue;
+ }
+ if (fi) {
+ ov[1] |= 0x100 >> fi; /* bits are reversed; first fi pos 1 not 0 */
+ }
+ }
+
+ if (fwrite(ov,1,3,stdout)!=3) { perror("writing"); exit(16); }
+
+ }
+
+ return 0;
+}
our $debug=0;
our $output_layer= '*';
our $subsegcmapreq=0;
+our $subsegmovfeatpos='f';
our $ps_page_shift= 615;
our $ps_page_xmul= 765.354;
elsif (s/^S([0-9.]+)$//) { $scale= $1 * 1.0; }
elsif (s/^P(\d+)x(\d+)$//) { $page_x= $1; $page_y= $2; }
elsif (s/^GR//) { $subsegcmapreq=1; }
+ elsif (s/^GP(\d+|f)$//) { $subsegmovfeatpos=$1; }
elsif (s/^GL(.*)$//) {
my ($sscmfn) = $1;
my ($sscmf);
$!=0; $_= <$sscmf>; die $! unless defined $_;
last if m/^E/;
next unless m/^C/;
- m,^C\s+(\w*/(?:[A-Za-z_]+\d+)?)\s+(\S.*\S)\s*$,
+ m,^C\s+(\w*/(?:[A-Za-z_]+)?)\s+(\S.*\S)\s*$,
or die "$sscmfn:$.: syntax error in subseg cmap\n";
$subsegcmap{$1}= $2;
}
print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
$draw= current_draw();
if ($draw =~ m/G/) {
- my ($pt,$going,$red,$csegbare);
+ my ($pt,$going,$red,$csegbare,$movfeat,$movstroke);
$going=0;
o("% segments @segments\n");
o(" $psu_subseglw setlinewidth\n");
$param=$p0;
$pt= &$calcfn;
for (;;) {
+ $movstroke= " stroke\n";
$csegbare= $segments[0];
$csegbare =~ s/^\-//;
if ($subsegcmapreq) {
print "$csegbare\n" or die $!;
$subsegcmap{$csegbare}++;
}
- } elsif (exists $subsegcmap{$csegbare}) {
+ } else {
+ $movfeat= $csegbare =~ s,(/\D+)(\d+)$,$1, ? $2 : 'f';
+ if ($subsegmovfeatpos ne $movfeat) {
+ $movstroke= "% no-stroke\n";
+ }
+ die "unknown subsegment colour for $csegbare\n"
+ unless exists $subsegcmap{$csegbare};
$red= $pt->{A} / (2*$pi);
$red *= 64;
$red += 128;
$red /= 255.0;
$red= sprintf("%f", $red);
o(" $red $subsegcmap{$csegbare} setrgbcolor\n");
- } else {
- die "unknown subsegment colour for $csegbare\n";
}
o_path_begin();
parametric__o_pt($pt);
segment_used_len($psu_ulen);
$pt= &$calcfn;
parametric__o_pt($pt);
- o_path_strokeonly();
+ o($movstroke);
}
segment_used_len(($p1-($param-$ppu)) * $lenperp);
$param=$p1;
parametric__o_pt(&$calcfn);
- o_path_strokeonly();
+ o($movstroke);
}
if ($draw =~ m/C/) {
my ($pt);
--- /dev/null
+#!/bin/sh
+set -e
+stem=$1
+echo '# autogenerated'
+while read dgram args; do
+ cat <<END
+$stem.dgram-$dgram.run-layout: $stem.d4 layout $stem.dgram.m
+ printf '#!/bin/sh -ex\n./layout "\$\$@" %s \$<\n' "$args" >\$@.new
+ chmod +x \$@.new && mv -f \$@.new \$@
+
+END
+done
--- /dev/null
+bot -l0 -e=5G
# lines:
#
# C <csss> <green> <blue>
-# where <csss> is N/[MP] (see informat.txt) and <green> and <blue>
+# where <csss> is N/[M] (see informat.txt) and <green> and <blue>
# contain no whitespace and are suitable for inserting like this
# into the PostScript output:
# ...code to compute and stack red in range [0,1>...
# <green> <blue> setrgbcolor
#
# S <segname> 0x<segnum>
-# F <segname> 0x<segnum> <featname> 0x<prefix> <configbits> <maxconfig>
+# F <segname> 0x<segnum> <featname> 0x<prefix> <configbits>
# where (1<<configbits)-1 are the bits for the config
# and ~((1<<configbits)-1) are the bits for the prefix
-# and maxconfig is the maximum configuration number used by the layout
#
# # comments for debugging segcmapassign etc.
# E
# final line, always present
#
-# Encoding is as follows (bits from MSbit to LSbit):
+# Encoding in final segment encoding map is as follows
+# (bits from MSbit to LSbit):
#
# RED
# 6 bits angle
# 2 bits segment overflow
# 6 bits moveable feature and position
# each moveable feature has an unambiguous prefix
-# the remainder of the bits are the position of that feature
+# the remainder of the bits are the positions of that feature
+# (LSbit is position 0, etc.)
# the feature all-bits-0 (0b000000) is for fixed track
# (so every moveable feature prefix must contain at least one 1)
# BUT all of the bits are in the reverse order (so the
-# MSbit of GREEN is the LSbit of the moveable feature position)
+# MSbit of GREEN is the LSbit of the moveable feature and position)
#
# BLUE
# 8 bits segment main IN REVERSE ORDER
#
-# The unknown/unidentified segment is 00 0000 0000, with feature 000000.
+# The unknown/unidentified segment is 00 0000 0000, with feature 00 0000
+# for fixed parts and feature 1x xxxx for moveable parts.
# Background is white (all bits set).
use strict;
our ($seg,$movfeat,$movconf,$si,$fi);
our (%seg);
+sub cssnmap ($$$$) {
+ my ($seg,$movfeat,$segnum,$posinfo) = @_;
+ my ($green,$blue,$greenr,$bluer);
+ $green= (($segnum >> 8) & 0x03)<<6;
+ $green |= $posinfo;
+ $blue= $segnum & 0xff;
+ $greenr= reverse_bits_in_byte($green);
+ $bluer= reverse_bits_in_byte($blue);
+ printf("C %s/%s %.6f %.6f\n".
+ "# %s/%s 0x%x 0x%x 0x%x 0x%x\n",
+ $seg,$movfeat, $greenr/255.0, $bluer/255.0,
+ $seg,$movfeat, $green, $blue, $greenr, $bluer)
+ or die $!;
+}
+
+our $movfeatposbits= 6;
+
while (<>) {
m,^(\w*)/([A-Za-z_]*)(\d*)$, or die;
($seg,$movfeat,$movconf)=($1,$2,$3);
if (!length $seg) {
- printf("C /%s%s 0 0\n",
- $movfeat, $movconf)
- or die $!;
+ die "too many $seg $movfeat" if
+ length $movfeat && $movconf >= $movfeatposbits-1;
+ cssnmap($seg,$movfeat,0,
+ length $movfeat ? 1<<($movfeatposbits-1) : 0);
next;
}
die if length $movconf && !length $movfeat;
return $d;
}
-sub cssnmap ($$$$) {
- my ($seg,$movfeatconf,$segnum,$posinfo) = @_;
- my ($green,$blue,$greenr,$bluer);
- $green= (($segnum >> 8) & 0x03)<<6;
- $green |= $posinfo;
- $blue= $segnum & 0xff;
- $greenr= reverse_bits_in_byte($green);
- $bluer= reverse_bits_in_byte($blue);
- printf("C %s/%s %.10f %.10f\n".
- "# %s/%s 0x%x 0x%x 0x%x 0x%x\n",
- $seg,$movfeatconf,
- $greenr/255, $bluer/255,
- $seg,$movfeatconf,
- $green, $blue, $greenr, $bluer)
- or die $!;
-}
-
our ($segnum) = 1;
our ($conf,$posbit,$posbiti,$abovenext);
$si= $seg{$seg};
$si->{Num}= $segnum++;
die if $si->{Num} >= 1024;
- $abovenext= 0x40;
+ $abovenext= 1<<$movfeatposbits;
printf("S %s 0x%x\n",
$seg, $si->{Num})
or die $!;
$si->{Feat}{$b}{Max} <=> $si->{Feat}{$a}{Max};
} keys %{ $si->{Feat} }) {
$fi= $si->{Feat}{$movfeat};
- for ($posbit=1,$posbiti=0;
- $posbit<=$fi->{Max};
- $posbit<<=1,$posbiti++) { }
+ $posbiti= $fi->{Max}+1;
+ $posbit= 1<<$posbiti;
$abovenext -= $posbit;
die "too many $seg" if $abovenext <= 0;
$fi->{Prefix}= $abovenext;
$fi->{ConfigMask}= $posbit-1;
$fi->{ConfigBits}= $posbiti;
- printf("F %s 0x%x %s 0x%x %d 0x%x\n",
+ printf("F %s 0x%x %s 0x%x %d\n",
$seg, $si->{Num},
- $movfeat, $fi->{Prefix}, $fi->{ConfigBits}, $fi->{Max});
- foreach ($conf=0; $conf<=$fi->{Max}; $conf++) {
- cssnmap($seg, $movfeat.$conf, $si->{Num}, $fi->{Prefix}+$conf);
- }
+ $movfeat, $fi->{Prefix}, $fi->{ConfigBits});
+ cssnmap($seg, $movfeat, $si->{Num}, $fi->{Prefix});
}
}
--- /dev/null
+#!/bin/sh
+set -e
+echo '# autogenerated'
+x="%.pf.segenco.ppm"
+for p in f 0 1 2 3 4 5; do
+ cat <<END
+%.p$p.segenco.ps: %.run-layout %.segcmap
+ ./\$< \$(LAYOUTOPTS_SEGS) -GL\$*.segcmap -GP$p \$o
+
+.PRECIOUS: %.p$p.segenco.ps %.p$p.segenco.ppm
+
+END
+ x="$x %.p$p.segenco.ppm"
+done
+cat <<END
+
+%.pa.segenco.ppm: compose-segenco $x
+ ./\$^ \$o
+
+END
file subseg2display
-set args ours-g0.ppm >t.ppm \
+set args ours.dgram-bot.pa.segenco.ppm >t.ppm \
b 0 200 200 200 \
0. 0 200 200 200 \
.. 0 000 000 000 \
r -660 0 0 0 \
F 500 1000 1000 1000 \
R -500 1000 1000 1000 \
- u0 \
+ u0 u0.0x20 u0.0x21 u0.0x22 u0.0x23 \
+ u0.0x24 u0.0x25 u0.0x26 u0.0x27 \
+ u0.0x28 u0.0x29 u0.0x2a u0.0x2b \
+ u0.0x2c u0.0x2d u0.0x2e u0.0x2f \
f0x1 f0x1.0x3e f0x1.0x3f \
F0x2 F0x2.0x3e F0x2.0x3f \
f0x3 f0x3.0x3e f0x3.0x3f \