開発環境
- macOS Mojave - Apple (OS)
- Emacs (Text Editor)
- Windows 10 Pro (OS)
- Visual Studio Code (Text Editor)
- Python 3.7 (プログラミング言語)
- GIMP (ビットマップ画像編集・加工ソフトウェア、PPM形式(portable pixmap)の画像用)
The Ray Tracer Challenge: A Test-Driven Guide to Your First 3D Renderer (Jamis Buck(著)、Pragmatic Bookshelf)、Chapter 15(Triangles)のWavefront OBJFiles、Test #11: OBJ File with Polygon Dataを取り組んでみる。
コード
obj_file_test.py
#!/usr/bin/env python3 from unittest import TestCase, main from obj_file import Parser import io from tuples import Point class ParserTest(TestCase): def setUp(self): pass def tearDown(self): pass def test_ingoring_unrecognized_lines(self): gibberish = io.StringIO('''There was a young lady named Bright who traveled much faster than light. She set out one day in a relative way, and came back the previous night. ''') parser = Parser(gibberish) self.assertEqual(parser.ignored_lines, 5) def test_vertex_records(self): f = io.StringIO('''v -1 1 0 v -1.0000 0.5000 0.0000 v 1 0 0 v 1 1 0 ''') parser = Parser(f) self.assertEqual(parser.vertices[1], Point(-1, 1, 0)) self.assertEqual(parser.vertices[2], Point(-1, 0.5, 0)) self.assertEqual(parser.vertices[3], Point(1, 0, 0)) self.assertEqual(parser.vertices[4], Point(1, 1, 0)) def test_parsing_triangle_faces(self): f = io.StringIO('''v -1 1 0 v -1 0 0 v 1 0 0 v 1 1 0 f 1 2 3 f 1 3 4 ''') parser = Parser(f) group = parser.default_group t1 = group[0] t2 = group[1] spam = [t1.point1, t1.point2, t1.point3, t2.point1, t2.point2, t2.point3] egg = [parser.vertices[1], parser.vertices[2], parser.vertices[3], parser.vertices[1], parser.vertices[3], parser.vertices[4]] for s, t in zip(spam, egg): self.assertEqual(s, t) def test_triangulating_polygons(self): f = io.StringIO('''v -1 1 0 v -1 0 0 v 1 0 0 v 1 1 0 v 0 2 0 f 1 2 3 4 5 ''') parser = Parser(f) group = parser.default_group t1 = group[0] t2 = group[1] t3 = group[2] spam = [t1.point1, t1.point2, t1.point3, t2.point1, t2.point2, t2.point3, t3.point1, t3.point2, t3.point3] egg = [parser.vertices[1], parser.vertices[2], parser.vertices[3], parser.vertices[1], parser.vertices[3], parser.vertices[4], parser.vertices[1], parser.vertices[4], parser.vertices[5]] for s, t in zip(spam, egg): self.assertEqual(s, t) if __name__ == '__main__': main()
obj_file.py
from tuples import Point from triangles import Triangle class Parser: def __init__(self, fh): self.ignored_lines = 0 self.vertices = [None] self.faces = [] for line in fh: cols = line.split() if len(cols) < 4 or cols[0] not in ['v', 'f']: self.ignored_lines += 1 continue if cols[0] == 'v': try: point = Point(*[float(col) for col in cols[1:]]) except ValueError as err: self.ignored_lines += 1 else: self.vertices.append(point) elif cols[0] == 'f': try: face = [int(col) for col in cols[1:]] except ValueError as err: self.ignored_lines += 1 else: self.faces.append(face) self.default_group = [] for face in self.faces: if len(face) == 3: self.default_group.append( Triangle(*[self.vertices[i] for i in face])) if len(face) == 5: for i, _ in enumerate(self.vertices[2:-1], 2): self.default_group.append( Triangle(self.vertices[1], self.vertices[i], self.vertices[i + 1]))
入出力結果(Bash、cmd.exe(コマンドプロンプト)、Terminal、Jupyter(IPython))
C:\Users\...>py obj_file_test.py .... ---------------------------------------------------------------------- Ran 4 tests in 0.001s OK C:\Users\...>
0 コメント:
コメントを投稿