Exemplo n.º 1
0
 def calc_bbox(self) -> Tuple[svg.Point, svg.Point]:
     '''Calculate bounding box of self'''
     self.bbox = (
         svg.Point(
             min(self.points, key=lambda v: v.x).x,
             min(self.points, key=lambda v: v.y).y),
         svg.Point(
             max(self.points, key=lambda v: v.x).x,
             max(self.points, key=lambda v: v.y).y),
     )
Exemplo n.º 2
0
    def process(self, transformer, flip, fill):

        points = []
        for point in self.points:

            point = transformer.transform_point(point, flip)

            if (len(points) < 1 or point.x != points[-1].x
                    or point.y != points[-1].y):
                points.append(point)

        if (points[0].x != points[-1].x or points[0].y != points[-1].y):
            #print( "Warning: Closing polygon. start=({}, {}) end=({}, {})".format(
            #points[ 0 ].x, points[ 0 ].y,
            #points[ -1 ].x, points[ -1 ].y,
            #) )

            if fill:
                points.append(svg.Point(
                    points[0].x,
                    points[0].y,
                ))

        #else:
        #print( "Polygon closed: start=({}, {}) end=({}, {})".format(
        #points[ 0 ].x, points[ 0 ].y,
        #points[ -1 ].x, points[ -1 ].y,
        #) )

        self.points = points
Exemplo n.º 3
0
    def _calculate_translation(self):

        min_point, max_point = self.imported.svg.bbox()

        if (self.center):
            # Center the drawing:
            adjust_x = min_point.x + (max_point.x - min_point.x) / 2.0
            adjust_y = min_point.y + (max_point.y - min_point.y) / 2.0

            self.translation = svg.Point(
                0.0 - adjust_x,
                0.0 - adjust_y,
            )

        else:
            self.translation = svg.Point(
                0.0,
                0.0,
            )
Exemplo n.º 4
0
 def vertical_intersection(p: svg.Point, q: svg.Point,
                           r: float) -> svg.Point:
     '''This is used for the in-lining algorithm
     it finds a point on a line p -> q where x = r
     '''
     if p.x == q.x:
         return min([p, q], key=lambda v: v.y)
     if r == p.x: return p
     if r == q.x: return q
     return svg.Point(r, (p.y - q.y) * (r - q.x) / (p.x - q.x) + q.y)
Exemplo n.º 5
0
    def points_starting_on_index(self, index):

        points = self.points

        if index > 0:

            # Strip off end point, which is a duplicate of the start point:
            points = points[:-1]

            points = points[index:] + points[:index]

            points.append(svg.Point(points[0].x, points[0].y))

        return points
Exemplo n.º 6
0
    def inline( self, segments ):

        if len( segments ) < 1:
            return self.points

        print( "    Inlining {} segments...".format( len( segments ) ) )

        all_segments = segments[ : ] + [ self ]
        insertions = []

        # Find the insertion point for each hole:
        for hole in segments:

            insertion = self._find_insertion_point(
                hole, all_segments
            )
            if insertion is not None:
                insertions.append( insertion )

        insertions.sort( key = lambda i: i[ 0 ] )

        inlined = [ self.points[ 0 ] ]
        ip = 1
        points = self.points

        for insertion in insertions:

            while ip <= insertion[ 0 ]:
                inlined.append( points[ ip ] )
                ip += 1

            if (
                inlined[ -1 ].x == insertion[ 1 ][ 0 ].x and
                inlined[ -1 ].y == insertion[ 1 ][ 0 ].y
            ):
                inlined += insertion[ 1 ][ 1 : -1 ]
            else:
                inlined += insertion[ 1 ]

            inlined.append( svg.Point(
                points[ ip - 1 ].x,
                points[ ip - 1 ].y,
            ) )

        while ip < len( points ):
            inlined.append( points[ ip ] )
            ip += 1

        return inlined
