chiark / gitweb /
edge and node numbering
authorian <ian>
Sun, 20 Mar 2005 02:43:22 +0000 (02:43 +0000)
committerian <ian>
Sun, 20 Mar 2005 02:43:22 +0000 (02:43 +0000)
layout/dlist.h
layout/extractgraph
layout/graph-data.h
layout/informat.txt
layout/layout
layout/redactgraph.c

index 76fc74c307713a0bedd25af1370c2e198ca0d5cf..8495c2d09c0bbe8ab710114516a0adb0a6272233 100644 (file)
     (list).tail= (node);                               \
   } while(0)
 
+
+#define LIST_CHECKNODE_PART(list,node,part)                            \
+  do {                                                                 \
+    if ((node)->next) assert((node)->part next->part back == (node));  \
+    else assert((node) == (list).tail);                                        \
+    if ((node)->back) assert((node)->part back->part next == (node));  \
+    else assert((node) == (list).head);                                        \
+  } while(0)
+
 #define LIST_UNLINK(list,node) LIST_UNLINK_PART(list,node,)
 #define LIST_LINK_TAIL(list,node) LIST_LINK_TAIL_PART(list,node,)
+#define LIST_CHECKNODE(list,node) LIST_CHECKNODE_PART(list,node,)
 
 #endif
index 7d7ff42ccba5d97451c9d91c6bef980b492eee15..26d64773326b8032539f0226d82f0f1ae0584942 100755 (executable)
@@ -70,6 +70,7 @@ our @nodes;
 our @edges;
 # $edges[]{"Node$far"}= [ \$nodes[], $back ]
 # $edges[]{Dist}
+# $edges[]{EdgeNum}
 # $edges[]{SubSegSpec}
 
 our %segments;
