tp@0
|
1 function [outputfile] = EDB1readcad(CADfile,outputfile,planecornerstype,checkgeom)
|
tp@0
|
2 % EDB1readcad - Reads a file of type .CAD (made by e.g. CATT-Acoustic) and saves all the geometry data in a mat-file.
|
tp@0
|
3 % CAD-files v6,v7,v8 are read.
|
tp@0
|
4 %
|
tp@0
|
5 % Input parameters:
|
tp@0
|
6 % CADfile (optional) The input file, with or without the .CAD extension.
|
tp@0
|
7 % If this file is not specified, a file opening window will appear.
|
tp@0
|
8 % outputfile (optional) The output file. If not specified, it will be given the
|
tp@0
|
9 % same name as the CAD file with an '_cadgeo.mat' ending instead of the '.CAD'.
|
tp@0
|
10 % planecornerstype (optional) Could have the value 'zero' or 'circ'.Default: 'circ'.
|
tp@0
|
11 % Affects the matrix planecorners, see below.
|
tp@0
|
12 % checkgeom (optional) If this parameter is given the value 'check', then a few checks
|
tp@0
|
13 % of the geometry consistency will be done: a check for duplicate corners
|
tp@0
|
14 % for redundant corners and for corners that are connected to only one plane.
|
tp@0
|
15 % Only warnings are given. As default, no check is done.
|
tp@0
|
16 % SHOWTEXT (global) If this global parameter has the value 3 or higher, informative text will
|
tp@0
|
17 % be printed on the screen.
|
tp@0
|
18 %
|
tp@0
|
19 % Output parameters:
|
tp@0
|
20 % outputfile The name of the outputfile, generated either automatically or specified as
|
tp@0
|
21 % an input parameter.
|
tp@0
|
22 %
|
tp@0
|
23 % Output parameters in the outputfile:
|
tp@0
|
24 % corners Matrix [ncorners,3] with the corner coordinates
|
tp@0
|
25 % cornernumbers Vector [ncorners,1] with the corner numbers used in the CAD-file. That is
|
tp@0
|
26 % in the outputfile, the corners will effectively be renumbered from 1 to ncorners
|
tp@0
|
27 % in the order they appeared in the CAD-file.
|
tp@0
|
28 % planecorners Matrix [planes,nmaxcornersperplane] with the corner numbers that make up each plane.
|
tp@0
|
29 % Since planes can have different numbers of corners, the number of columns is the
|
tp@0
|
30 % maximum number of corners that any plane has. NB! The corner numbers are in the
|
tp@0
|
31 % renumbered system, not in the CAD-file system.
|
tp@0
|
32 % planenames Matrix [nplanes,nmaxcharacters1] (sparse), with the planenames in the CAD file.
|
tp@0
|
33 % planeabstypes Matrix [nplanes,nmaxcharacters2] (sparse), with the absorber names in the CAD file.
|
tp@0
|
34 % planenumbers Vector [nplanes,1] with the plane numbers used in the CAD file.
|
tp@0
|
35 % cornercrossref Vector [nmaxnumberinCADfile,1] (sparse), which gives the matlab-file corner
|
tp@0
|
36 % numbers for each CAD-file corner number. For instance, if a CAD-file corner
|
tp@0
|
37 % number 1200 is translated to corner number 72 in the matlab-file, then
|
tp@0
|
38 % cornercrossref(1000) = 72.
|
tp@0
|
39 % Snumbers Vector [nsources,1] of the source numbers in the CAD-file. NB! Only CAD-files
|
tp@0
|
40 % v6 use source numbers; later versions use source names instead of numbers.
|
tp@0
|
41 % For CAD-file v7 and v8, Snumbers is empty.
|
tp@0
|
42 % Snames Matrix [nsources,2] of the source names in the CAD-file. NB! Only CAD-files v7
|
tp@0
|
43 % or later use source names (such as 'A0' etc). Older versions use source numbers,
|
tp@0
|
44 % in which case Snames is empty.
|
tp@0
|
45 % Sdirectivitynames Matrix [nsources,nmaxcharacters3] (sparse) with the source directivity names
|
tp@0
|
46 % in the CAD file.
|
tp@0
|
47 % Sdelays Vector [nsources,1] of the source delays in the CAD-file, in milliseconds.
|
tp@0
|
48 % Scoords Matrix [nsources,3] of the source coordinates.
|
tp@0
|
49 % Sdirections Matrix [nsources,3] of the aim point coordinates for the sources.
|
tp@0
|
50 % Srotations Vector [nsources,1] of the source rotations, in degrees.
|
tp@0
|
51 % Slevels Matrix [nsources,6/8] of the source levels for six (CAD-files v6) or eight
|
tp@0
|
52 % octave bands (CAD-files v7 or later).
|
tp@0
|
53 % Rnumbers Vector [nreceivers,1] of the receiver numbers in the CAD-file.
|
tp@0
|
54 % Rcoords Matrix [nreceivers,3] of the receiver coordinates.
|
tp@0
|
55 % CATTversionnumber 6,7 or 8
|
tp@0
|
56 % planeeqs Matrix [nplanes,4] of the plane equations as derived from the plane definitions.
|
tp@0
|
57 % Each row has the values [A B C D] of the plane equation on the form Ax + By + Cz = D
|
tp@0
|
58 % planenvecs Matrix [nplanes,3] of the normalized normal vectors of the planes.
|
tp@0
|
59 % ncornersperplanevec Vector [nplanes,1] which gives the number of corners for each plane.
|
tp@0
|
60 % planesatcorners Matrix [ncorners,4] which gives the plane numbers that each corner is connected to.
|
tp@0
|
61 % NB! Here it is assumed that each corner is connected to maximum four planes.
|
tp@0
|
62 % nplanespercorners Vector [ncorners,1] which gives the number of planes that each corner is connected to.
|
tp@0
|
63 % minvals Matrix [nplanes,3] which for each plane gives the smallest coordinate in the x-, y- and z-direction.
|
tp@0
|
64 % maxvals Matrix [nplanes,3] which for each plane gives the largest coordinate in the x-, y- and z-direction.
|
tp@0
|
65 % planehasindents Vector [nplanes,1] which for each plane gives the
|
tp@0
|
66 % number of indeting corners
|
tp@0
|
67 % indentingcorners Matrix [nplanes,max(ncornersperplanevec)] which for each plane gives the number to the first corner
|
tp@0
|
68 % in a corner triplet which identifies an indenting corner. The number of the corner is the
|
tp@0
|
69 % order given in planecorners for that plane.
|
tp@0
|
70 %
|
tp@0
|
71 % Uses the functions EDB1extrnums, EDB1cross
|
tp@0
|
72 %
|
tp@0
|
73 % ----------------------------------------------------------------------------------------------
|
tp@0
|
74 % This file is part of the Edge Diffraction Toolbox by Peter Svensson.
|
tp@0
|
75 %
|
tp@0
|
76 % The Edge Diffraction Toolbox is free software: you can redistribute it and/or modify
|
tp@0
|
77 % it under the terms of the GNU General Public License as published by the Free Software
|
tp@0
|
78 % Foundation, either version 3 of the License, or (at your option) any later version.
|
tp@0
|
79 %
|
tp@0
|
80 % The Edge Diffraction Toolbox is distributed in the hope that it will be useful,
|
tp@0
|
81 % but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
tp@0
|
82 % FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
tp@0
|
83 %
|
tp@0
|
84 % You should have received a copy of the GNU General Public License along with the
|
tp@0
|
85 % Edge Diffraction Toolbox. If not, see <http://www.gnu.org/licenses/>.
|
tp@0
|
86 % ----------------------------------------------------------------------------------------------
|
tp@0
|
87 % Peter Svensson (svensson@iet.ntnu.no) 20090718
|
tp@0
|
88 %
|
tp@0
|
89 % [outputfile] = EDB1readcad(CADfile,outputfile,planecornerstype,checkgeom);
|
tp@0
|
90
|
tp@0
|
91 global SHOWTEXT
|
tp@0
|
92
|
tp@0
|
93 if nargin == 0
|
tp@0
|
94 CADfile = '';
|
tp@0
|
95 outputfile = '';
|
tp@0
|
96 planecornerstype = '';
|
tp@0
|
97 checkgeom = '';
|
tp@0
|
98 elseif nargin == 1
|
tp@0
|
99 outputfile = '';
|
tp@0
|
100 planecornerstype = '';
|
tp@0
|
101 checkgeom = '';
|
tp@0
|
102 elseif nargin == 2
|
tp@0
|
103 planecornerstype = '';
|
tp@0
|
104 checkgeom = '';
|
tp@0
|
105 elseif nargin == 3
|
tp@0
|
106 checkgeom = '';
|
tp@0
|
107 end
|
tp@0
|
108
|
tp@0
|
109 geomacc = 1e-10;
|
tp@0
|
110
|
tp@0
|
111 %---------------------------------------------------------------
|
tp@0
|
112 % If no CAD-file was specified, present a file opening window
|
tp@0
|
113
|
tp@0
|
114 if isempty(CADfile)
|
tp@0
|
115 [CADfile,filepath] = uigetfile('*.cad','Please select the CADfile');
|
tp@0
|
116 [filepath,temp1,temp2] = fileparts(filepath);
|
tp@0
|
117 if ~isstr(CADfile)
|
tp@0
|
118 return
|
tp@0
|
119 end
|
tp@0
|
120 [temp1,filestem,temp2] = fileparts(CADfile);
|
tp@0
|
121
|
tp@0
|
122 CADfile = [[filepath,filesep],filestem,'.cad'];
|
tp@0
|
123 else
|
tp@0
|
124 [filepath,filestem,fileext] = fileparts(CADfile);
|
tp@0
|
125 CADfile = [[filepath,filesep],filestem,fileext];
|
tp@0
|
126 end
|
tp@0
|
127
|
tp@0
|
128 if exist(CADfile) ~= 2
|
tp@0
|
129 error(['ERROR: CAD-file: ',CADfile,' can not be found'])
|
tp@0
|
130 end
|
tp@0
|
131
|
tp@0
|
132 %---------------------------------------------------------------
|
tp@0
|
133 % If no output file was specified, construct an automatic file name
|
tp@0
|
134
|
tp@0
|
135 if isempty(outputfile)
|
tp@0
|
136 outputfile = [[filepath,filesep],filestem,'_cadgeo.mat'];
|
tp@0
|
137 end
|
tp@0
|
138
|
tp@0
|
139 %---------------------------------------------------------------
|
tp@0
|
140 % Read in the entire file into the string B
|
tp@0
|
141 % Find the line starts and ends
|
tp@0
|
142
|
tp@0
|
143 fid = fopen([CADfile],'r');
|
tp@0
|
144 if fid == 0
|
tp@0
|
145 error(['ERROR: The CADfile ',CADfile,' could not be opened.'])
|
tp@0
|
146 end
|
tp@0
|
147 B = fread(fid,inf,'char').';
|
tp@0
|
148 fclose(fid);
|
tp@0
|
149
|
tp@0
|
150 % Cut out sequential spaces to save some space.
|
tp@0
|
151 iv = find(B(1:length(B)-1)==32 & B(2:length(B))==32);
|
tp@0
|
152 B(iv) = [];
|
tp@0
|
153
|
tp@0
|
154 % If the text file was generated on a Mac, each line has ASCII 13 at the end.
|
tp@0
|
155 % On a PC, each line ends with ASCII 13, and the next line starts with ASCII 10.
|
tp@0
|
156 % In Unix, each line ends with ASCII 10.
|
tp@0
|
157 %
|
tp@0
|
158 % Change this to a single ASCII 13
|
tp@0
|
159
|
tp@0
|
160 % New 17 Jul 09: use the builtin function regexprep instead:
|
tp@0
|
161
|
tp@0
|
162 % 1. Replace all ASCII 10 by ASCII 13
|
tp@0
|
163
|
tp@0
|
164 B = regexprep(setstr(B),'\n','\r');
|
tp@0
|
165
|
tp@0
|
166 % 2. Cut out sequential CRs (ASCII13) to save some space.
|
tp@0
|
167 iv = find(B(1:length(B)-1)==13 & B(2:length(B))==13);
|
tp@0
|
168 B(iv) = [];
|
tp@0
|
169
|
tp@0
|
170 % 3. Cut out sequences of CR, space, CR because they "survived" the
|
tp@0
|
171 % search for consecutive blanks.
|
tp@0
|
172 iv = find(B(1:length(B)-1)==32 & B(2:length(B))==13);
|
tp@0
|
173 B(iv) = [];
|
tp@0
|
174 iv = find(B(1:length(B)-1)==13 & B(2:length(B))==13);
|
tp@0
|
175 B(iv) = [];
|
tp@0
|
176
|
tp@0
|
177 % 4. Convert all text to lower case
|
tp@0
|
178 B = lower(setstr(B));
|
tp@0
|
179
|
tp@0
|
180 % Some special characters might give negative ASCII values
|
tp@0
|
181 % (Comment by PS 17Jul09: Will this ever happen??)
|
tp@0
|
182
|
tp@0
|
183 iv = find(B<0);
|
tp@0
|
184 if ~isempty(iv)
|
tp@0
|
185 B(iv) = B(iv)+256;
|
tp@0
|
186 end
|
tp@0
|
187
|
tp@0
|
188 %---------------------------------------------------------------
|
tp@0
|
189 % Look for the text 'CATT-Acoustic v' anywhere, and read the numerical
|
tp@0
|
190 % value right after this text.
|
tp@0
|
191
|
tp@0
|
192 iv = regexp(B,'catt-acoustic v');
|
tp@0
|
193
|
tp@0
|
194 if isempty(iv)
|
tp@0
|
195 CATTversionnumber = [];
|
tp@0
|
196 else
|
tp@0
|
197 CATTversionnumber = str2num(setstr(B(iv(1)+15)));
|
tp@0
|
198 end
|
tp@0
|
199
|
tp@0
|
200 %---------------------------------------------------------------
|
tp@0
|
201 % Find the four sections of the file:
|
tp@0
|
202 % %CORNERS %PLANES %SOURCES %RECEIVERS
|
tp@0
|
203 % (or small letters)
|
tp@0
|
204 % We assume that they come in this order
|
tp@0
|
205
|
tp@0
|
206 stringposCORNERS = regexp(B,'%corners');
|
tp@0
|
207 if isempty(stringposCORNERS)
|
tp@0
|
208 error('ERROR: The .cad file must contain the word %CORNERS');
|
tp@0
|
209 end
|
tp@0
|
210
|
tp@0
|
211 stringposPLANES = regexp(B,'%planes');
|
tp@0
|
212 if isempty(stringposPLANES)
|
tp@0
|
213 error('ERROR: The .cad file must contain the word %PLANES');
|
tp@0
|
214 end
|
tp@0
|
215
|
tp@0
|
216 stringposSOURCES = regexp(B,'%sources');
|
tp@0
|
217
|
tp@0
|
218 stringposRECEIVERS = regexp(B,'%receivers');
|
tp@0
|
219
|
tp@0
|
220 %---------------------------------------------------------------
|
tp@0
|
221 % Look for the corners definitions between the lines containing
|
tp@0
|
222 % %SOURCES and another keyword (%PLANES or %SOURCES or %RECEIVERS)
|
tp@0
|
223 % The lines should look like:
|
tp@0
|
224 % 1 -0.2000 0.34 2.3
|
tp@0
|
225
|
tp@0
|
226 if stringposPLANES < stringposCORNERS
|
tp@0
|
227 error('ERROR: Sorry, but in the .cad file, the %CORNERS section must come before the %PLANES section')
|
tp@0
|
228 end
|
tp@0
|
229
|
tp@0
|
230 C = textscan(B(stringposCORNERS:stringposPLANES-1),'%d%f%f%f','Headerlines',1);
|
tp@0
|
231 cornernumbers = (C{1});
|
tp@0
|
232 corners = [C{2} C{3} C{4}];
|
tp@0
|
233 ncorners = length(cornernumbers);
|
tp@0
|
234
|
tp@0
|
235 %---------------------------------------------------------------
|
tp@0
|
236 % Look for the planes definitions between the lines containing
|
tp@0
|
237 % %PLANES and %SOURCES, or the end
|
tp@0
|
238 % The lines should look like:
|
tp@0
|
239 % 1 / planename /RIGID
|
tp@0
|
240 % 1 4 3 2
|
tp@0
|
241 % 2 / /RIGID
|
tp@0
|
242
|
tp@0
|
243 if ~isempty(stringposSOURCES)
|
tp@0
|
244 if stringposSOURCES < stringposPLANES
|
tp@0
|
245 error('ERROR: Sorry, but in the .cad file, the %PLANES section must come before the %SOURCES section')
|
tp@0
|
246 end
|
tp@0
|
247 Str = B(stringposPLANES:stringposSOURCES-1);
|
tp@0
|
248 else
|
tp@0
|
249 Str = B(stringposPLANES:end);
|
tp@0
|
250 end
|
tp@0
|
251
|
tp@0
|
252 % To make it easier with textscan, we put the two types of line onto
|
tp@0
|
253 % a single line, with a new '/' inserted. Then all lines have the same
|
tp@0
|
254 % format.
|
tp@0
|
255
|
tp@0
|
256 % Find all CR and replace every second with a '/'
|
tp@0
|
257 ivendlines = find(Str==13);
|
tp@0
|
258 Str(ivendlines(2:2:end)) = '/';
|
tp@0
|
259
|
tp@0
|
260 C = textscan(Str,'%d%s%s%s','Headerlines',1,'Delimiter','/','BufSize',32768);
|
tp@0
|
261
|
tp@0
|
262 planenumbers = C{1};
|
tp@0
|
263 Str2 = C{2};
|
tp@0
|
264 Str3 = C{3};
|
tp@0
|
265 Str = C{4};
|
tp@0
|
266
|
tp@0
|
267 nplanes = size(Str,1);
|
tp@0
|
268 ncornersperplanevec = zeros(nplanes,1);
|
tp@0
|
269 planecorners = zeros(nplanes,4);
|
tp@0
|
270 planenames = zeros(nplanes,30);
|
tp@0
|
271 planeabstypes = zeros(nplanes,6);
|
tp@0
|
272
|
tp@0
|
273 for ii = 1:nplanes
|
tp@0
|
274 listofplanes = EDB1extrnums(Str{ii});
|
tp@0
|
275 ncornersperplanevec(ii) = length(listofplanes);
|
tp@0
|
276 if ncornersperplanevec(ii) > size(planecorners,2)
|
tp@0
|
277 planecorners = [planecorners zeros(nplanes, ncornersperplanevec(ii)-size(planecorners,2))];
|
tp@0
|
278 end
|
tp@0
|
279 planecorners(ii,1:ncornersperplanevec(ii)) = listofplanes;
|
tp@0
|
280
|
tp@0
|
281 txtstr2 = Str2{ii};
|
tp@0
|
282 if length(txtstr2) > size(planenames,2)
|
tp@0
|
283 planenames = [planenames zeros(nplanes,length(txtstr2)-size(planenames,2))];
|
tp@0
|
284 end
|
tp@0
|
285 planenames(ii,1:length(txtstr2)) = txtstr2;
|
tp@0
|
286
|
tp@0
|
287 txtstr3 = Str3{ii};
|
tp@0
|
288 if length(txtstr3) > size(planeabstypes,2)
|
tp@0
|
289 planeabstypes = [planeabstypes zeros(nplanes,length(txtstr3)-size(planeabstypes,2))];
|
tp@0
|
290 end
|
tp@0
|
291 planeabstypes(ii,1:length(txtstr3)) = txtstr3;
|
tp@0
|
292 end
|
tp@0
|
293
|
tp@0
|
294 if max(max(planecorners)) > max(cornernumbers)
|
tp@0
|
295 error('ERROR: One plane definition in the CAD-file used a higher corner number than was defined in the CORNERS section')
|
tp@0
|
296 end
|
tp@0
|
297
|
tp@0
|
298 %---------------------------------------------------------------
|
tp@0
|
299 % Look for the sources definitions between the lines containing
|
tp@0
|
300 % %SOURCES and %RECEIVERS, or the end
|
tp@0
|
301 % The lines should look like: (v6)
|
tp@0
|
302 % 0 OMNI:SD0
|
tp@0
|
303 % 0.0000000 0.0000000 1.0000000
|
tp@0
|
304 % 0.0000000 0.0000000 0.0000000
|
tp@0
|
305 % 85.0 88.0 91.0 94.0 97.0 100.0
|
tp@0
|
306 %
|
tp@0
|
307 % or: (v7)
|
tp@0
|
308 % A0 OMNI:SD0
|
tp@0
|
309 % 0.0000000 0.0000000 1.0000000
|
tp@0
|
310 % 0.0000000 0.0000000 0.0000000 15.00000
|
tp@0
|
311 % 85.0 88.0 91.0 94.0 97.0 100.0 : 103.0 106.0
|
tp@0
|
312
|
tp@0
|
313 if ~isempty(stringposSOURCES)
|
tp@0
|
314
|
tp@0
|
315 if ~isempty(stringposRECEIVERS)
|
tp@0
|
316 if stringposRECEIVERS < stringposSOURCES
|
tp@0
|
317 error('ERROR: Sorry, but in the .cad file, the %SOURCES section must come before the %RECEIVERS section')
|
tp@0
|
318 end
|
tp@0
|
319 Str = B(stringposSOURCES:stringposRECEIVERS-1);
|
tp@0
|
320 else
|
tp@0
|
321 Str = B(stringposSOURCES:end);
|
tp@0
|
322 end
|
tp@0
|
323
|
tp@0
|
324 % To make it easier with textscan, we put the four types of line onto
|
tp@0
|
325 % a single line, with new '/' inserted. Then all lines have the same
|
tp@0
|
326 % format.
|
tp@0
|
327 % Find all CR and replace number 2,3,4, 6,7,8, etc with a '/'
|
tp@0
|
328
|
tp@0
|
329 ivendlines = find(Str==13);
|
tp@0
|
330 ivkeep = [1:4:length(ivendlines)];
|
tp@0
|
331 ivremove = [1:length(ivendlines)];
|
tp@0
|
332 ivremove(ivkeep) = [];
|
tp@0
|
333 Str(ivendlines(ivremove)) = '/';
|
tp@0
|
334
|
tp@0
|
335 C = textscan(Str,'%s%s%s%s','Headerlines',1,'Delimiter','/');
|
tp@0
|
336
|
tp@0
|
337 nsources = size( C{1},1 );
|
tp@0
|
338 Scoords = zeros(nsources,3);
|
tp@0
|
339 Sdirections = zeros(nsources,3);
|
tp@0
|
340 Srotations = zeros(nsources,1);
|
tp@0
|
341 Slevels = zeros(nsources,8);
|
tp@0
|
342 Snumbers = zeros(nsources,1);
|
tp@0
|
343 Snames = zeros(nsources,4);
|
tp@0
|
344 Sdirectivitynames = ( zeros(nsources,30) );
|
tp@0
|
345 Sdelays = zeros(nsources,1);
|
tp@0
|
346
|
tp@0
|
347 Str1 = C{1};
|
tp@0
|
348 Str2 = C{2};
|
tp@0
|
349 Str3 = C{3};
|
tp@0
|
350 Str4 = C{4};
|
tp@0
|
351 for ii = 1:nsources
|
tp@0
|
352 Scoords(ii,:) = EDB1extrnums(Str2{ii});
|
tp@0
|
353 listofvalues3 = EDB1extrnums(Str3{ii});
|
tp@0
|
354 listofvalues4 = EDB1extrnums(Str4{ii});
|
tp@0
|
355 if ii==1
|
tp@0
|
356 if length(listofvalues3)==3
|
tp@0
|
357 CATTversionnumber = 6;
|
tp@0
|
358 elseif length(listofvalues3)==4
|
tp@0
|
359 CATTversionnumber = 7;
|
tp@0
|
360 else
|
tp@0
|
361 error('ERROR: The source data should have three or four values for the direction')
|
tp@0
|
362 end
|
tp@0
|
363 end
|
tp@0
|
364
|
tp@0
|
365 Sdirections(ii,1:3) = listofvalues3(1:3);
|
tp@0
|
366
|
tp@0
|
367 % The first field contains three items which are a mix of text and numerical values.
|
tp@0
|
368 % First we remove possible consecutive blanks.
|
tp@0
|
369 textstr = Str1{ii};
|
tp@0
|
370 iv = find(textstr(1:length(textstr)-1)==32 & textstr(2:length(textstr))==32);
|
tp@0
|
371 textstr(iv) = [];
|
tp@0
|
372 iv = find(textstr==32);
|
tp@0
|
373
|
tp@0
|
374
|
tp@0
|
375 if CATTversionnumber == 7
|
tp@0
|
376 Srotations(ii) = listofvalues3(4);
|
tp@0
|
377 Snames(ii,1:length(textstr(1:iv(1)-1))) = textstr(1:iv(1)-1);
|
tp@0
|
378 Sdirectivitynames(ii,1:iv(2)-iv(1)-1) = textstr(iv(1)+1:iv(2)-1);
|
tp@0
|
379 Sdelays(ii) = str2num( textstr(iv(2)+1:end) );
|
tp@0
|
380 else
|
tp@0
|
381 Snumbers(ii) = str2num( textstr(1:iv(1)-1) );
|
tp@0
|
382 Sdirectivitynames(ii,1:length(textstr(iv(1)+1:end))) = textstr(iv(1)+1:end);
|
tp@0
|
383 end
|
tp@0
|
384 Slevels(ii,1:length(listofvalues4)) = listofvalues4;
|
tp@0
|
385 end
|
tp@0
|
386 Snames = setstr(Snames);
|
tp@0
|
387 Sdirectivitynames = setstr(Sdirectivitynames);
|
tp@0
|
388
|
tp@0
|
389 else
|
tp@0
|
390
|
tp@0
|
391 Scoords = [];
|
tp@0
|
392 Sdirections = [];
|
tp@0
|
393 Srotations = [];
|
tp@0
|
394 Slevels = [];
|
tp@0
|
395 Snumbers = [];
|
tp@0
|
396 Snames = [];
|
tp@0
|
397 Sdirectivitynames = [];
|
tp@0
|
398 Sdelays = [];
|
tp@0
|
399
|
tp@0
|
400 end
|
tp@0
|
401
|
tp@0
|
402 %---------------------------------------------------------------
|
tp@0
|
403 % Look for the receivers definitions after the line containing
|
tp@0
|
404 % %RECEIVERS
|
tp@0
|
405 % The lines should look like:
|
tp@0
|
406 % 1 -0.2000 0.34 2.3
|
tp@0
|
407
|
tp@0
|
408 if ~isempty(stringposRECEIVERS)
|
tp@0
|
409 C = textscan(B(stringposRECEIVERS:end),'%d%f%f%f','Headerlines',1);
|
tp@0
|
410 Rnumbers = (C{1});
|
tp@0
|
411 Rcoords= [C{2} C{3} C{4}];
|
tp@0
|
412 else
|
tp@0
|
413 Rnumbers = [];
|
tp@0
|
414 Rcoords = [];
|
tp@0
|
415 end
|
tp@0
|
416
|
tp@0
|
417 %---------------------------------------------------------------
|
tp@0
|
418 % Change the numbering in the CAD file to a contiguous one
|
tp@0
|
419
|
tp@0
|
420 % Corner numbers
|
tp@0
|
421 % First we make an inelegant crossreference vector giving the
|
tp@0
|
422 % resulting corner number in the position given by the CAD-file
|
tp@0
|
423 % corner number.
|
tp@0
|
424
|
tp@0
|
425 maxnumb = max(cornernumbers);
|
tp@0
|
426 cornercrossref = sparse(zeros(1,maxnumb));
|
tp@0
|
427
|
tp@0
|
428 % Temporary fix: if one corner has the number zero, then we make a
|
tp@0
|
429 % separate crossref variable for that one.
|
tp@0
|
430 if cornernumbers(1) == 0
|
tp@0
|
431 cornercrossrefzero = 1;
|
tp@0
|
432 cornercrossref(cornernumbers(2:end)) = [2:ncorners];
|
tp@0
|
433 else
|
tp@0
|
434 cornercrossrefzero = [];
|
tp@0
|
435 cornercrossref(cornernumbers) = [1:ncorners];
|
tp@0
|
436 end
|
tp@0
|
437
|
tp@0
|
438 [nplanes,ncornersperplane] = size(planecorners);
|
tp@0
|
439
|
tp@0
|
440 planecorners_CATTnumbers = planecorners;
|
tp@0
|
441
|
tp@0
|
442 iv = find(planecorners_CATTnumbers~=0);
|
tp@0
|
443 planecorners(iv) = full(cornercrossref(planecorners(iv)));
|
tp@0
|
444 iv = find(planecorners_CATTnumbers==0);
|
tp@0
|
445 planecorners(iv) = cornercrossrefzero;
|
tp@0
|
446
|
tp@0
|
447 %---------------------------------------------------------------
|
tp@0
|
448 % Go through all planes. If there is a plane definition including
|
tp@0
|
449 % zeros, and planecornerstype == 'circ', expand it repeating the
|
tp@0
|
450 % same corner order again.
|
tp@0
|
451
|
tp@0
|
452 if isempty(planecornerstype)
|
tp@0
|
453 planecornerstype = 'circ';
|
tp@0
|
454 else
|
tp@0
|
455 planecornerstype = setstr(lower(planecornerstype(1)));
|
tp@0
|
456 if planecornerstype(1) == 'z'
|
tp@0
|
457 planecornerstype = 'zero';
|
tp@0
|
458 else
|
tp@0
|
459 planecornerstype = 'circ';
|
tp@0
|
460 end
|
tp@0
|
461 end
|
tp@0
|
462
|
tp@0
|
463 if planecornerstype == 'circ'
|
tp@0
|
464 for ii = 1:nplanes
|
tp@0
|
465 iv = find( planecorners(ii,:) ~= 0);
|
tp@0
|
466 ncornersatplane = length(iv);
|
tp@0
|
467 if ncornersatplane ~= ncornersperplane
|
tp@0
|
468 pattern = planecorners(ii,iv);
|
tp@0
|
469 nrepeatings = ceil(ncornersperplane/ncornersatplane);
|
tp@0
|
470 for jj = 1:nrepeatings-1
|
tp@0
|
471 pattern = [pattern planecorners(ii,iv)];
|
tp@0
|
472 end
|
tp@0
|
473 planecorners(ii,:) = pattern(1:ncornersperplane);
|
tp@0
|
474 end
|
tp@0
|
475 end
|
tp@0
|
476 end
|
tp@0
|
477
|
tp@0
|
478 %---------------------------------------------------------------
|
tp@0
|
479 % Find the normal vectors to the planes using the cross products
|
tp@0
|
480 %
|
tp@0
|
481 % The normal vector is basically the cross product between two vectors
|
tp@0
|
482 % connecting three consecutive points. If there are indents though
|
tp@0
|
483 % they will cause reversed normal vectors, so one must go through all
|
tp@0
|
484 % combinations and choose the majority normal vector.
|
tp@0
|
485 %
|
tp@0
|
486 % 26mar09 Use the fact described above for detecting indention corners
|
tp@0
|
487
|
tp@0
|
488 planenvecs = zeros(nplanes,3);
|
tp@0
|
489 planehasindents = zeros(nplanes,1);
|
tp@0
|
490 indentingcorners = sparse(zeros(nplanes,max(ncornersperplanevec)));
|
tp@0
|
491
|
tp@0
|
492 for ii = 1:nplanes
|
tp@0
|
493
|
tp@0
|
494 iv = find(planecorners(ii,:)~=0);
|
tp@0
|
495 cornerlist = planecorners(ii,iv);
|
tp@0
|
496 iv = find(cornerlist == cornerlist(1));
|
tp@0
|
497 if length(iv) > 1
|
tp@0
|
498 cornerlist = cornerlist(1:iv(2)-1);
|
tp@0
|
499 end
|
tp@0
|
500 ncorners = length( cornerlist );
|
tp@0
|
501 cornerlist = [cornerlist cornerlist(1) cornerlist(2)];
|
tp@0
|
502
|
tp@0
|
503 nvectorlist = zeros(ncorners,3);
|
tp@0
|
504 nveclen = zeros(ncorners,1);
|
tp@0
|
505
|
tp@0
|
506 for jj = 1:ncorners
|
tp@0
|
507 co1numb = cornerlist(jj);
|
tp@0
|
508 co2numb = cornerlist(jj+1);
|
tp@0
|
509 co3numb = cornerlist(jj+2);
|
tp@0
|
510 vec1 = corners(co1numb,:) - corners(co2numb,:);
|
tp@0
|
511 vec2 = corners(co3numb,:) - corners(co2numb,:);
|
tp@0
|
512 nvec = EDB1cross(vec1.',vec2.').';
|
tp@0
|
513 nveclen(jj) = norm(nvec);
|
tp@0
|
514 if nveclen(jj) > 0
|
tp@0
|
515 nvectorlist(jj,:) = nvec./nveclen(jj);
|
tp@0
|
516 end
|
tp@0
|
517 end
|
tp@0
|
518
|
tp@0
|
519 iv = find(nveclen < max(nveclen)*0.001);
|
tp@0
|
520 nvectorlist(iv,:) = [];
|
tp@0
|
521 nvecref = nvectorlist(1,:);
|
tp@0
|
522
|
tp@0
|
523 [n1,slask] = size(nvectorlist);
|
tp@0
|
524 nvecsigns = round(sum( (nvectorlist.').*(nvecref(ones(n1,1),:).') ));
|
tp@0
|
525
|
tp@0
|
526 if sum(nvecsigns) == 0
|
tp@0
|
527 disp(' ')
|
tp@0
|
528 error(['ERROR: Plane ',int2str(planenumbers(ii)),' (plane numbering as in the CAD file) seems to be twisted.'])
|
tp@0
|
529 end
|
tp@0
|
530
|
tp@0
|
531
|
tp@0
|
532 if abs(sum(nvecsigns)) ~= n1
|
tp@0
|
533 disp(['Plane ',int2str(ii),' has indents!'])
|
tp@0
|
534 nindents = (n1 - abs(sum(nvecsigns)))/2;
|
tp@0
|
535 planehasindents(ii) = nindents;
|
tp@0
|
536 ivindent = find(nvecsigns == -1);
|
tp@0
|
537 if length(ivindent) == nindents
|
tp@0
|
538 indentingcorners(ii,ivindent) = 1;
|
tp@0
|
539 else
|
tp@0
|
540 if length(ivindent) == ncorners - nindents
|
tp@0
|
541 ivindent = find(nvecsigns == 1);
|
tp@0
|
542 indentingcorners(ii,ivindent) = 1;
|
tp@0
|
543 else
|
tp@0
|
544 error(['ERROR: An unexpected problem. Please report to the developer'])
|
tp@0
|
545 end
|
tp@0
|
546 end
|
tp@0
|
547 end
|
tp@0
|
548
|
tp@0
|
549 nvecdiff = [nvectorlist(2:n1,1).*nvecsigns(2:n1).' nvectorlist(2:n1,2).*nvecsigns(2:n1).' nvectorlist(2:n1,3).*nvecsigns(2:n1).'] - nvecref(ones(n1-1,1),:);
|
tp@0
|
550
|
tp@0
|
551 if n1 > 2
|
tp@0
|
552 nvecdiff = sum(nvecdiff.'.^2).';
|
tp@0
|
553 else
|
tp@0
|
554 nvecdiff = norm(nvecdiff);
|
tp@0
|
555 end
|
tp@0
|
556 if any(nvecdiff>1e-4),
|
tp@0
|
557 nvecdiff
|
tp@0
|
558 error(['ERROR: Normal vectors for plane ',int2str(planenumbers(ii)),' (in the CAD file, = ',int2str(ii),' in the EDB1 file), get different normal vectors for consecutive corner triplets. Check the geometry in the CAD-file'])
|
tp@0
|
559 elseif any(nvecdiff>1e-8)
|
tp@0
|
560 nvecdiff
|
tp@0
|
561 disp(['WARNING: Normal vectors for plane ',int2str(planenumbers(ii)),' (in the CAD file, = ',int2str(ii),' in the EDB1 file), get somewhat different normal vectors for consecutive corner triplets. Check the geometry in the CAD-file'])
|
tp@0
|
562 end
|
tp@0
|
563
|
tp@0
|
564 if ncorners > 5 & abs(sum(nvecsigns)) <= 1
|
tp@0
|
565 disp(['WARNING for plane number ',int2str(planenumbers(ii)),' in the CAD-file'])
|
tp@0
|
566 disp([' with the name ',strtrim(setstr(full(planenames(ii,:))))])
|
tp@0
|
567 disp(' The normal vector can not be determined for this plane because there are')
|
tp@0
|
568 disp(' the same number of inwards and outwards corners')
|
tp@0
|
569 disp(' This is a list of the possible normal vectors:')
|
tp@0
|
570 [nv1,slask] = size(nvectorlist);
|
tp@0
|
571 for kk = 1:nv1
|
tp@0
|
572 vecstr = [' ',int2str(kk),'. ',num2str(-nvectorlist(kk,1)),' ',num2str(-nvectorlist(kk,2)),' ',num2str(-nvectorlist(kk,3))];
|
tp@0
|
573 disp(vecstr)
|
tp@0
|
574 end
|
tp@0
|
575 disp(' ')
|
tp@0
|
576
|
tp@0
|
577 preferredsign = input(' Give the number of a correct normal vector for this plane please ');
|
tp@0
|
578 switchsign = nvecsigns.'./nvecsigns(preferredsign);
|
tp@0
|
579 nvectorlist = nvectorlist.*switchsign(:,ones(1,3));
|
tp@0
|
580 else
|
tp@0
|
581 mostcommonsign = sign(sum(nvecsigns));
|
tp@0
|
582
|
tp@0
|
583 switchsign = nvecsigns.'./mostcommonsign;
|
tp@0
|
584 nvectorlist = nvectorlist.*switchsign(:,ones(1,3));
|
tp@0
|
585 end
|
tp@0
|
586
|
tp@0
|
587 planenvecs(ii,:) = mean(nvectorlist);
|
tp@0
|
588 end
|
tp@0
|
589
|
tp@0
|
590 planenvecs = -planenvecs;
|
tp@0
|
591
|
tp@0
|
592 %---------------------------------------------------------------
|
tp@0
|
593 % Plane equations, as Ax + By + Cz = D for each plane
|
tp@0
|
594
|
tp@0
|
595 planeeqs = zeros(nplanes,4);
|
tp@0
|
596 planeeqs(:,1:3) = planenvecs;
|
tp@0
|
597 planeeqs(:,4) = sum( (planenvecs.').*(corners(planecorners(:,1),:).') ).';
|
tp@0
|
598
|
tp@0
|
599 %---------------------------------------------------------------
|
tp@0
|
600 % Useful data: planesatcorners, minvals and maxvals
|
tp@0
|
601
|
tp@0
|
602 [ncorners,slask] = size(corners);
|
tp@0
|
603 planesatcornerhits = zeros(ncorners,nplanes);
|
tp@0
|
604
|
tp@0
|
605 for ii = 1:nplanes
|
tp@0
|
606 cornerlist = planecorners(ii,1:ncornersperplanevec(ii));
|
tp@0
|
607 planesatcornerhits(cornerlist,ii) = planesatcornerhits(cornerlist,ii) + 1;
|
tp@0
|
608 end
|
tp@0
|
609
|
tp@0
|
610 maxplanespercorner = 0;
|
tp@0
|
611 for ii = 1:ncorners
|
tp@0
|
612 nplanes = length(find(planesatcornerhits(ii,:) ~= 0));
|
tp@0
|
613 if nplanes > maxplanespercorner
|
tp@0
|
614 maxplanespercorner = nplanes;
|
tp@0
|
615 end
|
tp@0
|
616 end
|
tp@0
|
617
|
tp@0
|
618 planesatcorners = zeros(ncorners,maxplanespercorner);
|
tp@0
|
619 nplanespercorners = zeros(ncorners,1);
|
tp@0
|
620 for ii = 1:ncorners
|
tp@0
|
621 iv = find(planesatcornerhits(ii,:)~=0);
|
tp@0
|
622 planesatcorners(ii,1:length(iv)) = iv;
|
tp@0
|
623 nplanespercorners(ii) = length(iv);
|
tp@0
|
624 end
|
tp@0
|
625
|
tp@0
|
626 % find cubic boxes inside which the planes are placed
|
tp@0
|
627
|
tp@0
|
628 [nplanes,slask] = size(planeeqs);
|
tp@0
|
629
|
tp@0
|
630 minvals = zeros(nplanes,3);
|
tp@0
|
631 maxvals = zeros(nplanes,3);
|
tp@0
|
632
|
tp@0
|
633 for ii = 1:nplanes
|
tp@0
|
634 cornerlist = planecorners(ii,:);
|
tp@0
|
635 cornerlist = cornerlist( find(cornerlist~= 0) );
|
tp@0
|
636 cornercoord = corners(cornerlist,:);
|
tp@0
|
637 minvals(ii,:) = min(cornercoord);
|
tp@0
|
638 maxvals(ii,:) = max(cornercoord);
|
tp@0
|
639 end
|
tp@0
|
640
|
tp@0
|
641 minvals = minvals - geomacc;
|
tp@0
|
642 maxvals = maxvals + geomacc;
|
tp@0
|
643
|
tp@0
|
644 %---------------------------------------------------------------
|
tp@0
|
645 % Check the geometry a bit
|
tp@0
|
646
|
tp@0
|
647 if isempty(checkgeom)
|
tp@0
|
648 checkgeom = 0;
|
tp@0
|
649 else
|
tp@0
|
650 if setstr(checkgeom(1)) == 'c'
|
tp@0
|
651 checkgeom = 1;
|
tp@0
|
652 else
|
tp@0
|
653 checkgeom = 0;
|
tp@0
|
654 end
|
tp@0
|
655 end
|
tp@0
|
656
|
tp@0
|
657 if checkgeom
|
tp@0
|
658
|
tp@0
|
659 badproblem = 0;
|
tp@0
|
660 disp(' ')
|
tp@0
|
661 disp(' Checking if there are corners with identical coordinates')
|
tp@0
|
662 for ii = 1:ncorners-1
|
tp@0
|
663 othercorners = [ii+1:ncorners];
|
tp@0
|
664 iv = find((corners(othercorners,1)==corners(ii,1)) & (corners(othercorners,2)==corners(ii,2)) & (corners(othercorners,3)==corners(ii,3)));
|
tp@0
|
665 if ~isempty(iv)
|
tp@0
|
666 disp([' WARNING: corner ',int2str(ii),' and ',int2str(othercorners(iv(1))),' have the same coordinates'])
|
tp@0
|
667 disp([' This should be fixed in the CAD-file or in the CATT-model'])
|
tp@0
|
668 badproblem = 1;
|
tp@0
|
669 end
|
tp@0
|
670 end
|
tp@0
|
671
|
tp@0
|
672 disp(' Checking if there are unused corners')
|
tp@0
|
673 iv = find(planesatcorners(:,1)==0);
|
tp@0
|
674 if ~isempty(iv)
|
tp@0
|
675 disp(' WARNING: The following corners in the CAD-file are not used:')
|
tp@0
|
676 printvec = int2str(cornernumbers(iv(1)));
|
tp@0
|
677 for iiprint = 2:length(iv)
|
tp@0
|
678 printvec = [printvec,' ',int2str(cornernumbers(iv(iiprint)))];
|
tp@0
|
679 end
|
tp@0
|
680 disp([' ',printvec])
|
tp@0
|
681 disp([' This is not a big problem'])
|
tp@0
|
682 planesatcorners(iv,:) = [];
|
tp@0
|
683 end
|
tp@0
|
684
|
tp@0
|
685 disp(' Checking if any corners seem redundant')
|
tp@0
|
686 iv = find(planesatcorners(:,2)==0);
|
tp@0
|
687 if ~isempty(iv)
|
tp@0
|
688 disp(' WARNING: The following corners in the CAD-file belong to only one plane:')
|
tp@0
|
689 printvec = int2str(cornernumbers(iv(1)));
|
tp@0
|
690 for iiprint = 2:length(iv)
|
tp@0
|
691 printvec = [printvec,' ',int2str(cornernumbers(iv(iiprint)))];
|
tp@0
|
692 end
|
tp@0
|
693 disp([' ',printvec])
|
tp@0
|
694 disp([' This should be fixed in the CAD-file or in the CATT-model'])
|
tp@0
|
695 badproblem = 1;
|
tp@0
|
696 end
|
tp@0
|
697
|
tp@0
|
698 if badproblem == 1
|
tp@0
|
699 disp(' ');
|
tp@0
|
700 error(['ERROR: Problems with the geometry defined in the CAD-file: ',CADfile])
|
tp@0
|
701 end
|
tp@0
|
702
|
tp@0
|
703 end
|
tp@0
|
704
|
tp@0
|
705 %---------------------------------------------------------------
|
tp@0
|
706 % Save the relevant variables in the output file
|
tp@0
|
707
|
tp@0
|
708 % NB! Sparse matrices can not get a non-double format
|
tp@0
|
709
|
tp@0
|
710 if ncorners < 256
|
tp@0
|
711 planecorners = uint8(planecorners);
|
tp@0
|
712 elseif ncorners < 65536
|
tp@0
|
713 planecorners = uint16(planecorners);
|
tp@0
|
714 end
|
tp@0
|
715
|
tp@0
|
716 if max(ncornersperplanevec) <= 255
|
tp@0
|
717 ncornersperplanevec = uint8(ncornersperplanevec);
|
tp@0
|
718 planehasindents = uint8(planehasindents);
|
tp@0
|
719 else
|
tp@0
|
720 ncornersperplanevec = uint16(ncornersperplanevec);
|
tp@0
|
721 planehasindents = uint16(planehasindents);
|
tp@0
|
722 end
|
tp@0
|
723
|
tp@0
|
724 Varlist = [' corners cornernumbers planecorners planenames planeabstypes '];
|
tp@0
|
725 Varlist = [Varlist,' planenumbers cornercrossref cornercrossrefzero Snumbers Snames Sdirectivitynames Sdelays'];
|
tp@0
|
726 Varlist = [Varlist,' Scoords Sdirections Srotations Slevels Rnumbers Rcoords CATTversionnumber'];
|
tp@0
|
727 Varlist = [Varlist,' planeeqs planenvecs ncornersperplanevec planesatcorners nplanespercorners'];
|
tp@0
|
728 Varlist = [Varlist,' minvals maxvals planehasindents indentingcorners'];
|
tp@0
|
729
|
tp@0
|
730 planenames = sparse(planenames+1-1);
|
tp@0
|
731 planeabstypes = sparse(planeabstypes+1-1);
|
tp@0
|
732 Sdirectivitynames = sparse(Sdirectivitynames+1-1);
|
tp@0
|
733
|
tp@0
|
734 eval(['save ',outputfile,Varlist])
|