|
1 | 1 | function [bbx] = bbox_tree(cas) |
2 | | -%function [bbx] = bbox_tree(cas) |
| 2 | +% function [bbx] = bbox_tree(cas) |
3 | 3 | % |
4 | | -% bbox_tree: calculate the boundary box of a GDSII structure tree |
| 4 | +% Calculates the boundary box of a GDSII structure tree |
5 | 5 | % |
6 | 6 | % Input: |
7 | 7 | % cas : a cell array of gds_structure objects |
|
11 | 11 | % lower left and upper right corners of the bounding box. |
12 | 12 |
|
13 | 13 | % Initial version, Ulf Griesmann, December 2015 |
| 14 | +% major bug fixes, Alexandre Simard, March 2021 |
14 | 15 |
|
15 | 16 | % calculate boundary boxes before resolving the hierarchy |
16 | 17 | % to minimize computations especially for leaf nodes |
17 | 18 | caslen = numel(cas); |
18 | 19 | bbdata = repmat(struct('bbox',[Inf,Inf,-Inf,-Inf], ... |
19 | | - 'ref',[]), caslen,1); |
| 20 | + 'ref',[],'name',[]), caslen,1); |
20 | 21 | for k = 1:caslen |
21 | 22 | [bbdata(k).bbox, bbdata(k).ref] = bbox(cas{k}); |
| 23 | + bbdata(k).name = get(cas{k},'sname'); |
22 | 24 | end |
23 | 25 |
|
24 | 26 | % find top level structure(s) - they have no parents |
25 | | - A = adjmatrix(cas); |
| 27 | + [A,N] = adjmatrix(cas); |
26 | 28 | T = find(sum(A)==0); % array with top parent indices |
27 | 29 |
|
28 | 30 | % calculate bounding boxes of all top level structures |
29 | 31 | bbst = zeros(length(T),4); |
30 | 32 | for k=1:length(T) |
31 | | - bbst(k,:) = bbox_struct(A, bbdata, T(k)); |
| 33 | + bbst(k,:) = bbox_struct(A, bbdata, T(k), N); |
32 | 34 | end |
33 | 35 |
|
34 | 36 | bbx = [min(bbst(:,1:2),[],1),max(bbst(:,3:4),[],1)]; |
35 | 37 |
|
36 | 38 | end |
37 | 39 |
|
38 | 40 |
|
39 | | -function [bbst] = bbox_struct(A, bbdata, sidx) |
| 41 | +function [bbst] = bbox_struct(A, bbdata, sidx, N) |
40 | 42 | % |
41 | 43 | % This function is called recursively to apply strans |
42 | 44 | % transformations to the pre-computed boundary boxes and to |
43 | 45 | % calculate the boundary boxes for the resolved structure |
44 | 46 | % hierarchy. |
45 | | -% |
46 | | - |
| 47 | +% |
47 | 48 | % indices of child structures referenced by structure sidx |
48 | 49 | chi = find(A(sidx,:)); |
49 | 50 |
|
|
60 | 61 | for k = 1:length(chi) |
61 | 62 |
|
62 | 63 | % recursively calculate boundary box of the referenced structures |
63 | | - bbr = bbox_struct(A, bbdata, chi(k)); |
| 64 | + bbr = bbox_struct(A, bbdata, chi(k), N); |
64 | 65 |
|
65 | 66 | % apply any transformations to the boundary box |
66 | | - nref = length(bbdata(sidx).ref); |
| 67 | + |
| 68 | + % Find the sref of this refrences structured |
| 69 | + refloc = bbdata(sidx).ref; |
| 70 | + ind = arrayfun(@(x)strcmp(N{chi(k)},x.sname), refloc, 'UniformOutput', false); |
| 71 | + ind = horzcat(ind{:}); |
| 72 | + refloc = refloc(ind); |
| 73 | + |
| 74 | + nref = length(refloc); |
67 | 75 | b = zeros(nref,4); |
68 | 76 | for m = 1:nref |
69 | | - if isempty(bbdata(sidx).ref(m).adim) % sref |
70 | | - b(m,:) = bbox_strans(bbr, bbdata(sidx).ref(m).strans); |
| 77 | + if isempty(refloc(m).adim) % sref |
| 78 | + b(m,:) = bbox_strans(bbr, refloc(m).strans); |
71 | 79 | b(m,:) = b(m,:) + ... |
72 | | - [bbdata(sidx).ref(m).xy, bbdata(sidx).ref(m).xy]; |
73 | | - else % aref |
74 | | - b(m,:) = bbox_aref(bbr, bbdata(sidx).ref(m).strans, ... |
75 | | - bbdata(sidx).ref(m).xy, ... |
76 | | - bbdata(sidx).ref(m).adim); |
| 80 | + [refloc(m).xy, refloc(m).xy]; |
| 81 | + else % aref |
| 82 | + b(m,:) = bbox_aref(bbr, refloc(m).strans, ... |
| 83 | + refloc(m).xy, ... |
| 84 | + refloc(m).adim); |
77 | 85 | end |
78 | 86 | end |
79 | 87 |
|
|
83 | 91 | % calculate the final boundary box |
84 | 92 | B(k+1,:) = bbdata(sidx).bbox; |
85 | 93 | bbst = [min(B(:,1:2),[],1), max(B(:,3:4),[],1)]; |
86 | | - |
87 | 94 | end |
88 | 95 |
|
89 | 96 |
|
|
145 | 152 |
|
146 | 153 |
|
147 | 154 | function [box] = apply_strans(box, strans) |
| 155 | + |
| 156 | + % reflection comes after rotation |
| 157 | + if isfield(strans,'reflect') && strans.reflect |
| 158 | + box(:,2) = -box(:,2); |
| 159 | + end |
148 | 160 |
|
149 | 161 | % first rotate |
150 | 162 | if isfield(strans,'angle') && ~isempty(strans.angle) && strans.angle~=0 |
151 | 163 | box = poly_rotzd(box, strans.angle); % rotated box |
152 | 164 | end |
153 | | - |
154 | | - % reflection comes after rotation |
155 | | - if isfield(strans,'reflect') && strans.reflect |
156 | | - box(:,1) = -box(:,1); |
157 | | - end |
158 | | - |
| 165 | + |
159 | 166 | % magnification |
160 | 167 | if isfield(strans,'mag') && ~isempty(strans.mag) |
161 | 168 | box = strans.mag * box; |
|
0 commit comments