Example #1
0
class Line(Node):
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.start_pos = Point(kwargs['start'])
        self.end_pos = Point(kwargs['end'])

        self.layer = kwargs.get('layer', 'F.SilkS')
        self.width = kwargs.get('width')

    def calculateBoundingBox(self):
        render_start_pos = self.getRealPosition(self.start_pos)
        render_end_pos = self.getRealPosition(self.end_pos)

        min_x = min([render_start_pos.x, render_end_pos.x])
        min_y = min([render_start_pos.y, render_end_pos.y])
        max_x = max([render_start_pos.x, render_end_pos.x])
        max_y = max([render_start_pos.y, render_end_pos.y])

        return Node.calculateBoundingBox({'min': Point(min_x, min_y), 'max': Point(max_x, max_y)})

    def _getRenderTreeText(self):
        render_strings = ['fp_line']
        render_strings.append(self.start_pos.render('(start {x} {y})'))
        render_strings.append(self.end_pos.render('(end {x} {y})'))
        render_strings.append('(layer {layer})'.format(layer=self.layer))
        render_strings.append('(width {width})'.format(width=self.width))

        render_text = Node._getRenderTreeText(self)
        render_text += ' ({})'.format(' '.join(render_strings))

        return render_text
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.start_pos = Point(kwargs['start'])
        self.end_pos = Point(kwargs['end'])

        self.layer = kwargs.get('layer', 'F.SilkS')
        self.width = kwargs.get('width')
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.start_pos = Point(kwargs["start"], **kwargs)
        self.end_pos = Point(kwargs["end"], **kwargs)

        self.layer = kwargs.get("layer", "F.SilkS")
        self.width = kwargs.get("width")
class Line(Node):

    _width_default = 0.15
    _layer_default = "F.SilkS"

    def __init__(self, **kwargs):
        Node.__init__(self)
        self.start_pos = Point(kwargs["start"], **kwargs)
        self.end_pos = Point(kwargs["end"], **kwargs)

        self.layer = kwargs.get("layer", "F.SilkS")
        self.width = kwargs.get("width")

    def calculateBoundingBox(self):
        render_start_pos = self.getRealPosition(self.start_pos)
        render_end_pos = self.getRealPosition(self.end_pos)

        min_x = min([render_start_pos.x, render_end_pos.x])
        min_y = min([render_start_pos.y, render_end_pos.y])
        max_x = max([render_start_pos.x, render_end_pos.x])
        max_y = max([render_start_pos.y, render_end_pos.y])

        return Node.calculateBoundingBox({"min": Point(min_x, min_y), "max": Point(max_x, max_y)})

    def _getRenderTreeText(self):
        render_strings = ["fp_line"]
        render_strings.append(self.start_pos.render("(start {x} {y})"))
        render_strings.append(self.end_pos.render("(end {x} {y})"))
        render_strings.append("(layer {layer})".format(layer=self.layer))
        render_strings.append("(width {width})".format(width=self.width))

        render_text = Node._getRenderTreeText(self)
        render_text += " ({})".format(" ".join(render_strings))

        return render_text
Example #5
0
    def calculateBoundingBox(self):
        # TODO: finish implementation
        min_x = min(self.start_pos.x, self._calulateEndPos().x)
        min_y = min(self.start_pos.x, self._calulateEndPos().y)
        max_x = max(self.start_pos.x, self._calulateEndPos().x)
        max_y = max(self.start_pos.x, self._calulateEndPos().y)
        '''
        for angle in range(4):
            float_angle = angle * math.pi/2.

            start_angle = _calculateStartAngle(self)
            end_angle = start_angle + math.radians(self.angle)

            # TODO: +- pi border
            if float_angle < start_angle:
                continue
            if float_angle > end_angle:
                continue

            print("TODO: add angle side: {1}".format(float_angle))
        '''

        return Node.calculateBoundingBox({
            'min': Point((min_x, min_y)),
            'max': Point((max_x, max_y))
        })
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.start_pos = Point(kwargs['start'])
        self.end_pos = Point(kwargs['end'])

        self.layer = kwargs.get('layer', 'F.SilkS')
        self.width = kwargs.get('width')
    def __init__(self, **kwargs):
        self.start_pos = Point(kwargs['start'])
        self.end_pos = Point(kwargs['end'])

        polygone_line = [{
            'x': self.start_pos.x,
            'y': self.start_pos.y
        }, {
            'x': self.start_pos.x,
            'y': self.end_pos.y
        }, {
            'x': self.end_pos.x,
            'y': self.end_pos.y
        }, {
            'x': self.end_pos.x,
            'y': self.start_pos.y
        }, {
            'x': self.start_pos.x,
            'y': self.start_pos.y
        }]

        PolygoneLine.__init__(self,
                              polygone=polygone_line,
                              layer=kwargs.get('layer', 'F.SilkS'),
                              width=kwargs.get('width'))
