Skip to content

Commit 8b71a1a

Browse files
committed
correct line endings
1 parent ee69a02 commit 8b71a1a

File tree

2 files changed

+246
-246
lines changed

2 files changed

+246
-246
lines changed

c2obj.py

+140-140
Original file line numberDiff line numberDiff line change
@@ -1,141 +1,141 @@
1-
"""
2-
This module attempts to parse the ``model.inc.c`` files and extract the
3-
3D models within as standard Wavefront OBJ files.
4-
5-
Example:
6-
Specify the path to the ``.inc.c`` file and a directory where to save
7-
the extracted ``.obj`` files.
8-
9-
$ python c2obj.py ./actors/mario/model.inc.c ./actors/mario/obj/
10-
11-
This is a work in progress and it currently has some serious limitations:
12-
* It only extracts geometry information, so no textures or any other info
13-
* It makes assumptions about the layout of the code in the C source
14-
* It hasn't been properly tested.
15-
16-
"""
17-
18-
def parse(filename, output_directory):
19-
from os import path, mkdir
20-
21-
if not path.isdir(output_directory):
22-
try:
23-
mkdir(output_directory)
24-
except OSError:
25-
print(f'Could not use output directory {output_directory}.')
26-
27-
vtx_def = 'static const Vtx '
28-
vtx_data = {}
29-
reading_vtx = False
30-
current_vtx_name = ''
31-
current_vtx_data = []
32-
current_vtx_vertices = 0
33-
34-
gfx_def = 'const Gfx '
35-
reading_gfx = False
36-
current_gfx_vertices = 0
37-
current_gfx_faces = 0
38-
insert_vert_call = 'gsSPVertex('
39-
insert_1tri_call = 'gsSP1Triangle('
40-
insert_2tri_call = 'gsSP2Triangles('
41-
gfx_count = 0
42-
43-
end_of_block = '};'
44-
45-
with open(filename, 'r') as f:
46-
for line in f:
47-
line = line.strip()
48-
49-
if line.startswith(vtx_def):
50-
vtx_name = line.split(' ')[3][:-2]
51-
current_vtx_name = vtx_name
52-
current_vtx_data = []
53-
reading_vtx = True
54-
continue
55-
56-
if line.startswith(gfx_def):
57-
from datetime import datetime
58-
59-
current_gfx_name = line.split(' ')[2][:-2]
60-
current_gfx_file = open(path.join(output_directory, current_gfx_name + '.obj'), 'w')
61-
current_gfx_file.write("# Armando Arredondo's SM64 Wavefront OBJ Geometry Converter\n")
62-
current_gfx_file.write('# File Created: {}\n\n'.format(datetime.now()))
63-
reading_gfx = True
64-
continue
65-
66-
if line == end_of_block:
67-
if reading_vtx:
68-
vtx_data[current_vtx_name] = current_vtx_data
69-
reading_vtx = False
70-
71-
elif reading_gfx:
72-
current_gfx_file.write(f'# {current_gfx_faces} faces\n\n')
73-
current_gfx_file.close()
74-
current_gfx_vertices = 0
75-
reading_gfx = False
76-
gfx_count += 1
77-
78-
continue
79-
80-
if reading_vtx:
81-
line = line.replace('{', '[').replace('}', ']')
82-
tri = eval(line[:-1])[0]
83-
current_vtx_data.append(tri)
84-
continue
85-
86-
if reading_gfx:
87-
if line.startswith(insert_vert_call):
88-
args = line[len(insert_vert_call):].split(',')
89-
current_vtx_name = args[0]
90-
91-
if current_gfx_vertices > 0:
92-
current_gfx_file.write(f'# {current_gfx_faces} faces\n\n')
93-
94-
current_gfx_faces = 0
95-
current_vtx_vertices = len(vtx_data[current_vtx_name])
96-
current_gfx_vertices += current_vtx_vertices
97-
98-
current_gfx_file.write(f'#\n# object {current_vtx_name}\n#\n\n')
99-
current_vtx_data = vtx_data[current_vtx_name]
100-
for tri in current_vtx_data:
101-
v = tri[0]
102-
current_gfx_file.write('v {:.3f} {:.3f} {:.3f}\n'.format(*v))
103-
current_gfx_file.write(f'# {current_vtx_vertices} vertices\n\n')
104-
105-
for tri in current_vtx_data:
106-
n = [_decode_normal(u) for u in tri[3][:3]]
107-
current_gfx_file.write('vn {:.3f} {:.3f} {:.3f}\n'.format(*n))
108-
current_gfx_file.write(f'# {current_vtx_vertices} vertex normals\n\n')
109-
110-
current_gfx_file.write(f'g {current_vtx_name}\n\n')
111-
112-
elif line.startswith(insert_2tri_call):
113-
args = line[len(insert_2tri_call):].split(',')
114-
correction = current_gfx_vertices - current_vtx_vertices + 1
115-
indexes = [eval(args[i]) + correction for i in [0, 1, 2, 4, 5, 6]]
116-
current_gfx_file.write('f {0}//{0} {1}//{1} {2}//{2}\n'.format(*indexes[:3]))
117-
current_gfx_file.write('f {0}//{0} {1}//{1} {2}//{2}\n'.format(*indexes[3:]))
118-
current_gfx_faces += 2
119-
120-
elif line.startswith(insert_1tri_call):
121-
args = line[len(insert_1tri_call):].split(',')
122-
correction = current_gfx_vertices - current_vtx_vertices + 1
123-
indexes = [eval(args[i]) + correction for i in [0, 1, 2]]
124-
current_gfx_file.write('f {0}//{0} {1}//{1} {2}//{2}\n'.format(*indexes))
125-
current_gfx_faces += 1
126-
127-
continue
128-
129-
print(f'{gfx_count} models extracted.')
130-
131-
def _decode_normal(x):
132-
y = x if x <= 127 else x - 255
133-
return y / 127
134-
135-
if __name__ == "__main__":
136-
import argparse
137-
parser = argparse.ArgumentParser()
138-
parser.add_argument('filename', help = 'filename of the .inc.c source file')
139-
parser.add_argument('output_directory', help = 'directory where to put the extracted .obj files')
140-
args = parser.parse_args()
1+
"""
2+
This module attempts to parse the ``model.inc.c`` files and extract the
3+
3D models within as standard Wavefront OBJ files.
4+
5+
Example:
6+
Specify the path to the ``.inc.c`` file and a directory where to save
7+
the extracted ``.obj`` files.
8+
9+
$ python c2obj.py ./actors/mario/model.inc.c ./actors/mario/obj/
10+
11+
This is a work in progress and it currently has some serious limitations:
12+
* It only extracts geometry information, so no textures or any other info
13+
* It makes assumptions about the layout of the code in the C source
14+
* It hasn't been properly tested.
15+
16+
"""
17+
18+
def parse(filename, output_directory):
19+
from os import path, mkdir
20+
21+
if not path.isdir(output_directory):
22+
try:
23+
mkdir(output_directory)
24+
except OSError:
25+
print(f'Could not use output directory {output_directory}.')
26+
27+
vtx_def = 'static const Vtx '
28+
vtx_data = {}
29+
reading_vtx = False
30+
current_vtx_name = ''
31+
current_vtx_data = []
32+
current_vtx_vertices = 0
33+
34+
gfx_def = 'const Gfx '
35+
reading_gfx = False
36+
current_gfx_vertices = 0
37+
current_gfx_faces = 0
38+
insert_vert_call = 'gsSPVertex('
39+
insert_1tri_call = 'gsSP1Triangle('
40+
insert_2tri_call = 'gsSP2Triangles('
41+
gfx_count = 0
42+
43+
end_of_block = '};'
44+
45+
with open(filename, 'r') as f:
46+
for line in f:
47+
line = line.strip()
48+
49+
if line.startswith(vtx_def):
50+
vtx_name = line.split(' ')[3][:-2]
51+
current_vtx_name = vtx_name
52+
current_vtx_data = []
53+
reading_vtx = True
54+
continue
55+
56+
if line.startswith(gfx_def):
57+
from datetime import datetime
58+
59+
current_gfx_name = line.split(' ')[2][:-2]
60+
current_gfx_file = open(path.join(output_directory, current_gfx_name + '.obj'), 'w')
61+
current_gfx_file.write("# Armando Arredondo's SM64 Wavefront OBJ Geometry Converter\n")
62+
current_gfx_file.write('# File Created: {}\n\n'.format(datetime.now()))
63+
reading_gfx = True
64+
continue
65+
66+
if line == end_of_block:
67+
if reading_vtx:
68+
vtx_data[current_vtx_name] = current_vtx_data
69+
reading_vtx = False
70+
71+
elif reading_gfx:
72+
current_gfx_file.write(f'# {current_gfx_faces} faces\n\n')
73+
current_gfx_file.close()
74+
current_gfx_vertices = 0
75+
reading_gfx = False
76+
gfx_count += 1
77+
78+
continue
79+
80+
if reading_vtx:
81+
line = line.replace('{', '[').replace('}', ']')
82+
tri = eval(line[:-1])[0]
83+
current_vtx_data.append(tri)
84+
continue
85+
86+
if reading_gfx:
87+
if line.startswith(insert_vert_call):
88+
args = line[len(insert_vert_call):].split(',')
89+
current_vtx_name = args[0]
90+
91+
if current_gfx_vertices > 0:
92+
current_gfx_file.write(f'# {current_gfx_faces} faces\n\n')
93+
94+
current_gfx_faces = 0
95+
current_vtx_vertices = len(vtx_data[current_vtx_name])
96+
current_gfx_vertices += current_vtx_vertices
97+
98+
current_gfx_file.write(f'#\n# object {current_vtx_name}\n#\n\n')
99+
current_vtx_data = vtx_data[current_vtx_name]
100+
for tri in current_vtx_data:
101+
v = tri[0]
102+
current_gfx_file.write('v {:.3f} {:.3f} {:.3f}\n'.format(*v))
103+
current_gfx_file.write(f'# {current_vtx_vertices} vertices\n\n')
104+
105+
for tri in current_vtx_data:
106+
n = [_decode_normal(u) for u in tri[3][:3]]
107+
current_gfx_file.write('vn {:.3f} {:.3f} {:.3f}\n'.format(*n))
108+
current_gfx_file.write(f'# {current_vtx_vertices} vertex normals\n\n')
109+
110+
current_gfx_file.write(f'g {current_vtx_name}\n\n')
111+
112+
elif line.startswith(insert_2tri_call):
113+
args = line[len(insert_2tri_call):].split(',')
114+
correction = current_gfx_vertices - current_vtx_vertices + 1
115+
indexes = [eval(args[i]) + correction for i in [0, 1, 2, 4, 5, 6]]
116+
current_gfx_file.write('f {0}//{0} {1}//{1} {2}//{2}\n'.format(*indexes[:3]))
117+
current_gfx_file.write('f {0}//{0} {1}//{1} {2}//{2}\n'.format(*indexes[3:]))
118+
current_gfx_faces += 2
119+
120+
elif line.startswith(insert_1tri_call):
121+
args = line[len(insert_1tri_call):].split(',')
122+
correction = current_gfx_vertices - current_vtx_vertices + 1
123+
indexes = [eval(args[i]) + correction for i in [0, 1, 2]]
124+
current_gfx_file.write('f {0}//{0} {1}//{1} {2}//{2}\n'.format(*indexes))
125+
current_gfx_faces += 1
126+
127+
continue
128+
129+
print(f'{gfx_count} models extracted.')
130+
131+
def _decode_normal(x):
132+
y = x if x <= 127 else x - 255
133+
return y / 127
134+
135+
if __name__ == "__main__":
136+
import argparse
137+
parser = argparse.ArgumentParser()
138+
parser.add_argument('filename', help = 'filename of the .inc.c source file')
139+
parser.add_argument('output_directory', help = 'directory where to put the extracted .obj files')
140+
args = parser.parse_args()
141141
parse(args.filename, args.output_directory)

0 commit comments

Comments
 (0)