3 # Reads the special comments in the subsegment encoding output from
4 # layout, determines the segment graph, and outputs a description of
9 # We read the segenco.ps and each time we find a `%L segmentpart'
10 # comment we add it to an annotated graph we construct. Each node in
11 # the annotated graph is a tuple consisting of a loc and range of
12 # layer levels. Each edge is a segment part from a %L comment. Each
13 # node has a `front' and a `back', and each edget attach either to
16 # Only segment parts with certain layer kinds are processed: by
17 # default, only the empty layer kind.
19 # When a loc is found in the input, as one end of a segmentpart, it
20 # is considered identical to a existing node (if its details are
21 # sufficiently similar) or creates a new node (if its details are
22 # sufficiently different). If the segmentpart's end is considered
23 # identical to an existing node then the existing node's layer level
24 # range is extended, but the existing node's X Y and A are not
27 # A loc and layer level are compared with a node as follows:
29 # The difference between each of the loc's details and the node's
30 # details is computed. If any of the differences is at least the
31 # min clearance, then the loc/layerb is a new node. Otherwise, all
32 # of the differences must be within the max tolerance and the
33 # loc/layer is the same as the node (coming out of the back if the
34 # 180deg was added to make the angle difference). Otherwise it is
37 # The detail differences are:
38 # Position difference: horizontal distance between loc and node
39 # Angle difference: difference betwen loc's and node's A, or
40 # difference minus 180deg between loc's and node's A, whichever
41 # is the smaller (both reduced mod 360deg to value with
42 # smallest magnitude).
43 # Level difference: 0 if layer level is within node's range
44 # or distance by which it is outside that range.
46 $conf{MinClearLayer}= 6;
47 $conf{MaxTolerLayer}= 4;
48 $conf{MinClearDist}= 2.0;
49 $conf{MaxTolerDist}= 0.2;
50 $conf{MinClearAngle}= 5.0;
51 $conf{MaxTolerAngle}= 0.5;
52 $conf{LayerKinds}= ','; # comma-separated list as for split /\,/, ..., -1;
58 # $nodes[$nodenum]{LayerMin}
59 # $nodes[$nodenum]{LayerMax}
62 print "/* $_[0] */\n";
65 sub sqr ($) { return $_[0]*$_[0]; }
68 my ($l,$x,$y,$a) = @_;
69 my ($any_outside_tol);
70 for ($ni=0; $ni<@nodes; $ni++) {
72 $diff{Layer}= (($d = $l - $node->{LayerMin}) < 0 ? $d :
73 ($d = $l - $node->{LayerMax}) > 0 ? $d :
75 $diff{Dist}= sqrt(sqr($x - $node->{X}) +
76 sqr($y - $node->{Y}));
77 $diff{Angle}= $a - $node->{A}; # <-360,360>
78 if ($diff{Angle} < 0) { $diff{Angle} += 360; } # [0,360>
79 $back= $diff{Angle} >= 90 && $diff{Angle} < 270; # $back <=> [90,270>
80 if ($back) { $diff{Angle} -= 180; } # [0,90> or [270,360>
81 if ($diff{Angle} > 180) { $diff{Angle} -= 360; } # [-90,90>
82 $any_outside_clear= 0;
83 $any_outside_toler= 0;
84 foreach $k (keys %diff) {
85 if (abs($diff{$k}) >= $conf{"MinClear$k"}) {
86 $any_outside_clear=1; last;
87 } elsif (abs($diff{$k}) <= $conf{"MaxToler$k"}) {
92 if ($any_outside_clear) {
93 } elsif ($any_outside_toler) {
94 die "$l,$x,$y,$a vs. $node->{LayerMin}..$node->{LayerMax}".
95 ",$node->{X},$node->{Y},$node->{A}".
96 " at <> line $node->{LineNum} and";
98 if ($diff{Layer} < 0) { $node->{LayerMin}= $l }
99 if ($diff{Layer} > 0) { $node->{LayerMax}= $l }
100 comment("nodulated ex.#$ni/$back $l,$x,$y,$a");
104 $node= { X => $x, Y => $y, A => $a,
105 LayerMin => $l, LayerMax => $l, LineNum => $. };
107 comment("nodulated new#$ni/0 $l,$x,$y,$a");
112 next unless m/^\%L /;
113 die unless m/^\%L (\w+)\b/;
114 next unless $1 eq 'segmentpart';
115 die unless m/^\%L segmentpart ([A-Za-z_]*)(\d+) (\S+) ([-.eE0-9 ]+)$/;
116 ($layerkind, $level, $subsegspec, $numbers) = ($1,$2,$3,$4);
117 next unless grep { $layerkind eq $_ } split /\,/, $conf{LayerKinds}, -1;
118 @numbers = map { $_ + 0 } split / /, $numbers;
119 $dist= shift @numbers;
120 @numbers == 6 or die;
121 for ($pti=0; $pti<2; $pti++) {
122 ($node[$pti], $back[$pti])=
123 find_node($level, @numbers[($i*3)..($i*3+2)]);
127 # ($pts[0]{X}, $pts[0]{Y}, $pts[0]{A},
128 # $pts[1]{X}, $pts[1]{Y}, $pts[1]{A}) =
131 #(\w+(?:(?:\/([A-Za-z]+)(\d+))?)?)