Example #8
0
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.center_pos = Point(kwargs['center'])
        self.start_pos = Point(kwargs['start'])
        self.angle = kwargs['angle']

        self.layer = kwargs.get('layer', 'F.SilkS')
        self.width = kwargs.get('width')
 def _initSize(self, **kwargs):
     if not kwargs.get('size'):
         raise KeyError('pad size not declared (like "size=[1,1]")')
     if type(kwargs.get('size')) in [int, float]:
         # when the attribute is a simple number, use it for x and y
         self.size = Point([kwargs.get('size'), kwargs.get('size')])
     else:
         self.size = Point(kwargs.get('size'))
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.center_pos = Point(kwargs['center'])
        self.start_pos = Point(kwargs['start'])
        self.angle = kwargs['angle']

        self.layer = kwargs.get('layer', 'F.SilkS')
        self.width = kwargs.get('width')
Example #11
0
 def _initSize(self, **kwargs):
     if not kwargs.get('size'):
         raise KeyError('pad size not declared (like "size=[1,1]")')
     if type(kwargs.get('size')) in [int, float]:
         # when the attribute is a simple number, use it for x and y
         self.size = Point([kwargs.get('size'), kwargs.get('size')])
     else:
         self.size = Point(kwargs.get('size'))
Example #12
0
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.center_pos = Point(kwargs['center'])
        self.radius = kwargs['radius']

        self.end_pos = {'x': self.center_pos.x+self.radius, 'y': self.center_pos.y}

        self.layer = kwargs.get('layer', 'F.SilkS')
        self.width = kwargs.get('width')
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.start_pos = Point(kwargs['start'])
        self.end_pos = Point(kwargs['end'])

        self.layer = kwargs.get('layer', 'F.SilkS')
        self.width = kwargs.get('width', 0.12)  # TODO: auto detection

        self.virtual_childs = self._createChildNodes(self.start_pos, self.end_pos, self.layer, self.width)
    def calculateBoundingBox(self):
        width = len(self.text)*self.size['x']
        height = self.size['y']

        min_x = self.at[x]-width/2.
        min_y = self.at[y]-height/2.
        max_x = self.at[x]+width/2.
        max_y = self.at[y]+height/2.

        return Node.calculateBoundingBox({'min': Point(min_x, min_y), 'max': Point(max_x, max_y)})
Example #15
0
    def calculateBoundingBox(self):
        render_start_pos = self.getRealPosition(self.start_pos)
        render_end_pos = self.getRealPosition(self.end_pos)

        min_x = min([render_start_pos.x, render_end_pos.x])
        min_y = min([render_start_pos.y, render_end_pos.y])
        max_x = max([render_start_pos.x, render_end_pos.x])
        max_y = max([render_start_pos.y, render_end_pos.y])

        return Node.calculateBoundingBox({'min': Point(min_x, min_y), 'max': Point(max_x, max_y)})
Example #16
0
    def __init__(self, **kwargs):
        self.start_pos = Point(kwargs['start'])
        self.end_pos = Point(kwargs['end'])

        # If specifed, an 'offset' can be applied to the RectLine.
        # For example, creating a border around a given Rect of a specified size
        if kwargs.get('offset'):
            # offset for the rect line
            # e.g. for creating a rectLine 0.5mm LARGER than the given rect, or similar
            offset = [0, 0]

            # Has an offset / inset been specified?
            if type(kwargs['offset']) in [int, float]:
                offset[0] = offset[1] = kwargs['offset']
            elif type(kwargs['offset']) in [list, tuple] and len(
                    kwargs['offset']) == 2:
                # Ensure that all offset params are numerical
                if all([type(i) in [int, float] for i in kwargs['offset']]):
                    offset = kwargs['offset']

            # For the offset to work properly, start-pos must be top-left, and end-pos must be bottom-right
            x1 = min(self.start_pos.x, self.end_pos.x)
            x2 = max(self.start_pos.x, self.end_pos.x)

            y1 = min(self.start_pos.y, self.end_pos.y)
            y2 = max(self.start_pos.y, self.end_pos.y)

            # Put the offset back in
            self.start_pos.x = x1 - offset[0]
            self.start_pos.y = y1 - offset[1]

            self.end_pos.x = x2 + offset[0]
            self.end_pos.y = y2 + offset[1]

        polygone_line = [{
            'x': self.start_pos.x,
            'y': self.start_pos.y
        }, {
            'x': self.start_pos.x,
            'y': self.end_pos.y
        }, {
            'x': self.end_pos.x,
            'y': self.end_pos.y
        }, {
            'x': self.end_pos.x,
            'y': self.start_pos.y
        }, {
            'x': self.start_pos.x,
            'y': self.start_pos.y
        }]

        PolygoneLine.__init__(self,
                              polygone=polygone_line,
                              layer=kwargs['layer'],
                              width=kwargs.get('width'))
