linetypes.py

Fri, 18 Sep 2020 20:22:22 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Fri, 18 Sep 2020 20:22:22 +0300
changeset 117
178d6e54694f
parent 91
c71a7d863c2e
permissions
-rw-r--r--

added unit testing

def ldraw_str(value):
    ' Like str() except removes unneeded ".0"-suffixes '
    rep = str(value)
    if isinstance(value, float):
        if rep.endswith('.0'):
            rep = rep[:-2]
        if rep == '-0':
            rep = '0'
    return rep

class EmptyLine:
    def __repr__(self):
        return 'linetypes.EmptyLine()'
    def textual_representation(self):
        return ''

class MetaCommand:
    def __init__(self, text, style = 'old'):
        self.text = text
    def __repr__(self):
        return str.format('linetypes.MetaCommand({text!r})',
            text = self.text,
        )
    def textual_representation(self):
        return ('0 ' + self.text).strip()

class Comment:
    def __init__(self, text, style = 'old'):
        self.text = text
    def __repr__(self):
        return str.format('linetypes.Comment({text!r})',
            text = self.text,
        )
    def textual_representation(self):
        return '0 //' + self.text

class SubfileReference:
    def __init__(self, *, colour, subfile_path, anchor, matrix):
        self.colour, self.subfile_path, = colour, subfile_path
        self.anchor, self.matrix = anchor, matrix
    def __repr__(self):
        return str.format('linetypes.SubfileReference(' \
            'colour = {colour!r}, ' \
            'subfile_path = {subfile_path!r}, ' \
            'anchor = {anchor!r}, ' \
            'matrix = {matrix!r})', **self.__dict__)
    def textual_representation(self):
        args = [
            1,
            self.colour,
            *self.anchor.coordinates,
            *self.matrix.values,
            self.subfile_path,
        ]
        return ' '.join(ldraw_str(arg) for arg in args)

class BasePolygon:
    def __init__(self, *, colour, geometry):
        self.colour, self.geometry = colour, geometry
    def __repr__(self):
        return str.format('linetypes.{typename}(' \
            'colour = {colour!r}, ' \
            'geometry = {geometry!r})',
            typename = type(self).__name__,
            colour = self.colour,
            geometry = self.geometry,
        )
    def base_textual_representation(self):
        args = [self.colour]
        for vertex in self.geometry.vertices:
            args += vertex.coordinates
        return ' '.join(ldraw_str(arg) for arg in args)

class LineSegment(BasePolygon):
    def textual_representation(self):
        return '2 ' + self.base_textual_representation()

class Triangle(BasePolygon):
    def textual_representation(self):
        return '3 ' + self.base_textual_representation()

class Quadrilateral(BasePolygon):
    def textual_representation(self):
        return '4 ' + self.base_textual_representation()

class ConditionalLine(LineSegment):
    def __init__(self, *, colour, geometry, control_points):
        super().__init__(colour = colour, geometry = geometry)
        self.control_points = control_points
        assert(len(self.control_points) == 2)
    def __repr__(self):
        return str.format('linetypes.ConditionalLine(' \
            'colour = {colour!r}, ' \
            'geometry = {geometry!r}, ' \
            'control_points = {control_points!r})', **self.__dict__)
    def textual_representation(self):
        result = '5 ' + self.base_textual_representation()
        for control_point in self.control_points:
            strings = (ldraw_str(value) for value in control_point.coordinates)
            result += ' '
            result += ' '.join(strings)
        return result

class Error:
    def __init__(self, line, reason):
        self.line = line
        self.reason = reason
    def __repr__(self):
        return str.format(
            'linetypes.Error(line = {line!r}, reason = {reason!r})',
            line = self.line,
            reason = self.reason,
        )
    def textual_representation(self):
        return self.line

mercurial