Home > matGeom > meshes3d > readMesh_off.m

readMesh_off

PURPOSE ^

Read mesh data stored in OFF format.

SYNOPSIS ^

function varargout = readMesh_off(fileName)

DESCRIPTION ^

 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

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

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

Generated on Wed 16-Feb-2022 15:10:47 by m2html © 2003-2019