meshlabxml/mlx.py
def find_texture_files(fbasename, log=None):
    """Finds the filenames of the referenced texture file(s) (and material
    file for obj) for the mesh.

    Args:
        fbasename (str): input filename. Supported file extensions:
            obj
            ply
            dae
            x3d
            wrl
        log (str): filename to log output

    Returns:
        list: list of all of the texture filenames referenced by the input file.
            May contain duplicates if the texture files are referenced more
            than once. List is empty if no texture files are found.
        list: list of all of the unique texture filenames, also empty if no
            texture files are found.
        str: for obj files only, returns the name of the referenced material file.
            Returns None if no material file is found.

    """
    fext = os.path.splitext(fbasename)[1][1:].strip().lower()
    material_file = None
    texture_files = []
    vert_colors = False
    face_colors = False
    if fext == 'obj':
        # Material Format: mtllib ./model_mesh.obj.mtl
        with open(fbasename, 'r') as fread:
            for line in fread:
                if 'mtllib' in line:
                    material_file = os.path.basename(line.split()[1])
                    break
        if material_file is not None:
            # Texture Format: map_Kd model_texture.jpg
            with open(material_file, 'r') as fread:
                for line in fread:
                    if 'map_Kd' in line:
                        texture_files.append(os.path.basename(line.split()[1]))
    elif fext == 'ply':
        # Texture Format: comment TextureFile model_texture.jpg
        # This works for MeshLab & itSeez3D, but may not work for
        # every ply file.
        face_element = False
        with open(fbasename, 'rb') as fread:
            # read ascii header; works for both ascii & binary files
            while True:
                line = fread.readline().strip().decode('ascii')
                # print(line)
                if 'element face' in line:
                    face_element = True
                if 'red' in line:
                    if face_element:
                        face_colors = True
                    else:
                        vert_colors = True
                if 'TextureFile' in line:
                    texture_files.append(os.path.basename(line.split()[2]))
                if 'end_header' in line:
                    break
    elif fext == 'dae':  # COLLADA
        # elif fext == 'mlp':
        # Texture Format:   <image id="texture0" name="texture0">
        #               <init_from>model_texture.jpg</init_from>
        #           </image>
        namespace = 'http://www.collada.org/2005/11/COLLADASchema'
        tree = ET.parse(fbasename)
        #root = tree.getroot()
        #print('root = ', root)
        #print('root.tag = ', root.tag, 'root.attrib = ', root.attrib)
        for elem in tree.findall(
                '{%s}library_images/{%s}image/{%s}init_from' % (namespace, namespace, namespace)):
            texture_files.append(elem.text)
    elif fext == 'x3d':
        # Texture Format: <ImageTexture url="model_texture.jpg"/>
        #ns = 'http://www.w3.org/2001/XMLSchema-instance'
        tree = ET.parse(fbasename)
        #root = tree.getroot()
        #print('root = ', root)
        #print('root.tag = ', root.tag, 'root.attrib = ', root.attrib)
        # for elem in root:
        # for elem in tree.iter(): # iterate through tree; very useful to see possible tags
        #print('elem.tag = ', elem.tag)
        #print('elem.attrib = ', elem.attrib)
        for elem in tree.iter(tag='ImageTexture'):
            #print('elem.attrib = ', elem.attrib)
            texture_files.append(elem.attrib['url'])
    elif fext == 'wrl':
        # Texture Format: texture ImageTexture { url "model_texture.jpg" }
        with open(fbasename, 'r') as fread:
            for line in fread:
                if 'ImageTexture' in line:
                    texture_files.append(os.path.basename(line.split('"')[1]))
    elif fext != 'stl':  # add other formats that don't support texture, e.g. xyz?
        print('File extension %s is not currently supported' % fext)
        # TODO: raise exception here
    texture_files_unique = list(set(texture_files))
    if log is not None:
        log_file = open(log, 'a')
        log_file.write('Results of find_texture_files:\n')
        log_file.write('fbasename = %s\n' % fbasename)
        log_file.write('texture_files = %s\n' % texture_files)
        log_file.write('texture_files_unique = %s\n' % texture_files_unique)
        log_file.write('Number of texture files = %s\n' % len(texture_files))
        log_file.write(
            'Number of unique texture files = %s\n\n' %
            len(texture_files_unique))
        log_file.write('vertex colors = %s\n' % vert_colors)
        log_file.write('face colors = %s\n' % face_colors)
        log_file.close()
    colors = {'texture':bool(texture_files), 'vert_colors':vert_colors, 'face_colors':face_colors}
    return texture_files, texture_files_unique, material_file, colors