class Line(Node):
    r"""Add a Line to the render tree

    :param \**kwargs:
        See below

    :Keyword Arguments:
        * *start* (``Point``) --
          start point of the line
        * *end* (``Point``) --
          end point of the line
        * *layer* (``str``) --
          layer on which the line is drawn (default: 'F.SilkS')
        * *width* (``float``) --
          width of the line (default: None, which means auto detection)

    :Example:

    >>> from KicadModTree import *
    >>> Line(start=[1, 0], end=[-1, 0], layer='F.SilkS')
    """
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.start_pos = Point(kwargs['start'])
        self.end_pos = Point(kwargs['end'])

        self.layer = kwargs.get('layer', 'F.SilkS')
        self.width = kwargs.get('width')

    def calculateBoundingBox(self):
        render_start_pos = self.getRealPosition(self.start_pos)
        render_end_pos = self.getRealPosition(self.end_pos)

        min_x = min([render_start_pos.x, render_end_pos.x])
        min_y = min([render_start_pos.y, render_end_pos.y])
        max_x = max([render_start_pos.x, render_end_pos.x])
        max_y = max([render_start_pos.y, render_end_pos.y])

        return Node.calculateBoundingBox({
            'min': Point(min_x, min_y),
            'max': Point(max_x, max_y)
        })

    def _getRenderTreeText(self):
        render_strings = ['fp_line']
        render_strings.append(self.start_pos.render('(start {x} {y})'))
        render_strings.append(self.end_pos.render('(end {x} {y})'))
        render_strings.append('(layer {layer})'.format(layer=self.layer))
        render_strings.append('(width {width})'.format(width=self.width))

        render_text = Node._getRenderTreeText(self)
        render_text += ' ({})'.format(' '.join(render_strings))

        return render_text
Example #18
0
    def getRealPosition(self, coordinate, rotation=None):
        '''
        return position of point after applying all transformation and rotation operations
        '''
        if not self._parent:
            if rotation is None:
                return Point(coordinate)
            else:
                return Point(coordinate), rotation

        return self._parent.getRealPosition(coordinate, rotation)
Example #19
0
class Circle(Node):
    r"""Add a Circle to the render tree

    :param \**kwargs:
        See below

    :Keyword Arguments:
        * *center* (``Point``) --
          center of the circle
        * *radius* (``float``) --
          radius of the circle
        * *layer* (``str``) --
          layer on which the circle is drawn (default: 'F.SilkS')
        * *width* (``float``) --
          width of the circle line (default: None, which means auto detection)

    :Example:

    >>> from KicadModTree import *
    >>> Circle(center=[0, 0], radius=1.5, layer='F.SilkS')
    """
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.center_pos = Point(kwargs['center'])
        self.radius = kwargs['radius']

        self.end_pos = Point(
            [self.center_pos.x + self.radius, self.center_pos.y])

        self.layer = kwargs.get('layer', 'F.SilkS')
        self.width = kwargs.get('width')

    def calculateBoundingBox(self):
        min_x = self.center_pos.x - self.radius
        min_y = self.center_pos.y - self.radius
        max_x = self.center_pos.x + self.radius
        max_y = self.center_pos.y + self.radius

        return Node.calculateBoundingBox({
            'min': ParseXY(min_x, min_y),
            'max': ParseXY(max_x, max_y)
        })

    def _getRenderTreeText(self):
        render_strings = ['fp_circle']
        render_strings.append(self.center_pos.render('(center {x} {y})'))
        render_strings.append(self.end_pos.render('(end {x} {y})'))
        render_strings.append('(layer {layer})'.format(layer=self.layer))
        render_strings.append('(width {width})'.format(width=self.width))

        render_text = Node._getRenderTreeText(self)
        render_text += ' ({})'.format(' '.join(render_strings))

        return render_text
