chiark / gitweb /
layout/Makefile and .cvsignore tidied up after move; segment encoding and assignment...
authorian <ian>
Thu, 21 Oct 2004 20:54:03 +0000 (20:54 +0000)
committerian <ian>
Thu, 21 Oct 2004 20:54:03 +0000 (20:54 +0000)
.cvsignore
layout/.cvsignore [new file with mode: 0644]
layout/Makefile [new file with mode: 0644]
layout/informat.txt
layout/layout
layout/segcmapassign [new file with mode: 0755]

index d134ecbe800dc52d6cfb1773d51d664b49c10467..f01613b7b88c7057ac34709eaaf4195fc512db53 100644 (file)
@@ -3,7 +3,6 @@ qs
 t
 u
 testjoin
-*.d4
 *.new
 *,*.gnuplot-data
 *,*.gnuplot-cmd
@@ -21,6 +20,5 @@ divider-table.txt
 *.oprints-l-tmp
 *.tmp
 *.oprint-*.ps
-ours-*.ps
 parts.ps
 *.zip.d
diff --git a/layout/.cvsignore b/layout/.cvsignore
new file mode 100644 (file)
index 0000000..6995301
--- /dev/null
@@ -0,0 +1,5 @@
+*.d4
+ours-*.ps
+*.new
+*.segcmapreq
+*.segcmap
diff --git a/layout/Makefile b/layout/Makefile
new file mode 100644 (file)
index 0000000..a31aea4
--- /dev/null
@@ -0,0 +1,68 @@
+
+M4INCS=                parts.i4
+
+E_TRACK=       ArsCLMNo
+LAYOUTOPTS_ALL=        -ep=*Cm
+LAYOUTOPTS=    -E=*$(E_TRACK) $(LAYOUTOPTS_ALL)
+LAYOUTOPTS_PHYS= -S1.0 $(LAYOUTOPTS) '-e*A'
+XLAYOUTOPTS_LAYER= -e'=5AN' -E'*~=5rsm' -e'p~=5r' -e'*~=9C' -e'*=*l'
+
+LAYOUTOPTS_SEGS= '-e*=*r' '-e=5G'
+
+LAYERS_LS=     0 10 20
+LAYERS_PS=     $(addsuffix .ps, $(LAYERS_LS))
+LAYERS_L=      $(addprefix ours-l, $(LAYERS_PS))
+LAYERS_E=      $(addprefix ours-e, $(LAYERS_PS))
+LAYERS=                $(LAYERS_L) $(LAYERS_E)
+
+LPAGES=         $(foreach x, 0 1 2 3 4 5 6, $(foreach y, 1 2 3 4 5, ours-p0-$xx$y.ps))
+
+default:       layers
+all:           default lpages
+
+layers:                $(LAYERS)
+lpages:                $(LPAGES)
+
+o=>$@.new && mv -f $@.new $@
+
+%.d4:          %.m4 $(M4INCS) Makefile
+               m4 -s <$< $o
+
+%-a.ps:                %.d4 layout
+               ./layout <$< $(LAYOUTOPTS) '-E*l' $o
+
+%-al.ps:       %.d4 layout
+               ./layout <$< $(LAYOUTOPTS) '-e*C' '-ep=rm' $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) -GRours-g$*.segcmap $o
+
+ours-g%.segcmap: ours-g%.segcmapreq segcmapassign
+               ./segcmapassign <$< $o
+
+ours-g%.segcmapreq: ours.d4 layout
+               ./layout <$< -l$* $(LAYOUTOPTS_SEGS) -GL $o
+
+ours-l%.ps:    ours.d4 layout
+               ./layout <$< -l$* $(LAYOUTOPTS) $(XLAYOUTOPTS_LAYER) $o
+
+ours-e%.ps:    ours.d4 layout
+               ./layout <$< -l$* -E'=*aRsclMno' \
+                       -e'p=*rm' -e'=5RN' -E'*~=5rsm' -e'p~=5r' -e'*=*l' $o
+
+ours-p%.ps:    ours.d4 layout
+               ./layout <$< -l$$(printf %s "$*" | sed -e 's/-/ -P/') \
+                       $(LAYOUTOPTS_PHYS) $(XLAYOUTOPTS_LAYER) $o
+
+parts.ps:      showlib.d4 layout
+               ./layout <$< $(LAYOUTOPTS_ALL) $o
+
+clean:
+               -rm -f -- *.d4 *~ *.new
+               -rm -f ours-*.ps parts.ps
+               -rm -f *.oprint-*.ps
+
+.PRECIOUS:     $(OPRINTS)
index ea1cf8b3c0910bb82d705ffd72a6df6277649823..f03004b30965a350e3535654ea9c0bc3a1d6e04b 100644 (file)
@@ -33,6 +33,83 @@ Commands
   Defines loc T: start at loc F, go forward L, translate right R,
   turn left A (defaults are all 0).
 
