Home > matGeom > meshes3d > concatenateMeshes.m

concatenateMeshes

PURPOSE ^

CONCATENATEMESHES Concatenate multiple meshes.

SYNOPSIS ^

function varargout = concatenateMeshes(varargin)

DESCRIPTION ^

CONCATENATEMESHES Concatenate multiple meshes.

   [V, F] = concatenateMeshes(V1, F1, V2, F2, ...)
   Returns one mesh represented by vertices V and faces F by concatenating
   the meshes defined by V1, V2, ... and F1, F2, ...

   [V, F] = concatenateMeshes(MESH1, MESH2, ...)
   where MESH1, MESH2, ... are structs or struct arrays with the fields  
   vertices and faces

   Example
     apple = readMesh('apple.ply');
     apple.vertices = apple.vertices*50;
     apple = transformMesh(apple, ...
         createTranslation3d([-7 -6 0])*createRotationOx(pi/2));
     bunny = readMesh('bunny_F1k.ply');
     bunnyEatsApple = concatenateMeshes(bunny, apple);
     drawMesh(bunnyEatsApple)
     view(3)

   See also
     splitMesh

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function varargout = concatenateMeshes(varargin)
0002 %CONCATENATEMESHES Concatenate multiple meshes.
0003 %
0004 %   [V, F] = concatenateMeshes(V1, F1, V2, F2, ...)
0005 %   Returns one mesh represented by vertices V and faces F by concatenating
0006 %   the meshes defined by V1, V2, ... and F1, F2, ...
0007 %
0008 %   [V, F] = concatenateMeshes(MESH1, MESH2, ...)
0009 %   where MESH1, MESH2, ... are structs or struct arrays with the fields
0010 %   vertices and faces
0011 %
0012 %   Example
0013 %     apple = readMesh('apple.ply');
0014 %     apple.vertices = apple.vertices*50;
0015 %     apple = transformMesh(apple, ...
0016 %         createTranslation3d([-7 -6 0])*createRotationOx(pi/2));
0017 %     bunny = readMesh('bunny_F1k.ply');
0018 %     bunnyEatsApple = concatenateMeshes(bunny, apple);
0019 %     drawMesh(bunnyEatsApple)
0020 %     view(3)
0021 %
0022 %   See also
0023 %     splitMesh
0024 
0025 % ------
0026 % Authors: oqilipo (parsing), Alec Jacobson (loop)
0027 % E-mail: N/A
0028 % Created: 2017-09-12
0029 % Copyright 2017-2024
0030 
0031 %% parsing inputs
0032 assert(~isempty(varargin))
0033 
0034 if isstruct(varargin{1})
0035     VF_fields = {'vertices','faces'};
0036     
0037     errorStructFields=['If the first input argument is a struct '...
0038         'with the fields vertices and faces the additonal ' ...
0039         'arguments must have the same format'];
0040     % Check, if all input arguments are structs
0041     assert(all(cellfun(@isstruct, varargin)), errorStructFields)
0042     % Check, if all structs contain the two fields vertices and faces
0043     assert(all(cellfun(@(x) all(ismember(VF_fields, ...
0044         fieldnames(x))), varargin)), errorStructFields)
0045 
0046     % Delete all fields except vertices and faces
0047     for s = 1:length(varargin)
0048         delFields = fieldnames(varargin{s});
0049         delFields(ismember(fieldnames(varargin{s}), VF_fields))=[];
0050         varargin{s} = rmfield(varargin{s}, delFields);
0051     end
0052     
0053     
0054     if isscalar(varargin)
0055         errorArgAndStructLength = ['If the input is only one struct ' ...
0056             'it has to contain more than one mesh.'];
0057         assert(length(varargin{1})>1, ...
0058             errorArgAndStructLength)
0059     end
0060     
0061     % Order of the fields: vertices, faces
0062     varargin = cellfun(@(x) orderfields(x, VF_fields),varargin, 'UniformOutput',0);
0063     
0064     % Convert the structs into one cell array
0065     varargin = cellfun(@struct2cell, varargin, 'UniformOutput', false);
0066     varargin = cellfun(@squeeze, varargin, 'UniformOutput',0);
0067     varargin = reshape([varargin{:}],[],1)';
0068 end
0069 
0070 NoA = length(varargin);
0071 assert(mod(NoA,2)==0);
0072 
0073 cellfun(@(x) validateattributes(x, {'numeric'},...
0074     {'size',[NaN,3],'finite'}), varargin(1:2:end))
0075 cellfun(@(x) validateattributes(x, {'numeric'},...
0076     {'integer'}), varargin(2:2:end))
0077 % Check if all faces have the same number of columns
0078 errorFacesRows='The faces of all meshes must have the same number of columns';
0079 assert(isscalar(unique(cellfun(@(x) size(x,2), varargin(2:2:end)))), errorFacesRows)
0080 
0081 
0082 %% loop
0083 v = [];
0084 f = [];
0085 for m = 1:NoA/2
0086     vm = varargin{2*m-1};
0087     fm = varargin{2*m};
0088     f = [f; fm+size(v,1)]; %#ok<AGROW>
0089     v = [v; vm]; %#ok<AGROW>
0090 end
0091 
0092 
0093 %% parsing outputs
0094 [v, f] = trimMesh(v, f);
0095 
0096 switch nargout
0097     case 1
0098         mesh.vertices = v;
0099         mesh.faces = f;
0100         varargout{1} = mesh;
0101     case 2
0102         varargout{1} = v;
0103         varargout{2} = f;
0104 end

Generated on Thu 21-Nov-2024 11:30:22 by m2html © 2003-2022