0001 function out = mk_thorax_model(str, varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 if nargin>0 && ischar(str)
0034 switch(str)
0035 case 'UNIT_TEST';
0036 do_unit_test; return;
0037 case 'list_shapes'
0038 out = list_basic_shapes; return;
0039 case 'list'
0040 out = list_predef_models; return;
0041 end
0042 end
0043
0044 opt.fstr = 'mk_thorax_model';
0045 out = eidors_cache(@do_mk_thorax_model,[{str}, varargin(:)'],opt);
0046
0047 end
0048
0049 function out = do_mk_thorax_model(str, elec_pos, elec_shape, maxh)
0050
0051 if ismember(str,list_predef_models)
0052 out = build_predef_model(str);
0053 return
0054 end
0055
0056 if ~ismember(str, list_basic_shapes)
0057 error('Shape str "%s" not understood.',str);
0058 end
0059
0060
0061
0062 out = build_basic_model(str);
0063 if nargin > 1
0064 out = place_elec_on_surf(out,elec_pos,elec_shape,[],maxh);
0065 out = fix_boundary(out);
0066 end
0067
0068 end
0069
0070 function ls = list_basic_shapes
0071 ls = {'male','female'};
0072 end
0073
0074 function out = build_basic_model(str)
0075 switch(str)
0076 case {'male', 'female'}
0077 out = eidors_cache(@remesh_at_model, {str});
0078 end
0079 end
0080
0081 function out = remesh_at_model(str)
0082 tmpnm = tempname;
0083
0084 stlfile = [tmpnm '.stl'];
0085 volfile = [tmpnm '.vol'];
0086
0087 contrib = 'at-thorax-mesh'; file = sprintf('%s_t_mdl.mat',str);
0088 load(get_contrib_data(contrib,file));
0089 if strcmp(str,'male')
0090 fmdl.nodes = fmdl.nodes - 10;
0091 end
0092 fmdl = fix_boundary(fmdl);
0093 STL.vertices = fmdl.nodes;
0094 STL.faces = fmdl.boundary;
0095 stl_write(STL,stlfile);
0096 opt.stloptions.yangle = 55;
0097 opt.stloptions.edgecornerangle = 5;
0098 opt.meshoptions.fineness = 6;
0099 opt.options.meshsize = 30;
0100 opt.options.minmeshsize = 10;
0101 opt.stloptions.resthsurfcurvfac = 2;
0102 opt.stloptions.resthsurfcurvenable = 1;
0103 opt.stloptions.chartangle = 30;
0104 opt.stloptions.outerchartangle = 90;
0105 ng_write_opt(opt);
0106 call_netgen(stlfile,volfile);
0107 out=ng_mk_fwd_model(volfile,[],[],[],[]);
0108 delete(stlfile);
0109 delete(volfile);
0110 delete('ng.opt');
0111
0112 out = rmfield(out,...
0113 {'mat_idx','np_fwd_solve','boundary_numbers'});
0114
0115 end
0116
0117 function mdl = fix_boundary(mdl)
0118 opt.elem2face = 1;
0119 opt.boundary_face = 1;
0120 opt.inner_normal = 1;
0121 mdl = fix_model(mdl,opt);
0122 flip = mdl.elem2face(logical(mdl.boundary_face(mdl.elem2face).*mdl.inner_normal));
0123 mdl.faces(flip,:) = mdl.faces(flip,[1 3 2]);
0124 mdl.normals(flip,:) = -mdl.normals(flip,:);
0125 mdl.boundary = mdl.faces(mdl.boundary_face,:);
0126 end
0127
0128 function ls = list_predef_models
0129 ls = {'adult_male_grychtol2016a_1x32'
0130 'adult_male_grychtol2016a_2x16'};
0131 end
0132
0133 function out = build_predef_model(str)
0134 switch str
0135 case 'adult_male_grychtol2016a_1x32'
0136 out = mk_thorax_model_grychtol2016a('1x32_ring');
0137
0138 case 'adult_male_grychtol2016a_2x16'
0139 out = mk_thorax_model_grychtol2016a('2x16_planar');
0140 end
0141 end
0142
0143
0144 function do_unit_test
0145 subplot(221)
0146 show_fem(mk_thorax_model('male'));
0147
0148 subplot(222)
0149 show_fem(mk_thorax_model('female'));
0150
0151 subplot(223)
0152 eth16 = 360*cumsum([0.2 0.4*ones(1,7) 0.5 0.4*ones(1,7)])/6.5 - 90; eth16 = eth16';
0153 eth32 = 360*cumsum([0.1 0.2*ones(1,15) 0.25 0.2*ones(1,15)])/6.45 - 90; eth32 = eth32';
0154 ep = eth16; ep(:,2) = 150;
0155 ep(17:48,1) = eth32; ep(17:48,2) = 175;
0156 ep(49:64,1) = eth16; ep(49:64,2) = 200;
0157 mdl = mk_thorax_model('male',ep,[5 0 .5],10);
0158 show_fem(mdl);
0159
0160 subplot(224)
0161 mdl = mk_thorax_model('female',ep,[5 0 .5],10);
0162 show_fem(mdl);
0163
0164
0165
0166
0167
0168 end