Example #20
0
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.type = kwargs['type']
        self.text = kwargs['text']
        self.at = Point(kwargs['at'])
        self.rotation = kwargs.get('rotation', 0)

        self.layer = kwargs['layer']
        self.size = Point(kwargs.get('size', [1, 1]))
        self.thickness = kwargs.get('thickness', 0.15)

        self.hide = kwargs.get('hide', False)
Example #21
0
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.start_pos = Point(kwargs['start'])
        self.end_pos = Point(kwargs['end'])

        self.layer = kwargs.get('layer', 'F.SilkS')
        self.width = kwargs.get(
            'width', 0.15)  # TODO: better variation to get line width

        self.virtual_childs = self._createChildNodes(self.start_pos,
                                                     self.end_pos, self.layer,
                                                     self.width)
    def testInit(self):
        p1 = Point([1, 2, 3])
        self.assertEqual(p1.x, 1)
        self.assertEqual(p1.y, 2)
        self.assertEqual(p1.z, 3)

        p1_xy = Point([1, 2])
        self.assertEqual(p1_xy.x, 1)
        self.assertEqual(p1_xy.y, 2)
        self.assertEqual(p1_xy.z, 0)

        p2 = Point((4, 5, 6))
        self.assertEqual(p2.x, 4)
        self.assertEqual(p2.y, 5)
        self.assertEqual(p2.z, 6)

        p2_xy = Point((4, 5))
        self.assertEqual(p2_xy.x, 4)
        self.assertEqual(p2_xy.y, 5)
        self.assertEqual(p2_xy.z, 0)

        p3 = Point({'x': 7, 'y': 8, 'z': 9})
        self.assertEqual(p3.x, 7)
        self.assertEqual(p3.y, 8)
        self.assertEqual(p3.z, 9)

        p3_xy = Point({'x': 7, 'y': 8})
        self.assertEqual(p3_xy.x, 7)
        self.assertEqual(p3_xy.y, 8)
        self.assertEqual(p3_xy.z, 0)

        p3_empty = Point({})
        self.assertEqual(p3_empty.x, 0)
        self.assertEqual(p3_empty.y, 0)
        self.assertEqual(p3_empty.z, 0)

        p4 = Point(p1)
        self.assertEqual(p4.x, 1)
        self.assertEqual(p4.y, 2)
        self.assertEqual(p4.z, 3)

        p5 = Point(1, 2, 3)
        self.assertEqual(p5.x, 1)
        self.assertEqual(p5.y, 2)
        self.assertEqual(p5.z, 3)

        p5_xy = Point(1, 2)
        self.assertEqual(p5_xy.x, 1)
        self.assertEqual(p5_xy.y, 2)
        self.assertEqual(p5_xy.z, 0)
Example #23
0
 def _initDrill(self, **kwargs):
     if self.type in [Pad.TYPE_THT, Pad.TYPE_NPTH]:
         if not kwargs.get('drill'):
             raise KeyError('drill size required (like "drill=1")')
         if type(kwargs.get('drill')) in [int, float]:
             # when the attribute is a simple number, use it for x and y
             self.drill = Point([kwargs.get('drill'), kwargs.get('drill')])
         else:
             self.drill = Point(kwargs.get('drill'))
         if self.drill.x < 0 or self.drill.y < 0:
             raise ValueError("negative drill size not allowed")
     else:
         self.drill = None
         if kwargs.get('drill'):
             pass  # TODO: throw warning because drill is not supported
Example #24
0
    def getRealPosition(self, coordinate, rotation=None):
        if rotation is None:
            rotation = 0

        parsed_coordinate = Point(coordinate)

        phi = self.rotation * math.pi / 180
        rotation_coordinate = {
            'x':
            parsed_coordinate.x * math.cos(phi) +
            parsed_coordinate.y * math.sin(phi),
            'y':
            -parsed_coordinate.x * math.sin(phi) +
            parsed_coordinate.y * math.cos(phi)
        }

        if not self._parent:
            if rotation is None:
                return rotation_coordinate
            else:
                return rotation_coordinate, rotation + self.rotation
        else:
            if rotation is None:
                rotation = 0
            return self._parent.getRealPosition(rotation_coordinate,
                                                rotation + self.rotation)
