0001 function out = mk_thorax_model(str, elec_pos, elec_shape, maxh)
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 if ismember(str,list_predef_models)
0044 out = build_predef_model(str);
0045 return
0046 end
0047
0048 if ~ismember(str, list_basic_shapes)
0049 error('Shape str "%s" not understood.',str);
0050 end
0051
0052
0053
0054 out = build_basic_model(str);
0055 if nargin > 1
0056 out = place_elec_on_surf(out,elec_pos,elec_shape,[],maxh);
0057 out = fix_boundary(out);
0058 end
0059
0060 end
0061
0062 function ls = list_basic_shapes
0063 ls = {'male','female'};
0064 end
0065
0066 function out = build_basic_model(str)
0067 switch(str)
0068 case {'male', 'female'}
0069 out = remesh_at_model(str);
0070 end
0071 end
0072
0073 function out = remesh_at_model(str)
0074 tmpnm = tempname;
0075
0076 stlfile = [tmpnm '.stl'];
0077 volfile = [tmpnm '.vol'];
0078
0079 contrib = 'at-thorax-mesh'; file = sprintf('%s_t_mdl.mat',str);
0080 load(get_contrib_data(contrib,file));
0081 if strcmp(str,'male')
0082 fmdl.nodes = fmdl.nodes - 10;
0083 end
0084 fmdl = fix_boundary(fmdl);
0085 STL.vertices = fmdl.nodes;
0086 STL.faces = fmdl.boundary;
0087 stl_write(STL,stlfile);
0088 opt.stloptions.yangle = 55;
0089 opt.stloptions.edgecornerangle = 5;
0090 opt.meshoptions.fineness = 6;
0091 opt.options.meshsize = 30;
0092 opt.options.minmeshsize = 10;
0093 opt.stloptions.resthsurfcurvfac = 2;
0094 opt.stloptions.resthsurfcurvenable = 1;
0095 opt.stloptions.chartangle = 30;
0096 opt.stloptions.outerchartangle = 90;
0097 ng_write_opt(opt);
0098 call_netgen(stlfile,volfile);
0099 out=ng_mk_fwd_model(volfile,[],[],[],[]);
0100 delete(stlfile);
0101 delete(volfile);
0102 delete('ng.opt');
0103
0104 out = rmfield(out,...
0105 {'mat_idx','np_fwd_solve','boundary_numbers'});
0106
0107 end
0108
0109 function mdl = fix_boundary(mdl)
0110 opt.elem2face = 1;
0111 opt.boundary_face = 1;
0112 opt.inner_normal = 1;
0113 mdl = fix_model(mdl,opt);
0114 flip = mdl.elem2face(logical(mdl.boundary_face(mdl.elem2face).*mdl.inner_normal));
0115 mdl.faces(flip,:) = mdl.faces(flip,[1 3 2]);
0116 mdl.normals(flip,:) = -mdl.normals(flip,:);
0117 mdl.boundary = mdl.faces(mdl.boundary_face,:);
0118 end
0119
0120 function ls = list_predef_models
0121 ls = {'adult_male_grychtol2016a_1x32'
0122 'adult_male_grychtol2016a_2x16'};
0123 end
0124
0125 function out = build_predef_model(str)
0126 switch str
0127 case 'adult_male_grychtol2016a_1x32'
0128 out = mk_thorax_model_grychtol2016a('1x32_ring');
0129
0130 case 'adult_male_grychtol2016a_2x16'
0131 out = mk_thorax_model_grychtol2016a('2x16_planar');
0132 end
0133 end
0134
0135
0136 function do_unit_test
0137 subplot(121)
0138 show_fem(mk_thorax_model('male'));
0139
0140 subplot(122)
0141 show_fem(mk_thorax_model('female'));
0142
0143 end