chiark / gitweb /
segment labelling work-in-progress - yet to do are labels and graph colouring
[trains.git] / layout / redactgraph.c
index da95ea32c80962a275d28f9333578ac552e4128e..09bc197dfc1fccff9f4e5fb33563304c3dd7250e 100644 (file)
@@ -1,4 +1,35 @@
-/**/
+/*
+ * output format from printforforsafety is lines like this:
+ *   segment <node>.<side> <node>.<side> <segment>[/<movinfo>] <distance>
+ *   #...         (comment)
+ *                (blank)
+ *   end          (at end of file, mandatory)
+ * syntactic restrictions:
+ *   <node> is alphanumeric and starts with a letter
+ *   <side> is precisely the digit 0 or the digit 1
+ *   <segment> is alphanumeric (and comes from the layout)
+ *   <movinfo> is  <movfeat><movpos>[<movfeat><movpos>...]*<combpos>
+ *            where <movfeat> is alphabetic and <movpos> is and
+ *            <combpos> are in decimal and have no unnecessary leading 0's
+ *   <distance> contains only digits and perhaps decimal point
+ * semantic restrictions (not enforced by redactgraph but ought to
+ * be impossible for layout designer to violate):
+ *   Each <segment>[/<movinfo>] appears exactly once.
+ *   <segment> appears either once without /<movinfo> or always with.
+ *   Each side of each node appears either
+ *    - once as the 0th or 1th end of a <segment>
+ *    - one or more times as the same end of <segment>/<movinfo>'s with
+ *      the same <segment>
+ *    - not at all (indicates a terminus)
+ * Refer to safety.h for info regarding <combpos>.
+ *
+ * See layout-data.h comment for info regarding layout data for
+ * control system.
+ */
+/* for debugging, runes like
+ *  ./ours.redactgraph consistency movfeatsplitedges consistency movfeatrmstubs consistency movfeatsplitnodes consistency trivpairnodes consistency trivnullnodes consistency printforneato | neato -Tps >u.ps
+ * are often useful.
+ */
 
 #include <stdarg.h>
 #include <string.h>
@@ -239,7 +270,7 @@ static void node_surely_orphaned(Node *node) {
   LIST_UNLINK(all_nodes, node);
 }
 
-/*---------- operations ----------*/
+/*---------- operations - heavyweight graph redaction ----------*/
 
   /* We combine the individual moveable features in each segment into
    * a single `feature' with the cross-product of all of the
@@ -424,7 +455,7 @@ static int movfeat_isinnernode(Node *node) {
     trace(" not inner: no edges?!\n");
     return 0;
   }
-  trace(" inner %s ",segment->segname);
+  trace(" inner %s ",all_segment->segname);
   return 1;
 }
 
@@ -492,13 +523,15 @@ static void movfeatsplitnodes(void) {
       edge= edgeend->edge;
       mate= movfeat_findmate(edgeend);
       assert(mate);
-      newnode= node_create(masprintf("%s/*%d",node->pname,edge->movpos));
+      newnode= node_create(masprintf("%sx%d",node->pname,edge->movpos));
       edgeend_replumb(mate, &newnode->sides[mate->node->side]);
       edgeend_replumb(edgeend, &newnode->sides[edgeend->node->side]);
     }
   }
 }
 
+/*---------- operations - trivial graph redaction etc. ----------*/
+
 static void trivpairnodes(void) {
   /* Eliminate near-trivial nodes - in this case, ones which have only
    * two edges, which come in on opposite sides, have the same
@@ -529,8 +562,10 @@ static void trivpairnodes(void) {
       continue;
     }
     trace(" yes:\n");
-    rightedge->edge->pname=
-      masprintf("%s+%s", leftedge->edge->pname, rightedge->edge->pname);
+    if (!strchr(rightedge->edge->pname, '+')) {
+      rightedge->edge->pname=
+       masprintf("%s+", rightedge->edge->pname);
+    }
     rightedge->edge->distance += leftedge->edge->distance;
     edgeend_replumb(rightedge, edgeend_otherend(leftedge)->node);
     edge_delete(leftedge);
@@ -614,6 +649,8 @@ static void consistency(void) {
   check("command-line request");
 }
 
+/*---------- operations - output ----------*/
+
 static void printforneato(void) {
   Node *node;
   EdgeEnd *edgeend;
@@ -649,6 +686,79 @@ static void printforneato(void) {
   output("}\n");
 }
 
+static void printforforsafety(void) {
+  Node *node;
+  Edge *edge;
+  EdgeEnd *edgeend;
+  int side, end, weight, i;
+  Segment *segment;
+  MovFeat *movfeat;
+  
+  FOR_ALL_NODES(node) {
+    FOR_EDGES(edge, node,side,edgeend) {
+      output("segment ");
+      FOR_BOTH(end) {
+       output("n%s.%d ",
+              edge->ends[end].node->node->pname,
+              edge->ends[end].node->side);
+      }
+      segment= edge->subseg->segment;
+      output(segment->segname);
+      if (segment->n_movfeats>1) {
+       if (!segment->starfeature) {
+         fprintf(stderr,"printforforsafety before movfeatsplitedges!\n");
+         exit(8);
+       }
+       output("/");
+       weight= 1;
+       FOR_SEGMENT_MOVFEATS(i,movfeat, segment) {
+         if (!movfeat->movfeat) continue;
+         output("%s%d", movfeat->movfeat,
+                (edge->movpos / weight) % movfeat->n_positions);
+         weight *= movfeat->n_positions;
+       }
+       output("*%d", edge->movpos);
+      }
+      output(" %f\n", edge->distance);
+    }
+  }
+  output("end\n");
+}
+
+static void printforlayoutsegjoins(void) {
+  Node *node;
+  EdgeEnd *edgeend;
+  Segment **segmentp, *segment;
+  int side;
+  
+  FOR_ALL_NODES(node) {
+    output("layer ");
+    FOR_BOTH(side)
+      if (!node->sides[side].head) {
+       output("segterminus");
+       goto one_sided;
+      }
+    output("segjoin");
+  one_sided:
+    output("%d\n", (node->layermin + node->layermax)/2);
+
+    output("abs segjoin_%s",node->pname);
+    FOR_NODE_EDGEENDS(side,edgeend, node)
+      output("_%s",edgeend->edge->subseg->segment->segname);
+    output(" %f %f %f\n", node->x,node->y,node->a);
+    FOR_ALL_SEGMENTS(segmentp,segment) segment->u= 0;
+    FOR_NODE_EDGEENDS(side,edgeend, node) {
+      segment= edgeend->edge->subseg->segment;
+      if (segment->u++) continue;
+      output("segend %s\n",segment->segname);
+      output("segcmap %s  0.5 setgray\n",segment->segname);
+    }
+    output("\n");
+  }
+}
+
+/*---------- main program ----------*/
+
 typedef struct {
   const char *name;
   void (*fn)(void);
@@ -657,6 +767,8 @@ typedef struct {
 static const OpInfo opinfos[]= {
 #define OI(x) { #x, x },
   OI(printforneato)
+  OI(printforforsafety)
+  OI(printforlayoutsegjoins)
   OI(consistency)
   OI(movfeatsplitedges)
   OI(movfeatrmstubs)