Guidance to write a parser for .Obj and mtl file

.Obj file is an ascii file that stores 3D geometric models. It contains information about vertex, normals, and textures.

.mtl file is an ascii file, that saves object materials used for obj files.

Wiki link: http://en.wikipedia.org/wiki/Wavefront_.obj_file

In this lab you will need to write a parser for .obj and .mtl file to extract the geometric objects and also their materials.

The guide includes three parts:

·        File format for .Obj file

·        File format for .mtl file

·        Guidance on writing a parser for the files

1.  Obj File Format

Each line of .Obj file starts from a special character or word

Starting character / word

Meaning

#

Comment line

v

Defines  vertex points in 3D space, with coordinates of( x, y,z,w), w is optional

vt

Define   texture coordinates (u,v,w) where w is optional

vn

Defines normals (x,y,z)

f

Defines a face, composed of index of  vertex/texture/normal. Note that texture and normal is optional.

If both texture and normal are absent

f 1 2 3

If texture exists, but normal absent

f 1/3  2/2  3/4

If texture is absent, but normal exists

f 1//3  2//2  3//4
if all them exist
f 1/2/3  2/3/2  3/2/4
each face can contains more than 3 elements
mtllib 

Materials that describe the visual aspects of the polygons are stored in external .mtl files. The .mtl file may contain one or more named material definitions.

o

Object name

g

group name

usemtl

Defines a material to use, this material will continue

to be used until another usemtl line (corresponding material is saved in .mtl file)

s

Smooth shading

mtllib

Point to an external .mtl file that saves the object materials

Note: all index starts from 1

An example Obj file:

mtllib al.mtl # al.mtl is the file that defines the materials used

# vertex coordinates

v  8 0 11.0  

v  16 0 6

v  3 0 3

….

#vertex textures

vt 0.500 -1.352 0.234 #vertex texture

#vertex normal

vn -0.717798 -0.043116 0.694915

vn -0.322618 -0.014997 0.946410

vn -0.218708 -0.027535 0.975402

#material for the following face, defined in .mtl file (al.mtl in this example)

usemtl dolph01

#faces

f 1795//1880 1794//1879 1793//1878

f 1796//1881 1794//1879 1795//1880

f 1797//1882 1796//1881 1795//1880

...

usemtl green_material

f 1/2/3 2/1/6 4/6/7

 

2.   mtl File Format

Each line of .mtl file starts from a special character or word

Starting character / word

Meaning

newmtl

Start a definition of a new material

Ka

ambient color (r,g,b)

Kd

diffuse color (r,g,b)

Ks

specular color (r,g,b)

illum

Define the illumination model: illum = 1 a flat material with no specular highlights, illum = 2 denotes the presence of specular highlights

Ns

shininess of the material

d or Tr

the transparency of the material

map_Ka

names a file containing a texture map, which should just be an ASCII dump of RGB values

 

An example .mtl file

newmtl dolph01

Ka 0.4000 0.4000 0.4000

Kd 0.0000 0.2000 1.0000

Ks 0.5000 0.5000 0.5000

illum 2

Ns 60.0000

 

3.  Writing a parser

The following is a sequence of possible steps you can follow to create the parser, it can give you a overview of the structure of the program.

3.1 Define the storage classes

a)      A 3D vector class that used to save the components of vertex coordinates, vertex normals and texture coordinates

b)      A class to save face

c)      A class to save material defined in .mtl file

d)      A class to save the whole scene that saves list of vertex, face, list of materials etc.

 

3.2  Write subroutines that takes a line of text as input and return a pointer to the object of the class defined (vector, face, material…)

You can write different subroutines for different primitives to make the code clean

 

3.3  write a top level parser function (for both .obj and .mtl file) that completes the following tasks by calling the functions defined in 3.2

a)      open a file

b)      a loop that read one text line a time, until read the end of the file

                                                                          i.      extract the first token (use strtok() function )

                                                                        ii.      compare again ‘#’, ‘v’, ‘vn’,’vt’…,

                                                                      iii.      if equals ‘v’ use the subroutine that parse vectors to parse it

                                                                       iv.      if equals ‘f’ use the subroutine that parse face to parse it

                                                                         v.      add the parse result (can be a pointer to a proper object) to the scene class

 

Note: About Memory management

The amount of memory will be needed to hold the model is not known beforehand (no such field as total vertex),

You can either wait the memory by allocating a large buffer at the beginning, or more desirably allow dynamic growing of your buffer size.