Example #25
0
    def _createChildNodes(self, start_pos, end_pos, layer, width):
        nodes = []

        cur_y_pos = min([start_pos.y, end_pos.y])
        max_y_pos = max([start_pos.y, end_pos.y])

        while (cur_y_pos + width) < max_y_pos:
            cur_y_pos += width
            new_node = Line(start=Point(start_pos.x, cur_y_pos),
                            end=Point(end_pos.x, cur_y_pos),
                            layer=layer,
                            width=width)
            new_node._parent = self
            nodes.append(new_node)

        return nodes
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.start_pos = Point(kwargs['start'])
        self.end_pos = Point(kwargs['end'])

        self.layer = kwargs.get('layer', 'F.SilkS')
        self.width = kwargs.get(
            'width', 0.15)  # TODO: better variation to get line width

        rect_line = RectLine(**kwargs)
        rect_line._parent = self

        rect_fill = RectFill(**kwargs)
        rect_fill._parent = self

        self.virtual_childs = [rect_line, rect_fill]
    def testSub(self):
        p1 = Point([1, 2, 3])
        self.assertEqual(p1.x, 1)
        self.assertEqual(p1.y, 2)
        self.assertEqual(p1.z, 3)

        p2 = p1 - 5
        self.assertEqual(p2.x, -4)
        self.assertEqual(p2.y, -3)
        self.assertEqual(p2.z, -2)

        p3 = p1 - (-5)
        self.assertEqual(p3.x, 6)
        self.assertEqual(p3.y, 7)
        self.assertEqual(p3.z, 8)

        p4 = p1 - [4, 2, -2]
        self.assertEqual(p4.x, -3)
        self.assertEqual(p4.y, 0)
        self.assertEqual(p4.z, 5)

        p5 = p1 - [-5, -3]
        self.assertEqual(p5.x, 6)
        self.assertEqual(p5.y, 5)
        self.assertEqual(p5.z, 3)
    def testMul(self):
        p1 = Point([1, 2, 3])
        self.assertEqual(p1.x, 1)
        self.assertEqual(p1.y, 2)
        self.assertEqual(p1.z, 3)

        p2 = p1 * 5
        self.assertEqual(p2.x, 5)
        self.assertEqual(p2.y, 10)
        self.assertEqual(p2.z, 15)

        p3 = p1 * (-5)
        self.assertEqual(p3.x, -5)
        self.assertEqual(p3.y, -10)
        self.assertEqual(p3.z, -15)

        p4 = p1 * [4, 5, -2]
        self.assertEqual(p4.x, 4)
        self.assertEqual(p4.y, 10)
        self.assertEqual(p4.z, -6)

        p5 = p1 * [-5, -3]
        self.assertEqual(p5.x, -5)
        self.assertEqual(p5.y, -6)
        self.assertEqual(p5.z, 3)
    def testDiv(self):
        p1 = Point([1, 2, 3])
        self.assertEqual(p1.x, 1)
        self.assertEqual(p1.y, 2)
        self.assertEqual(p1.z, 3)

        p2 = p1 / 5
        self.assertEqual(p2.x, 0.2)
        self.assertEqual(p2.y, 0.4)
        self.assertEqual(p2.z, 0.6)

        p3 = p1 / (-5)
        self.assertEqual(p3.x, -0.2)
        self.assertEqual(p3.y, -0.4)
        self.assertEqual(p3.z, -0.6)

        p4 = p1 / [4, 5, -2]
        self.assertEqual(p4.x, 0.25)
        self.assertEqual(p4.y, 0.4)
        self.assertEqual(p4.z, -1.5)

        p5 = p1 / [-5, -2]
        self.assertEqual(p5.x, -0.2)
        self.assertEqual(p5.y, -1)
        self.assertEqual(p5.z, 3)
Example #30
0
class Circle(Node):
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.center_pos = Point(kwargs['center'])
        self.radius = kwargs['radius']

        self.end_pos = {'x': self.center_pos.x+self.radius, 'y': self.center_pos.y}

        self.layer = kwargs.get('layer', 'F.SilkS')
        self.width = kwargs.get('width')

    def calculateBoundingBox(self):
        min_x = self.center_pos.x-self.radius
        min_y = self.center_pos.y-self.radius
        max_x = self.center_pos.x+self.radius
        max_y = self.center_pos.y+self.radius

        return Node.calculateBoundingBox({'min': ParseXY(min_x, min_y), 'max': ParseXY(max_x, max_y)})

    def _getRenderTreeText(self):
        render_strings = ['fp_circle']
        render_strings.append(self.center_pos.render('(center {x} {y})'))
        render_strings.append(self.end_pos.render('(end {x} {y})'))
        render_strings.append('(layer {layer})'.format(layer=self.layer))
        render_strings.append('(width {width})'.format(width=self.width))

        render_text = Node._getRenderTreeText(self)
        render_text += ' ({})'.format(' '.join(render_strings))

        return render_text
    def testAdd(self):
        p1 = Point([1, 2, 3])
        self.assertEqual(p1.x, 1)
        self.assertEqual(p1.y, 2)
        self.assertEqual(p1.z, 3)

        p2 = p1 + 5
        self.assertEqual(p2.x, 6)
        self.assertEqual(p2.y, 7)
        self.assertEqual(p2.z, 8)

        p3 = p1 + (-5)
        self.assertEqual(p3.x, -4)
        self.assertEqual(p3.y, -3)
        self.assertEqual(p3.z, -2)

        p4 = p1 + [4, 2, -2]
        self.assertEqual(p4.x, 5)
        self.assertEqual(p4.y, 4)
        self.assertEqual(p4.z, 1)

        p5 = p1 + [-5, -3]
        self.assertEqual(p5.x, -4)
        self.assertEqual(p5.y, -1)
        self.assertEqual(p5.z, 3)