Exemplo n.º 7
0
    def points_starting_on_index(self, index: int) -> List[svg.Point]:
        ''' Return the list of ordered points starting on the given index, ensuring
        that the first and last points are the same.
        '''

        points = self.points

        if index > 0:

            # Strip off end point, which is a duplicate of the start point:
            points = points[:-1]

            points = points[index:] + points[:index]

            points.append(svg.Point(points[0].x, points[0].y))

        return points
Exemplo n.º 8
0
    def _find_insertion_point(self, hole: 'PolygonSegment', holes: list,
                              other_insertions: list):
        ''' KiCad will not "pick up the pen" when moving between a polygon outline
        and holes within it, so we search for a pair of points connecting the
        outline (self) or other previously inserted points to the hole such
        that the connecting segment will not cross the visible inner space
        within any hole.
        '''

        highest_point = max(hole.points, key=lambda v: v.y)
        vertical_line = LineSegment(
            highest_point, svg.Point(highest_point.x, self.bbox[1].y + 1))

        intersections = {
            self:
            self.intersects(vertical_line,
                            False,
                            count_intersections=True,
                            get_points=True)
        }
        for _, h, __ in other_insertions:
            if h.bbox[0].x < highest_point.x and h.bbox[1].x > highest_point.x:
                intersections[h] = h.intersects(vertical_line,
                                                False,
                                                count_intersections=True,
                                                get_points=True)

        best = [self, intersections[self][0]]
        best.append(
            LineSegment.vertical_intersection(best[1][0], best[1][1],
                                              highest_point.x))
        for path in intersections:
            for p, q in intersections[path]:
                pnt = LineSegment.vertical_intersection(p, q, highest_point.x)
                if pnt.y < best[2].y:
                    best = [path, (p, q), pnt]

        if best[2] != best[1][0] and best[2] != best[1][1]:
            p = best[0].points.index(best[1][0])
            q = best[0].points.index(best[1][1])
            ip = p if p < q else q
            best[0]._set_points(best[0].points[:ip + 1] + [best[2]] +
                                best[0].points[ip + 1:])

        return (best[2], hole, highest_point)
Exemplo n.º 9
0
    def transform_point(self, point, flip=False):

        transformed_point = svg.Point(
            (point.x + self.translation.x) * self.scale_factor,
            (point.y + self.translation.y) * self.scale_factor,
        )

        if flip:
            transformed_point.x *= -1

        if self.use_mm:
            transformed_point.x = round(transformed_point.x, 12)
            transformed_point.y = round(transformed_point.y, 12)
        else:
            transformed_point.x = int(round(transformed_point.x))
            transformed_point.y = int(round(transformed_point.y))

        return transformed_point
Exemplo n.º 10
0
    def transform_point( self, point, flip = False ):
        ''' Transform provided point by this
        classes scale factor.
        '''

        transformed_point = svg.Point(
            ( point.x + self.translation.x ) * self.scale_factor,
            ( point.y + self.translation.y ) * self.scale_factor,
        )

        if flip:
            transformed_point.x *= -1

        if self.use_mm:
            transformed_point.x = transformed_point.x
            transformed_point.y = transformed_point.y
        else:
            transformed_point.x = int( round( transformed_point.x ) )
            transformed_point.y = int( round( transformed_point.y ) )

        return transformed_point
Exemplo n.º 11
0
    def are_distinct(self, polygon):
        ''' Checks if the supplied polygon either contains or insets our bounding box'''
        distinct = True

        smaller = min([self, polygon],
                      key=lambda p: svg.Segment(p.bbox[0], p.bbox[1]).length())
        larger = self if smaller == polygon else polygon

        if (larger.bbox[0].x < smaller.bbox[0].x
                and larger.bbox[0].y < smaller.bbox[0].y
                and larger.bbox[1].x > smaller.bbox[1].x
                and larger.bbox[1].y > smaller.bbox[1].y):
            distinct = False

        # Check number of horizontal intersections. If the number is odd then it the smaller polygon
        # is contained. If the number is even then the polygon is outside of the larger polygon
        if not distinct:
            tline = LineSegment(
                smaller.points[0],
                svg.Point(larger.bbox[1].x + 1, smaller.points[0].y))
            distinct = bool((larger.intersects(tline, False, True) + 1) % 2)

        return distinct
