tp@0
|
1 function [outputfile] = EDB1readac(CADfile,outputfile,planecornerstype,checkgeom)
|
tp@0
|
2 % EDB1readac - Reads a file of type .AC (made by e.g. Invis AC3D) and saves all the geometry data in a mat-file.
|
tp@0
|
3 %
|
tp@0
|
4 % Input parameters:
|
tp@0
|
5 % CADfile (optional) The input file, with or without the .AC extension.
|
tp@0
|
6 % If this file is not specified, a file opening window will appear.
|
tp@0
|
7 % outputfile (optional) The output file. If not specified, it will be given the
|
tp@0
|
8 % same name as the CAD file with an '_cadgeo.mat' ending instead of the '.AC'.
|
tp@0
|
9 % planecornerstype (optional) Could have the value 'zero' or 'circ'.Default: 'circ'.
|
tp@0
|
10 % Affects the matrix planecorners, see below.
|
tp@0
|
11 % checkgeom (optional) If this parameter is given the value 'check', then a few checks
|
tp@0
|
12 % of the geometry consistency will be done: a check for duplicate corners
|
tp@0
|
13 % for redundant corners and for corners that are connected to only one plane.
|
tp@0
|
14 % Only warnings are given. As default, no check is done.
|
tp@0
|
15 % SHOWTEXT (global) If this global parameter has the value 3 or higher, informative text will
|
tp@0
|
16 % be printed on the screen.
|
tp@0
|
17 %
|
tp@0
|
18 % Output parameters:
|
tp@0
|
19 % outputfile The name of the outputfile, generated either automatically or specified as
|
tp@0
|
20 % an input parameter.
|
tp@0
|
21 %
|
tp@0
|
22 % Output parameters in the outputfile:
|
tp@0
|
23 % corners Matrix [ncorners,3] with the corner coordinates
|
tp@0
|
24 % cornernumbers Vector [ncorners,1] with the corner numbers used in the CAD-file. That is
|
tp@0
|
25 % in the outputfile, the corners will effectively be renumbered from 1 to ncorners
|
tp@0
|
26 % in the order they appeared in the CAD-file.
|
tp@0
|
27 % planecorners Matrix [planes,nmaxcornersperplane] with the corner numbers that make up each plane.
|
tp@0
|
28 % Since planes can have different numbers of corners, the number of columns is the
|
tp@0
|
29 % maximum number of corners that any plane has. NB! The corner numbers are in the
|
tp@0
|
30 % renumbered system, not in the CAD-file system.
|
tp@0
|
31 % planenames Matrix [nplanes,nmaxcharacters1] (sparse), with the planenames in the CAD file.
|
tp@0
|
32 % planeabstypes Matrix [nplanes,nmaxcharacters2] (sparse), with the absorber names in the CAD file.
|
tp@0
|
33 % planenumbers Vector [nplanes,1] with the plane numbers used in the CAD file.
|
tp@0
|
34 % cornercrossref Vector [nmaxnumberinCADfile,1] (sparse), which gives the matlab-file corner
|
tp@0
|
35 % numbers for each CAD-file corner number. For instance, if a CAD-file corner
|
tp@0
|
36 % number 1200 is translated to corner number 72 in the matlab-file, then
|
tp@0
|
37 % cornercrossref(1000) = 72.
|
tp@0
|
38 % Snumbers Vector [nsources,1] of the source numbers in the CAD-file. NB! Only CAD-files
|
tp@0
|
39 % v6 use source numbers; later versions use source names instead of numbers.
|
tp@0
|
40 % For CAD-file v7 and v8, Snumbers is empty.
|
tp@0
|
41 % Snames Matrix [nsources,2] of the source names in the CAD-file. NB! Only CAD-files v7
|
tp@0
|
42 % or later use source names (such as 'A0' etc). Older versions use source numbers,
|
tp@0
|
43 % in which case Snames is empty.
|
tp@0
|
44 % Sdirectivitynames Matrix [nsources,nmaxcharacters3] (sparse) with the source directivity names
|
tp@0
|
45 % in the CAD file.
|
tp@0
|
46 % Sdelays Vector [nsources,1] of the source delays in the CAD-file, in milliseconds.
|
tp@0
|
47 % Scoords Matrix [nsources,3] of the source coordinates.
|
tp@0
|
48 % Sdirections Matrix [nsources,3] of the aim point coordinates for the sources.
|
tp@0
|
49 % Srotations Vector [nsources,1] of the source rotations, in degrees.
|
tp@0
|
50 % Slevels Matrix [nsources,6/8] of the source levels for six (CAD-files v6) or eight
|
tp@0
|
51 % octave bands (CAD-files v7 or later).
|
tp@0
|
52 % Rnumbers Vector [nreceivers,1] of the receiver numbers in the CAD-file.
|
tp@0
|
53 % Rcoords Matrix [nreceivers,3] of the receiver coordinates.
|
tp@0
|
54 % CATTversionnumber 6,7 or 8
|
tp@0
|
55 % planeeqs Matrix [nplanes,4] of the plane equations as derived from the plane definitions.
|
tp@0
|
56 % Each row has the values [A B C D] of the plane equation on the form Ax + By + Cz = D
|
tp@0
|
57 % planenvecs Matrix [nplanes,3] of the normalized normal vectors of the planes.
|
tp@0
|
58 % ncornersperplanevec Vector [nplanes,1] which gives the number of corners for each plane.
|
tp@0
|
59 % planesatcorners Matrix [ncorners,4] which gives the plane numbers that each corner is connected to.
|
tp@0
|
60 % NB! Here it is assumed that each corner is connected to maximum four planes.
|
tp@0
|
61 % nplanespercorners Vector [ncorners,1] which gives the number of planes that each corner is connected to.
|
tp@0
|
62 % minvals Matrix [nplanes,3] which for each plane gives the smallest coordinate in the x-, y- and z-direction.
|
tp@0
|
63 % maxvals Matrix [nplanes,3] which for each plane gives the largest coordinate in the x-, y- and z-direction.
|
tp@0
|
64 % planehasindents Vector [nplanes,1] which for each plane gives the
|
tp@0
|
65 % number of indeting corners
|
tp@0
|
66 % indentingcorners Matrix [nplanes,max(ncornersperplanevec)] which for each plane gives the number to the first corner
|
tp@0
|
67 % in a corner triplet which identifies an indenting corner. The number of the corner is the
|
tp@0
|
68 % order given in planecorners for that plane.
|
tp@0
|
69 %
|
tp@0
|
70 % Uses the functions EDB1fistr, EDB1extrnums, EDB1cross
|
tp@0
|
71 %
|
tp@0
|
72 % ----------------------------------------------------------------------------------------------
|
tp@0
|
73 % This file is part of the Edge Diffraction Toolbox by Peter Svensson.
|
tp@0
|
74 %
|
tp@0
|
75 % The Edge Diffraction Toolbox is free software: you can redistribute it and/or modify
|
tp@0
|
76 % it under the terms of the GNU General Public License as published by the Free Software
|
tp@0
|
77 % Foundation, either version 3 of the License, or (at your option) any later version.
|
tp@0
|
78 %
|
tp@0
|
79 % The Edge Diffraction Toolbox is distributed in the hope that it will be useful,
|
tp@0
|
80 % but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
tp@0
|
81 % FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
tp@0
|
82 %
|
tp@0
|
83 % You should have received a copy of the GNU General Public License along with the
|
tp@0
|
84 % Edge Diffraction Toolbox. If not, see <http://www.gnu.org/licenses/>.
|
tp@0
|
85 % ----------------------------------------------------------------------------------------------
|
tp@0
|
86 % Peter Svensson (svensson@iet.ntnu.no) 18Jul09
|
tp@0
|
87 %
|
tp@0
|
88 % ----------------------------------------------------------------------------------------------
|
tp@0
|
89 % This File is created based on EDB1eadcad.m to support the Edge Diffraction Toolbox
|
tp@0
|
90 % ----------------------------------------------------------------------------------------------
|
tp@0
|
91 % Alexander Pohl (alexander.pohl@hcu-hamburg.de) 25May2011
|
tp@0
|
92 %
|
tp@0
|
93 % [outputfile] = EDB1readac(CADfile,outputfile,planecornerstype,checkgeom);
|
tp@0
|
94
|
tp@0
|
95 % Modified by Peter Svensson on 3Dec2011
|
tp@0
|
96
|
tp@0
|
97 global SHOWTEXT
|
tp@0
|
98
|
tp@0
|
99 if nargin == 0
|
tp@0
|
100 CADfile = '';
|
tp@0
|
101 outputfile = '';
|
tp@0
|
102 planecornerstype = '';
|
tp@0
|
103 checkgeom = '';
|
tp@0
|
104 elseif nargin == 1
|
tp@0
|
105 outputfile = '';
|
tp@0
|
106 planecornerstype = '';
|
tp@0
|
107 checkgeom = '';
|
tp@0
|
108 elseif nargin == 2
|
tp@0
|
109 planecornerstype = '';
|
tp@0
|
110 checkgeom = '';
|
tp@0
|
111 elseif nargin == 3
|
tp@0
|
112 checkgeom = '';
|
tp@0
|
113 end
|
tp@0
|
114
|
tp@0
|
115 geomacc = 1e-10;
|
tp@0
|
116
|
tp@0
|
117 %---------------------------------------------------------------
|
tp@0
|
118 % If no AC-file was specified, present a file opening window
|
tp@0
|
119
|
tp@0
|
120 if isempty(CADfile)
|
tp@0
|
121 [CADfile,filepath] = uigetfile('*.ac','Please select the AC3Dfile');
|
tp@0
|
122
|
tp@0
|
123 [filepath,temp1] = fileparts(filepath);
|
tp@0
|
124
|
tp@0
|
125 if ~isstr(CADfile)
|
tp@0
|
126 return
|
tp@0
|
127 end
|
tp@0
|
128
|
tp@0
|
129 [temp1,filestem] = fileparts(CADfile);
|
tp@0
|
130
|
tp@0
|
131
|
tp@0
|
132 CADfile = [[filepath,filesep],filestem,'.ac'];
|
tp@0
|
133 else
|
tp@0
|
134
|
tp@0
|
135 [filepath,filestem,fileext] = fileparts(CADfile);
|
tp@0
|
136 CADfile = [[filepath,filesep],filestem,fileext];
|
tp@0
|
137 end
|
tp@0
|
138
|
tp@0
|
139
|
tp@0
|
140 if exist(CADfile) ~= 2
|
tp@0
|
141 error(['ERROR: AC3D-file: ',CADfile,' can not be found'])
|
tp@0
|
142 end
|
tp@0
|
143
|
tp@0
|
144 %---------------------------------------------------------------
|
tp@0
|
145 % If no output file was specified, construct an automatic file name
|
tp@0
|
146
|
tp@0
|
147 if isempty(outputfile)
|
tp@0
|
148 outputfile = [[filepath,filesep],filestem,'_cadgeo.mat'];
|
tp@0
|
149 end
|
tp@0
|
150
|
tp@0
|
151 %---------------------------------------------------------------
|
tp@0
|
152 % Read in the entire file into the string B
|
tp@0
|
153 % Find the line starts and ends
|
tp@0
|
154
|
tp@0
|
155 fid = fopen([CADfile],'r');
|
tp@0
|
156 if fid == 0
|
tp@0
|
157 error(['ERROR: The AC3Dfile ',CADfile,' could not be opened.'])
|
tp@0
|
158 end
|
tp@0
|
159
|
tp@0
|
160 %---------------------------------------------------------------
|
tp@0
|
161 % read header "AC3Db"
|
tp@0
|
162 tline = fgetl(fid);
|
tp@0
|
163 if (~strcmp(tline,'AC3Db'))
|
tp@0
|
164 disp('AC3Db header missing');
|
tp@0
|
165 end
|
tp@0
|
166
|
tp@0
|
167 % read materials
|
tp@0
|
168 p_NumberOfMaterials=0;
|
tp@0
|
169 while(true)
|
tp@0
|
170 tline = fgetl(fid);
|
tp@0
|
171 tokens = readLineToToken(tline);
|
tp@0
|
172
|
tp@0
|
173 if(strcmp(tokens{1},'MATERIAL'))
|
tp@0
|
174 p_MaterialList{p_NumberOfMaterials+1}=tokens{2};
|
tp@0
|
175 p_NumberOfMaterials=p_NumberOfMaterials+1;
|
tp@0
|
176
|
tp@0
|
177 else
|
tp@0
|
178 break;
|
tp@0
|
179 end
|
tp@0
|
180 end
|
tp@0
|
181
|
tp@0
|
182 % read world object (all objects are kids of this)
|
tp@0
|
183 m_LocalMatrix = [1.0 0.0 0.0 0.0;
|
tp@0
|
184 0.0 1.0 0.0 0.0;
|
tp@0
|
185 0.0 0.0 1.0 0.0;
|
tp@0
|
186 0.0 0.0 0.0 1.0];
|
tp@0
|
187
|
tp@0
|
188 % Read OBJECT world
|
tp@0
|
189 tokens = readLineToToken(tline);
|
tp@0
|
190 if(~strcmp(tokens{1},'OBJECT'))
|
tp@0
|
191 disp('Section does not start with "object"');
|
tp@0
|
192 end
|
tp@0
|
193 if(~strcmp(tokens{2},'world'))
|
tp@0
|
194 disp('Section does not start with "world"');
|
tp@0
|
195 end
|
tp@0
|
196
|
tp@0
|
197 % Read kids
|
tp@0
|
198 tline = fgetl(fid);
|
tp@0
|
199 tokens = readLineToToken(tline);
|
tp@0
|
200 if(~strcmp(tokens{1},'kids'))
|
tp@0
|
201 disp('root object section does not start with kids');
|
tp@0
|
202 end
|
tp@0
|
203 p_Kids = str2num(tokens{2});
|
tp@0
|
204
|
tp@0
|
205 for i = 1:p_Kids
|
tp@0
|
206 p_Objects{i}=read_ac3d_object(fid, m_LocalMatrix);
|
tp@0
|
207 end
|
tp@0
|
208
|
tp@0
|
209 fclose(fid);
|
tp@0
|
210
|
tp@0
|
211 %% Export
|
tp@0
|
212 eval(['save a.mat p_Objects']);
|
tp@0
|
213 % Combine Vertices of EVERY Object to on corner list (incl. Counting PlanesPerPoly)
|
tp@0
|
214 for i = 1:p_Kids
|
tp@0
|
215 if(i==1)
|
tp@0
|
216 corners=p_Objects{i}{1}';
|
tp@0
|
217 p_CornersPerPoly = size(p_Objects{i}{1},2);
|
tp@0
|
218 p_PlanesPerPoly = size(p_Objects{i}{2},2);
|
tp@0
|
219 else
|
tp@0
|
220 corners = [corners; p_Objects{i}{1}'];
|
tp@0
|
221 p_PlanesPerPoly = [p_PlanesPerPoly size(p_Objects{i}{2},2)];
|
tp@0
|
222 p_CornersPerPoly = [p_CornersPerPoly size(p_Objects{i}{1},2)];
|
tp@0
|
223 end
|
tp@0
|
224 end
|
tp@0
|
225
|
tp@0
|
226 % Enumerate each corner from 1:end
|
tp@0
|
227 ncorners = size(corners,1);
|
tp@0
|
228 cornernumbers=(1:ncorners)';
|
tp@0
|
229
|
tp@0
|
230 %Number of Planes is sum over all PlanesPerPoly
|
tp@0
|
231 nplanes=sum(p_PlanesPerPoly);
|
tp@0
|
232
|
tp@0
|
233 ncornersperplanevec=zeros(nplanes,1);
|
tp@0
|
234 currentPlaneIndex=1;
|
tp@0
|
235 for i = 1:p_Kids
|
tp@0
|
236 for j=1:p_PlanesPerPoly(i);
|
tp@0
|
237 ncornersperplanevec(currentPlaneIndex)=length(p_Objects{i}{2}{j});
|
tp@0
|
238 currentPlaneIndex=currentPlaneIndex+1;
|
tp@0
|
239 end
|
tp@0
|
240 end
|
tp@0
|
241
|
tp@0
|
242 % We need to compute the maximum number of vertices for any plane
|
tp@0
|
243 % (others are filled up with 0)
|
tp@0
|
244 p_MaximumNumberOfVerticesOfPlane = max(ncornersperplanevec);
|
tp@0
|
245
|
tp@0
|
246 % Compute indices of corners for each plane
|
tp@0
|
247 % Simple for first Object, as here numbers are identical
|
tp@0
|
248 % For every further object, the number of previous used corners has be be
|
tp@0
|
249 % taken as offset
|
tp@0
|
250 planecorners=zeros(nplanes,p_MaximumNumberOfVerticesOfPlane);
|
tp@0
|
251 currentPlaneIndex=1;
|
tp@0
|
252 p_Offset=0;
|
tp@0
|
253 for i = 1:p_Kids
|
tp@0
|
254 for j=1:p_PlanesPerPoly(i);
|
tp@0
|
255 for k=1:length(p_Objects{i}{2}{j})
|
tp@0
|
256 planecorners(currentPlaneIndex,k)=p_Objects{i}{2}{j}(k)+p_Offset;
|
tp@0
|
257 end
|
tp@0
|
258 currentPlaneIndex=currentPlaneIndex+1;
|
tp@0
|
259 end
|
tp@0
|
260 p_Offset=p_Offset+p_CornersPerPoly(i);
|
tp@0
|
261 end
|
tp@0
|
262
|
tp@0
|
263 planenames=zeros(nplanes,30);
|
tp@0
|
264 currentPlaneIndex=1;
|
tp@0
|
265 for i = 1:p_Kids
|
tp@0
|
266 for j=1:p_PlanesPerPoly(i);
|
tp@0
|
267 p_Text = sparse(double(p_MaterialList{p_Objects{i}{4}{j}+1}));
|
tp@0
|
268
|
tp@0
|
269 if length(p_Text) > size(planenames,2)
|
tp@0
|
270 planenames = [planenames zeros(planenumbers(currentPlaneIndex),length(p_Text)-size(planenames,2))];
|
tp@0
|
271 end
|
tp@0
|
272 planenames(currentPlaneIndex,1:length(p_Text)) = p_Text;
|
tp@0
|
273 currentPlaneIndex=currentPlaneIndex+1;
|
tp@0
|
274 end
|
tp@0
|
275 end
|
tp@0
|
276
|
tp@0
|
277 planeabstypes = sparse(planenames(:,1:6));
|
tp@0
|
278
|
tp@0
|
279 % Addition on 2.12.2011 by Peter Svensson
|
tp@0
|
280 % The absorber names had an initial " which must be removed.
|
tp@0
|
281 % We remove columns until A-Z,a-z
|
tp@0
|
282
|
tp@0
|
283 if size(planeabstypes,1) > 1
|
tp@0
|
284 columnhasalphabet = 1 - sign( prod(sign(64-full(planeabstypes))+1));
|
tp@0
|
285 else
|
tp@0
|
286 columnhasalphabet = 1 - sign( (sign(64-full(planeabstypes))+1));
|
tp@0
|
287 end
|
tp@0
|
288 firstOKcolumn = find(columnhasalphabet);
|
tp@0
|
289 if isempty(firstOKcolumn)
|
tp@0
|
290 error('ERROR: All plane absorber types have names without any letters. They must start with a letter')
|
tp@0
|
291 end
|
tp@0
|
292 firstOKcolumn = firstOKcolumn(1);
|
tp@0
|
293 planeabstypes = planeabstypes(:,firstOKcolumn:end);
|
tp@0
|
294
|
tp@0
|
295
|
tp@0
|
296 planenumbers=1:nplanes;
|
tp@0
|
297
|
tp@0
|
298 eval(['save ',outputfile,' corners planecorners ncornersperplanevec'])
|
tp@0
|
299
|
tp@0
|
300 %% Begining from here, it is code based of EDB1readcad.m without changes - except SOURCE - RECIEVER Values, as not in AC3Dfile
|
tp@0
|
301 %---------------------------------------------------------------
|
tp@0
|
302 % Change the numbering in the CAD file to a contiguous one
|
tp@0
|
303
|
tp@0
|
304 % Corner numbers
|
tp@0
|
305 % First we make an inelegant crossreference vector giving the
|
tp@0
|
306 % resulting corner number in the position given by the CAD-file
|
tp@0
|
307 % corner number.
|
tp@0
|
308
|
tp@0
|
309 % PS 20120414: CHECK Corners with number zero are not handled correctly.
|
tp@0
|
310 % Insert code from EDB1readcad here.
|
tp@0
|
311
|
tp@0
|
312 maxnumb = max(cornernumbers);
|
tp@0
|
313 cornercrossref = sparse(zeros(1,maxnumb));
|
tp@0
|
314 cornercrossref(cornernumbers) = [1:ncorners];
|
tp@0
|
315
|
tp@0
|
316 [nplanes,ncornersperplane] = size(planecorners);
|
tp@0
|
317 iv = find(planecorners~=0);
|
tp@0
|
318 planecorners(iv) = full(cornercrossref(planecorners(iv)));
|
tp@0
|
319
|
tp@0
|
320 %---------------------------------------------------------------
|
tp@0
|
321 % Go through all planes. If there is a plane definition including
|
tp@0
|
322 % zeros, and planecornerstype == 'circ', expand it repeating the
|
tp@0
|
323 % same corner order again.
|
tp@0
|
324
|
tp@0
|
325 if isempty(planecornerstype)
|
tp@0
|
326 planecornerstype = 'circ';
|
tp@0
|
327 else
|
tp@0
|
328 planecornerstype = setstr(lower(planecornerstype(1)));
|
tp@0
|
329 if planecornerstype(1) == 'z'
|
tp@0
|
330 planecornerstype = 'zero';
|
tp@0
|
331 else
|
tp@0
|
332 planecornerstype = 'circ';
|
tp@0
|
333 end
|
tp@0
|
334 end
|
tp@0
|
335
|
tp@0
|
336 if planecornerstype == 'circ'
|
tp@0
|
337 for ii = 1:nplanes
|
tp@0
|
338 iv = find( planecorners(ii,:) ~= 0);
|
tp@0
|
339 ncornersatplane = length(iv);
|
tp@0
|
340 if ncornersatplane ~= ncornersperplane
|
tp@0
|
341 pattern = planecorners(ii,iv);
|
tp@0
|
342 nrepeatings = ceil(ncornersperplane/ncornersatplane);
|
tp@0
|
343 for jj = 1:nrepeatings-1
|
tp@0
|
344 pattern = [pattern planecorners(ii,iv)];
|
tp@0
|
345 end
|
tp@0
|
346 planecorners(ii,:) = pattern(1:ncornersperplane);
|
tp@0
|
347 end
|
tp@0
|
348 end
|
tp@0
|
349 end
|
tp@0
|
350
|
tp@0
|
351
|
tp@0
|
352 %---------------------------------------------------------------
|
tp@0
|
353 % Find the normal vectors to the planes using the cross products
|
tp@0
|
354 %
|
tp@0
|
355 % The normal vector is basically the cross product between two vectors
|
tp@0
|
356 % connecting three consecutive points. If there are indents though
|
tp@0
|
357 % they will cause reversed normal vectors, so one must go through all
|
tp@0
|
358 % combinations and choose the majority normal vector.
|
tp@0
|
359 %
|
tp@0
|
360 % 26mar09 Use the fact described above for detecting indention corners
|
tp@0
|
361
|
tp@0
|
362 planenvecs = zeros(nplanes,3);
|
tp@0
|
363 planehasindents = zeros(nplanes,1);
|
tp@0
|
364 indentingcorners = sparse(zeros(nplanes,max(ncornersperplanevec)));
|
tp@0
|
365
|
tp@0
|
366 for ii = 1:nplanes
|
tp@0
|
367
|
tp@0
|
368 iv = find(planecorners(ii,:)~=0);
|
tp@0
|
369 cornerlist = planecorners(ii,iv);
|
tp@0
|
370 iv = find(cornerlist == cornerlist(1));
|
tp@0
|
371 if length(iv) > 1
|
tp@0
|
372 cornerlist = cornerlist(1:iv(2)-1);
|
tp@0
|
373 end
|
tp@0
|
374 ncorners = length( cornerlist );
|
tp@0
|
375 cornerlist = [cornerlist cornerlist(1) cornerlist(2)];
|
tp@0
|
376
|
tp@0
|
377 nvectorlist = zeros(ncorners,3);
|
tp@0
|
378 nveclen = zeros(ncorners,1);
|
tp@0
|
379
|
tp@0
|
380 for jj = 1:ncorners
|
tp@0
|
381 co1numb = cornerlist(jj);
|
tp@0
|
382 co2numb = cornerlist(jj+1);
|
tp@0
|
383 co3numb = cornerlist(jj+2);
|
tp@0
|
384 vec1 = corners(co1numb,:) - corners(co2numb,:);
|
tp@0
|
385 vec2 = corners(co3numb,:) - corners(co2numb,:);
|
tp@0
|
386
|
tp@0
|
387 nvec = EDB1cross(vec1.',vec2.').';
|
tp@0
|
388 nveclen(jj) = norm(nvec);
|
tp@0
|
389 if nveclen(jj) > 0
|
tp@0
|
390 nvectorlist(jj,:) = nvec./nveclen(jj);
|
tp@0
|
391 end
|
tp@0
|
392 end
|
tp@0
|
393
|
tp@0
|
394 iv = find(nveclen < max(nveclen)*0.001);
|
tp@0
|
395 nvectorlist(iv,:) = [];
|
tp@0
|
396 nvecref = nvectorlist(1,:);
|
tp@0
|
397
|
tp@0
|
398 [n1,slask] = size(nvectorlist);
|
tp@0
|
399 nvecsigns = round(sum( (nvectorlist.').*(nvecref(ones(n1,1),:).') ));
|
tp@0
|
400
|
tp@0
|
401 if sum(nvecsigns) == 0
|
tp@0
|
402 disp(' ')
|
tp@0
|
403 error(['ERROR: Plane ',int2str(planenumbers(ii)),' (plane numbering as in the CAD file) seems to be twisted.'])
|
tp@0
|
404 end
|
tp@0
|
405
|
tp@0
|
406
|
tp@0
|
407 if abs(sum(nvecsigns)) ~= n1
|
tp@0
|
408 disp(['Plane ',int2str(ii),' has indents!'])
|
tp@0
|
409 nindents = (n1 - abs(sum(nvecsigns)))/2;
|
tp@0
|
410 planehasindents(ii) = nindents;
|
tp@0
|
411 ivindent = find(nvecsigns == -1);
|
tp@0
|
412 if length(ivindent) == nindents
|
tp@0
|
413 indentingcorners(ii,ivindent) = 1;
|
tp@0
|
414 else
|
tp@0
|
415 if length(ivindent) == ncorners - nindents
|
tp@0
|
416 ivindent = find(nvecsigns == 1);
|
tp@0
|
417 indentingcorners(ii,ivindent) = 1;
|
tp@0
|
418 else
|
tp@0
|
419 error(['ERROR: An unexpected problem. Please report to the developer'])
|
tp@0
|
420 end
|
tp@0
|
421 end
|
tp@0
|
422
|
tp@0
|
423 end
|
tp@0
|
424
|
tp@0
|
425 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
|
426
|
tp@0
|
427 if n1 > 2
|
tp@0
|
428 nvecdiff = sum(nvecdiff.'.^2).';
|
tp@0
|
429 else
|
tp@0
|
430 nvecdiff = norm(nvecdiff);
|
tp@0
|
431 end
|
tp@0
|
432
|
tp@0
|
433 %APO Change
|
tp@0
|
434 if any(nvecdiff>1e-3),
|
tp@0
|
435 nvecdiff
|
tp@0
|
436 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
|
437 elseif any(nvecdiff>1e-8)
|
tp@0
|
438 nvecdiff
|
tp@0
|
439 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
|
440 end
|
tp@0
|
441
|
tp@0
|
442 if ncorners > 5 & abs(sum(nvecsigns)) <= 1
|
tp@0
|
443 disp(['WARNING for plane number ',int2str(planenumbers(ii)),' in the CAD-file'])
|
tp@0
|
444 disp([' with the name ',strtrim(setstr(full(planenames(ii,:))))])
|
tp@0
|
445 disp(' The normal vector can not be determined for this plane because there are')
|
tp@0
|
446 disp(' the same number of inwards and outwards corners')
|
tp@0
|
447 disp(' This is a list of the possible normal vectors:')
|
tp@0
|
448 [nv1,slask] = size(nvectorlist);
|
tp@0
|
449 for kk = 1:nv1
|
tp@0
|
450 vecstr = [' ',int2str(kk),'. ',num2str(-nvectorlist(kk,1)),' ',num2str(-nvectorlist(kk,2)),' ',num2str(-nvectorlist(kk,3))];
|
tp@0
|
451 disp(vecstr)
|
tp@0
|
452 end
|
tp@0
|
453 disp(' ')
|
tp@0
|
454
|
tp@0
|
455 preferredsign = input(' Give the number of a correct normal vector for this plane please ');
|
tp@0
|
456 switchsign = nvecsigns.'./nvecsigns(preferredsign);
|
tp@0
|
457 nvectorlist = nvectorlist.*switchsign(:,ones(1,3));
|
tp@0
|
458 else
|
tp@0
|
459 mostcommonsign = sign(sum(nvecsigns));
|
tp@0
|
460
|
tp@0
|
461 switchsign = nvecsigns.'./mostcommonsign;
|
tp@0
|
462 nvectorlist = nvectorlist.*switchsign(:,ones(1,3));
|
tp@0
|
463 end
|
tp@0
|
464
|
tp@0
|
465 planenvecs(ii,:) = mean(nvectorlist);
|
tp@0
|
466 end
|
tp@0
|
467
|
tp@0
|
468 planenvecs = -planenvecs;
|
tp@0
|
469
|
tp@0
|
470 %---------------------------------------------------------------
|
tp@0
|
471 % Plane equations, as Ax + By + Cz = D for each plane
|
tp@0
|
472
|
tp@0
|
473 planeeqs = zeros(nplanes,4);
|
tp@0
|
474 planeeqs(:,1:3) = planenvecs;
|
tp@0
|
475 planeeqs(:,4) = sum( (planenvecs.').*(corners(planecorners(:,1),:).') ).';
|
tp@0
|
476
|
tp@0
|
477 %---------------------------------------------------------------
|
tp@0
|
478 % Useful data: planesatcorners, minvals and maxvals
|
tp@0
|
479
|
tp@0
|
480 [ncorners,slask] = size(corners);
|
tp@0
|
481 planesatcornerhits = zeros(ncorners,nplanes);
|
tp@0
|
482
|
tp@0
|
483 for ii = 1:nplanes
|
tp@0
|
484 cornerlist = planecorners(ii,1:ncornersperplanevec(ii));
|
tp@0
|
485 planesatcornerhits(cornerlist,ii) = planesatcornerhits(cornerlist,ii) + 1;
|
tp@0
|
486 end
|
tp@0
|
487
|
tp@0
|
488 maxplanespercorner = 0;
|
tp@0
|
489 for ii = 1:ncorners
|
tp@0
|
490 nplanes = length(find(planesatcornerhits(ii,:) ~= 0));
|
tp@0
|
491 if nplanes > maxplanespercorner
|
tp@0
|
492 maxplanespercorner = nplanes;
|
tp@0
|
493 end
|
tp@0
|
494 end
|
tp@0
|
495
|
tp@0
|
496 planesatcorners = zeros(ncorners,maxplanespercorner);
|
tp@0
|
497 nplanespercorners = zeros(ncorners,1);
|
tp@0
|
498 for ii = 1:ncorners
|
tp@0
|
499 iv = find(planesatcornerhits(ii,:)~=0);
|
tp@0
|
500 planesatcorners(ii,1:length(iv)) = iv;
|
tp@0
|
501 nplanespercorners(ii) = length(iv);
|
tp@0
|
502 end
|
tp@0
|
503
|
tp@0
|
504 % find cubic boxes inside which the planes are placed
|
tp@0
|
505
|
tp@0
|
506 [nplanes,slask] = size(planeeqs);
|
tp@0
|
507
|
tp@0
|
508 minvals = zeros(nplanes,3);
|
tp@0
|
509 maxvals = zeros(nplanes,3);
|
tp@0
|
510
|
tp@0
|
511 for ii = 1:nplanes
|
tp@0
|
512 cornerlist = planecorners(ii,:);
|
tp@0
|
513 cornerlist = cornerlist( find(cornerlist~= 0) );
|
tp@0
|
514 cornercoord = corners(cornerlist,:);
|
tp@0
|
515 minvals(ii,:) = min(cornercoord);
|
tp@0
|
516 maxvals(ii,:) = max(cornercoord);
|
tp@0
|
517 end
|
tp@0
|
518
|
tp@0
|
519 minvals = minvals - geomacc;
|
tp@0
|
520 maxvals = maxvals + geomacc;
|
tp@0
|
521
|
tp@0
|
522 %---------------------------------------------------------------
|
tp@0
|
523 % Check the geometry a bit
|
tp@0
|
524
|
tp@0
|
525 if isempty(checkgeom)
|
tp@0
|
526 checkgeom = 0;
|
tp@0
|
527 else
|
tp@0
|
528 if setstr(checkgeom(1)) == 'c'
|
tp@0
|
529 checkgeom = 1;
|
tp@0
|
530 else
|
tp@0
|
531 checkgeom = 0;
|
tp@0
|
532 end
|
tp@0
|
533 end
|
tp@0
|
534
|
tp@0
|
535 if checkgeom
|
tp@0
|
536
|
tp@0
|
537 badproblem = 0;
|
tp@0
|
538 disp(' ')
|
tp@0
|
539 disp(' Checking if there are corners with identical coordinates')
|
tp@0
|
540 for ii = 1:ncorners-1
|
tp@0
|
541 othercorners = [ii+1:ncorners];
|
tp@0
|
542 iv = find((corners(othercorners,1)==corners(ii,1)) & (corners(othercorners,2)==corners(ii,2)) & (corners(othercorners,3)==corners(ii,3)));
|
tp@0
|
543 if ~isempty(iv)
|
tp@0
|
544 disp([' WARNING: corner ',int2str(ii),' and ',int2str(othercorners(iv(1))),' have the same coordinates'])
|
tp@0
|
545 disp([' This should be fixed in the CAD-file or in the CATT-model'])
|
tp@0
|
546 badproblem = 1;
|
tp@0
|
547 end
|
tp@0
|
548 end
|
tp@0
|
549
|
tp@0
|
550 disp(' Checking if there are unused corners')
|
tp@0
|
551 iv = find(planesatcorners(:,1)==0);
|
tp@0
|
552 if ~isempty(iv)
|
tp@0
|
553 disp(' WARNING: The following corners in the CAD-file are not used:')
|
tp@0
|
554 printvec = int2str(cornernumbers(iv(1)));
|
tp@0
|
555 for iiprint = 2:length(iv)
|
tp@0
|
556 printvec = [printvec,' ',int2str(cornernumbers(iv(iiprint)))];
|
tp@0
|
557 end
|
tp@0
|
558 disp([' ',printvec])
|
tp@0
|
559 disp([' This is not a big problem'])
|
tp@0
|
560 planesatcorners(iv,:) = [];
|
tp@0
|
561 end
|
tp@0
|
562
|
tp@0
|
563 disp(' Checking if any corners seem redundant')
|
tp@0
|
564 iv = find(planesatcorners(:,2)==0);
|
tp@0
|
565 if ~isempty(iv)
|
tp@0
|
566 disp(' WARNING: The following corners in the CAD-file belong to only one plane:')
|
tp@0
|
567 printvec = int2str(cornernumbers(iv(1)));
|
tp@0
|
568 for iiprint = 2:length(iv)
|
tp@0
|
569 printvec = [printvec,' ',int2str(cornernumbers(iv(iiprint)))];
|
tp@0
|
570 end
|
tp@0
|
571 disp([' ',printvec])
|
tp@0
|
572 disp([' This should be fixed in the CAD-file or in the CATT-model'])
|
tp@0
|
573 badproblem = 1;
|
tp@0
|
574 end
|
tp@0
|
575
|
tp@0
|
576 if badproblem == 1
|
tp@0
|
577 disp(' ');
|
tp@0
|
578 error(['ERROR: Problems with the geometry defined in the CAD-file: ',CADfile])
|
tp@0
|
579 end
|
tp@0
|
580
|
tp@0
|
581 end
|
tp@0
|
582
|
tp@0
|
583 %---------------------------------------------------------------
|
tp@0
|
584 % Save the relevant variables in the output file
|
tp@0
|
585
|
tp@0
|
586 % NB! Sparse matrices can not get a non-double format
|
tp@0
|
587
|
tp@0
|
588 if ncorners < 256
|
tp@0
|
589 planecorners = uint8(planecorners);
|
tp@0
|
590 elseif ncorners < 65536
|
tp@0
|
591 planecorners = uint16(planecorners);
|
tp@0
|
592 end
|
tp@0
|
593
|
tp@0
|
594 if max(ncornersperplanevec) <= 255
|
tp@0
|
595 ncornersperplanevec = uint8(ncornersperplanevec);
|
tp@0
|
596 planehasindents = uint8(planehasindents);
|
tp@0
|
597 else
|
tp@0
|
598 ncornersperplanevec = uint16(ncornersperplanevec);
|
tp@0
|
599 planehasindents = uint16(planehasindents);
|
tp@0
|
600 end
|
tp@0
|
601
|
tp@0
|
602 Varlist = [' corners cornernumbers planecorners planenames planeabstypes '];
|
tp@0
|
603 Varlist = [Varlist,' planenumbers cornercrossref '];
|
tp@0
|
604 Varlist = [Varlist,' planeeqs planenvecs ncornersperplanevec planesatcorners nplanespercorners'];
|
tp@0
|
605 Varlist = [Varlist,' minvals maxvals planehasindents indentingcorners'];
|
tp@0
|
606 %Varlist = [Varlist,' Scoords Sdirections Srotations Slevels Rnumbers Rcoords CATTversionnumber'];
|
tp@0
|
607
|
tp@0
|
608 planenames = sparse(planenames+1-1);
|
tp@0
|
609 planeabstypes = sparse(planeabstypes+1-1);
|
tp@0
|
610 %Sdirectivitynames = sparse(Sdirectivitynames+1-1);
|
tp@0
|
611
|
tp@0
|
612 eval(['save ',outputfile,Varlist])
|
tp@0
|
613
|
tp@0
|
614 end
|
tp@0
|
615
|
tp@0
|
616 function [p_Plane, p_Norm, p_Mat] = read_ac3d_surface(fid, i_Vertices)
|
tp@0
|
617 tline = fgetl(fid);
|
tp@0
|
618 tokens = readLineToToken(tline);
|
tp@0
|
619 if(~strcmp(tokens{1},'SURF'))
|
tp@0
|
620 disp(['surface section does not start with SURF',tokens{1}]);
|
tp@0
|
621 end
|
tp@0
|
622 if(~strcmp(tokens{2},'0x10'))
|
tp@0
|
623 disp(['only polygons are accepted TODO?', tokens{2}]);
|
tp@0
|
624 end
|
tp@0
|
625
|
tp@0
|
626 tline = fgetl(fid);
|
tp@0
|
627 tokens = readLineToToken(tline);
|
tp@0
|
628 if(~strcmp(tokens{1},'mat'))
|
tp@0
|
629 disp('missing expected token "mat"');
|
tp@0
|
630 end
|
tp@0
|
631 p_Mat=str2num(tokens{2});
|
tp@0
|
632
|
tp@0
|
633 tline = fgetl(fid);
|
tp@0
|
634 tokens = readLineToToken(tline);
|
tp@0
|
635
|
tp@0
|
636 if(~strcmp(tokens{1},'refs'))
|
tp@0
|
637 disp('surface section missing refs');
|
tp@0
|
638 end
|
tp@0
|
639
|
tp@0
|
640 p_NumberOfRefs = str2num(tokens{2});
|
tp@0
|
641
|
tp@0
|
642 if(tokens{2}<3)
|
tp@0
|
643 disp(['too less points in surface:',tokens{2}]);
|
tp@0
|
644 return;
|
tp@0
|
645 end
|
tp@0
|
646
|
tp@0
|
647 p_Plane=zeros(p_NumberOfRefs,1);
|
tp@0
|
648
|
tp@0
|
649 for r=1:p_NumberOfRefs
|
tp@0
|
650 tline = fgetl(fid);
|
tp@0
|
651 tokens = readLineToToken(tline);
|
tp@0
|
652 p_Plane(r)=str2num(tokens{1})+1;
|
tp@0
|
653 end
|
tp@0
|
654
|
tp@0
|
655 v1 = i_Vertices(:,p_Plane(2))-i_Vertices(:,p_Plane(1));
|
tp@0
|
656 v2 = i_Vertices(:,p_Plane(3))-i_Vertices(:,p_Plane(1));
|
tp@0
|
657 p_Norm = cross(v1,v2);
|
tp@0
|
658 p_Norm = p_Norm./norm(p_Norm);
|
tp@0
|
659 end
|
tp@0
|
660
|
tp@0
|
661 function [token] = readLineToToken(tline)
|
tp@0
|
662 [token{1}, remain] = strtok(tline);
|
tp@0
|
663 i=1;
|
tp@0
|
664 while(remain~=0)
|
tp@0
|
665 i=i+1;
|
tp@0
|
666 tline = remain;
|
tp@0
|
667 [token{i}, remain] = strtok(tline);
|
tp@0
|
668 end
|
tp@0
|
669 end
|
tp@0
|
670
|
tp@0
|
671 function [p_Object] = read_ac3d_object(fid, i_LocalMatrix)
|
tp@0
|
672
|
tp@0
|
673 tline = fgetl(fid);
|
tp@0
|
674 tokens = readLineToToken(tline);
|
tp@0
|
675 if(~strcmp(tokens{1},'OBJECT'))
|
tp@0
|
676 disp('Section does not start with "object"');
|
tp@0
|
677 end
|
tp@0
|
678 if(strcmp(tokens{2},'poly'))
|
tp@0
|
679 p_Object = read_ac3d_poly(fid, i_LocalMatrix);
|
tp@0
|
680 elseif(strcmp(tokens{2},'group'))
|
tp@0
|
681 disp('GROUP not implemented yet');
|
tp@0
|
682 elseif(strcmp(tokens{2},'light'))
|
tp@0
|
683 disp('LIGHT not implemented yet');
|
tp@0
|
684 else
|
tp@0
|
685 disp('Section does not start with valid key');
|
tp@0
|
686 end
|
tp@0
|
687 end
|
tp@0
|
688 function [p_Polygon] = read_ac3d_poly(fid, i_LocalMatrix)
|
tp@0
|
689
|
tp@0
|
690 p_LocalMatrix = [1.0 0.0 0.0 0.0;
|
tp@0
|
691 0.0 1.0 0.0 0.0;
|
tp@0
|
692 0.0 0.0 1.0 0.0;
|
tp@0
|
693 0.0 0.0 0.0 1.0];
|
tp@0
|
694
|
tp@0
|
695 tline = fgetl(fid);
|
tp@0
|
696
|
tp@0
|
697 p_Vertices=0;
|
tp@0
|
698 while(ischar(tline))
|
tp@0
|
699 tokens = readLineToToken(tline);
|
tp@0
|
700
|
tp@0
|
701 if(strcmp(tokens{1},'numvert'))
|
tp@0
|
702
|
tp@0
|
703 p_ResultMatrix = i_LocalMatrix * p_LocalMatrix;
|
tp@0
|
704
|
tp@0
|
705 p_NumVertices=str2num(tokens{2});
|
tp@0
|
706 p_Vertices=zeros(3,p_NumVertices);
|
tp@0
|
707 for l=1:p_NumVertices
|
tp@0
|
708 tline = fgetl(fid);
|
tp@0
|
709 tokens = readLineToToken(tline);
|
tp@0
|
710 if(~ischar(tline))
|
tp@0
|
711 disp(['unexpected EOF while reading vertex (', num2str(l),'/',num2str(p_NumVertices)]);
|
tp@0
|
712 end
|
tp@0
|
713 if(size(tokens,2)~=3)
|
tp@0
|
714 disp(['error while reading vertex coords (', num2str(l),'/',num2str(p_NumVertices)]);
|
tp@0
|
715 end
|
tp@0
|
716
|
tp@0
|
717 p_Vec = p_ResultMatrix * [str2num(tokens{1}); str2num(tokens{2}); str2num(tokens{3}); 1];
|
tp@0
|
718 p_Vertices(:,l) = p_Vec(1:3);
|
tp@0
|
719 end
|
tp@0
|
720
|
tp@0
|
721 elseif(strcmp(tokens{1},'numsurf'))
|
tp@0
|
722 p_NumSurfaces=str2num(tokens{2});
|
tp@0
|
723 for s=1:p_NumSurfaces
|
tp@0
|
724 [p_Planes{s}, p_Norms{s}, p_Mats{s}] = read_ac3d_surface(fid, p_Vertices);
|
tp@0
|
725 end
|
tp@0
|
726 elseif(strcmp(tokens{1},'loc'))
|
tp@0
|
727 p_LocalMatrix(1,4)=str2num(tokens{2});
|
tp@0
|
728 p_LocalMatrix(2,4)=str2num(tokens{3});
|
tp@0
|
729 p_LocalMatrix(3,4)=str2num(tokens{4});
|
tp@0
|
730 elseif(strcmp(tokens{1},'rot'))
|
tp@0
|
731 p_LocalMatrix(1,1)=str2num(tokens{2});
|
tp@0
|
732 p_LocalMatrix(1,2)=str2num(tokens{3});
|
tp@0
|
733 p_LocalMatrix(1,3)=str2num(tokens{4});
|
tp@0
|
734 p_LocalMatrix(2,1)=str2num(tokens{5});
|
tp@0
|
735 p_LocalMatrix(2,2)=str2num(tokens{6});
|
tp@0
|
736 p_LocalMatrix(2,3)=str2num(tokens{7});
|
tp@0
|
737 p_LocalMatrix(3,1)=str2num(tokens{8});
|
tp@0
|
738 p_LocalMatrix(3,2)=str2num(tokens{9});
|
tp@0
|
739 p_LocalMatrix(3,3)=str2num(tokens{10});
|
tp@0
|
740 elseif(strcmp(tokens{1},'kids'))
|
tp@0
|
741 if(str2num(tokens{2})>2)
|
tp@0
|
742 disp(['Warning: Kids of Polygon not handled yet:',tokens{2}])
|
tp@0
|
743 p_Polygon=0;
|
tp@0
|
744 return;
|
tp@0
|
745 end
|
tp@0
|
746 p_Polygon{1}=p_Vertices;
|
tp@0
|
747 p_Polygon{2}=p_Planes;
|
tp@0
|
748 p_Polygon{3}=p_Norms;
|
tp@0
|
749 p_Polygon{4}=p_Mats;
|
tp@0
|
750 return;
|
tp@0
|
751 else
|
tp@0
|
752 if(strcmp(tokens{1},'name'))
|
tp@0
|
753 % Only name of poly, irrelevant -->SKIP
|
tp@0
|
754 elseif(strcmp(tokens{1},'crease'))
|
tp@0
|
755 else
|
tp@0
|
756 disp(['Warning: Ignored Entry in AC3D File: ', tokens{1}]);
|
tp@0
|
757 end
|
tp@0
|
758 end
|
tp@0
|
759 tline = fgetl(fid);
|
tp@0
|
760 end
|
tp@0
|
761 end
|