class Model(Node):
    r"""Add a 3D-Model to the render tree

    :param \**kwargs:
        See below

    :Keyword Arguments:
        * *filename* (``str``) --
          name of the 3d-model file
        * *at* (``Point``) --
          position of the model
        * *scale* (``Point``) --
          scale of the model
        * *rotate* (``Point``) --
          rotation of the model

    :Example:

    >>> from KicadModTree import *
    >>> Model(filename="example.3dshapes/example_footprint.wrl",
    ...       at=[0, 0, 0], scale=[1, 1, 1], rotate=[0, 0, 0])
    """
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.filename = kwargs['filename']
        self.at = Point(kwargs['at'])
        self.scale = Point(kwargs['scale'])
        self.rotate = Point(kwargs['rotate'])

    def _getRenderTreeText(self):
        render_text = Node._getRenderTreeText(self)

        render_string = [
            'filename: {filename}'.format(filename=self.filename),
            'at: {at}'.format(at=self.at.render('(xyz {x} {y} {z})')),
            'scale: {scale}'.format(
                scale=self.scale.render('(xyz {x} {y} {z})')),
            'rotate: {rotate}'.format(
                rotate=self.rotate.render('(xyz {x} {y} {z})'))
        ]

        render_text += " [{}]".format(", ".join(render_string))

        return render_text
Example #33
0
    def calculateBoundingBox(self, outline=None):
        min_x, min_y = 0, 0
        max_x, max_y = 0, 0

        if outline:
            min_x = outline['min']['x']
            min_y = outline['min']['y']
            max_x = outline['max']['x']
            max_y = outline['max']['y']

        for child in self.getAllChilds():
            child_outline = child.calculateBoundingBox()

            min_x = min([min_x, child_outline['min']['x']])
            min_y = min([min_y, child_outline['min']['y']])
            max_x = max([max_x, child_outline['max']['x']])
            max_y = max([max_y, child_outline['max']['y']])

        return {'min': Point(min_x, min_y), 'max': Point(max_x, max_y)}
class Model(Node):
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.filename = kwargs['filename']
        self.at = Point(kwargs['at'])
        self.scale = Point(kwargs['scale'])
        self.rotate = Point(kwargs['rotate'])

    def _getRenderTreeText(self):
        render_text = Node._getRenderTreeText(self)

        render_string = ['filename: {filename}'.format(filename=self.filename),
                         'at: {at}'.format(at=self.at.render('(xyz {x} {y} {z})')),
                         'scale: {scale}'.format(scale=self.scale.render('(xyz {x} {y} {z})')),
                         'rotate: {rotate}'.format(rotate=self.rotate.render('(xyz {x} {y} {z})'))]

        render_text += " [{}]".format(", ".join(render_string))

        return render_text
Example #35
0
class Text(Node):
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.type = kwargs['type']
        self.text = kwargs['text']
        self.at = Point(kwargs['at'])
        self.rotation = kwargs.get('rotation', 0)

        self.layer = kwargs['layer']
        self.size = Point(kwargs.get('size', [1, 1]))
        self.thickness = kwargs.get('thickness', 0.15)

        self.hide = kwargs.get('hide', False)

    def calculateBoundingBox(self):
        width = len(self.text) * self.size['x']
        height = self.size['y']

        min_x = self.at[x] - width / 2.
        min_y = self.at[y] - height / 2.
        max_x = self.at[x] + width / 2.
        max_y = self.at[y] + height / 2.

        return Node.calculateBoundingBox({
            'min': Point(min_x, min_y),
            'max': Point(max_x, max_y)
        })

    def _getRenderTreeText(self):
        render_text = Node._getRenderTreeText(self)

        render_string = [
            'type: "{}"'.format(self.type), 'text: "{}"'.format(self.text),
            'at: {}'.format(self.at.render('(at {x} {y})')),
            'layer: {}'.format(self.layer),
            'size: {}'.format(self.size.render('(size {x} {y})')),
            'thickness: {}'.format(self.thickness)
        ]

        render_text += " [{}]".format(", ".join(render_string))

        return render_text
