forked from koolkdev/rsdkv5_extract
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmdl2stl.py
108 lines (98 loc) · 3.36 KB
/
mdl2stl.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
from construct import *
import sys
MDL = Struct(
"Magic" / Const("MDL\0"),
# Flags
"Flags" / FlagsEnum(Int8ul,
HasNormals=1,
HasUnknown=2,
HasColors=4),
# How many vertices in face. 3 or 4
"FaceVerticesCount" / Int8ul,
"VerticesCount" / Int16ul,
"FramesCount" / Int16ul,
"UnknownList" / If(lambda ctx: ctx.Flags.HasUnknown,
Array(this.VerticesCount,
Struct(
"x" / Float32l,
"y" / Float32l,
)
)
),
"Colors" / If(lambda ctx: ctx.Flags.HasColors,
Array(this.VerticesCount,
Struct(
"b" / Int8ul,
"g" / Int8ul,
"r" / Int8ul,
"a" / Int8ul,
)
)
),
# Should be in multiply of FaceVerticesCount
# It has FaceVerticesCount vertices for each face
"FacesVertices" / PrefixedArray(Int16ul, Int16ul),
"Frames" / Array(this.FramesCount,
Struct(
"Vertices" / Array(this._.VerticesCount,
Struct(
"x" / Float32l,
"y" / Float32l,
"z" / Float32l,
# I am not sure if it is normals
"Normal" / If(this._._.Flags.HasNormals,
Struct(
"x" / Float32l,
"y" / Float32l,
"z" / Float32l,
)
)
)
)
)
)
)
def write_vertex(vertex):
output.write(" vertex %f %f %f\n" % (vertex.x, vertex.z, vertex.y))
if __name__ == "__main__":
if len(sys.argv) != 2:
print "Usage: mdl2stl.py mesh.bin"
sys.exit(-1)
if not sys.argv[1].endswith(".bin"):
print "Expected .bin file"
sys.exit(-1)
mdl = MDL.parse(open(sys.argv[1], "rb").read())
if not 3 <= mdl.FaceVerticesCount <= 4:
print "Unsupported model"
sys.exit(-1)
# TODO: Colors (need to be binary stl)
base_name = sys.argv[1][:-4]
file_index = 0
for mesh in mdl.Frames:
if len(mdl.Frames) > 1:
output = open(base_name + "_%d.stl" % file_index, "w")
file_index += 1
else:
output = open(base_name + ".stl", "w")
output.write("solid obj\n")
for i in xrange(0, len(mdl.FacesVertices), mdl.FaceVerticesCount):
face_vertices = [mesh.Vertices[x] for x in mdl.FacesVertices[i:i+mdl.FaceVerticesCount]]
# TODO: normal per vertex (need other file format?)
output.write(" facet normal 0 0 0\n")
output.write(" outer loop\n")
write_vertex(face_vertices[0])
write_vertex(face_vertices[1])
write_vertex(face_vertices[2])
output.write(" endloop\n")
output.write(" endfacet\n")
if mdl.FaceVerticesCount == 4:
# If it is quad-face, split it to two triangle faces
output.write(" facet normal 0 0 0\n")
output.write(" outer loop\n")
write_vertex(face_vertices[0])
write_vertex(face_vertices[2])
write_vertex(face_vertices[3])
output.write(" endloop\n")
output.write(" endfacet\n")
output.write("endsolid\n")
output.close()