@@ -86,10 +87,11 @@ sub sqr ($) { return $_[0]*$_[0]; }
 sub find_node (@) {
     my ($lni,$isdest,$l,$x,$y,$a) = @_;
     my ($any_outside_toler, $any_outside_clear, $updlayer);
-    my ($ni, $node, %diff, $back, $d, $k, $pinfo);
+    my ($ni, $nodei, $node, %diff, $back, $d, $k, $pinfo);
     $pinfo= sprintf "%.2f %.2f %.2f", $x,$y,$a;
     $a -= 360.0 * floor($a / 360.0);
-    for $node (@nodes) {
+    for ($nodei=0; $nodei<@nodes; $nodei++) {
+       $node= $nodes[$nodei];
        $diff{Layer}= (($d = $l - $node->{LayerMin}) < 0 ? $d :
                       ($d = $l - $node->{LayerMax}) > 0 ? $d :
                       0);
@@ -127,7 +129,7 @@ sub find_node (@) {
                $node->{"Layer$updlayer"}= $l;
                $node->{LineInfo}.="($l<-$lni)";
            }
-           comment("nodulated $lni ex.$node/$back ($pinfo)");
+           comment("nodulated $lni ex.$nodei/$back ($pinfo)");
            return ($node,$back);
        }
     }
@@ -135,25 +137,29 @@ sub find_node (@) {
             LayerMin => $l, LayerMax => $l, LineInfo => $lni };
     $back= $isdest;
     push @nodes, $node;
-    comment("nodulated $lni new$node/$back ($pinfo)");
+    comment("nodulated $lni new$#nodes/$back ($pinfo)");
     return ($node,$back);
 }
 
 sub readin () {
     my ($layerkind, $level, $subsegspec, $numbers, @numbers, $dist);
-    my ($node,$back,$far,@nodeinfo,@endnums,$edge);
+    my ($edgenum,$node,$back,$far,@nodeinfo,@endnums,$edge);
     while (<>) {
        next unless m/^\%L /;
        die unless m/^\%L (\w+)\b/;
        next unless $1 eq 'segmentpart';
-       die unless m/^\%L segmentpart ([A-Za-z_]*)(\d+) (\S+) ([-.eE0-9 ]+)$/;
-       ($layerkind, $level, $subsegspec, $numbers) = ($1,$2,$3,$4);
+       die unless
+           m/^\%L segmentpart (\d+) ([A-Za-z_]*)(\d+) (\S+) ([-.eE0-9 ]+)$/;
+       ($edgenum, $layerkind, $level, $subsegspec, $numbers) =
+           ($1,$2,$3,$4,$5);
        next unless grep { $layerkind eq $_ } @layerkinds;
        next unless $subsegspec =~ m,^[^/], or $conf{EvenUnknownSegments};
        @numbers = map { $_ + 0 } split / /, $numbers;
        $dist= shift @numbers;
        @numbers == 6 or die;
-       $edge= { Dist => $dist, SubSegSpec => $subsegspec };
+       $edge= { EdgeNum => $edgenum,
+                Dist => $dist,
+                SubSegSpec => $subsegspec };
        for ($far=0; $far<2; $far++) {
            @endnums= @numbers[($far*3)..($far*3+2)];
            ($node,$back)= find_node("$.:$far",$far,$level,@endnums);
@@ -244,7 +250,7 @@ sub writeout () {
     o("\n");
     for ($i=0; $i<@nodes; $i++) {
        $node= $nodes[$i];
-       o("static Node ",pr(Node,$node),"= { \n");
+       o("static Node ",pr(Node,$node),"= { $i,\n");
        o("  ".($i>0 ? '&'.pr(Node,$nodes[$i-1]) : '0').
          ", ".($i<$#nodes ? '&'.pr(Node,$nodes[$i+1]) : '0'));
        o(", {");
@@ -266,8 +272,9 @@ sub writeout () {
        o("\n  }\n};\n");
     }
     o("\n");
-    for $edge (@edges) {
-       o("static Edge ",pr(Edge,$edge),"= {\n");
+    for ($i=0; $i<@edges; $i++) {
+       $edge= $edges[$i];
+       o("static Edge ",pr(Edge,$edge),"= { $edge->{EdgeNum},\n");
        o("  $edge->{Dist}, ");
        $sss= $edge->{SubSegSpec};
        $reverse= !!($sss =~ s/^\-//);
index 9b7f770ffc01b07a9f912cd920adbea616e2bcc8..b9fbfe94ad11c5a255acded1be6d59ca021f879c 100644 (file)
@@ -33,6 +33,7 @@ struct EdgeEnd {
 };
 
 struct Edge {
+  int edgenum;
   double distance;
   MovFeat *subseg;
   int movpos; /* 0 if fixed */
@@ -46,6 +47,7 @@ struct NodeSide {
 };
 
 struct Node {
+  int nodenum;
   Node *back, *next;
   NodeSide sides[2];
 };
index 5756cedea263619fdbd7bba71107babbc4d52bf5..15be4eee5e72864594d3f8f96e0628fc76f22456 100644 (file)
@@ -294,11 +294,13 @@ Special comments in PostScript:
  %L bbox no locs, no bbox
        there were no locs, so there is no bounding box
        usu because input file was just obj defns and showlibrary
- %L segmentpart KL [-]S D X0 Y0 A0 X1 Y1 A1
+ %L segmentpart KL [-]S D X0 Y0 A0 X1 Y1 A1
        records that a piece of subsegment S is drawn in the subsegment
        encoding.  The piece is of length D, in layer KL (which may be
        the empty string, depending on layer configurations), and runs
-       from the loc X0,Y0,A0 to X1,Y1,A1.
+       from the loc X0,Y0,A0 to X1,Y1,A1.  I is a counter which starts
+       at 0 and is simply there to help cross-reference between
+       various programs and formats.
 
  Scope S is
    O!    when defining object or part O
index 0d2db4bab8f6e4b4dab4ae19945894fae8239400..2c5321580c68e71003a1dcaab8e777e1f108fb70 100755 (executable)
@@ -625,11 +625,13 @@ sub parametric__o_pt ($) {
 
 our $segused_incurrent;
 our $segused_currentpt;
+our $segmentpart_counter=0;
 
 sub segment_used__print ($) {
     my ($pt) = @_;
     if ($segused_incurrent > 0) {
        o("%L segmentpart ".
+         $segmentpart_counter++." ".
          $ctx->{Layer}{Level}.$ctx->{Layer}{Kind}." ".
          $segments[0]." ".
          $segused_incurrent." ".
index e2ecc61658b9ffc4e8d0bd310f6c997ada9aad43..b330172e47f7c0c4f0eec3c95831b863d5aa97fe 100644 (file)
@@ -227,7 +227,62 @@ static void elimtrivial(void) {
   }
 } 
 
+static void check(const char *why) {
+  Node *node;
+  int alloc_edone, used_edone;
+  typedef struct { Edge *edge; int endsdone; } EdgeDone;
+  EdgeDone *edone, *search_edone;
+  int side;
+  EdgeEnd *edgeend;
+  Edge *edge;
+
+  edone= 0;
+  alloc_edone= used_edone= 0;
+  
+  trace("consistency check (%s) ...\n",why);
+  for (node=all_nodes.head; node; node=node->next) {
+    trace(" consistency node %p\n", node);
+    LIST_CHECKNODE(all_nodes,node);
+    for (side=0; side<2; side++) {
+      trace(" consistency node %p%c\n", node, "OI"[side]);
+      assert(node->sides[side].node == node);
+      assert(node->sides[side].side == side);
+      for (edgeend=node->sides[side].head; edgeend; edgeend=edgeend->next) {
+       trace(" consistency node %p%c ", node, "OI"[side]);
+       trace_edgeend(edgeend);
+       trace("\n");
+       
+       edge= edgeend->edge;
+       LIST_CHECKNODE(node->sides[side], edgeend);
+       assert(edgeend == &edge->ends[edgeend->end]);
+       assert(edgeend->node == &node->sides[side]);
+       if (used_edone==alloc_edone) {
+         alloc_edone += 2; alloc_edone *= 2;
+         edone= realloc(edone, alloc_edone * sizeof(*edone));
+         if (!edone) { perror("realloc check edone"); exit(16); }
+       }
+       for (search_edone= edone;
+            search_edone < edone + used_edone && search_edone->edge != edge;
+            search_edone++);
+       if (search_edone >= edone + used_edone) {
+         search_edone->edge= 0;
+         search_edone->endsdone= 0;
+         used_edone++;
+       }
+       search_edone->endsdone++;
+       assert(search_edone->endsdone <= 2);
+      }
+    }
+  }
+  for (search_edone= edone;
+       search_edone < edone + used_edone;
+       search_edone++)
+    assert(search_edone->endsdone == 2);
+  trace("consistency check (%s) ok\n",why);
+}
+
 static void consistency(void) {
+  check("command-line request");
 }
 
 static void printforneato(void) {
@@ -239,18 +294,21 @@ static void printforneato(void) {
   output("digraph L {\n");
 
   for (node=all_nodes.head; node; node=node->next) {
-    output("  n%pO [label=\"O\"];\n"
-          "  n%pI [label=\"+\"];\n",
-          node, node);
-    output("  n%pO -> n%pI [len=0.25 arrowsize=0];\n",
-          node, node);
+    output("  n%dO [label=\"%d\"];\n"
+          "  n%dI [label=\"+\"];\n",
+          node->nodenum, node->nodenum, node->nodenum);
+    output("  n%dO -> n%dI [len=0.25 arrowsize=0];\n",
+          node->nodenum, node->nodenum);
     for (side=0; side<2; side++) {
       for (edgeend=node->sides[side].head; edgeend; edgeend=edgeend->next) {
        if (edgeend->end) continue; /* do each edge once, from end 0, only */
        edge= edgeend->edge;
-       output("  n%p%c -> n%p%c [label=\"",
-              edge->ends[0].node->node, "OI"[edge->ends[0].node->side],
-              edge->ends[1].node->node, "OI"[edge->ends[1].node->side]);
+       output("  n%d%c -> n%d%c [label=\"%d:",
+              edge->ends[0].node->node->nodenum,
+              "OI"[edge->ends[0].node->side],
+              edge->ends[1].node->node->nodenum,
+              "OI"[edge->ends[1].node->side],
+              edge->edgenum);
        if (!edge->subseg->segment->segname) {
          output("?");
        } else {
@@ -259,7 +317,7 @@ static void printforneato(void) {
            output("/%s%d",edge->subseg->movfeat,edge->movpos);
          }
        }
-       output("\"];\n");
+       output(":%.2f\"];\n",edge->distance);
       }
     }
   }