(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
our @edges;
# $edges[]{"Node$far"}= [ \$nodes[], $back ]
# $edges[]{Dist}
+# $edges[]{EdgeNum}
# $edges[]{SubSegSpec}
our %segments;
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);
$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);
}
}
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);
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(", {");
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/^\-//);
};
struct Edge {
+ int edgenum;
double distance;
MovFeat *subseg;
int movpos; /* 0 if fixed */
};
struct Node {
+ int nodenum;
Node *back, *next;
NodeSide sides[2];
};
%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 I 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
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." ".
}
}
+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) {
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 {
output("/%s%d",edge->subseg->movfeat,edge->movpos);
}
}
- output("\"];\n");
+ output(":%.2f\"];\n",edge->distance);
}
}
}