1function mesh = DetectEdges(CSX, mesh, varargin) 2% mesh = DetectEdges(CSX <, mesh, varargin>) 3% 4% Returns a mesh with the edges added of certain (see below) primitives 5% found in the CSX structure. 6% 7% optional arguments: 8% mesh: add edges to an existing (predefined) mesh 9% 10% optional: 'keyword', value 11% 'Debug' enable debug mode (default is 1) 12% 'AddPropertyType' add a list of additional property types to detect 13% e.g. 'DumpBox' or {'DumpBox','ProbeBox'} 14% 'SetPropertyType' set the list of property types to detect (override default) 15% e.g. 'Metal' or {'Metal','ConductingSheet'} 16% 'ExcludeProperty' give a list of property names to exclude from 17% detection 18% 'SetProperty' give a list of property names to handly exlusively for detection 19% 20% advanced options: 'keyword', value 21% '2D_Metal_Edge_Res' define a one-third/two-third metal edge resolution 22% 23% example: 24% CSX = InitCSX(); 25% % define all properties and primitives to detect 26% % ... 27% % ... 28% mesh = DetectEdges(CSX); 29% mesh = SmoothMesh(mesh, lambda/20/unit); 30% CSX = DefineRectGrid(CSX, unit, mesh); 31% 32% Note: 33% - Only primitives contained in Metal, Material, Excitation, LumpedElement 34% or ConductingSheet properties are processed 35% - Currently this function handles only Box, Polygons, LinPoly and Cylinder. 36% 37% CSXCAD matlab interface 38% ----------------------- 39% author: Koen De Vleeschauwer (c) 2012 40% modified by: Thorsten Liebig (c) 2012, 2013 41% 42% See also InitCSX, SmoothMesh, DefineRectGrid 43 44supported_properties = {}; 45supported_properties{end+1}='Metal'; 46supported_properties{end+1}='Material'; 47supported_properties{end+1}='Excitation'; 48supported_properties{end+1}='LumpedElement'; 49supported_properties{end+1}='ConductingSheet'; 50 51exclude_list = {}; 52prop_list_only = {}; 53 54debug = 1; 55mesh_2D_metal_edges = 0; 56 57for n=1:2:numel(varargin) 58 if (strcmpi(varargin{n},'debug')==1); 59 debug = varargin{n+1}; 60 elseif (strcmpi(varargin{n},'AddPropertyType')==1); 61 if iscell(varargin{n+1}) 62 supported_properties(end+1) = varargin{n+1}; 63 elseif ischar(varargin{n+1}) 64 supported_properties{end+1} = varargin{n+1}; 65 else 66 error('CSXCAD:DetectEdges','unknown property definition'); 67 end 68 elseif (strcmpi(varargin{n},'SetPropertyType')==1); 69 if iscell(varargin{n+1}) 70 supported_properties = varargin{n+1}; 71 elseif ischar(varargin{n+1}) 72 supported_properties = {varargin{n+1}}; 73 else 74 error('CSXCAD:DetectEdges','unknown property definition'); 75 end 76 elseif (strcmpi(varargin{n},'ExcludeProperty')==1); 77 exclude_list = varargin{n+1}; 78 elseif (strcmpi(varargin{n},'SetProperty')==1); 79 prop_list_only = varargin{n+1}; 80 elseif (strcmpi(varargin{n},'2D_Metal_Edge_Res')==1); 81 mesh_2D_metal_edges = varargin{n+1}*[-1 2]/3; 82 else 83 warning('CSXCAD:DetectEdges',['unknown argument: ' varargin{n}]); 84 end 85end 86 87if (nargin<2) 88 mesh = []; 89end 90 91if isempty(mesh) 92 if (CSX.ATTRIBUTE.CoordSystem==0) 93 mesh.x = []; 94 mesh.y = []; 95 mesh.z = []; 96 elseif (CSX.ATTRIBUTE.CoordSystem==1) 97 mesh.r = []; 98 mesh.a = []; 99 mesh.z = []; 100 else 101 error('CSXCAD:DetectEdges','unknown coordinate system used'); 102 end 103end 104 105edges = {}; 106edges.x = [ ]; 107edges.y = [ ]; 108edges.z = [ ]; 109 110if (~isstruct(CSX)) 111 error('expected a CSX structure'); 112end 113 114CoordSystem = CSX.ATTRIBUTE.CoordSystem; 115 116if (isfield(CSX, 'Properties')) 117 prop_fn = fieldnames(CSX.Properties); 118 for p = 1:numel(prop_fn) 119 if (sum(strcmpi(prop_fn{p}, supported_properties))==0) 120 continue; 121 end 122 isMetal = sum(strcmpi(prop_fn{p},{'Metal','ConductingSheet'})); 123 property_group = CSX.Properties.(prop_fn{p}); 124 for m = 1:numel(property_group) 125 property=property_group{m}; 126 if ~isfield(property, 'Primitives') 127 continue; 128 end 129 if (sum(strcmpi(property.ATTRIBUTE.Name,exclude_list))) 130 continue; 131 end 132 if (~isempty(prop_list_only) && (sum(strcmpi(property.ATTRIBUTE.Name,prop_list_only))==0)) 133 continue; 134 end 135 primitives = property.Primitives; 136 prim_fn = fieldnames(primitives); 137 for n_prim = 1:numel(prim_fn) 138 if (strcmp(prim_fn{n_prim}, 'Box')) 139 for b = 1:length(primitives.Box) 140 box = primitives.Box{b}; 141 x1 = box.P1.ATTRIBUTE.X; 142 y1 = box.P1.ATTRIBUTE.Y; 143 z1 = box.P1.ATTRIBUTE.Z; 144 x2 = box.P2.ATTRIBUTE.X; 145 y2 = box.P2.ATTRIBUTE.Y; 146 z2 = box.P2.ATTRIBUTE.Z; 147 % check dimension 148 dim = (x1~=x2) + (y1~=y2) + (z1~=z2); 149 if ((dim==2) && isMetal) 150 % add to global list of edges, with a given 2D 151 % edge resolution 152 edges = AddEdge (edges, box, x1+sign(x1-x2)*mesh_2D_metal_edges, y1+sign(y1-y2)*mesh_2D_metal_edges, ... 153 z1+sign(z1-z2)*mesh_2D_metal_edges, CoordSystem, debug); 154 edges = AddEdge (edges, box, x2+sign(x2-x1)*mesh_2D_metal_edges, y2+sign(y2-y1)*mesh_2D_metal_edges, ... 155 z2+sign(z2-z1)*mesh_2D_metal_edges, CoordSystem, debug); 156 else 157 % add to global list of edges 158 edges = AddEdge (edges, box, x1, y1, z1, CoordSystem, debug); 159 edges = AddEdge (edges, box, x2, y2, z2, CoordSystem, debug); 160 end 161 end 162 elseif (strcmp(prim_fn{n_prim}, 'LinPoly') || strcmp(prim_fn{n_prim}, 'Polygon')) 163 for l = 1:length(primitives.(prim_fn{n_prim})) 164 poly = primitives.(prim_fn{n_prim}){l}; 165 dir = poly.ATTRIBUTE.NormDir + 1; 166 dirP = mod(poly.ATTRIBUTE.NormDir+1,3) + 1; 167 dirPP = mod(poly.ATTRIBUTE.NormDir+2,3) + 1; 168 lin_length = 0; 169 if (strcmp(prim_fn{n_prim}, 'LinPoly')) 170 lin_length = poly.ATTRIBUTE.Length; 171 end 172 if (isfield(poly, 'Vertex')) 173 for v = 1:length(poly.Vertex) 174 vertex = poly.Vertex{v}; 175 edge(dir) = poly.ATTRIBUTE.Elevation; 176 edge(dirP) = vertex.ATTRIBUTE.X1; 177 edge(dirPP) = vertex.ATTRIBUTE.X2; 178 edges = AddEdge (edges, poly, edge(1), edge(2), edge(3), CoordSystem, debug); 179 if (lin_length~=0) 180 edge(dir) = edge(dir) + lin_length; 181 edges = AddEdge (edges, poly, edge(1), edge(2), edge(3), CoordSystem, debug); 182 end 183 end 184 end 185 end 186 elseif (strcmp(prim_fn{n_prim}, 'Cylinder')) 187 for c = 1:length(primitives.Cylinder) 188 cylinder = primitives.Cylinder{c}; 189 r = cylinder.ATTRIBUTE.Radius; 190 x1 = cylinder.P1.ATTRIBUTE.X; 191 y1 = cylinder.P1.ATTRIBUTE.Y; 192 z1 = cylinder.P1.ATTRIBUTE.Z; 193 x2 = cylinder.P2.ATTRIBUTE.X; 194 y2 = cylinder.P2.ATTRIBUTE.Y; 195 z2 = cylinder.P2.ATTRIBUTE.Z; 196 if ((x1 == x2) && (y1 == y2) && (z1 ~= z2)) 197 % cylinder parallel with z axis 198 edges = AddEdge (edges, cylinder, x1 - r, y1 - r, z1, CoordSystem, debug); 199 edges = AddEdge (edges, cylinder, x2 + r, y2 + r, z2, CoordSystem, debug); 200 elseif ((x1 == x2) && (y1 ~= y2) && (z1 == z2)) 201 % cylinder parallel with y axis 202 edges = AddEdge (edges, cylinder, x1 - r, y1, z1 - r, CoordSystem, debug); 203 edges = AddEdge (edges, cylinder, x2 + r, y2, z2 + r, CoordSystem, debug); 204 elseif ((x1 ~= x2) && (y1 == y2) && (z1 == z2)) 205 % cylinder parallel with x axis 206 edges = AddEdge (edges, cylinder, x1, y1 - r, z1 - r, CoordSystem, debug); 207 edges = AddEdge (edges, cylinder, x2, y2 + r, z2 + r, CoordSystem, debug); 208 elseif (debug > 0) 209 warning('CSXCAD:DetectEdges',['unsupported primitive of type: "' prim_fn{n_prim} '" found, skipping edges']); 210 end 211 end 212 else 213 if (debug>0) 214 warning('CSXCAD:DetectEdges',['unsupported primitive of type: "' prim_fn{n_prim} '" found, skipping edges']); 215 end 216 end 217 end 218 end 219 end 220end 221 222if (CSX.ATTRIBUTE.CoordSystem==0) 223 mesh.x = sort(unique([mesh.x edges.x])); 224 mesh.y = sort(unique([mesh.y edges.y])); 225 mesh.z = sort(unique([mesh.z edges.z])); 226elseif (CSX.ATTRIBUTE.CoordSystem==1) 227 mesh.r = sort(unique([mesh.r edges.x])); 228 mesh.a = sort(unique([mesh.a edges.y])); 229 mesh.z = sort(unique([mesh.z edges.z])); 230else 231 error('CSXCAD:DetectEdges','unknown coordinate system used'); 232end 233 234end 235 236 237function edges = AddEdge(edges, csx_prim, x, y, z, CoordSystem, debug) 238% Add edges of CSX primitives including some transformations 239 240xt = unique(x); 241yt = unique(y); 242zt = unique(z); 243 244if isfield(csx_prim.ATTRIBUTE,'CoordSystem') 245 if (csx_prim.ATTRIBUTE.CoordSystem~=CoordSystem) 246 if (debug>2) 247 warning('CSXCAD:DetectEdges','different coordinate systems not supported, skipping edges'); 248 end 249 return 250 end 251end 252 253if (isfield(csx_prim, 'Transformation')) 254 255 transformation = csx_prim.Transformation; 256 trans_fn = fieldnames(transformation); 257 258 for t=1:numel(trans_fn) 259 if (strcmp(trans_fn{t}, 'Translate')) 260 xt = xt + transformation.Translate.ATTRIBUTE.Argument(1); 261 yt = yt + transformation.Translate.ATTRIBUTE.Argument(2); 262 zt = zt + transformation.Translate.ATTRIBUTE.Argument(3); 263 else 264 if (debug>0) 265 warning('CSXCAD:DetectEdges','unsupported transformation found in primitive, skipping edges'); 266 end 267 return 268 end 269 end 270 271end 272 273% add to global list of edges 274edges.x = [edges.x xt]; 275edges.y = [edges.y yt]; 276edges.z = [edges.z zt]; 277end 278 279