0001 function [K,V] = convhulln_clean(pts,p);
0002
0003
0004
0005
0006
0007
0008 if ischar(pts) && strcmp(pts,'UNIT_TEST'); do_unit_test; return; end
0009
0010
0011 K=0; V=0; dim = size(pts,2);
0012
0013 if size(pts,1) < 3; return; end
0014
0015
0016 ctr = mean(pts);
0017 pts = bsxfun(@minus,pts,ctr);
0018 scale = max(abs(pts(:)));
0019
0020 if scale == 0; return; end
0021
0022
0023 pts = pts ./ scale;
0024 p.scale = scale;
0025
0026
0027
0028 pts= uniquetol(pts,1e-13,'ByRows',true,'DataScale',1);
0029
0030 if size(pts,1)<=size(pts,2); return; end
0031 if any(std(pts)<1e-14); return; end
0032 [K,V] = call_convhulln(pts,p);
0033
0034
0035
0036 V = scale^dim * max(V,0);
0037
0038 function [K,V] = call_convhulln(pts,p);
0039 K=0; V=0;
0040 dim = size(pts,2);
0041
0042
0043
0044
0045
0046
0047 if exist('OCTAVE_VERSION')
0048 [K, V] = convhulln(pts,{'Qt Pp Qs QJ'});
0049 if V<1e-8; V=0; end
0050 else
0051 try
0052 [K, V] = convhulln(pts,{'Qt Pp Qs'});
0053 catch
0054
0055 [K, V] = convhulln(pts,{'Qt Pp Qs QJ'});
0056 if V<1e-8; V=0; end
0057 end
0058 end
0059
0060
0061 function [K,V] = call_convhulln_old(pts,p);
0062 K=0; V=0;
0063 dim = size(pts,2);
0064
0065 try
0066 [K, V] = convhulln(pts,{'Qt Pp Qs'});
0067 catch err
0068 ok = false;
0069 if exist('OCTAVE_VERSION')
0070 if strcmp(err.message,'convhulln: qhull failed')
0071 err.identifier = 'MATLAB:qhullmx:DegenerateData';
0072 end
0073
0074 end
0075 switch err.identifier
0076 case {'MATLAB:qhullmx:DegenerateData', 'MATLAB:qhullmx:UndefinedError'}
0077
0078
0079
0080 u = uniquetol(pts*p.scale,1e-14,'ByRows',true,'DataScale', 1);
0081 ok = ok | (size(u,1) <= dim );
0082 if ~ok; switch dim;
0083 case 2; ok = colinear_test2d(u);
0084 case 3; ok = colinear_test3d(pts*p.scale);
0085 otherwise; error('not 2D or 3D');
0086 end; end
0087 end
0088
0089
0090
0091
0092 if ~ok
0093 if eidors_debug('query','mk_tet_c2f:convhulln');
0094 debug_plot_tet(p.fmdl,p.rmdl,p.tri_todo,p.t, p.pts)
0095 keyboard
0096 elseif eidors_debug('query','mk_tri2tet_c2f:convhulln');
0097 debug_plot_tri2tet(p.fmdl,p.rmdl,p.v,p.t, p.bot, p.top, p.pts)
0098 keyboard
0099 else
0100 fprintf('\n');
0101 eidors_msg(['convhulln has thrown an error. (',err.message,')', ...
0102 'Enable "eidors_debug on convhulln_clean" and re-run to see a debug plot'],0);
0103 rethrow(err);
0104 end
0105 end
0106 end
0107
0108
0109 function ok = colinear_test2d(u,ok)
0110 ok = false;
0111 cp = bsxfun(@minus, u(2:end,:), u(1,:));
0112 l = sqrt(sum(cp.^2,2));
0113 cp = bsxfun(@rdivide, cp, l);
0114 u = uniquetol(cp,1e-14,'ByRows',true,'DataScale',1);
0115 ok = ok | size(u,1) == 1;
0116
0117
0118 function ok = colinear_test3d(pts);
0119 ok = false;
0120 u12 = uniquetol(pts(:,1:2),1e-14,'ByRows',true,'DataScale',1);
0121 cp = bsxfun(@minus, u12(2:end,1:2), u12(1,1:2));
0122 l = sqrt(sum(cp.^2,2));
0123 cp = bsxfun(@rdivide, cp, l);
0124
0125 cp = abs(cp);
0126 un = uniquetol(cp,1e-12,'ByRows',true,'DataScale',1);
0127 ok = ok | size(un,1) == 1;
0128 if ok; return; end
0129
0130
0131 top = max(pts(:,3));
0132 bot = min(pts(:,3));
0133 ok = ok | all(abs(pts(:,3) - top) < eps);
0134 ok = ok | all(abs(pts(:,3) - bot) < eps);
0135
0136 function debug_plot_tet(fmdl,rmdl,tri_todo,t, pts)
0137 clf
0138 tri.nodes = fmdl.nodes;
0139 vox.nodes = rmdl.nodes;
0140 tri.type = 'fwd_model';
0141 vox.type = 'fwd_model';
0142 vox.elems = rmdl.elems(v,:);
0143 vox.boundary = p.vox.elems;
0144 tri.elems = fmdl.elems(tri_todo(t),:);
0145 show_fem(vox)
0146 hold on
0147 h = show_fem(tri);
0148 set(h,'EdgeColor','b')
0149 pts = bsxfun(@plus,pts*scale,ctr);
0150 plot(pts(:,1),pts(:,2),'o');
0151 hold off
0152 axis auto
0153
0154 function debug_plot_tri2tet(fmdl,rmdl,v,t, bot, top, pts)
0155 clf
0156 tet.nodes = fmdl.nodes;
0157 tri.nodes = repmat(rmdl.nodes(rmdl.elems(v,:),:),2,1);
0158 tri.nodes(:,3) = [repmat(bot,3,1); repmat(top,3,1)];
0159 tri.elems = [ 1 2 5 4
0160 2 3 6 5
0161 3 1 4 6];
0162 tri.boundary = tri.elems;
0163 tet.type = 'fwd_model';
0164 tri.type = 'fwd_model';
0165 tet.elems = fmdl.elems(t,:);
0166 clf
0167 show_fem(tri)
0168 hold on
0169 h = show_fem(tet);
0170 set(h,'EdgeColor','b')
0171
0172 plot3(pts(:,1),pts(:,2),pts(:,3),'o');
0173 hold off
0174 axis auto
0175
0176 function do_unit_test
0177 t1.type = 'fwd_model'; t1.elems = [1 2 3 4];
0178 t1.nodes = [0 0 0; 0 1 0; 1 0 0; 0 0 1]; t2 = t1;
0179 unit_test_cmp('A',mk_tet_c2f(t1,t2), 1,10*eps);
0180 t2.nodes(end,end) = -1;
0181 unit_test_cmp('B',mk_tet_c2f(t1,t2), 0,10*eps);
0182