class Model(Node):
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.filename = kwargs['filename']
        self.at = Point(kwargs.get('at', [0, 0, 0]))
        self.scale = Point(kwargs.get('scale', [1, 1, 1]))
        self.rotate = Point(kwargs.get('rotate', [0, 0, 0]))

    def _getRenderTreeText(self):
        render_text = Node._getRenderTreeText(self)

        render_string = [
            'filename: {filename}'.format(filename=self.filename),
            'at: {at}'.format(at=self.at.render('(xyz {x} {y} {z})')),
            'scale: {scale}'.format(
                scale=self.scale.render('(xyz {x} {y} {z})')),
            'rotate: {rotate}'.format(
                rotate=self.rotate.render('(xyz {x} {y} {z})'))
        ]

        render_text += " [{}]".format(", ".join(render_string))

        return render_text
 def __init__(self, **kwargs):
     Node.__init__(self)
     self.filename = kwargs['filename']
     self.at = Point(kwargs.get('at',[0,0,0]))
     self.scale = Point(kwargs.get('scale',[1,1,1]))
     self.rotate = Point(kwargs.get('rotate',[0,0,0]))
class Arc(Node):
    def __init__(self, **kwargs):
        Node.__init__(self)
        self.center_pos = Point(kwargs['center'])
        self.start_pos = Point(kwargs['start'])
        self.angle = kwargs['angle']

        self.layer = kwargs.get('layer', 'F.SilkS')
        self.width = kwargs.get('width')

    def calculateBoundingBox(self):
        # TODO: finish implementation
        min_x = min(self.start_pos.x, self._calulateEndPos().x)
        min_y = min(self.start_pos.x, self._calulateEndPos().y)
        max_x = max(self.start_pos.x, self._calulateEndPos().x)
        max_y = max(self.start_pos.x, self._calulateEndPos().y)

        '''
        for angle in range(4):
            float_angle = angle * math.pi/2.

            start_angle = _calculateStartAngle(self)
            end_angle = start_angle + math.radians(self.angle)

            # TODO: +- pi border
            if float_angle < start_angle:
                continue
            if float_angle > end_angle:
                continue

            print("TODO: add angle side: {1}".format(float_angle))
        '''

        return Node.calculateBoundingBox({'min': Point((min_x, min_y)), 'max': Point((max_x, max_y))})

    def _calulateEndPos(self):
        radius = self._calculateRadius()

        angle = self._calculateStartAngle() + math.radians(self.angle)

        return Point(math.sin(angle)*radius, math.cos(angle)*radius)

    def _calculateRadius(self):
        x_size = self.start_pos.x - self.center_pos.x
        y_size = self.start_pos.y - self.center_pos.y

        return math.sqrt(math.pow(x_size, 2) + math.pow(y_size, 2))

    def _calculateStartAngle(self):
        x_size = self.start_pos.x - self.center_pos.x
        y_size = self.start_pos.y - self.center_pos.y

        return math.atan2(y_size, x_size)

    def _getRenderTreeText(self):
        render_strings = ['fp_arc']
        render_strings.append(self.center_pos.render('(center {x} {y})'))
        render_strings.append(self.start_pos.render('(start {x} {y})'))
        render_strings.append('(angle {angle})'.format(angle=self.angle))
        render_strings.append('(layer {layer})'.format(layer=self.layer))
        render_strings.append('(width {width})'.format(width=self.width))

        render_text = Node._getRenderTreeText(self)
        render_text += ' ({})'.format(' '.join(render_strings))

        return render_text
    def _initPosition(self, **kwargs):
        if not kwargs.get('at'):
            raise KeyError('center position not declared (like "at=[0,0]")')
        self.at = Point(kwargs.get('at'))

        self.rotation = kwargs.get('rotation', 0)
 def __init__(self, **kwargs):
     Node.__init__(self)
     self.filename = kwargs['filename']
     self.at = Point(kwargs['at'])
     self.scale = Point(kwargs['scale'])
     self.rotate = Point(kwargs['rotate'])