Exemplo n.º 12
0
		def _write_wirepad( self ):
			root = (self.imported.svg.root)

			pad_string = ""
			count = 0

			pad_template = """
				(module Wire_Pads:SolderWirePad_single_0-8mmDrill (layer F.Cu) (tedit 0) (tstamp 5ABD66D0)
					(at %f %f)
					(pad %d thru_hole circle (at 0 0) (size 1.99898 1.99898) (drill 0.8001) (layers *.Cu *.Mask))
				)
			"""

			items = self.imported.svg.items
			for item in items:
				# print item.name
				if (item.name == "Drill"): 
					# item.transform()

					for drill in item.items:
						count = count + 1
						# print drill.matrix.vect
						old_center = drill.center
						# drill.transform(item.matrix)
						new_center = drill.center

						# transx = ((new_center.x - old_center.x) * 2 ) / (96/25.4)
						# transy = ((new_center.y - old_center.y) * 2 ) / (96/25.4)

						test = svg.Point(drill.center.x*1.0666794869689005,drill.center.y*1.0666794869689005)
						new_pad = self.transform_point(test)
						pad_x = new_pad.x
						pad_y = new_pad.y
						pad_string = pad_string + pad_template % (pad_x, pad_y, count)
			
			self.output_file.write(pad_string)
Exemplo n.º 13
0
    def process(self, transformer, flip, fill):
        ''' Apply all transformations, then remove duplicate
        consecutive points along the path.
        '''

        points = []
        for point in self.points:

            point = transformer.transform_point(point, flip)

            if (len(points) < 1 or point.x != points[-1].x
                    or point.y != points[-1].y):
                points.append(point)

        if (points[0].x != points[-1].x or points[0].y != points[-1].y):

            if fill:
                points.append(svg.Point(
                    points[0].x,
                    points[0].y,
                ))

        self.points = points
        self.calc_bbox()
Exemplo n.º 14
0
    def renderLabel(self, inString):
        # t is an svg Text element
        t = svg.Text()

        t.set_font(self.fontName)
        
        for i,s in enumerate(inString.split('\n')):
            t.add_text(s, origin=svg.Point(0, 15*i))
        
        # This needs to be called to convert raw text to useable path elements
        t.convert_to_path()
    
        # bounds check padding
        padding = self.padding
        for attr in ['left', 'right', 'top', 'bottom']:
            if getattr(padding,attr) <= 0: setattr(padding, attr, 0.001)

        bbox = t.bbox()
        height = bbox[1].y - bbox[0].y
        
        height += padding.top + padding.bottom
        width = bbox[1].x - bbox[0].x
        textWidth = (width + (self.padding.left + self.padding.right))


        fixedWidth = max(0, self.width - (self.padding.left + self.padding.right))
        width = max(width, fixedWidth)

        alignmentOffset = 0
        if self.alignment == 'Left' or fixedWidth != width:
            alignmentOffset = 0
        elif self.alignment == 'Center':
            alignmentOffset = (self.width - textWidth)/2
        elif self.alignment == 'Right':
            alignmentOffset = (self.width - textWidth)
            
        # Create outline around text 
        if (self.leftCap != '') & (self.rightCap != ''):
            pstr = "M {},{} ".format(bbox[0].x - alignmentOffset, bbox[0].y-padding.top)
            pstr += "h {} ".format(-padding.left)
            
            if self.leftCap == 'round':
                pstr += "a {},{} 0 0 0 0,{} ".format(height/2,height/2,height)
            if self.leftCap == 'square':
                pstr += "v {} ".format(height)
            if self.leftCap == 'fslash':
                pstr += "l {},{} h {} ".format(-0.3*height, height, 0.3*height)
            if self.leftCap == 'bslash':
                pstr += "h {} l {},{} ".format(-0.3*height, 0.3*height, height)
            if self.leftCap == 'pointer':
                pstr += "l {},{} l {},{} ".format(height/-3, height/2, height/3, height/2)
            if self.leftCap == 'flagtail':
                pstr += "h {} l {},{} l {},{} h {}".format(height/-3, height/3, height/2, height/-3, height/2, height/3)

            pstr += "h {} ".format(padding.left)        
            pstr += "h {} ".format(width)
            pstr += "h {} ".format(padding.right)
            
            if self.rightCap == 'round':
                pstr += "a {},{} 0 0 0 0,{} ".format(height/2, height/2,-height)
            if self.rightCap == 'square':
                pstr += "v {} ".format(-height)
            if self.rightCap == 'fslash':
                pstr += "l {},{} h {} ".format(0.3*height, -height, -0.3*height)
            if self.rightCap == 'bslash':
                pstr += "h {} l {},{} ".format(0.3*height, -0.3*height, -height)
            if self.rightCap == 'pointer':
                pstr += "l {},{} l {},{} ".format(height/3, height/-2, height/-3, height/-2)
            if self.rightCap == 'flagtail':
                pstr += "h {} l {},{} l {},{} h {}".format(height/3, height/-3, height/-2, height/3, height/-2, height/-3)
            
            pstr += "h {} ".format(-padding.right)
            pstr += "h {} z".format(-1*width)

            p = svg.Path()
            p.parse(pstr)
            t.paths.append([p])

        return t
