This repository has been archived by the owner on Sep 3, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
fflExtract.py
114 lines (97 loc) · 3.3 KB
/
fflExtract.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from ffl.FFLiResource import FFLiResource
from utils.glbExporter import glbExporter
from utils.textureImage import textureImage
import sys
import os
VERSION = "1.0.0"
def print_help():
print("\n".join([
"",
"===========================",
"fflExtract.py version " + str(VERSION),
"===========================",
"Extract resource files used by Nintendo's Mii Face Library",
"By Jaames (github.com/jaames)",
"FFL archive structure reverse-engineered by Kinnay (https://github.com/Kinnay)",
"",
"Usage:",
"======",
"Extract meshes and textures (refer to docs for texture_count and mesh_count):",
"python3 ffl.py -i <input resource file> <texture count> <mesh count> -m <mesh output path> -t <texture output path>",
"",
"Issues:",
"=======",
"If you find any bugs in this script, please report them here:",
"https://github.com/jaames/mii/issues",
""
]))
if __name__ == "__main__":
args = sys.argv[1::]
argIndex = 0
if "-v" in args:
print(VERSION)
sys.exit()
if "-h" in args:
print_help()
sys.exit()
if "-i" not in args:
print("Error: no input file specified")
print_help()
sys.exit()
resource_path = False
texture_count = False
shape_count = False
shape_export_dir = False
texture_export_dir = False
while argIndex < len(args):
arg = args[argIndex]
if arg == "-i":
resource_path = args[argIndex + 1]
texture_count = int(args[argIndex + 2])
shape_count = int(args[argIndex + 3])
argIndex += 4
elif arg == "-m":
shape_export_dir = args[argIndex + 1]
argIndex += 2
elif arg == "-t":
texture_export_dir = args[argIndex + 1]
argIndex += 2
else:
print("Unrecognised arg:", arg)
sys.exit()
if all([resource_path, texture_count, shape_count]) and any([shape_export_dir, texture_export_dir]):
with open(resource_path, "rb") as ffl:
res = FFLiResource.parse(ffl, texture_count, shape_count)
# extract meshes
if shape_export_dir:
print("Extracting meshes...")
os.makedirs(shape_export_dir, exist_ok=True)
for index in range(len(res.shapes)):
shape = res.get_shape(index)
if shape:
shape_path = os.path.join(shape_export_dir, "shape_{index}.glb".format(index=index))
glb = glbExporter()
verts = shape.get_verts()[["x", "y", "z"]]
uvs = shape.get_tex_coords()
colors = shape.get_vert_colors()
faces = shape.get_faces()
glb.add_verts(verts)
glb.add_faces(faces)
if len(uvs) > 0:
glb.add_tex_coords(uvs)
if len(colors) > 1:
glb.add_vert_colors(colors)
glb.save(shape_path)
print("Done!")
# extract textures
if texture_export_dir:
print("Extracting textures...")
os.makedirs(texture_export_dir, exist_ok=True)
for index in range(len(res.textures)):
texture = res.get_texture(index)
if texture:
texture_path = os.path.join(texture_export_dir, "tex_{index}.png".format(index=index))
image = textureImage(texture.width, texture.height, texture.format)
image.set_pixels(texture.get_pixels())
image.save(texture_path)
print("Done!")