Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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,
    }
Exemple #4
0
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
Exemple #5
0
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
Exemple #6
0
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
Exemple #9
0
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
Exemple #10
0
    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
Exemple #11
0
 def __init__(self):
     self.reader = tinyobjloader.ObjReader()
Exemple #12
0
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
Exemple #13
0
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))
Exemple #14
0
    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))