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