0001 function [refMesh, distListIters, refVerticesIters] = averageMesh(meshList, varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 nIters = 10;
0024 verbose = false;
0025
0026
0027 while length(varargin) > 1
0028 name = varargin{1};
0029 if ~ischar(name)
0030 error('require parameter name-value pairs');
0031 end
0032
0033 if strcmpi(name, 'verbose')
0034 verbose = varargin{2};
0035 elseif strcmpi(name, 'nIters')
0036 nIters = varargin{2};
0037 else
0038 error(['Unknown parameter name: ' name]);
0039 end
0040 varargin(1:2) = [];
0041 end
0042
0043
0044
0045
0046 nMeshes = length(meshList);
0047
0048
0049 treeList = cell(nMeshes, 1);
0050 for iMesh = 1:nMeshes
0051 treeList{iMesh} = KDTreeSearcher(meshList{iMesh}.vertices);
0052 end
0053
0054
0055 refMesh = struct('vertices', meshList{1}.vertices, 'faces', meshList{1}.faces);
0056
0057 refVerticesIters = cell(1, nIters);
0058 distListIters = cell(1, nIters);
0059
0060
0061
0062
0063 for iIter = 1:nIters
0064 if verbose
0065 fprintf('iter %d/%d\n', iIter, nIters);
0066 end
0067 refMesh = smoothMesh(refMesh);
0068
0069
0070 newVerts = zeros(size(refMesh.vertices));
0071 distList = zeros(size(refMesh.vertices, 1), 1);
0072
0073
0074 for iMesh = 1:nMeshes
0075 if verbose
0076 fprintf(' mesh %d/%d\n', iMesh, nMeshes);
0077 end
0078
0079
0080 inds = knnsearch(treeList{iMesh}, refMesh.vertices);
0081
0082
0083 closest = treeList{iMesh}.X(inds,:);
0084 newVerts = newVerts + closest;
0085 distList = distList + sum((closest - refMesh.vertices).^2, 2);
0086 end
0087
0088
0089 newVerts = newVerts / nMeshes;
0090 refVerticesIters{iIter} = newVerts;
0091 refMesh.vertices = newVerts;
0092
0093
0094 distList = sqrt(distList / nMeshes);
0095 distListIters{iIter} = distList;
0096 end
0097
0098
0099
0100
0101
0102
0103
0104