fix render gerber for outlines

This commit is contained in:
Andrei 2021-02-21 18:56:09 +02:00
parent 3d5ecf0275
commit 7b2adc25c8
1 changed files with 37 additions and 9 deletions

View File

@ -42,6 +42,11 @@ class HellenGerberCairoContext(GerberCairoContext):
verbose=verbose)
self.dump(filename, verbose)
def addPoint(self, start, end, additional):
start = (start[0] + self.origin_in_pixels[0], start[1] + self.origin_in_pixels[1])
end = (end[0] + self.origin_in_pixels[0], end[1] + self.origin_in_pixels[1])
self.lineList.append([start, end, additional])
# this override is needed to gather all line segments from the outline layers
def _render_line(self, line, color):
if self.isOutline == False or self._render_count != 1: # outline layer
@ -49,24 +54,34 @@ class HellenGerberCairoContext(GerberCairoContext):
return
start = self.scale_point(line.start)
end = self.scale_point(line.end)
start = (start[0] + self.origin_in_pixels[0], start[1] + self.origin_in_pixels[1])
end = (end[0] + self.origin_in_pixels[0], end[1] + self.origin_in_pixels[1])
# we don't draw lines, we store the line segments
with self._clip_primitive(line):
self.lineList.append([start, end])
self.addPoint(start, end, None)
# thi override is needed to render the actual outline layers in a form of closed filled polygon
# this override is needed to gather all arcs from the outline layers
def _render_arc(self, arc, color):
if self.isOutline == False or self._render_count != 1: # outline layer
GerberCairoContext._render_arc(self, arc, color)
return
start = self.scale_point(arc.start)
end = self.scale_point(arc.end)
# we don't draw arcs, we store them
with self._clip_primitive(arc):
self.addPoint(start, end, arc)
# this override is needed to render the actual outline layers in a form of closed filled polygon
def flatten(self, color=None, alpha=None):
if self.isOutline == True and self._render_count == 1: # outline layer
# reconstruct the contour (the original lines go in no particular order)
curPoint = self.lineList[0]
countourPoints = []
for i in range(1000):
countourPoints.append(curPoint[0])
countourPoints.append([curPoint[0][0], curPoint[0][1], curPoint[2]])
dist = sys.float_info.max
# find the closest point among the
for ll in self.lineList:
if ll == curPoint:
llinv = [ll[1], ll[0], ll[2]]
if ll == curPoint or llinv == curPoint:
continue
d = (ll[0][0] - curPoint[1][0])**2 + (ll[0][1] - curPoint[1][1])**2
if d < dist:
@ -75,7 +90,7 @@ class HellenGerberCairoContext(GerberCairoContext):
d = (ll[1][0] - curPoint[1][0])**2 + (ll[1][1] - curPoint[1][1])**2
if d < dist:
dist = d
nextCurPoint = [ll[1], ll[0]]
nextCurPoint = llinv
if dist < 1.e-4:
break
if nextCurPoint[0] in countourPoints:
@ -84,9 +99,22 @@ class HellenGerberCairoContext(GerberCairoContext):
# draw the filled contour
with self._new_mask() as mask:
mask.ctx.move_to(*countourPoints[0])
mask.ctx.move_to(countourPoints[0][0], countourPoints[0][1])
wasArc = False
for ll in countourPoints:
mask.ctx.line_to(*ll)
if ll[2]:
arc = ll[2]
center = self.scale_point(arc.center)
radius = self.scale[0] * arc.radius
two_pi = 2 * math.pi
angle1 = (arc.start_angle + two_pi) % two_pi
angle2 = (arc.end_angle + two_pi) % two_pi
if arc.direction == 'counterclockwise':
mask.ctx.arc(center[0], center[1], radius, angle1, angle2)
else:
mask.ctx.arc_negative(center[0], center[1], radius, angle1, angle2)
else:
mask.ctx.line_to(ll[0], ll[1])
mask.ctx.set_source_rgba(1.0, 1.0, 1.0, 1.0)
mask.ctx.fill()
self.ctx.mask_surface(mask.surface, 0.0, 0.0)