Simple .obj mesh reader for MATLAB

matlab obj mesh reader screenshotI wrote a little .obj file format reader in MATLAB. It only reads the vertices and faces of a triangle mesh (ignoring all the other commands and features). I use it to extract the vertex and face arrays.

Here’s the code, I save it in a file called read_vertices_and_faces_from_obj_file.m:


function [V,F] = read_vertices_and_faces_from_obj_file(filename)
  % Reads a .obj mesh file and outputs the vertex and face list
  % assumes a 3D triangle mesh and ignores everything but:
  % v x y z and f i j k lines
  % Input:
  %  filename  string of obj file's path
  %
  % Output:
  %  V  number of vertices x 3 array of vertex positions
  %  F  number of faces x 3 array of face indices
  %
  V = zeros(0,3);
  F = zeros(0,3);
  vertex_index = 1;
  face_index = 1;
  fid = fopen(filename,'rt');
  line = fgets(fid);
  while ischar(line)
    vertex = sscanf(line,'v %f %f %f');
    face = sscanf(line,'f %d %d %d');
    face_long = sscanf(line,'f %d/%d/%d %d/%d/%d %d/%d/%d');

    % see if line is vertex command if so add to vertices
    if(size(vertex)>0)
      V(vertex_index,:) = vertex;
      vertex_index = vertex_index+1;
    % see if line is simple face command if so add to faces
    elseif(size(face)>0)
      F(face_index,:) = face;
      face_index = face_index+1;
    % see if line is a long face command if so add to faces
    elseif(size(face_long)>0)
      % remove normal and texture indices
      face_long = face_long(1:3:end)
      F(face_index,:) = face_long;
      face_index = face_index+1;
    else
      fprintf('Ignored: %s',line);
    end

    line = fgets(fid);
  end
  fclose(fid);
end

Then I can read and render a mesh with phong shading:


[V,F] = read_vertices_and_faces_from_obj_file('path/to/your/mesh.obj');
trisurf(F,V(:,1),V(:,2),V(:,3),'FaceColor',[0.26,0.33,1.0 ]);
light('Position',[-1.0,-1.0,100.0],'Style','infinite');
lighting phong;

Tags: , ,

9 Responses to “Simple .obj mesh reader for MATLAB”

  1. Joshua says:

    This is exactly what I needed! Works like a charm.

    Thanks a lot.

  2. Amanda says:

    cool! exactly what I was looking for. Thanks.

  3. Vivian Allen says:

    Hey, great file, really quick and simple! I would potentially like to use it for research (part of a series of functions for determining mass props from a mesh): A) is that ok with you, and B) if so, how would you prefer to be referenced?
    Cheers again!

    Viv

  4. Vivian Allen says:

    Oh yeah, and I made a few tweaks (like two changes and a conditional formatting statement at the end) to make it work with quads as well as tris, if you want the edited function lemme know.
    Thanks!

    Viv

  5. Ava says:

    Nice job!

    Is it possible to have the code which works with quads?

    Thanks

  6. ajx says:

    For a quad mesh, just simply change it to read in 4 face indices instead of 3. Like this:

    face = sscanf(line,'f %d %d %d %d');
    face_long = sscanf(line,'f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d');

    Then to display the mesh (faking it as a triangle mesh to show the filled surface and plotting lines around each quad):

    [V,F] = read_obj_quads('mudbox-car-VF.obj');
    E = [F(:,1) F(:,2);F(:,2) F(:,3); F(:,3) F(:,4); F(:,4) F(:,1)];
    trisurf([F(:,1:3);F(:,[1 3 4])],V(:,1),V(:,2),V(:,3),'FaceColor',[0.26,0.33,1.0 ],'EdgeColor','none');
    hold on; plot3([V(E(:,1),1) V(E(:,2),1)]',[V(E(:,1),2) V(E(:,2),2)]',[V(E(:,1),3) V(E(:,2),3)]','k-'); hold off
    light('Position',[-1.0,-1.0,100.0],'Style','infinite');
    lighting phong;
    axis equal

  7. ainajay says:

    hi can this code be applied for human body segmentation?

  8. moira says:

    Great great great!!
    I’ve never worked with 3D in Matlab. Those days I really needed to implement sth like that in order to proceed further with my research. Thx a loottttt!!
    P.S. the same questions as Vvivan: A) is that ok with you to use your script? B) if so, how should I refer to your work?

  9. Jeff says:

    Thanks!!! this is precisely what i was looking for.

Leave a Reply