class Pad(Node):
    TYPE_THT = 'thru_hole'
    TYPE_SMT = 'smd'
    TYPE_CONNECT = 'connect'
    TYPE_NPTH = 'np_thru_hole'
    _TYPES = [TYPE_THT, TYPE_SMT, TYPE_CONNECT, TYPE_NPTH]

    SHAPE_CIRCLE = 'circle'
    SHAPE_OVAL = 'oval'
    SHAPE_RECT = 'rect'
    SHAPE_TRAPEZE = 'trapezoid'
    _SHAPES = [SHAPE_CIRCLE, SHAPE_OVAL, SHAPE_RECT, SHAPE_TRAPEZE]
    
    LAYERS_SMT = ['F.Cu','F.Mask','F.Paste']
    LAYERS_THT = ['*.Cu','*.Mask']
    LAYERS_NPTH = ['*.Cu']

    def __init__(self, **kwargs):
        Node.__init__(self)

        self._initNumber(**kwargs)
        self._initType(**kwargs)
        self._initShape(**kwargs)
        self._initPosition(**kwargs)
        self._initSize(**kwargs)
        self._initOffset(**kwargs)
        self._initDrill(**kwargs)  # requires pad type and offset
        self._initSolderPasteMargin(**kwargs)
        self._initLayers(**kwargs)

    def _initNumber(self, **kwargs):
        self.number = kwargs.get('number','""') #default to an un-numbered pad

    def _initType(self, **kwargs):
        if not kwargs.get('type'):
            raise KeyError('type not declared (like "type=Pad.TYPE_THT")')
        self.type = kwargs.get('type')
        if self.type not in Pad._TYPES:
            raise ValueError('{type} is an invalid type for pads'.format(type=self.type))

    def _initShape(self, **kwargs):
        if not kwargs.get('shape'):
            raise KeyError('shape not declared (like "shape=Pad.SHAPE_CIRCLE")')
        self.shape = kwargs.get('shape')
        if self.shape not in Pad._SHAPES:
            raise ValueError('{shape} is an invalid shape for pads'.format(shape=self.shape))

    def _initPosition(self, **kwargs):
        if not kwargs.get('at'):
            raise KeyError('center position not declared (like "at=[0,0]")')
        self.at = Point(kwargs.get('at'))

        self.rotation = kwargs.get('rotation', 0)

    def _initSize(self, **kwargs):
        if not kwargs.get('size'):
            raise KeyError('pad size not declared (like "size=[1,1]")')
        if type(kwargs.get('size')) in [int, float]:
            # when the attribute is a simple number, use it for x and y
            self.size = Point([kwargs.get('size'), kwargs.get('size')])
        else:
            self.size = Point(kwargs.get('size'))

    def _initOffset(self, **kwargs):
        self.offset = Point(kwargs.get('offset', [0, 0]))

    def _initDrill(self, **kwargs):
        if self.type in [Pad.TYPE_THT, Pad.TYPE_NPTH]:
            if not kwargs.get('drill'):
                raise KeyError('drill size required (like "drill=1")')
            if type(kwargs.get('drill')) in [int, float]:
                # when the attribute is a simple number, use it for x and y
                self.drill = Point([kwargs.get('drill'), kwargs.get('drill')])
            else:
                self.drill = Point(kwargs.get('drill'))
            if self.drill.x < 0 or self.drill.y < 0:
                raise ValueError("negative drill size not allowed")
        else:
            self.drill = None
            if kwargs.get('drill'):
                pass  # TODO: throw warning because drill is not supported

    def _initSolderPasteMargin(self, **kwargs):
        self.solder_paste_margin_ratio = kwargs.get('solder_paste_margin_ratio', 0)

    def _initLayers(self, **kwargs):
        if not kwargs.get('layers'):
            raise KeyError('layers not declared (like "layers=[\'*.Cu\', \'*.Mask\', \'F.SilkS\']")')
        self.layers = kwargs.get('layers')

    #calculate the outline of a pad
    def calculateBoundingBox(self):
        return Node.calculateBoundingBox(self)

    def _getRenderTreeText(self):
        render_strings = ['pad']
        render_strings.append(lispString(self.number))
        render_strings.append(lispString(self.type))
        render_strings.append(lispString(self.shape))
        render_strings.append(self.at.render('(at {x} {y})'))
        render_strings.append(self.size.render('(size {x} {y})'))
        render_strings.append('(drill {})'.format(self.drill))
        render_strings.append('(layers {})'.format(' '.join(self.layers)))

        render_text = Node._getRenderTreeText(self)
        render_text += '({})'.format(' '.join(render_strings))

        return render_text