REMOVEUNREFERENCEDVERTICES Remove unreferenced vertices of a mesh. [V2, F2] = removeUnreferencedVertices(V, F) Remove unreferenced/unindexed vertices of a mesh defined by the vertices V and faces F. [VIDX, FIDX] = removeUnreferencedVertices(V, F, 'indexOutput', true) Gives the indices instead of the final mesh. This means: V2 = V(VIDX,:) F2 = FIDX(F) Example: [v, f] = createCube; % Add unreferenced vertices for idx = [2, 5, 7] v = [v(1:idx,:); rand(1,3); v(idx+1:end,:)]; f(find(f>idx))=f(find(f>idx))+1; %#ok<FNDSB> end [v2, f2] = removeUnreferencedVertices(v, f); See also trimMesh, removeDuplicateFaces, removeDuplicateVertices Source remove_unreferenced.m by Alec Jacobson: https://github.com/alecjacobson/gptoolbox
0001 function varargout = removeUnreferencedVertices(v, varargin) 0002 %REMOVEUNREFERENCEDVERTICES Remove unreferenced vertices of a mesh. 0003 % 0004 % [V2, F2] = removeUnreferencedVertices(V, F) 0005 % Remove unreferenced/unindexed vertices of a mesh defined by the 0006 % vertices V and faces F. 0007 % 0008 % [VIDX, FIDX] = removeUnreferencedVertices(V, F, 'indexOutput', true) 0009 % Gives the indices instead of the final mesh. This means: 0010 % V2 = V(VIDX,:) 0011 % F2 = FIDX(F) 0012 % 0013 % Example: 0014 % [v, f] = createCube; 0015 % % Add unreferenced vertices 0016 % for idx = [2, 5, 7] 0017 % v = [v(1:idx,:); rand(1,3); v(idx+1:end,:)]; 0018 % f(find(f>idx))=f(find(f>idx))+1; %#ok<FNDSB> 0019 % end 0020 % [v2, f2] = removeUnreferencedVertices(v, f); 0021 % 0022 % See also 0023 % trimMesh, removeDuplicateFaces, removeDuplicateVertices 0024 % 0025 % Source 0026 % remove_unreferenced.m by Alec Jacobson: 0027 % https://github.com/alecjacobson/gptoolbox 0028 0029 % ------ 0030 % Author: oqilipo 0031 % E-mail: N/A 0032 % Created: 2023-07-14, using Matlab 9.13.0.2080170 (R2022b) Update 1 0033 % Copyright 2023-2024 0034 0035 %% Parse input 0036 if isstruct(v) 0037 [v, f] = parseMeshData(v); 0038 else 0039 f = varargin{1}; 0040 varargin(1) = []; 0041 end 0042 0043 parser = inputParser; 0044 logParValidFunc = @(x) (islogical(x) || isequal(x,1) || isequal(x,0)); 0045 addParameter(parser, 'indexOutput', false, logParValidFunc); 0046 parse(parser, varargin{:}); 0047 indexOutput = parser.Results.indexOutput; 0048 0049 %% Remove unreferenced/unindexed vertices 0050 if isempty(f) 0051 [vIdx, fIdx] = deal([]); 0052 else 0053 % Get list of unique vertex indices that occur in faces 0054 sF = sort(f(:)); 0055 I = [true;diff(sF)~=0]; 0056 U = sF(I); 0057 % Get list of vertices that do not occur in faces 0058 n = size(v,1); 0059 NU = find(0==sparse(U,1,1,n,1)); 0060 % assert((size(U,1) + size(NU,1)) == n); 0061 % Allocate space for an indexmap 0062 fIdx = zeros(n,1); 0063 % Reindex vertices that occur in faces to be first 0064 fIdx(U) = 1:size(U,1); 0065 % Reindex vertices that do not occur in faces to come after those that do 0066 fIdx(NU) = size(U,1) + (1:size(NU,1)); 0067 % New vertices 0068 vIdx = ismember(1:length(v),U); 0069 % v2(fIdx,:) = v; 0070 % v2 = v2(1:max(fIdx(f(:))),:); 0071 end 0072 0073 %% Parse output 0074 if indexOutput 0075 % If indices are requested 0076 varargout = {vIdx, fIdx}; 0077 else 0078 v2 = v(vIdx,:); 0079 f2 = fIdx(f); 0080 varargout = formatMeshOutput(nargout, v2, f2); 0081 end 0082 0083 end