Home > matGeom > meshes3d > averageMesh.m

averageMesh

PURPOSE ^

Compute average mesh from a list of meshes.

SYNOPSIS ^

function [refMesh, distListIters, refVerticesIters] = averageMesh(meshList, varargin)

DESCRIPTION ^

 Compute average mesh from a list of meshes.

   AVG = averageMesh(MESHLIST)

   Example
   averageMesh

   See also
     meshes3d

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [refMesh, distListIters, refVerticesIters] = averageMesh(meshList, varargin)
0002 % Compute average mesh from a list of meshes.
0003 %
0004 %   AVG = averageMesh(MESHLIST)
0005 %
0006 %   Example
0007 %   averageMesh
0008 %
0009 %   See also
0010 %     meshes3d
0011  
0012 % ------
0013 % Author: David Legland
0014 % e-mail: david.legland@inrae.fr
0015 % INRAE - BIA Research Unit - BIBS Platform (Nantes)
0016 % Created: 2020-01-31,    using Matlab 9.7.0.1247435 (R2019b) Update 2
0017 % Copyright 2020 INRAE.
0018 
0019 
0020 %% Parse input values
0021 
0022 % default values
0023 nIters = 10;
0024 verbose = false;
0025 
0026 % parse input arguments
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 %% Initialisations
0045 
0046 nMeshes = length(meshList);
0047 
0048 % initialize kd-trees to accelerate nearest-neighbor searches
0049 treeList = cell(nMeshes, 1);
0050 for iMesh = 1:nMeshes
0051     treeList{iMesh} = KDTreeSearcher(meshList{iMesh}.vertices);
0052 end
0053 
0054 % choose arbitrary initial mesh
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 %% Main iteration
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     % create new array for average vertices
0070     newVerts = zeros(size(refMesh.vertices));
0071     distList = zeros(size(refMesh.vertices, 1), 1);
0072     
0073     % iterate over all meshes
0074     for iMesh = 1:nMeshes
0075         if verbose
0076             fprintf('    mesh %d/%d\n', iMesh, nMeshes);
0077         end
0078         
0079 %         mesh = meshList{iMesh};
0080         inds = knnsearch(treeList{iMesh}, refMesh.vertices); 
0081 
0082 %         closest = mesh.vertices(inds,:);
0083         closest = treeList{iMesh}.X(inds,:);
0084         newVerts = newVerts + closest;
0085         distList = distList + sum((closest - refMesh.vertices).^2, 2);
0086     end
0087 
0088     % update new vertices
0089     newVerts = newVerts / nMeshes;
0090     refVerticesIters{iIter} = newVerts;
0091     refMesh.vertices = newVerts;
0092     
0093     % keep list of distances
0094     distList = sqrt(distList / nMeshes);
0095     distListIters{iIter} = distList;
0096 end
0097 
0098 
0099 % figure; drawMesh(refMesh, 'lineStyle', 'none', 'faceColor', [.5 .5 .5])
0100 % axis equal; view(3); hold on; axis([-2.5 2.5 -2 2 -3.5 3.5]); light;
0101 % lighting gouraud
0102 % title('Average mesh');
0103 % print(gcf, 'averageMesh_initial.png', '-dpng');
0104

Generated on Wed 16-Feb-2022 15:10:47 by m2html © 2003-2019