예제 #1
0
def _create_blender_textures_from_mod(mod, base_dir):
    textures = [None]  # materials refer to textures in index-1
    # TODO: check why in Arc.header.file_entries[n].file_path it returns a bytes, and
    # here the whole array of chars

    for i, texture_path in enumerate(mod.textures_array):
        path = texture_path[:].decode('ascii').partition('\x00')[0]
        folder = ntpath.dirname(path)
        path = os.path.join(base_dir, *path.split(ntpath.sep))
        path = '.'.join((path, 'tex'))
        if not os.path.isfile(path):
            # TODO: log warnings, figure out 'rtex' format
            continue
        tex = Tex112(path)
        try:
            dds = tex.to_dds()
        except TextureError as err:
            # TODO: log this instead of printing it
            print('Error converting "{}"to dds: {}'.format(path, err))
            textures.append(None)
            continue
        dds_path = path.replace('.tex', '.dds')
        with open(dds_path, 'wb') as w:
            w.write(dds)
        image = bpy.data.images.load(dds_path)
        texture = bpy.data.textures.new(os.path.basename(path), type='IMAGE')
        texture.image = image
        textures.append(texture)
        # saving meta data for export
        texture.albam_imported_texture_folder = folder
        texture.albam_imported_texture_value_1 = tex.unk_float_1
        texture.albam_imported_texture_value_2 = tex.unk_float_2
        texture.albam_imported_texture_value_3 = tex.unk_float_3
        texture.albam_imported_texture_value_4 = tex.unk_float_4
    return textures
예제 #2
0
def test_tex_calculate_mipmap_count(tex_file):
    tex = Tex112(file_path=tex_file)

    mipmap_count_from_file = tex.mipmap_count
    mipmap_calculated = DDS.calculate_mipmap_count(tex.width, tex.height)

    # There might be cases where tex don't have mipmaps?
    assert mipmap_count_from_file == mipmap_calculated
예제 #3
0
def test_tex_from_dds(dds_path_1, tmpdir):
    tex_1 = Tex112.from_dds(file_path=dds_path_1)
    tex_1_name = os.path.basename(dds_path_1).replace('.dds', '.tex')
    tex_1_path = os.path.join(str(tmpdir), tex_1_name)

    with open(tex_1_path, 'wb') as w:
        w.write(tex_1)

    tex_2 = Tex112(file_path=tex_1_path)
    tex_2_name = tex_1_name.replace('.tex', '1.tex')
    tex_2_path = os.path.join(str(tmpdir), tex_2_name)

    with open(tex_2_path, 'wb') as w2:
        w2.write(tex_2)

    with open(tex_1_path, 'rb') as w, open(tex_2_path, 'rb') as w2:
        c1 = w.read()
        c2 = w2.read()

    assert sha1(c1).hexdigest() == sha1(c2).hexdigest()
예제 #4
0
def test_tex_112(tex_file, tmpdir):
    tex = Tex112(file_path=tex_file)
    out = os.path.join(str(tmpdir), 'test.tex')
    with open(out, 'wb') as w:
        w.write(tex)
    with open(tex_file, 'rb') as f, open(out, 'rb') as f2:
        s1 = sha1(f.read()).hexdigest()
        s2 = sha1(f2.read()).hexdigest()

    assert s1 == s2
    assert os.path.getsize(out) == os.path.getsize(tex_file)
예제 #5
0
def test_tex112_to_dds(tmpdir, tex_file):
    tex = Tex112(file_path=tex_file)
    dds = tex.to_dds()
    tex_name = os.path.basename(tex_file)
    dds_name = tex_name.replace('.tex', '.dds')
    out = os.path.join(str(tmpdir), dds_name)

    with open(out, 'wb') as w:
        w.write(dds)

    assert dds.header.id_magic == b'DDS '
    assert os.path.getsize(out) == sizeof(DDSHeader) + len(tex.dds_data)
예제 #6
0
def test_tex112_calculate_mipmap_offsets(tex_file):
    tex = Tex112(file_path=tex_file)

    offsets_from_file = list(tex.mipmap_offsets)
    w = tex.width
    h = tex.height
    mc = tex.mipmap_count
    fmt = tex.compression_format
    fixed_size_of_header = 40  # mmm...
    start_offset = fixed_size_of_header + (mc * 4)
    calculated_offsets = tex.calculate_mipmap_offsets(mc, w, h, fmt,
                                                      start_offset)

    assert offsets_from_file == calculated_offsets
예제 #7
0
def test_tex_from_dds(dds_path_1, tmpdir):
    tex_1 = Tex112.from_dds(file_path=dds_path_1)
    tex_1_name = os.path.basename(dds_path_1).replace('.dds', '.tex')
    tex_1_path = os.path.join(str(tmpdir), tex_1_name)

    with open(tex_1_path, 'wb') as w:
        w.write(tex_1)

    tex_2 = Tex112(file_path=tex_1_path)
    tex_2_name = tex_1_name.replace('.tex', '1.tex')
    tex_2_path = os.path.join(str(tmpdir), tex_2_name)

    with open(tex_2_path, 'wb') as w2:
        w2.write(tex_2)

    with open(tex_1_path, 'rb') as w, open(tex_2_path, 'rb') as w2:
        c1 = w.read()
        c2 = w2.read()

    assert sha1(c1).hexdigest() == sha1(c2).hexdigest()
