@@ -10,20 +10,22 @@ class ObjParser(Parser):
1010 """This parser parses lines from .obj files."""
1111 material_parser_cls = MaterialParser
1212
13- def __init__ (self , wavefront , file_name , strict = False , encoding = "utf-8" , parse = True ):
13+ def __init__ (self , wavefront , file_name , strict = False , encoding = "utf-8" , create_materials = False , parse = True ):
1414 """
1515 Create a new obj parser
1616 :param wavefront: The wavefront object
1717 :param file_name: file name and path of obj file to read
1818 :param strict: Enable strict mode
1919 :param encoding: Encoding to read the text files
20+ :param create_materials: Create materials if they don't exist
2021 :param parse: Should parse be called immediately or manually called later?
2122 """
2223 super (ObjParser , self ).__init__ (file_name , strict = strict , encoding = encoding )
2324 self .wavefront = wavefront
2425
2526 self .mesh = None
2627 self .material = None
28+ self .create_materials = create_materials
2729
2830 # Stores ALL vertices, normals and texcoords for the entire file
2931 self .vertices = []
@@ -123,17 +125,28 @@ def consume_texture_coordinates(self):
123125 @auto_consume
124126 def parse_mtllib (self ):
125127 mtllib = os .path .join (self .dir , " " .join (self .values [1 :]))
126- materials = self .material_parser_cls (mtllib , encoding = self .encoding , strict = self .strict ).materials
128+ try :
129+ materials = self .material_parser_cls (mtllib , encoding = self .encoding , strict = self .strict ).materials
130+ except IOError :
131+ if self .create_materials :
132+ return
133+ raise
127134
128135 for name , material in materials .items ():
129136 self .wavefront .materials [name ] = material
130137
131138 @auto_consume
132139 def parse_usemtl (self ):
133- self .material = self .wavefront .materials .get (self .values [1 ], None )
140+ name = " " .join (self .values [1 :])
141+ self .material = self .wavefront .materials .get (name , None )
134142
135143 if self .material is None :
136- raise PywavefrontException ('Unknown material: %s' % self .values [1 ])
144+ if not self .create_materials :
145+ raise PywavefrontException ('Unknown material: %s' % name )
146+
147+ # Create a new default material if configured to resolve missing ones
148+ self .material = Material (name = name , is_default = True )
149+ self .wavefront .materials [name ] = self .material
137150
138151 if self .mesh is not None :
139152 self .mesh .add_material (self .material )
@@ -214,7 +227,10 @@ def consume_faces(self):
214227
215228 # If the material already have vertex data, ensure the same format is used
216229 if self .material .vertex_format and self .material .vertex_format != vertex_format :
217- raise ValueError ("Trying to merge vertex data with different formats" )
230+ raise ValueError ((
231+ "Trying to merge vertex data with different format: {}. "
232+ "Material {} has vertex format {}"
233+ ).format (vertex_format , self .material .name , self .material .vertex_format ))
218234
219235 self .material .vertex_format = vertex_format
220236
0 commit comments