def read_obj(filename): reader = tinyobjloader.ObjReader() ret = reader.ParseFromFile(filename) if ret == False: print("Warn:", reader.Warning()) print("Err:", reader.Error()) print("Failed to load : ", filename) sys.exit(-1) attrib = reader.GetAttrib() shapes = reader.GetShapes() faces = [] vertices = list(map(tuple, np.asarray(attrib.vertices).reshape(-1, 3))) for shape in shapes: index_offset = 0 for fv in shape.mesh.num_face_vertices: face = [] for v in range(fv): face.append(shape.mesh.indices[index_offset + v].vertex_index) faces.append(face) index_offset = index_offset + fv return vertices, faces
def load_obj(fname: str): """Load .obj file using TinyOBJ and extract info. This is more robust since it can triangulate polygon meshes with up to 255 sides per face. Args: fname (str): path to Wavefront .obj file """ assert os.path.exists(fname), \ 'Invalid file path and/or format, must be an existing Wavefront .obj' reader = tinyobjloader.ObjReader() config = tinyobjloader.ObjReaderConfig() config.triangulate = True # Ensure we don't have any polygons ret = reader.ParseFromFile(fname, config) # Get vertices attrib = reader.GetAttrib() vertices = torch.FloatTensor(attrib.vertices).reshape(-1, 3) # Get triangle face indices shapes = reader.GetShapes() faces = [] for shape in shapes: faces += [idx.vertex_index for idx in shape.mesh.indices] faces = torch.LongTensor(faces).reshape(-1, 3) return vertices, faces
def faster_load_obj(obj_path): reader = tinyobjloader.ObjReader() ret = reader.ParseFromFile(obj_path) if ret is False: raise RuntimeError(f"Could not load {obj_path} with tinyobjloader") attrib = reader.GetAttrib() shapes = reader.GetShapes() vert_nb = len(attrib.vertices) // 3 vertices = np.array(attrib.vertices).reshape(vert_nb, 3) faces = [ index.vertex_index for shape in shapes for index in shape.mesh.indices ] face_nb = len(faces) // 3 faces = np.array(faces).reshape(face_nb, 3) colors = np.array(attrib.colors).reshape( vert_nb, len(attrib.colors) // vert_nb ) if len(attrib.texcoords): tex_coords_nb = len(attrib.texcoords) // 2 texcoords = np.array(attrib.texcoords).reshape(tex_coords_nb, 2) else: texcoords = None return { "vertices": vertices, "faces": faces, "colors": colors, "texcoords": texcoords, }
def obj_loader(path): # Create reader. reader = tinyobjloader.ObjReader() # Load .obj(and .mtl) using default configuration ret = reader.ParseFromFile(path) if ret == False: print("Failed to load : ", path) return None # note here for wavefront obj, #v might not equal to #vt, same as #vn. attrib = reader.GetAttrib() v = np.array(attrib.vertices).reshape(-1, 3) vn = np.array(attrib.normals).reshape(-1, 3) vt = np.array(attrib.texcoords).reshape(-1, 2) shapes = reader.GetShapes() tri = shapes[0].mesh.numpy_indices().reshape(-1, 9) f_v = tri[:, [0, 3, 6]] f_vn = tri[:, [1, 4, 7]] f_vt = tri[:, [2, 5, 8]] faces = f_v #[m, 3] face_normals = vn[f_vn].mean(axis=1) #[m, 3] face_uvs = vt[f_vt].mean(axis=1) #[m, 2] verts = v #[n, 3] vert_normals = np.zeros((verts.shape[0], 3), dtype=np.float32) #[n, 3] vert_normals[f_v.reshape(-1)] = vn[f_vn.reshape(-1)] vert_uvs = np.zeros((verts.shape[0], 2), dtype=np.float32) #[n, 2] vert_uvs[f_v.reshape(-1)] = vt[f_vt.reshape(-1)] return verts, faces, vert_normals, face_normals, vert_uvs, face_uvs
def load_obj_verts(mesh_path): # Create reader. reader = tinyobjloader.ObjReader() # Load .obj(and .mtl) using default configuration ret = reader.ParseFromFile(mesh_path) if ret == False: print("Failed to load : ", mesh_path) return None # note here for wavefront obj, #v might not equal to #vt, same as #vn. attrib = reader.GetAttrib() verts = np.array(attrib.vertices).reshape(-1, 3) return verts
def load_model_from_file(filename): reader = tinyobjloader.ObjReader() ret = reader.ParseFromFile(filename) if ret == False: print("Warn:", reader.Warning()) print("Err:", reader.Error()) print("Failed to load : ", filename) sys.exit(-1) if reader.Warning(): print("Warn:", reader.Warning()) attrib = reader.GetAttrib() print("attrib.vertices = ", len(attrib.vertices)) print("attrib.normals = ", len(attrib.normals)) print("attrib.texcoords = ", len(attrib.texcoords)) shapes = reader.GetShapes() print("Num shapes: ", len(shapes)) mesh_info = [] for shape in shapes: print(shape.name) print("num_indices = {}".format(len(shape.mesh.indices))) vertices = [] normals = [] uvCoords = [] for idxs in shape.mesh.indices: vertices.extend( attrib.vertices[3 * idxs.vertex_index:3 * idxs.vertex_index + 3]) normals.extend( attrib.vertices[3 * idxs.normal_index:3 * idxs.normal_index + 3]) uvCoords.extend( attrib.texcoords[2 * idxs.texcoord_index:2 * idxs.texcoord_index + 2]) mesh_info.append(Mesh(vertices, normals, uvCoords)) return mesh_info
import numpy as np import tinyobjloader import glm import VkInline as vki import FeiRaysInline as fri from PIL import Image reader = tinyobjloader.ObjReader() reader.ParseFromFile('spider.obj') attrib = reader.GetAttrib() positions = np.array(attrib.vertices, dtype=np.float32) positions = np.reshape(positions, (-1, 3)) normals = np.array(attrib.normals, dtype=np.float32) normals = np.reshape(normals, (-1, 3)) shapes = reader.GetShapes() lst_vertex_inds = [] lst_normal_inds = [] for shape in shapes: for ind in shape.mesh.indices: lst_vertex_inds += [ind.vertex_index] lst_normal_inds += [ind.normal_index] vertex_inds = np.array(lst_vertex_inds, dtype=np.uint32) normal_inds = np.array(lst_normal_inds, dtype=np.uint32) VK_FORMAT_R8G8B8A8_SRGB = 43 width = 900
def load_box_model(path_to_model_obj : str, flags : BoxLoadFlags = BoxLoadFlags.LOAD_ALL): # Create reader. reader = tinyobjloader.ObjReader() # Load .obj(and .mtl) using default configuration ret = reader.ParseFromFile(path_to_model_obj) if ret == False: print("Warn:", reader.Warning()) print("Err:", reader.Error()) print("Failed to load : ", path_to_model_obj) sys.exit(-1) if reader.Warning(): print("Warn:", reader.Warning()) attrib = reader.GetAttrib() shapes = reader.GetShapes() def _filter_shape(shape_name : str): if (flags & BoxLoadFlags.LOAD_DOWN) and ("_down_" in shape_name): return True elif (flags & BoxLoadFlags.LOAD_UP) and ("_up_" in shape_name): return True elif (flags & BoxLoadFlags.LOAD_SIDES) and (("_front_" in shape_name) or ("_back_" in shape_name) or ("_left_" in shape_name) or ("_right_" in shape_name)): return True return False filtered_shapes = list(filter(lambda x: _filter_shape(x.name),shapes)) side_names = [] vertices = [] normals = [] indices = [] index_map = dict() for shape in filtered_shapes: side_names.append(shape.name) for idx in shape.mesh.indices: if(idx.vertex_index in index_map): index = index_map[idx.vertex_index] else: newidx = len(index_map) index_map[idx.vertex_index] = newidx index = newidx # for all coordinates (x,y,z) for j in range(3): vertices.append(attrib.vertices[idx.vertex_index*3+j]) normals.append(attrib.normals[idx.normal_index*3+j]) indices.append(index) box_model = { "side_names" : side_names, "vertices" : vertices, "normals" : normals, "indices" : indices, "index_map" : index_map } return box_model
def read_obj(fname, force_subdivision_mesh=False): if not have_tinyobjloader: print('Warning: tinyobjloader module not found') return [] r = tinyobjloader.ObjReader() r.ParseFromFile(fname) attributes = r.GetAttrib() vertices = numpy.array(attributes.vertices) vertices = vertices.reshape((-1, 3)).astype('float32') shapes = r.GetShapes() print('%s: %d vertices, %d shapes' % (fname, vertices.shape[0], len(shapes))) meshes = [] for s in r.GetShapes(): mesh = s.mesh indices = mesh.numpy_indices() # [ v0, n0, t0, v1, n1, t1, ... ] vertex_indices = indices[::3] face_lengths = mesh.numpy_num_face_vertices() mesh_type, minn, maxn = determine_mesh_type(face_lengths) print('%s (%s): %d faces' % (s.name, mesh_type, face_lengths.shape[0])) if mesh_type.startswith('pure-') and not force_subdivision_mesh: mesh = ospray.Geometry('mesh') vertex_indices = vertex_indices.reshape( (-1, minn)).astype('uint32') mesh.set_param('index', ospray.data_constructor_vec(vertex_indices)) elif mesh_type == 'mixed-tris-and-quads' and not force_subdivision_mesh: mesh = ospray.Geometry('mesh') # Duplicate last index of triangles to get all quads new_indices = [] first = 0 for n in loop_length: if n == 3: new_indices.extend(vertex_indices[first:first + 3]) new_indices.append(vertex_indices[first + 2]) else: new_indices.extend(vertex_indices[first:first + 4]) first += n new_indices = numpy.array(new_indices, dtype=numpy.uint32).reshape( (-1, 4)) mesh.set_param('index', ospray.data_constructor_vec(new_indices)) else: # Use subdivision surface mesh = ospray.Geometry('subdivision') mesh.set_param('index', ospray.data_constructor(vertex_indices)) mesh.set_param('face', face_lengths) mesh.set_param('vertex.position', ospray.data_constructor_vec(vertices)) mesh.commit() meshes.append(mesh) return meshes
def mesh_from_file(filename: str): reader = tinyobjloader.ObjReader() ret = reader.ParseFromFile(filename) if ret == False: print("Warn:", reader.Warning()) print("Err:", reader.Error()) print("Failed to load : ", filename) if reader.Warning(): print("Warn:", reader.Warning()) attrib = reader.GetAttrib() print("attrib.vertices = ", len(attrib.vertices)) print("attrib.normals = ", len(attrib.normals)) print("attrib.texcoords = ", len(attrib.texcoords)) shapes = reader.GetShapes() print("Num shapes: ", len(shapes)) print("Num materials: ", len(reader.GetMaterials())) model_mesh = ModelMesh() print(f"material: {reader.GetMaterials()[0].ambient}") for num_shape, shape in enumerate(shapes): print(shape.name) print("num_indices = {}".format(len(shape.mesh.indices))) print(f"material = [{reader.GetMaterials()[num_shape].ambient}]") print( f"material = [{reader.GetMaterials()[num_shape].ambient_texname}]" ) vertices = [] normals = [] uvCoords = [] for idxs in shape.mesh.indices: vertices.extend( attrib.vertices[3 * idxs.vertex_index:3 * idxs.vertex_index + 3]) normals.extend( attrib.vertices[3 * idxs.normal_index:3 * idxs.normal_index + 3]) uvCoords.extend(attrib.texcoords[2 * idxs.texcoord_index:2 * idxs.texcoord_index + 2]) for i in range(len(vertices) // 9): p0 = glm.vec3(*vertices[9 * i:9 * i + 3]) p1 = glm.vec3(*vertices[9 * i + 3:9 * i + 6]) p2 = glm.vec3(*vertices[9 * i + 6:9 * i + 9]) v0 = p1 - p0 v1 = p2 - p0 N = glm.normalize(glm.cross(v0, v1)) normals[9 * i] = N.x normals[9 * i + 1] = N.y normals[9 * i + 2] = N.z normals[9 * i + 3] = N.x normals[9 * i + 4] = N.y normals[9 * i + 5] = N.z normals[9 * i + 6] = N.x normals[9 * i + 7] = N.y normals[9 * i + 8] = N.z #print(f"Adding mesh of {len(vertices),") material_info = MaterialInfo() mesh = None if not reader.GetMaterials()[num_shape].ambient_texname == "": mesh = TexturedMesh(vertices, normals, uvCoords, material_info) else: material_info.color = glm.vec3( *reader.GetMaterials()[num_shape].diffuse) print(f"material_info.color = {material_info.color}") mesh = RawMesh(vertices, normals, material_info) model_mesh.add(mesh) return model_mesh
def __init__(self): self.reader = tinyobjloader.ObjReader()
def load_obj( fname : str, load_materials : bool = False): """Load .obj file using TinyOBJ and extract info. This is more robust since it can triangulate polygon meshes with up to 255 sides per face. Args: fname (str): path to Wavefront .obj file """ assert fname is not None and os.path.exists(fname), \ 'Invalid file path and/or format, must be an existing Wavefront .obj' reader = tinyobjloader.ObjReader() config = tinyobjloader.ObjReaderConfig() config.triangulate = True # Ensure we don't have any polygons reader.ParseFromFile(fname, config) # Get vertices attrib = reader.GetAttrib() vertices = torch.FloatTensor(attrib.vertices).reshape(-1, 3) # Get triangle face indices shapes = reader.GetShapes() faces = [] for shape in shapes: faces += [idx.vertex_index for idx in shape.mesh.indices] faces = torch.LongTensor(faces).reshape(-1, 3) mats = {} if load_materials: # Load per-faced texture coordinate indices texf = [] matf = [] for shape in shapes: texf += [idx.texcoord_index for idx in shape.mesh.indices] matf.extend(shape.mesh.material_ids) # texf stores [tex_idx0, tex_idx1, tex_idx2, mat_idx] texf = torch.LongTensor(texf).reshape(-1, 3) matf = torch.LongTensor(matf).reshape(-1, 1) texf = torch.cat([texf, matf], dim=-1) # Load texcoords texv = torch.FloatTensor(attrib.texcoords).reshape(-1, 2) # Load texture maps parent_path = os.path.dirname(fname) materials = reader.GetMaterials() for i, material in enumerate(materials): mats[i] = {} diffuse = getattr(material, 'diffuse') if diffuse != '': mats[i]['diffuse'] = torch.FloatTensor(diffuse) for texopt in texopts: mat_path = getattr(material, texopt) if mat_path != '': img = load_mat(os.path.join(parent_path, mat_path)) mats[i][texopt] = img #mats[i][texopt.split('_')[0]] = img return vertices, faces, texv, texf, mats return vertices, faces
def load_model_from_file_1(filename): # Create reader. reader = tinyobjloader.ObjReader() ret = reader.ParseFromFile(filename) if ret == False: print("Warn:", reader.Warning()) print("Err:", reader.Error()) print("Failed to load : ", filename) sys.exit(-1) if reader.Warning(): print("Warn:", reader.Warning()) attrib = reader.GetAttrib() print("attrib.vertices = ", len(attrib.vertices)) print("attrib.normals = ", len(attrib.normals)) print("attrib.texcoords = ", len(attrib.texcoords)) materials = reader.GetMaterials() print("Num materials: ", len(materials)) for m in materials: print(m.name) print(m.diffuse) shapes = reader.GetShapes() print("Num shapes: ", len(shapes)) for shape in shapes: print(shape.name) print("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)) v_idx = [x.vertex_index for x in shape.mesh.indices] print(f"indices = [{v_idx}]") print(f"vertices = {attrib.vertices}") vertex_list = [] normal_list = [ 0, ] * len(shape.mesh.indices) for face in range(len(shape.mesh.indices) // 3): idx = (shape.mesh.indices[3 * face], shape.mesh.indices[3 * face + 1], shape.mesh.indices[3 * face + 2]) vertex_indices = [x.vertex_index for x in idx] normal_indices = [x.normal_index for x in idx] print(f"[{face}] = ( {vertex_indices}, {normal_indices})") #print(idx.vertex_index,idx.normal_index,) p1 = glm.vec3(attrib.vertices[3 * vertex_indices[0]], attrib.vertices[3 * vertex_indices[0] + 1], attrib.vertices[3 * vertex_indices[0] + 2]) p2 = glm.vec3(attrib.vertices[3 * vertex_indices[1]], attrib.vertices[3 * vertex_indices[1] + 1], attrib.vertices[3 * vertex_indices[1] + 2]) p3 = glm.vec3(attrib.vertices[3 * vertex_indices[2]], attrib.vertices[3 * vertex_indices[2] + 1], attrib.vertices[3 * vertex_indices[2] + 2]) for v in range(3): vertex_list.append(attrib.vertices[3 * vertex_indices[v]]) vertex_list.append(attrib.vertices[3 * vertex_indices[v] + 2]) vertex_list.append(attrib.vertices[3 * vertex_indices[v] + 1]) for v in range(3): normal_list.append(attrib.normals[3 * normal_indices[v]]) normal_list.append(attrib.normals[3 * normal_indices[v] + 2]) normal_list.append(attrib.normals[3 * normal_indices[v] + 1]) print(f"vertices = {vertex_list}") vaoID = createVAO() bindIndicesToBuffer([x for x in range(len(shape.mesh.indices))]) storeDataInVBO(0, 3, vertex_list) storeDataInVBO(1, 3, normal_list) unbindVAO() return BasicModel(vao=vaoID, size=len(attrib.vertices))
def readGeometry(filename, geometry, swapyz=False): start_time = time.time() """ Loads a Wavefront OBJ file. """ reader = tinyobjloader.ObjReader() # Load .obj(and .mtl) using default configuration ret = reader.ParseFromFile(filename) if ret == False: logger.warning(reader.Warning()) logger.error(reader.Error()) logger.error("Failed to load : %s" % filename) raise BaseException("HUY") else: if reader.Warning(): logger.warning(reader.Warning()) attrib = reader.GetAttrib() print("attrib.vertices = ", len(attrib.vertices)) print("attrib.normals = ", len(attrib.normals)) print("attrib.texcoords = ", len(attrib.texcoords)) # 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 # create Point's geometry.createPoints(np.reshape(attrib.numpy_vertices(), (-1, 3))) # create primitives shapes = reader.GetShapes() print("Num shapes: ", len(shapes)) for shape in shapes: print(shape.name) #print("num_indices = {}".format(len(shape.mesh.indices))) #print(shape.mesh.numpy_indices()) #print(shape.mesh.numpy_num_face_vertices()) point_indices = shape.mesh.numpy_indices()[0::3] normal_indices = None if len(attrib.normals) > 0: normal_indices = shape.mesh.numpy_indices()[1::3] txcoord_indices = None if len(attrib.texcoords) > 0: txcoord_indices = shape.mesh.numpy_indices()[2::3] face_pts_offset = 0 points = [] for face_pts_num in shape.mesh.numpy_num_face_vertices(): points.append(point_indices[face_pts_offset:face_pts_offset + face_pts_num]) face_pts_offset += face_pts_num geometry.createPolygons(points) end_time = time.time() logger.debug("Geometry read from .obj in %s seconds" % (end_time - start_time))