File Exchange

image thumbnail

Wavefront OBJ toolbox

version (203 KB) by Dirk-Jan Kroon
Read and Write Wavefront OBJ geometry and MTL files


Updated 09 Sep 2011

View License

Read and Write Wavefront OBJ geometry and MTL files.

A Wavefront Geometry Object file is supported by many 3D programs, it looks like:
v 0.000000 2.000000 0.000000
v 0.000000 0.000000 0.000000
v 2.000000 0.000000 0.000000
v 2.000000 2.000000 0.000000
% Vertices Coordinates 4
f 1 2 3 4
% Faces 1

The function read_wobj allow Wavefront object files including material MTL files to be read into a Matlab structure.
The function write_wobj exports a Matlab structure to an OBJ file.

It doesn't matter if the object file contains splines or polygon based geometry, it reads and writes almost all .obj files.

See "help read_wobj" and "help write_wobj"

Comments and bug reports are welcome

Comments and Ratings (30)

Devon Jakob

naveen B

thanqq soo much sir

Jerry Wang

If you export the .obj with a material library .mtl file that is in a subdirectory, the .obj file will try to import the library using the line "mtllib <subdirectory>/<material name>.mtl". The .mtl file seems to always be generated in the same directory as the .obj file, so when you import the .obj file residing in <subdirectory>, the <subdirectory> will be dublicated for the material library and cause an error, at least in the native blender import. I propose the following change that works for me in R2018a, ubuntu 18.04, blender 2.79:


filename_mtl=fullfile(filefolder,[filename '.mtl']);
%fprintf(fid,'mtllib %s\n',filename_mtl);

% --- Added by Jerry Wang on Feb 6, 2019 ----------
filename_mtl2=[filename '.mtl'];
fprintf(fid,'mtllib %s\n',filename_mtl2);
% --- End amendment -------------------------------



Great work! How do I get the (X,Y,Z) coordinates for this mesh?

Linus Boehm

pretty buggy, but it works for me with the changes suggested by Mike in the comments


even when I use slash or back slash same error:
Undefined function 'read_wobj' for input arguments of type 'char'.


plz to fix this error:

Undefined function 'read_wobj' for input arguments of type 'char'.

can you tell from where we can get .obj and .mtl files.



This is not the finest example of modern coding practices. But, it sure saved me a lot of time over writing my own. Thank you, Dirk-Jan Kroon!

I came across two bugs which I addressed as follows:

ERROR 1: “invalid file identifier…”

I encapsulated the ‘readmtl’ call (near line 80) using the following:
if exist(filename_mtl,'file') == 2

ERROR 2: "field assignment to a non-structure array object."

This error is due to the preallocation of the variable "objects." I fixed the problem by defining a 'defaultobject' and using this value you preallocate the array. Of course this defaultobject needs to be defined in every function that uses this preallocation schema.

% At lines ~50 and ~370, I added the following line:
defaultobject = struct('data',struct(),'type','');
% Then I search and replaced:
% with

This works for now.
*backs away slowly*


It does not check if there is a mtl file in the first place. After fixing that myself I had a weird error about the "object" variable: error trying to assign a field in a non-struct object. Couldn't be bothered after that so I'll just write my own.


Excellent. However, I have found a bug with Di3D files that do not have a normal defined; the read file gets confused by a trailing / as in f 1271/674/
My kludgy fix is to amend the function stringsplit:
%i=find(tline(2:end-1)==tchar)+1; i_start=[1 i+1]; i_end=[i-1 length(tline)]; %as supplied
if i(end)==length(tline) % theres a 'char' at the end of the line
i = i(1:end-1); %drop last one
i_start=[1 i+1]; i_end=[i-1 length(tline)-1];
i_start=[1 i+1]; i_end=[i-1 length(tline)];



Sorry for the 1 star. Mathworks's commenting system is clearly not very polished.

In any case, code doesn't work with example .obj format provided and then example code in the function. After some fiddling, it is clear that % is being recognized as an object type, and if .obj file contains types other than those specified, the code doesn't execute well.


Joe Wang

Works well for me but question is how to show the mesh model in Matlab?


I tried this on an obj file created by meshlab and it returned this error

% OBJ File Generated by Meshlab
% Object example-cloud.obj
% Vertices: 197749
% Faces: 0
??? Subscripted assignment dimension mismatch.

Error in ==> read_wobj at 90

do you know how to fix it ? or how to obtain a 3d coordinates from meshlab?

I have the same problem as Nabil. you have found the solution? Thank you

Dalia Nabil

I tried this on an obj file created by meshlab and it returned this error

% OBJ File Generated by Meshlab
% Object example-cloud.obj
% Vertices: 197749
% Faces: 0
??? Subscripted assignment dimension mismatch.

Error in ==> read_wobj at 90

do you know how to fix it ? or how to obtain a 3d coordinates from meshlab?


mourad, check filename for correct slash orientation.

Under Linux, you should use
instead of
from commented example.

Rely good work but it give me that error so any one can help me cause i'm anew user for matlab
??? Error using ==> fread
Invalid file identifier. Use fopen to generate a valid file identifier.

Error in ==> read_wobj>file2cellarray at 298
file_text=fread(fid, inf, 'uint8=>char')';

Error in ==> read_wobj>readmtl at 363

Error in ==> read_wobj at 78
and that in read file
thanks for help

However, it is painfully slow at reading larger files.

Works well, good help text, well written.

Worked great!


So far this is a good find. I have found a bug if the file name of the obj contains a space. In line 69 of read_wobj.m: filename_mtl=fullfile(filefolder,data); returns the error:

??? Undefined function or method 'eq' for input arguments of type 'cell'.

Error in ==> fullfile at 39
elseif (f(end)==fs) || (part(1)==fs || (bIsPC && (f(end)=='/' || part(1)=='/')) )

I know the for-loop is killing the speed in Matlab, especially because the wavefront obj. format is really broad.
If you know your data at forehand, you can remove probably more than 80% of the lines of code.


Too slow for large models!

Jun wan

thanks for your code.I have a question that how can i using the texture data when show the 3D objtect? In your code ,you only used in vertices and faces. Looking forword to your answer.

Jun wan

it's great work! thanks


Bug fixes,
- Filename '.mtl' with space now supported
- Blender uses face objects in case of a line

Fixed Nan Bug (Detected by Owens M.A.)

Add file-format help and made the code compatible with all most all possible .obj files.

MATLAB Release Compatibility
Created with R2010a
Compatible with any release
Platform Compatibility
Windows macOS Linux