+ segment [K*] [S0 D0 ...] Sn
+  Specifies that arcs and lines in layer kind K are part of subsegment
+  Sn.
+
+  If additional Di and Si are provided then each Si apart from the
+  last is followed by a distance Di saying how much track it applies
+  to; the first D0 of track is part of subsegment S0, the next D1 of
+  track is part of the next subsegment S1, and so on, with the last
+  subsegment Sn (without a distance restriction) being used for track
+  beyond that.  Each segment command resets the distance counter, and
+  it is not an error for there to be unused subsegment specs in a
+  segment command.  For these distances, only track whose subsegment
+  encoding is actually drawn counts.
+
+  If a part or object is used, then the arcs and lines inside it are
+  processed for subsegments as if they appeared directly.
+
+  A subsegment is a specification of:
+    * The named electrically separate track segment of which
+      this track forms part.
+    * If this track is part of one possible configuration of a
+      junction or point, the moveable feature name and configuration
+      number.  Any one junction or point is one moveable feature and
+      must be associated with and form part of one track segment.
+      Moveable segments must be entirely contained within objects or
+      parts (ie, one moveable segment cannot span multiple parts).
+      Configuration numbers should start at 0 and be allocated densely.
+
+  Subsegment specs Si are
+    N[/[MP]]
+  where
+    N is the segment name (alphanumeric, may be empty)
+    M is the moveable feature name (alphabetic, nonempty)
+    P is the moveable feature position (numeric, nonempty, 0-indexed)
+  If N is empty and MP is omitted then / must be present.
+
+  If a segment command occurs in a part or object, N is appended to
+  the N in force at the start of the part or object.  (Note that it is
+  not usually a good idea to rely on how a complex object leaves the 
+  setting of the segment, as probably the calling code will end up
+  using the object's segment names.)
+
+  At the start of processing at the toplevel, the empty-named fixed
+  subsegment is in use.  The empty-named top-level subsegment
+  indicates that the subsegment is unspecified, unknown or absent.
+
+ segmap S D ...
+
+  Maps specified (sub)segments or moveable feature(s) S to
+  consequently defined (sub)segments or moveable features D.  This is
+  primarily intended so that parts' internal segment and feature names
+  can be remapped to correspond to the layout naming scheme.
+
+   S       O
+   ----    ----
+   N       N'     remaps an entire segment including all features
+   N/M     M'     remaps a particular moveable feature; N is the
+                    unmapped name (if applicable)
+
+  The effect is that (sub)segments or features used in segment
+  commands are translated when the segment command is read; the
+  specified names (S) are those which the segment command would
+  define.
+
+  Where segmap is used outside a part or object, the mappings apply to
+  the segment names which would result at the toplevel.  When segmap
+  is used inside a part or object, the mappings apply to the segment
+  names defined within the part (perhaps by its subparts).  Ie, the
+  mapping operates on the segment names visible at the level at which
+  segmap is used (and thus several segmaps at different levels may
+  operate on a signal segment name, in sequence).
+
+  Mappings in later segmap commands replace earlier mappings at the
+  same level.
+
+  The remapping may coalesce otherwise-distinct segments.
+
  layer K[L]
   K is layer kind (letters and `_', may be empty), L is a layer depth
   (digits, or `=' meaning current layer, or `*' meaning output layer;
@@ -132,20 +209,22 @@ Command-line options
           Turn on and off drawing of elements in groups.
           These are abbreviations for various -E... options.
             track                                                 -E....
-              A  full track                                         ARSc
-              R  rails only                                         aRsc
-              S  rails and sleepers only                            aRSc
-              C  centrelines only                                   arsC
-              c  swept area and ticks only                          Arsc
-              r  no lines drawn at all                              arcs
+              A  full track                                        ARScg
+              R  rails only                                        aRscg
+              S  rails and sleepers only                           aRScg
+              C  centrelines only                                  arsCg
+              c  swept area and ticks only                         Arscg
+              r  no lines drawn at all                             arcs
             labels at locs
-              L  label top-level locs (turns on bars for them too)  LM
+              L  label top-level locs (turns on bars for them too)  LMg
               l  do not label any locs                              l
             bars at locs (thick lines perp to track dir'n)
-              M  bars for top-level locs only                       Mno
-              N  bars for top-level locs and those in obj's         MNo
-              O  bars for everything, including those inside parts  MNO
+              M  bars for top-level locs only                       Mnog
+              N  bars for top-level locs and those in obj's         MNog
+              O  bars for everything, including those inside parts  MNOg
               m  no bars (turns off labelling too)                  mnol
+            subsegment encoding
+              G  draw only subsegment encoding                 Garcslmno
 
  -E<layersel>[ARSCLMNOarsclmno]...
           enable (capitals) or disable (lowercase) drawing of
@@ -158,6 +237,12 @@ Command-line options
               M  mark locs with a bar
               N  mark locs with a bar in objs
               O  mark locs with a bar in parts
+              G  draw subsegment encoding
+
+ -GL      output segment colour map request list
+          use with -eG or -EG to write out the list of subsegment
+          specs which will need colours, one per line (and not
+          necessarily only once each)
 
  -q       quiet: do not print info to stderr
           (default: prints bounding box, at the moment)
index 03a8d0c580ef88ab7af790519ae193635de61588..20f4ede294ed9c2d7d3397921c0602697f331e89 100755 (executable)
@@ -10,26 +10,30 @@ our $page_y= 0;
 our $quiet=0;
 our $debug=0;
 our $output_layer= '*';
+our $subsegcmapreq=0;
 
 our $ps_page_shift= 615;
 our $ps_page_xmul= 765.354;
 our $ps_page_ymul= 538.583;
 
 our @eopts;
-
-our $drawers= 'arsclmno';
-our %chdraw_emap= qw(A ARSc
-                    R aRsc
-                    S aRSc
-                    C arsC
-                    c Arsc
+our @segments= ('/');
+our %subsegcmap;
+
+our $drawers= 'arsclmnog';
+our %chdraw_emap= qw(A ARScg
+                    R aRscg
+                    S aRScg
+                    C arsCg
+                    c Arscg
                     r arcs
-                    L LM
+                    L LMg
                     l l
-                    M Mno
-                    N MNo
-                    O MNO
-                    m mnol);
+                    M Mnog
+                    N MNog
+                    O MNOg
+                    m mnol
+                    G Garsclmno);
 
 while (@ARGV && $ARGV[0] =~ m/^\-/) {
     last if $ARGV[0] eq '-';
@@ -43,7 +47,21 @@ while (@ARGV && $ARGV[0] =~ m/^\-/) {
        elsif (s/^l(\d+|\*)//) { $output_layer=$1; }
        elsif (s/^S([0-9.]+)$//) { $scale= $1 * 1.0; }
        elsif (s/^P(\d+)x(\d+)$//) { $page_x= $1; $page_y= $2; }
-       elsif (s/^(e)
+       elsif (s/^GL//) { $subsegcmapreq=1; }
+       elsif (s/^GR(.*)$//) {
+           my ($sscmfn) = $1;
+           my ($sscmf);
+           local ($_);
+           $sscmf= new IO::File $sscmfn, 'r'
+               or die "$sscmfn: cannot open: $!\n";
+           while (<$sscmf>) {
+               m,^\s*(\w+/(?:[a-z]+\d+))\s+(\S.*\S)\s*$,
+                   or die "$sscmfn:$.: syntax error in subseg cmap\n";
+               $subsegcmap{$1}= $2;
+           }
+           $sscmf->error and die "$sscmfn: error reading: $!\n";
+           close $sscmf;
+       } elsif (s/^(e)
               ((?:[a-z]|\*|\?|\[[a-z][-a-z]*\])*?)
               (\~?) (\d*) (\=*|\-+|\++) (\d*|\*)
               ([a-z]+)$//ix) {
@@ -118,6 +136,7 @@ our $psu_sleeperlen= 17;
 our $psu_sleeperlw= 15;
 our $psu_raillw= 1.0;
 our $psu_thinlw= 1.0;
+our $psu_subseglw= 2.0;
 
 our $lmu_marklw= 4;
 our $lmu_marktpt= 11;
@@ -170,6 +189,7 @@ our $allwidthmin= allwidth(undef);
 #  $ctx->{DrawMap}        # =$fn s.t.
 #                         #  &$fn($drawchrs_spec_by_layer_cmdline)
 #                         #   = $drawchrs_we_should_use_due_to_obj_etc
+#  $ctx->{SegName}        # initial segment name (at start of object or file)
 #  $ctx->{Layer}{Level}
 #  $ctx->{Layer}{Kind}
 #
@@ -180,6 +200,11 @@ our $allwidthmin= allwidth(undef);
 #  $eopts[]{GlobRe}       # regexp for K
 #  $eopts[]{LayerCheck}   # =$fn where &$fn($l) is true iff layer matches
 #  $eopts[]{DrawMods}     # modifier chars for drawing
+#
+#  @segments= ( $csss0, $dist0, $csss1, $dist1, ..., $csssn )
+#
+#  $subsegcmap{$csss} = "$green $blue"
+#                         # $csss is canonical subseg spec; always has '/'
 
 our $ctx;
 our %objs;
@@ -510,6 +535,7 @@ sub dv {
 sub o ($) { $o .= $_[0]; }
 sub ol ($) { $ol .= $_[0]; }
 sub oflushpage () {
+    return if $subsegcmapreq;
     print $o, $ol, "  showpage\n"
        or die $!;
     $o=$ol='';
@@ -529,7 +555,10 @@ sub o_path_point ($) {
 sub o_path_stroke ($) {
     my ($width)=@_;
     o("        $width setlinewidth stroke\n");
-}    
+}
+sub o_path_strokeonly () {
+    o("      stroke\n");
+}
 
 sub o_line ($$$) {
     my ($a,$b,$width)=@_;
@@ -566,6 +595,14 @@ sub parametric__o_pt ($) {
     o_path_point("$pt->{X} $pt->{Y}");
 }
 
+sub segment_used_len ($) {
+    my ($used) = @_;
+    return if @segments < 3;
+    $segments[1] -= $used;
+    return if $segments[1] > 0;
+    @segments= @segments[2..-1];
+}
+    
 sub parametric_segment ($$$$$) {
     my ($p0,$p1,$lenperp,$minradius,$calcfn) = @_;
     # makes $p (global) go from $p0 to $p1  ($p1>$p0)
@@ -574,7 +611,7 @@ sub parametric_segment ($$$$$) {
     # $calcfn is invoked with $p set and should return a loc
     # (ie, ref to X =>, Y =>, A =>).
     my ($pa,$pb,@ends,$side,$ppu,$e,$v,$tick,$draw,$allwidth);
-    return unless $ctx->{Draw} =~ m/[ARSC]/;
+    return unless $ctx->{Draw} =~ m/[ARSCG]/;
     $ppu= $psu_ulen/$lenperp;
     $allwidth= allwidth($minradius);
     my ($railctr)=($psu_gauge + $psu_raillw)*0.5;
@@ -584,6 +621,41 @@ sub parametric_segment ($$$$$) {
     my ($sleeperend)=($psu_sleeperlen*0.5);
 print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
     $draw= current_draw();
+    if ($draw =~ m/G/) {
+       my ($pt,$going,$red);
+       $going=0;
+       o("    $psu_subseglw setlinewidth\n");
+       $param=$p0;
+       $pt= &$calcfn;
+       for (;;) {
+           if ($subsegcmapreq) {
+               next if $subsegcmap{$segments[0]}++;
+               print "$segments[0]\n" or die $!;
+           } elsif (exists $subsegcmap{$segments[0]}) {
+               $red= $pt->{A} / (2*$pi);
+               $red *= 64;
+               $red %= 64;
+               $red /= 64.0;
+               $red= sprintf("%f", $red);
+               o("    $red $subsegcmap{$segments[0]} setrgbcolor\n");
+           } else {
+               die "unknown subsegment colour for $segments[0]\n";
+           }
+           o_path_begin();
+           parametric__o_pt($pt);
+
+           $param += $ppu;
+           last if $param>=$p1;
+           segment_used_len($psu_ulen);
+           $pt= &$calcfn;
+           parametric__o_pt($pt);
+           o_path_strokeonly();
+       }
+       segment_used_len(($p1-($param-$ppu)) * $lenperp);
+       $param=$p1;
+       parametric__o_pt(&$calcfn);
+       o_path_strokeonly();
+    }
     if ($draw =~ m/C/) {
        my ($pt);
        o("    $psu_thinlw setlinewidth\n");
@@ -976,7 +1048,8 @@ sub newctx (;$) {
     $ctx= {
        Trans => { X => 0.0, Y => 0.0, A => 0.0, R => 1.0 },
        InRunObj => "",
-       DrawMap => sub { $_[0]; }
+       DrawMap => sub { $_[0]; },
+       SegName => ""
        };
     %{ $ctx->{Layer} }= %{ $ctx_save->{Layer} }
         if defined $ctx_save;
@@ -1001,6 +1074,8 @@ sub cmd__defobj ($) {
     $ctx->{Draw}= $defobj_save->{Draw}.'X';
     $ctx->{DrawMap}= sub { ''; };
     $ctx->{Layer}= { Level => 5, Kind => '' };
+    $segments[0] =~ m,/, or die;
+    $ctx->{SegName}= $`;
 }
 
 sub cmd_enddef {
@@ -1282,23 +1357,17 @@ sub cmd__one {
     cmd__do();
 }
 
-print
-    "%!\n".
-    "  /lf /Courier-New findfont $lmu_marktpt scalefont def\n".
-    "  $ps_page_shift 0 translate 90 rotate\n"
-    or die $!;
+o("%!\n".
+  "  /lf /Courier-New findfont $lmu_marktpt scalefont def\n".
+  "  $ps_page_shift 0 translate 90 rotate\n");
 
 if ($page_x || $page_y) {
-    print
-       "  /Courier-New findfont 15 scalefont setfont\n".
-       "  30 30 moveto (${page_x}x${page_y}) show\n"
-        or die $!;
+    o("  /Courier-New findfont 15 scalefont setfont\n".
+      "  30 30 moveto (${page_x}x${page_y}) show\n");
 }
 
-print
-    "  -$ps_page_xmul $page_x mul  -$ps_page_ymul $page_y mul  translate\n".
-    "  $ptscale $ptscale scale\n"
-    or die $!;
+o("  -$ps_page_xmul $page_x mul  -$ps_page_ymul $page_y mul  translate\n".
+  "  $ptscale $ptscale scale\n");
 
 newctx();
 
@@ -1338,7 +1407,7 @@ while (<>) {
     }
     if (!$quiet) { print STDERR $bboxstr; }
     $bboxstr =~ s/^/\%L bbox /mg;
-    print $bboxstr or die $!;
+    o($bboxstr) or die $!;
 
     if ($scale < 1.5) {
        my ($tick_x, $tick_y, $ticklen);
diff --git a/layout/segcmapassign b/layout/segcmapassign
new file mode 100755 (executable)
index 0000000..1fa5bdb
--- /dev/null
@@ -0,0 +1,26 @@
+#!/usr/bin/perl
+# input:
+#   lines, with one canonical subsegment specification (csss) each
+#   (need not be unique)
+# output:
+#   lines:
+#       <csss> <green> <blue> <stuff which will be ignored...>
+#   where <csss> is N/[MP] (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
+#
+# Encoding is as follows:
+#
+#  RED
+#     6 bits angle
+#     1 bit `edge or core' (currently 0 meaning `core')
+#     1 bit reserved (0)
+#
+#  GREEN
+#     2 bits segment overflow
+#     6 bits moveable feature
+#
+#  
+#  10 bits