import sys import tinyobjloader is_numpy_available = False try: import numpy is_numpy_available = True except: print( "NumPy not installed. Do not use numpy_*** API. If you encounter slow performance, see a performance tips for non-numpy API https://github.com/tinyobjloader/tinyobjloader/issues/275" ) filename = "../models/cornell_box.obj" if len(sys.argv) > 1: filename = sys.argv[1] reader = tinyobjloader.ObjReader() # Load .obj(and .mtl) using default configuration ret = reader.ParseFromFile(filename) # Optionally you can set custom `config` # config = tinyobj.ObjReaderConfig() # config.triangulate = False # ret = reader.ParseFromFile(filename, config) if ret == False: print("Failed to load : ", filename) print("Warn:", reader.Warning()) print("Err:", reader.Error()) sys.exit(-1) if reader.Warning(): print("Warn:", reader.Warning()) attrib = reader.GetAttrib() print("len(attrib.vertices) = ", len(attrib.vertices)) print("len(attrib.vertex_weights) = ", len(attrib.vertex_weights)) print("len(attrib.normals) = ", len(attrib.normals)) print("len(attrib.texcoords) = ", len(attrib.texcoords)) print("len(attrib.colors) = ", len(attrib.colors)) print("len(attrib.skin_weights) = ", len(attrib.skin_weights)) # vertex data must be `xyzxyzxyz...` assert len(attrib.vertices) % 3 == 0 # normal data must be `xyzxyzxyz...` assert len(attrib.normals) % 3 == 0 # texcoords data must be `uvuvuv...` assert len(attrib.texcoords) % 2 == 0 # colors data must be `rgbrgbrgb...` assert len(attrib.texcoords) % 3 == 0 # Performance note # (direct?) array access through member variable is quite slow. # https://github.com/tinyobjloader/tinyobjloader/issues/275#issuecomment-753465833 # # We encourage first copy(?) varible to Python world: # # vertices = attrib.vertices # # for i in range(...) # v = vertices[i] # # Or please consider using numpy_*** interface(e.g. numpy_vertices()) for i, v in enumerate(attrib.vertices): print("v[{}] = {}".format(i, v)) # vw is filled with 1.0 if [w] component is not present in `v` line in .obj for i, w in enumerate(attrib.vertex_weights): print("vweight[{}] = {}".format(i, w)) for i, v in enumerate(attrib.normals): print("vn[{}] = {}".format(i, v)) for i, v in enumerate(attrib.texcoords): print("vt[{}] = {}".format(i, v)) for i, v in enumerate(attrib.colors): print("vcol[{}] = {}".format(i, v)) if len(attrib.skin_weights): print("num skin weights", len(attrib.skin_weights)) for i, skin in enumerate(attrib.skin_weights): print("skin_weight[{}]".format(i)) print(" vertex_id = ", skin.vertex_id) print(" len(weights) = ", len(skin.weightValues)) for k, w in enumerate(skin.weightValues): print(" [{}] joint_id: {}, weight: {}".format(k, w.joint_id, w.weight)) if is_numpy_available: print("numpy_v = {}".format(attrib.numpy_vertices())) print("numpy_vn = {}".format(attrib.numpy_normals())) print("numpy_vt = {}".format(attrib.numpy_texcoords())) print("numpy_vcol = {}".format(attrib.numpy_colors())) materials = reader.GetMaterials() print("Num materials: ", len(materials)) for m in materials: print(m.name) print(m.diffuse) print(m.diffuse_texname) # Partial update(array indexing) does not work # m.diffuse[1] = 1.0 # Update with full object assignment works m.diffuse = [1, 2, 3] print(m.diffuse) # print(m.shininess) # print(m.illum) shapes = reader.GetShapes() print("Num shapes: ", len(shapes)) for shape in shapes: print(shape.name) print("len(num_indices) = {}".format(len(shape.mesh.indices))) for i, idx in enumerate(shape.mesh.indices): print("[{}] v_idx {}".format(i, idx.vertex_index)) print("[{}] vn_idx {}".format(i, idx.normal_index)) print("[{}] vt_idx {}".format(i, idx.texcoord_index)) print("material_ids = {}".format(shape.mesh.material_ids)) # faster access to indices a = shape.mesh.vertex_indices() print("vertex_indices", shape.mesh.vertex_indices()) if is_numpy_available: print("numpy_indices = {}".format(shape.mesh.numpy_indices())) print("numpy_num_face_vertices = {}".format(shape.mesh.numpy_num_face_vertices())) print("numpy_material_ids = {}".format(shape.mesh.numpy_material_ids()))