forked from ZhengZerong/pyrender
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathobjio.py
124 lines (108 loc) · 4.94 KB
/
objio.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
115
116
117
118
119
120
121
122
123
124
import numpy as np
def load_obj_data(filename):
"""load model data from .obj file"""
v_list = [] # vertex coordinate
vt_list = [] # vertex texture coordinate
vc_list = [] # vertex color
vn_list = [] # vertex normal
f_list = [] # face vertex indices
fn_list = [] # face normal indices
ft_list = [] # face texture indices
# read data
fp = open(filename, 'r')
lines = fp.readlines()
fp.close()
for line in lines:
if len(line) < 2:
continue
line_data = line.strip().split(' ')
line_data = list(filter(lambda x: len(x) > 0, line_data))
# parse vertex cocordinate
if line_data[0] == 'v':
v_list.append((float(line_data[1]), float(line_data[2]), float(line_data[3])))
if len(line_data) == 7:
vc_list.append((float(line_data[4]), float(line_data[5]), float(line_data[6])))
# parse vertex texture coordinate
if line_data[0] == 'vt':
vt_list.append((float(line_data[1]), float(line_data[2])))
# parse vertex normal
if line_data[0] == 'vn':
vn_list.append((float(line_data[1]), float(line_data[2]), float(line_data[3])))
# parse face
if line_data[0] == 'f':
# used for parsing face element data
def segElementData(ele_str):
fv = None
ft = None
fn = None
eles = ele_str.strip().split('/')
if len(eles) == 1:
fv = int(eles[0]) - 1
elif len(eles) == 2:
fv = int(eles[0]) - 1
ft = int(eles[1]) - 1
elif len(eles) == 3:
fv = int(eles[0]) - 1
fn = int(eles[2]) - 1
ft = None if eles[1] == '' else int(eles[1]) - 1
return fv, ft, fn
fv0, ft0, fn0 = segElementData(line_data[1])
fv1, ft1, fn1 = segElementData(line_data[2])
fv2, ft2, fn2 = segElementData(line_data[3])
f_list.append((fv0, fv1, fv2))
if ft0 is not None and ft1 is not None and ft2 is not None:
ft_list.append((ft0, ft1, ft2))
if fn0 is not None and fn1 is not None and fn2 is not None:
fn_list.append((fn0, fn1, fn2))
v_list = np.asarray(v_list)
vn_list = np.asarray(vn_list)
vt_list = np.asarray(vt_list)
vc_list = np.asarray(vc_list)
f_list = np.asarray(f_list)
ft_list = np.asarray(ft_list)
fn_list = np.asarray(fn_list)
model = {'v': v_list, 'vt': vt_list, 'vc': vc_list, 'vn': vn_list,
'f': f_list, 'ft': ft_list, 'fn': fn_list}
return model
def save_obj_data(filename, model):
assert 'v' in model and model['v'].size != 0
with open(filename, 'w') as fp:
if 'v' in model and model['v'].size != 0:
if 'vc' in model and model['vc'].size != 0:
for v, vc in zip(model['v'], model['vc']):
fp.write('v %f %f %f %f %f %f\n' % (v[0], v[1], v[2], vc[0], vc[1], vc[2]))
else:
for v in model['v']:
fp.write('v %f %f %f\n' % (v[0], v[1], v[2]))
if 'vn' in model and model['vn'].size != 0:
for vn in model['vn']:
fp.write('vn %f %f %f\n' % (vn[0], vn[1], vn[2]))
if 'vt' in model and model['vt'].size != 0:
for vt in model['vt']:
fp.write('vt %f %f\n' % (vt[0], vt[1]))
if 'f' in model and model['f'].size != 0:
if 'fn' in model and model['fn'].size != 0 and 'ft' in model and model['ft'].size != 0:
assert model['f'].size == model['fn'].size
assert model['f'].size == model['ft'].size
for f_, ft_, fn_ in zip(model['f'], model['ft'], model['fn']):
f = np.copy(f_) + 1
ft = np.copy(ft_) + 1
fn = np.copy(fn_) + 1
fp.write('f %d/%d/%d %d/%d/%d %d/%d/%d\n' %
(f[0], ft[0], fn[0], f[1], ft[1], fn[1], f[2], ft[2], fn[2]))
elif 'fn' in model and model['fn'].size != 0:
assert model['f'].size == model['fn'].size
for f_, fn_ in zip(model['f'], model['fn']):
f = np.copy(f_) + 1
fn = np.copy(fn_) + 1
fp.write('f %d//%d %d//%d %d//%d\n' % (f[0], fn[0], f[1], fn[1], f[2], fn[2]))
elif 'ft' in model and model['ft'].size != 0:
assert model['f'].size == model['ft'].size
for f_, ft_ in zip(model['f'], model['ft']):
f = np.copy(f_) + 1
ft = np.copy(ft_) + 1
fp.write('f %d/%d %d/%d %d/%d\n' % (f[0], ft[0], f[1], ft[1], f[2], ft[2]))
else:
for f_ in model['f']:
f = np.copy(f_) + 1
fp.write('f %d %d %d\n' % (f[0], f[1], f[2]))