-
Notifications
You must be signed in to change notification settings - Fork 1
/
objects.py
executable file
·103 lines (88 loc) · 4.1 KB
/
objects.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
# Purpose: Define shapes for .obj files.
# http://paulbourke.net/dataformats/obj/
import sys
import datetime
from pathlib import Path
import collections
from functools import reduce
import config
logger = config.get_logger()
Object = collections.namedtuple('Object', '{} {} {}'.format('v', 'vn', 'f'))
Vertex = collections.namedtuple('Vertex', '{} {} {}'.format('x', 'y', 'z', 'w'))
Normal = collections.namedtuple('Normal', '{} {} {}'.format('i', 'j', 'k'))
Face = collections.namedtuple('Face', '{}'.format('vs'))
PlacedObject = collections.namedtuple('PlacedObject', '{} {} {} {} {}'.format('o', 'x', 'y', 'z', 'size'))
def cube():
o = Object(v=list(), vn=list(), f=list())
o.v.append(Vertex(x=0.0, y=0.0, z=0.0))
o.v.append(Vertex(x=0.0, y=0.0, z=1.0))
o.v.append(Vertex(x=0.0, y=1.0, z=0.0))
o.v.append(Vertex(x=0.0, y=1.0, z=1.0))
o.v.append(Vertex(x=1.0, y=0.0, z=0.0))
o.v.append(Vertex(x=1.0, y=0.0, z=1.0))
o.v.append(Vertex(x=1.0, y=1.0, z=0.0))
o.v.append(Vertex(x=1.0, y=1.0, z=1.0))
# o.vn.append(Normal(i=0.0, j=0.0, k=1.0))
# o.vn.append(Normal(i=0.0, j=0.0, k=-1.0))
# o.vn.append(Normal(i=0.0, j=1.0, k=0.0))
# o.vn.append(Normal(i=0.0, j=-1.0, k=0.0))
# o.vn.append(Normal(i=1.0, j=0.0, k=0.0))
# o.vn.append(Normal(i=-1.0, j=0.0, k=0.0))
o.f.append(Face([(1, None, 2), (7, None, 2), (5, None, 2)]))
o.f.append(Face([(1, None, 2), (3, None, 2), (7, None, 2)]))
o.f.append(Face([(1, None, 6), (4, None, 6), (3, None, 6)]))
o.f.append(Face([(1, None, 6), (2, None, 6), (4, None, 6)]))
o.f.append(Face([(3, None, 3), (8, None, 3), (7, None, 3)]))
o.f.append(Face([(3, None, 3), (4, None, 3), (8, None, 3)]))
o.f.append(Face([(5, None, 5), (7, None, 5), (8, None, 5)]))
o.f.append(Face([(5, None, 5), (8, None, 5), (6, None, 5)]))
o.f.append(Face([(1, None, 4), (5, None, 4), (6, None, 4)]))
o.f.append(Face([(1, None, 4), (6, None, 4), (2, None, 4)]))
o.f.append(Face([(2, None, 1), (6, None, 1), (8, None, 1)]))
# o.f.append(Face([(2, None, 1), (8, None, 1), (4, None, 1)]))
# o.f.append(Face(['2//1', '8//1', '4//1']))
return o
def generate_lines(placed_objects, generated_by, group):
datetimestamp = datetime.datetime.now().isoformat().replace(':', '-').replace('.', '-')
lines = list()
lines.append('# Generated by: {}'.format(generated_by))
lines.append('# Generated on: {}'.format(datetimestamp))
lines.append('')
lines.append('g {}'.format(group))
lines.append('')
for po in [po for po in placed_objects if po.o.v]:
lines.extend(['v ' + '{} {} {}'.format(
po.x + v.x * po.size,
po.y + v.y * po.size,
po.z + v.z * po.size
) for v in po.o.v])
lines.append('')
# for o in [ps.o for ps in placed_objects if ps.o.vn]:
# lines.extend(['vn ' + '{} {} {}'.format(vn.i, vn.j, vn.k) for vn in o.vn])
# lines.append('')
vertex_count = 0
for po in [po for po in placed_objects if po.o.f]:
lines.extend(['f ' + join_with_space(apply_relative_indices(f.vs, vertex_offset=vertex_count)) for f in po.o.f])
if po.o.v:
vertex_count = vertex_count + len(po.o.v)
lines.append('')
return lines
def apply_relative_indices(indices, vertex_offset):
relative_indices = list()
for index in indices:
if index[1]:
relative_index = '{}/{}/{}'.format(vertex_offset + index[0], index[1], vertex_offset + index[2])
else:
relative_index = '{}//{}'.format(vertex_offset + index[0], vertex_offset + index[2])
relative_indices.append(relative_index)
return relative_indices
def join_with_space(values):
return reduce((lambda x, y: '{} {}'.format(x, y)), values)
def save_as_obj(objects, output_filepath, generated_by=None, group=None):
if not generated_by:
generated_by = Path(sys.argv[0]).name
if not group:
group = output_filepath.stem
obj_file_lines = generate_lines(objects, generated_by=generated_by, group=group)
with open(str(output_filepath), 'w') as f:
f.writelines([l + '\n' for l in obj_file_lines])