Exemplo n.º 15
0
    def renderLabel(self, inString):
        # t is an svg Text element
        t = svg.Text()

        t.set_font(self.fontName)

        for i, s in enumerate(inString.split('\n')):
            t.add_text(s, origin=svg.Point(0, 15 * i))

        # This needs to be called to convert raw text to useable path elements
        t.convert_to_path()

        bbox = t.bbox()
        height = bbox[1].y - bbox[0].y
        buff = t.size / 5
        height += buff * 2
        width = bbox[1].x - bbox[0].x

        # Create outline around text
        if (self.leftCap != '') & (self.rightCap != ''):
            pstr = "M {},{} ".format(bbox[0].x, bbox[0].y - buff)

            if self.leftCap == 'round':
                pstr += "a {},{} 0 0 0 0,{} ".format(height / 2, height / 2,
                                                     height)
            if self.leftCap == 'square':
                pstr += "l {},0 l 0,{} l {},0 ".format(-buff, height, buff)
            if self.leftCap == 'fslash':
                pstr += "l {},0 l {},{} l {},0 ".format(
                    -buff, -2 * buff, height, 3 * buff)
            if self.leftCap == 'bslash':
                pstr += "l {},0 l {},{} l {},0 ".format(
                    -3 * buff, 2 * buff, height, buff)
            if self.leftCap == 'pointer':
                pstr += "l {},{} l {},{} ".format(height / -2, height / 2,
                                                  height / 2, height / 2)
            if self.leftCap == 'flagtail':
                pstr += "l {},0 l {},{} l {},{} l {},0".format(
                    -1 * buff - height / 2, height / 2, height / 2,
                    height / -2, height / 2, buff + height / 2)

            pstr += "h {} ".format(width)

            if self.rightCap == 'round':
                pstr += "a {},{} 0 0 0 0,{} ".format(height / 2, height / 2,
                                                     -height)
            if self.rightCap == 'square':
                pstr += "l {},0 l 0,{} l {},0 ".format(buff, -height, -buff)
            if self.rightCap == 'fslash':
                pstr += "l {},0 l {},{} l {},0 ".format(
                    buff, 2 * buff, -height, -3 * buff)
            if self.rightCap == 'bslash':
                pstr += "l {},0 l {},{} l {},0 ".format(
                    3 * buff, -2 * buff, -height, -buff)
            if self.rightCap == 'pointer':
                pstr += "l {},{} l {},{} ".format(height / 2, height / -2,
                                                  height / -2, height / -2)
            if self.rightCap == 'flagtail':
                pstr += "l {},0 l {},{} l {},{} l {},0 ".format(
                    1 * buff + height / 2, height / -2, height / -2,
                    height / 2, height / -2, -buff - height / 2)

            pstr += "h {} z".format(-1 * width)

            p = svg.Path()
            p.parse(pstr)
            t.paths.append([p])

        return t