Read mesh data stored in OFF format. [VERTICES, FACES] = readMesh_off(FILENAME) Read the data stored in file FILENAME and return the vertex and face arrays as NV-by-3 array and NF-by-N array respectively, where NV is the number of vertices and NF is the number of faces. MESH = readMesh_off(FILENAME) Read the data stored in file FILENAME and return the mesh into a struct with fields 'vertices' and 'faces'. Example [v, f] = readMesh_off('mushroom.off'); figure; drawMesh(v, f, 'faceColor', [0 1 0], 'edgeColor', 'none') view([5 80]); light; lighting gouraud See also meshes3d, readMesh, writeMesh_off, drawMesh
0001 function varargout = readMesh_off(fileName) 0002 % Read mesh data stored in OFF format. 0003 % 0004 % [VERTICES, FACES] = readMesh_off(FILENAME) 0005 % Read the data stored in file FILENAME and return the vertex and face 0006 % arrays as NV-by-3 array and NF-by-N array respectively, where NV is the 0007 % number of vertices and NF is the number of faces. 0008 % 0009 % MESH = readMesh_off(FILENAME) 0010 % Read the data stored in file FILENAME and return the mesh into a struct 0011 % with fields 'vertices' and 'faces'. 0012 % 0013 % Example 0014 % [v, f] = readMesh_off('mushroom.off'); 0015 % figure; drawMesh(v, f, 'faceColor', [0 1 0], 'edgeColor', 'none') 0016 % view([5 80]); light; lighting gouraud 0017 % 0018 % See also 0019 % meshes3d, readMesh, writeMesh_off, drawMesh 0020 % 0021 0022 % ------ 0023 % Author: David Legland 0024 % e-mail: david.legland@inra.fr 0025 % Created: 2011-12-20, using Matlab 7.9.0.529 (R2009b) 0026 % Copyright 2011 INRA - Cepia Software Platform. 0027 0028 0029 %% Read header 0030 0031 % open file 0032 f = fopen(fileName, 'r'); 0033 if f == -1 0034 error('matGeom:readMesh_off:FileNotFound', ... 0035 ['Could not find file: ' fileName]); 0036 end 0037 0038 % check format 0039 line = fgetl(f); % -1 if eof 0040 if ~strcmp(line(1:3), 'OFF') 0041 error('matGeom:readMesh_off:FileFormatError', ... 0042 'Not a valid OFF file'); 0043 end 0044 0045 % number of faces and vertices 0046 line = fgetl(f); 0047 vals = sscanf(line, '%d %d'); 0048 nVertices = vals(1); 0049 nFaces = vals(2); 0050 0051 0052 %% Read vertex data 0053 [vertices, count] = fscanf(f, '%f ', [3 nVertices]); 0054 if count ~= nVertices * 3 0055 error('matGeom:readMesh_off:FileFormatError', ... 0056 ['Could not read all the ' num2str(nVertices) ' vertices']); 0057 end 0058 vertices = vertices'; 0059 0060 0061 %% Read Face data 0062 % First try to read faces as an homogeneous array. It if fails, start from 0063 % face offset and parse each face individually. In the latter case, faces 0064 % can have different number of vertices. 0065 0066 % keep position of face info within file 0067 faceOffset = ftell(f); 0068 0069 % read first face to assess number of vertices per face 0070 line = fgetl(f); 0071 if line == -1 0072 error('matGeom:readMesh_off:FileFormatError', ... 0073 'Unexpected end of file'); 0074 end 0075 tokens = split(line); 0076 face1 = str2double(tokens(2:end))' + 1; 0077 nv = length(face1); 0078 0079 try 0080 % attenpt to read the remaining faces assuming they all have the same 0081 % number of vertices 0082 pattern = ['%d' repmat(' %d', 1, nv) '\n']; 0083 [faces, count] = fscanf(f, pattern, [(nv+1) (nFaces-1)]); 0084 if count ~= (nFaces-1) * (nv+1) 0085 error('matGeom:readMesh_off:FileFormatError', ... 0086 'Could not read all the %d faces', nFaces); 0087 end 0088 0089 % transpose, remove first column, use 1-indexing, and concatenate with 0090 % first face 0091 faces = [face1 ; faces(2:end,:)'+1]; 0092 0093 catch 0094 % if attempt failed, switch to slower face-by-face parsing 0095 disp('readMesh_off: Inhomogeneous number of vertices per face, switching to face-per-face parsing'); 0096 0097 fseek(f, faceOffset, 'bof'); 0098 0099 % allocate cell array 0100 faces = cell(1, nFaces); 0101 0102 % iterate over faces 0103 for iFace = 1:nFaces 0104 % read next line 0105 line = fgetl(f); 0106 if line == -1 0107 error('matGeom:readMesh_off:FileFormatError', ... 0108 'Unexpected end of file'); 0109 end 0110 0111 % parse vertex indices for current face 0112 tokens = split(line); 0113 faces{iFace} = str2double(tokens(2:end))' + 1; 0114 end 0115 end 0116 0117 0118 %% Post-processing 0119 0120 % close the file 0121 fclose(f); 0122 0123 % format output arguments 0124 if nargout < 2 0125 mesh.vertices = vertices; 0126 mesh.faces = faces; 0127 varargout = {mesh}; 0128 else 0129 varargout = {vertices, faces}; 0130 end