def find_texture_files(fbasename, log=None):
    """Finds the filenames of the referenced texture file(s) (and material
    file for obj) for the mesh.

    Args:
        fbasename (str): input filename. Supported file extensions:
            obj
            ply
            dae
            x3d
            wrl
        log (str): filename to log output

    Returns:
        list: list of all of the texture filenames referenced by the input file.
            May contain duplicates if the texture files are referenced more
            than once. List is empty if no texture files are found.
        list: list of all of the unique texture filenames, also empty if no
            texture files are found.
        str: for obj files only, returns the name of the referenced material file.
            Returns None if no material file is found.

    """
    fext = os.path.splitext(fbasename)[1][1:].strip().lower()
    material_file = None
    texture_files = []
    vert_colors = False
    face_colors = False
    if fext == 'obj':
        # Material Format: mtllib ./model_mesh.obj.mtl
        with open(fbasename, 'r') as fread:
            for line in fread:
                if 'mtllib' in line:
                    material_file = os.path.basename(line.split()[1])
                    break
        if material_file is not None:
            # Texture Format: map_Kd model_texture.jpg
            with open(material_file, 'r') as fread:
                for line in fread:
                    if 'map_Kd' in line:
                        texture_files.append(os.path.basename(line.split()[1]))
    elif fext == 'ply':
        # Texture Format: comment TextureFile model_texture.jpg
        # This works for MeshLab & itSeez3D, but may not work for
        # every ply file.
        face_element = False
        with open(fbasename, 'rb') as fread:
            # read ascii header; works for both ascii & binary files
            while True:
                line = fread.readline().strip().decode('ascii')
                # print(line)
                if 'element face' in line:
                    face_element = True
                if 'red' in line:
                    if face_element:
                        face_colors = True
                    else:
                        vert_colors = True
                if 'TextureFile' in line:
                    texture_files.append(os.path.basename(line.split()[2]))
                if 'end_header' in line:
                    break
    elif fext == 'dae':  # COLLADA
        # elif fext == 'mlp':
        # Texture Format:   <image id="texture0" name="texture0">
        #               <init_from>model_texture.jpg</init_from>
        #           </image>
        namespace = 'http://www.collada.org/2005/11/COLLADASchema'
        tree = ET.parse(fbasename)
        #root = tree.getroot()
        #print('root = ', root)
        #print('root.tag = ', root.tag, 'root.attrib = ', root.attrib)
        for elem in tree.findall(
                '{%s}library_images/{%s}image/{%s}init_from' % (namespace, namespace, namespace)):
            texture_files.append(elem.text)
    elif fext == 'x3d':
        # Texture Format: <ImageTexture url="model_texture.jpg"/>
        #ns = 'http://www.w3.org/2001/XMLSchema-instance'
        tree = ET.parse(fbasename)
        #root = tree.getroot()
        #print('root = ', root)
        #print('root.tag = ', root.tag, 'root.attrib = ', root.attrib)
        # for elem in root:
        # for elem in tree.iter(): # iterate through tree; very useful to see possible tags
        #print('elem.tag = ', elem.tag)
        #print('elem.attrib = ', elem.attrib)
        for elem in tree.iter(tag='ImageTexture'):
            #print('elem.attrib = ', elem.attrib)
            texture_files.append(elem.attrib['url'])
    elif fext == 'wrl':
        # Texture Format: texture ImageTexture { url "model_texture.jpg" }
        with open(fbasename, 'r') as fread:
            for line in fread:
                if 'ImageTexture' in line:
                    texture_files.append(os.path.basename(line.split('"')[1]))
    elif fext != 'stl':  # add other formats that don't support texture, e.g. xyz?
        print('File extension %s is not currently supported' % fext)
        # TODO: raise exception here
    texture_files_unique = list(set(texture_files))
    if log is not None:
        log_file = open(log, 'a')
        log_file.write('Results of find_texture_files:\n')
        log_file.write('fbasename = %s\n' % fbasename)
        log_file.write('texture_files = %s\n' % texture_files)
        log_file.write('texture_files_unique = %s\n' % texture_files_unique)
        log_file.write('Number of texture files = %s\n' % len(texture_files))
        log_file.write(
            'Number of unique texture files = %s\n\n' %
            len(texture_files_unique))
        log_file.write('vertex colors = %s\n' % vert_colors)
        log_file.write('face colors = %s\n' % face_colors)
        log_file.close()
    colors = {'texture':bool(texture_files), 'vert_colors':vert_colors, 'face_colors':face_colors}
    return texture_files, texture_files_unique, material_file, colors
Finds the filenames of the referenced texture file(s) (and material
    file for obj) for the mesh.

    Args:
        fbasename (str): input filename. Supported file extensions:
            obj
            ply
            dae
            x3d
            wrl
        log (str): filename to log output

    Returns:
        list: list of all of the texture filenames referenced by the input file.
            May contain duplicates if the texture files are referenced more
            than once. List is empty if no texture files are found.
        list: list of all of the unique texture filenames, also empty if no
            texture files are found.
        str: for obj files only, returns the name of the referenced material file.
            Returns None if no material file is found.