MESHBOUNDARY Boundary of a mesh as a collection of 3D line strings. CURVES = meshBoundary(V, F) Example % create centered icosahedron [v, f] = createIcosahedron; v(:,3) = v(:,3) - mean(v(:,3)); % convert to simili-sphere [v2, f2] = subdivideMesh(v, f, 3); v3 = normalizeVector3d(v2); % clip with plane plane = createPlane([0 0 0], [-1 -2 3]); [vc, fc] = clipMeshVertices(v3, f2, plane, 'shape', 'plane'); figure; drawMesh(vc, fc); axis equal; view(3); % draw mesh boundary curves = meshBoundary(vc, fc); hold on; drawPolygon3d(curves{1}, 'linewidth', 2, 'color', 'b'); See also meshes3d, meshBoundaryEdgeIndices, meshBoundaryVertexIndices
0001 function polyList = meshBoundary(varargin) 0002 %MESHBOUNDARY Boundary of a mesh as a collection of 3D line strings. 0003 % 0004 % CURVES = meshBoundary(V, F) 0005 % 0006 % Example 0007 % % create centered icosahedron 0008 % [v, f] = createIcosahedron; 0009 % v(:,3) = v(:,3) - mean(v(:,3)); 0010 % % convert to simili-sphere 0011 % [v2, f2] = subdivideMesh(v, f, 3); 0012 % v3 = normalizeVector3d(v2); 0013 % % clip with plane 0014 % plane = createPlane([0 0 0], [-1 -2 3]); 0015 % [vc, fc] = clipMeshVertices(v3, f2, plane, 'shape', 'plane'); 0016 % figure; drawMesh(vc, fc); axis equal; view(3); 0017 % % draw mesh boundary 0018 % curves = meshBoundary(vc, fc); 0019 % hold on; drawPolygon3d(curves{1}, 'linewidth', 2, 'color', 'b'); 0020 % 0021 % See also 0022 % meshes3d, meshBoundaryEdgeIndices, meshBoundaryVertexIndices 0023 % 0024 0025 % ------ 0026 % Author: David Legland 0027 % e-mail: david.legland@inra.fr 0028 % Created: 2019-05-01, using Matlab 8.6.0.267246 (R2015b) 0029 % Copyright 2019 INRA - Cepia Software Platform. 0030 0031 [vertices, edges, faces] = parseMeshData(varargin{:}); 0032 0033 % Compute edge-vertex map if not specified 0034 if isempty(edges) 0035 edges = meshEdges(vertices, faces); 0036 end 0037 0038 bndEdgeInds = meshBoundaryEdgeIndices(vertices, edges, faces); 0039 bndEdges = edges(bndEdgeInds, :); 0040 0041 if isempty(bndEdgeInds) 0042 polyList = {}; 0043 return; 0044 end 0045 0046 % allocate empty array 0047 polyList = {}; 0048 0049 nPolys = 0; 0050 while ~isempty(bndEdges) 0051 nPolys = nPolys + 1; 0052 0053 % current edge 0054 edge = bndEdges(1, :); 0055 0056 % initialize new polyline at first vertex 0057 ind0 = edge(1); 0058 vertexInds = ind0; 0059 0060 % current vertex 0061 index = edge(2); 0062 bndEdges(1, :) = []; 0063 0064 % iterate over edges until current vertex becomes ind0 0065 while index ~= ind0 0066 % append current vertex to list of indices for current polygon 0067 vertexInds = [vertexInds ; index]; %#ok<AGROW> 0068 0069 % index of the next edge containing current vertex 0070 edgeInd = find(sum(bndEdges == index, 2) > 0); 0071 0072 % check validity 0073 if isempty(edgeInd) 0074 error('could not find next edge for vertex index %d', index); 0075 end 0076 if length(edgeInd) > 1 0077 error('two many edges contains vertex index %d', index); 0078 end 0079 0080 % remove current edge from the list of edges to process 0081 edge = bndEdges(edgeInd, :); 0082 bndEdges(edgeInd, :) = []; 0083 0084 % % check if current edge closes current polygon 0085 % if index == ind0 0086 % break; 0087 % end 0088 0089 % identify the next index 0090 index = edge(edge ~= index); 0091 end 0092 0093 % create the 3D polyline 0094 polyList{nPolys} = vertices(vertexInds, :); %#ok<AGROW> 0095 end