2019年9月4日水曜日

開発環境

The Ray Tracer Challenge: A Test-Driven Guide to Your First 3D Renderer (Jamis Buck(著)、Pragmatic Bookshelf)、Chapter 15(Triangles)のWavefront OBJFiles、Test #10: OBJ File with Triangle 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)


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]))

入出力結果(Bash、cmd.exe(コマンドプロンプト)、Terminal、Jupyter(IPython))

C:\Users\...>py obj_file_test.py
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

C:\Users\...>

0 コメント:

コメントを投稿