예제 #8
0
def export_arc(blender_object):
    '''Exports an arc file containing mod and tex files, among others from a
    previously imported arc.'''
    mods = {}
    try:
        saved_arc = Arc(
            file_path=BytesIO(blender_object.albam_imported_item.data))
    except AttributeError:
        raise ExportError(
            'Object {0} did not come from the original arc'.format(
                blender_object.name))

    for child in blender_object.children:
        try:
            basename = posixpath.basename(child.name)
            folder = child.albam_imported_item.folder
            if os.sep == ntpath.sep:  # Windows
                mod_filepath = ntpath.join(ensure_ntpath(folder), basename)
            else:
                mod_filepath = os.path.join(folder, basename)
        except AttributeError:
            raise ExportError(
                'Object {0} did not come from the original arc'.format(
                    child.name))
        assert child.albam_imported_item.file_type == 'mtframework.mod'
        mod, textures = export_mod156(child)
        mods[mod_filepath] = (mod, textures)

    with tempfile.TemporaryDirectory() as tmpdir:
        tmpdir_slash_ending = tmpdir + os.sep if not tmpdir.endswith(
            os.sep) else tmpdir
        saved_arc.unpack(tmpdir)
        mod_files = [
            os.path.join(root, f) for root, _, files in os.walk(tmpdir)
            for f in files if f.endswith('.mod')
        ]
        # tex_files = {os.path.join(root, f) for root, _, files in os.walk(tmpdir)
        #             for f in files if f.endswith('.tex')}
        new_tex_files = set()
        for modf in mod_files:
            rel_path = modf.split(tmpdir_slash_ending)[1]
            try:
                new_mod = mods[rel_path]
            except KeyError:
                raise ExportError(
                    "Can't export to arc, a mod file is missing: {}".format(
                        rel_path))

            with open(modf, 'wb') as w:
                w.write(new_mod[0])
            mod_textures = new_mod[1]
            for texture in mod_textures:
                tex = Tex112.from_dds(
                    file_path=bpy.path.abspath(texture.image.filepath))
                try:
                    tex.unk_float_1 = texture.albam_imported_texture_value_1
                    tex.unk_float_2 = texture.albam_imported_texture_value_2
                    tex.unk_float_3 = texture.albam_imported_texture_value_3
                    tex.unk_float_4 = texture.albam_imported_texture_value_4
                except AttributeError:
                    pass

                tex_name = os.path.basename(texture.image.filepath)
                tex_filepath = os.path.join(os.path.dirname(modf),
                                            tex_name.replace('.dds', '.tex'))
                new_tex_files.add(tex_filepath)
                with open(tex_filepath, 'wb') as w:
                    w.write(tex)
        # probably other files can reference textures besides mod, this is in case
        # textures applied have other names.
        # TODO: delete only textures referenced from saved_mods at import time
        # unused_tex_files = tex_files - new_tex_files
        # for utex in unused_tex_files:
        #    os.unlink(utex)
        new_arc = Arc.from_dir(tmpdir)
    return new_arc
예제 #9
0
def export_arc(blender_object):
    '''Exports an arc file containing mod and tex files, among others from a
    previously imported arc.'''
    mods = {}
    try:
        saved_arc = Arc(file_path=BytesIO(blender_object.albam_imported_item.data))
    except AttributeError:
        raise ExportError('Object {0} did not come from the original arc'.format(blender_object.name))

    for child in blender_object.children:
        try:
            basename = posixpath.basename(child.name)
            folder = child.albam_imported_item.folder
            if os.sep == ntpath.sep:  # Windows
                mod_filepath = ntpath.join(ensure_ntpath(folder), basename)
            else:
                mod_filepath = os.path.join(folder, basename)
        except AttributeError:
            raise ExportError('Object {0} did not come from the original arc'.format(child.name))
        assert child.albam_imported_item.file_type == 'mtframework.mod'
        mod, textures = export_mod156(child)
        mods[mod_filepath] = (mod, textures)

    with tempfile.TemporaryDirectory() as tmpdir:
        tmpdir_slash_ending = tmpdir + os.sep if not tmpdir.endswith(os.sep) else tmpdir
        saved_arc.unpack(tmpdir)
        mod_files = [os.path.join(root, f) for root, _, files in os.walk(tmpdir)
                     for f in files if f.endswith('.mod')]
        # tex_files = {os.path.join(root, f) for root, _, files in os.walk(tmpdir)
        #             for f in files if f.endswith('.tex')}
        new_tex_files = set()
        for modf in mod_files:
            rel_path = modf.split(tmpdir_slash_ending)[1]
            try:
                new_mod = mods[rel_path]
            except KeyError:
                raise ExportError("Can't export to arc, a mod file is missing: {}".format(rel_path))

            with open(modf, 'wb') as w:
                w.write(new_mod[0])
            mod_textures = new_mod[1]
            for texture in mod_textures:
                tex = Tex112.from_dds(file_path=bpy.path.abspath(texture.image.filepath))
                try:
                    tex.unk_float_1 = texture.albam_imported_texture_value_1
                    tex.unk_float_2 = texture.albam_imported_texture_value_2
                    tex.unk_float_3 = texture.albam_imported_texture_value_3
                    tex.unk_float_4 = texture.albam_imported_texture_value_4
                except AttributeError:
                    pass

                tex_name = os.path.basename(texture.image.filepath)
                tex_filepath = os.path.join(os.path.dirname(modf), tex_name.replace('.dds', '.tex'))
                new_tex_files.add(tex_filepath)
                with open(tex_filepath, 'wb') as w:
                    w.write(tex)
        # probably other files can reference textures besides mod, this is in case
        # textures applied have other names.
        # TODO: delete only textures referenced from saved_mods at import time
        # unused_tex_files = tex_files - new_tex_files
        # for utex in unused_tex_files:
        #    os.unlink(utex)
        new_arc = Arc.from_dir(tmpdir)
    return new_arc