- PDF import tool: added support for save/restore Graphics stack. Only for scale and offset transformations and for the linewidth. This is the final fix for Microsoft PDF printer who saves in PDF format 1.7

This commit is contained in:
Marius Stanciu 2019-04-22 15:35:21 +03:00 committed by Marius
parent 53444fc685
commit 8a2a48f668
2 changed files with 123 additions and 109 deletions

View File

@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing.
================================================= =================================================
22.04.2019
- PDF import tool: added support for save/restore Graphics stack. Only for scale and offset transformations and for the linewidth. This is the final fix for Microsoft PDF printer who saves in PDF format 1.7
21.04.2019 21.04.2019
- fixed the PDF import tool to work with files generated by the Microsoft PDF printer (chained subpaths) - fixed the PDF import tool to work with files generated by the Microsoft PDF printer (chained subpaths)

View File

@ -75,16 +75,30 @@ class ToolPDF(FlatCAMTool):
self.no_op_re = re.compile(r'^n$') self.no_op_re = re.compile(r'^n$')
# detect offset transformation. Pattern: (1) (0) (0) (1) (x) (y) # detect offset transformation. Pattern: (1) (0) (0) (1) (x) (y)
self.offset_re = re.compile(r'^1\.?0*\s0?\.?0*\s0?\.?0*\s1\.?0*\s(-?\d+\.?\d*)\s(-?\d+\.?\d*)\s*cm$') # self.offset_re = re.compile(r'^1\.?0*\s0?\.?0*\s0?\.?0*\s1\.?0*\s(-?\d+\.?\d*)\s(-?\d+\.?\d*)\s*cm$')
# detect scale transformation. Pattern: (factor_x) (0) (0) (factor_y) (0) (0) # detect scale transformation. Pattern: (factor_x) (0) (0) (factor_y) (0) (0)
self.scale_re = re.compile(r'^q? (-?\d+\.?\d*) 0\.?0* 0\.?0* (-?\d+\.?\d*) 0\.?0* 0\.?0*\s+cm$') # self.scale_re = re.compile(r'^q? (-?\d+\.?\d*) 0\.?0* 0\.?0* (-?\d+\.?\d*) 0\.?0* 0\.?0*\s+cm$')
# detect combined transformation. Should always be the last # detect combined transformation. Should always be the last
self.combined_transform_re = re.compile(r'^q?\s*(-?\d+\.?\d*) (-?\d+\.?\d*) (-?\d+\.?\d*) (-?\d+\.?\d*) ' self.combined_transform_re = re.compile(r'^(q)?\s*(-?\d+\.?\d*) (-?\d+\.?\d*) (-?\d+\.?\d*) (-?\d+\.?\d*) '
r'(-?\d+\.?\d*) (-?\d+\.?\d*)\s+cm$') r'(-?\d+\.?\d*) (-?\d+\.?\d*)\s+cm$')
# detect clipping path # detect clipping path
self.clip_path_re = re.compile(r'^W[*]? n?$') self.clip_path_re = re.compile(r'^W[*]? n?$')
# detect save graphic state in graphic stack
self.save_gs_re = re.compile(r'^q.*?$')
# detect restore graphic state from graphic stack
self.restore_gs_re = re.compile(r'^Q.*$')
# graphic stack where we save parameters like transformation, line_width
self.gs = dict()
# each element is a list composed of sublist elements
# (each sublist has 2 lists each having 2 elements: first is offset like:
# offset_geo = [off_x, off_y], second element is scale list with 2 elements, like: scale_geo = [sc_x, sc_yy])
self.gs['transform'] = []
self.gs['line_width'] = [] # each element is a float
self.geo_buffer = [] self.geo_buffer = []
self.pdf_parsed = '' self.pdf_parsed = ''
@ -201,8 +215,8 @@ class ToolPDF(FlatCAMTool):
# store the start point (when 'm' command is encountered) # store the start point (when 'm' command is encountered)
current_subpath = None current_subpath = None
# set True when 'h' command is encountered (close path) # set True when 'h' command is encountered (close subpath)
close_path = False close_subpath = False
start_point = None start_point = None
current_point = None current_point = None
@ -212,80 +226,94 @@ class ToolPDF(FlatCAMTool):
offset_geo = [0, 0] offset_geo = [0, 0]
scale_geo = [1, 1] scale_geo = [1, 1]
c_offset_f= [0, 0]
c_scale_f = [1, 1]
# initial aperture # initial aperture
aperture = 10 aperture = 10
# store the apertures here # store the apertures here
apertures_dict = {} apertures_dict = {}
# it seems that first transform apply to the whole PDF; signal here if it's first
first_transform = True
line_nr = 0 line_nr = 0
lines = pdf_content.splitlines() lines = pdf_content.splitlines()
for pline in lines: for pline in lines:
line_nr += 1 line_nr += 1
log.debug("line %d: %s" % (line_nr, pline)) # log.debug("line %d: %s" % (line_nr, pline))
# TRANSFORMATIONS DETECTION # # TRANSFORMATIONS DETECTION #
# # Detect Scale transform # Detect combined transformation.
# match = self.scale_re.search(pline)
# if match:
# log.debug(
# "ToolPDF.parse_pdf() --> SCALE transformation found on line: %s --> %s" % (line_nr, pline))
# if first_transform:
# first_transform = False
# c_scale_f = [float(match.group(1)), float(match.group(2))]
# else:
# scale_geo = [float(match.group(1)), float(match.group(2))]
# continue
# # Detect Offset transform
# match = self.offset_re.search(pline)
# if match:
# log.debug(
# "ToolPDF.parse_pdf() --> OFFSET transformation found on line: %s --> %s" % (line_nr, pline))
# offset_geo = [float(match.group(1)), float(match.group(2))]
# continue
# Detect combined transformation. Must be always the last from transformations to be checked.
match = self.combined_transform_re.search(pline) match = self.combined_transform_re.search(pline)
if match: if match:
# detect save graphic stack event
# sometimes they combine save_to_graphics_stack with the transformation on the same line
if match.group(1) == 'q':
log.debug(
"ToolPDF.parse_pdf() --> Save to GS found on line: %s --> offset=[%f, %f] ||| scale=[%f, %f]" %
(line_nr, offset_geo[0], offset_geo[1], scale_geo[0], scale_geo[1]))
self.gs['transform'].append(deepcopy([offset_geo, scale_geo]))
self.gs['line_width'].append(deepcopy(size))
# transformation = TRANSLATION (OFFSET) # transformation = TRANSLATION (OFFSET)
if (float(match.group(2)) == 0 and float(match.group(3)) == 0) and \ if (float(match.group(3)) == 0 and float(match.group(4)) == 0) and \
(float(match.group(5)) != 0 or float(match.group(6)) != 0): (float(match.group(6)) != 0 or float(match.group(7)) != 0):
log.debug( log.debug(
"ToolPDF.parse_pdf() --> OFFSET transformation found on line: %s --> %s" % (line_nr, pline)) "ToolPDF.parse_pdf() --> OFFSET transformation found on line: %s --> %s" % (line_nr, pline))
if first_transform:
c_offset_f = [float(match.group(5)), float(match.group(6))] offset_geo[0] += float(match.group(6))
else: offset_geo[1] += float(match.group(7))
offset_geo = [float(match.group(5)), float(match.group(6))] # log.debug("Offset= [%f, %f]" % (offset_geo[0], offset_geo[1]))
# transformation = SCALING # transformation = SCALING
if float(match.group(1)) != 1 and float(match.group(4)) != 1: if float(match.group(2)) != 1 and float(match.group(5)) != 1:
log.debug( log.debug(
"ToolPDF.parse_pdf() --> SCALE transformation found on line: %s --> %s" % (line_nr, pline)) "ToolPDF.parse_pdf() --> SCALE transformation found on line: %s --> %s" % (line_nr, pline))
if first_transform:
c_scale_f = [float(match.group(1)), float(match.group(4))]
else:
scale_geo = [float(match.group(1)), float(match.group(4))]
if first_transform: scale_geo[0] *= float(match.group(2))
first_transform = False scale_geo[1] *= float(match.group(5))
# log.debug("Scale= [%f, %f]" % (scale_geo[0], scale_geo[1]))
continue continue
# detect save graphic stack event
match = self.save_gs_re.search(pline)
if match:
log.debug(
"ToolPDF.parse_pdf() --> Save to GS found on line: %s --> offset=[%f, %f] ||| scale=[%f, %f]" %
(line_nr, offset_geo[0], offset_geo[1], scale_geo[0], scale_geo[1]))
self.gs['transform'].append(deepcopy([offset_geo, scale_geo]))
self.gs['line_width'].append(deepcopy(size))
# detect restore from graphic stack event
match = self.restore_gs_re.search(pline)
if match:
log.debug(
"ToolPDF.parse_pdf() --> Restore from GS found on line: %s --> %s" % (line_nr, pline))
try:
restored_transform = self.gs['transform'].pop(-1)
offset_geo = restored_transform[0]
scale_geo = restored_transform[1]
except IndexError:
# nothing to remove
log.debug("ToolPDF.parse_pdf() --> Nothing to restore")
pass
try:
size = self.gs['line_width'].pop(-1)
except IndexError:
log.debug("ToolPDF.parse_pdf() --> Nothing to restore")
# nothing to remove
pass
# log.debug("Restored Offset= [%f, %f]" % (offset_geo[0], offset_geo[1]))
# log.debug("Restored Scale= [%f, %f]" % (scale_geo[0], scale_geo[1]))
# PATH CONSTRUCTION # # PATH CONSTRUCTION #
# Start SUBPATH # Start SUBPATH
match = self.start_subpath_re.search(pline) match = self.start_subpath_re.search(pline)
if match: if match:
# we just started a subpath so we mark it as not closed yet # we just started a subpath so we mark it as not closed yet
close_path = False close_subpath = False
# init subpaths # init subpaths
subpath['lines'] = [] subpath['lines'] = []
@ -295,8 +323,8 @@ class ToolPDF(FlatCAMTool):
# detect start point to move to # detect start point to move to
x = float(match.group(1)) + offset_geo[0] x = float(match.group(1)) + offset_geo[0]
y = float(match.group(2)) + offset_geo[1] y = float(match.group(2)) + offset_geo[1]
pt = (x * self.point_to_unit_factor * scale_geo[0] * c_scale_f[0], pt = (x * self.point_to_unit_factor * scale_geo[0],
y * self.point_to_unit_factor * scale_geo[1] * c_scale_f[1]) y * self.point_to_unit_factor * scale_geo[1])
start_point = pt start_point = pt
# add the start point to subpaths # add the start point to subpaths
@ -312,8 +340,8 @@ class ToolPDF(FlatCAMTool):
current_subpath = 'lines' current_subpath = 'lines'
x = float(match.group(1)) + offset_geo[0] x = float(match.group(1)) + offset_geo[0]
y = float(match.group(2)) + offset_geo[1] y = float(match.group(2)) + offset_geo[1]
pt = (x * self.point_to_unit_factor * scale_geo[0] * c_scale_f[0], pt = (x * self.point_to_unit_factor * scale_geo[0],
y * self.point_to_unit_factor * scale_geo[1] * c_scale_f[1]) y * self.point_to_unit_factor * scale_geo[1])
subpath['lines'].append(pt) subpath['lines'].append(pt)
current_point = pt current_point = pt
continue continue
@ -325,16 +353,16 @@ class ToolPDF(FlatCAMTool):
start = current_point start = current_point
x = float(match.group(1)) + offset_geo[0] x = float(match.group(1)) + offset_geo[0]
y = float(match.group(2)) + offset_geo[1] y = float(match.group(2)) + offset_geo[1]
c1 = (x * self.point_to_unit_factor * scale_geo[0] * c_scale_f[0], c1 = (x * self.point_to_unit_factor * scale_geo[0],
y * self.point_to_unit_factor * scale_geo[1] * c_scale_f[1]) y * self.point_to_unit_factor * scale_geo[1])
x = float(match.group(3)) + offset_geo[0] x = float(match.group(3)) + offset_geo[0]
y = float(match.group(4)) + offset_geo[1] y = float(match.group(4)) + offset_geo[1]
c2 = (x * self.point_to_unit_factor * scale_geo[0] * c_scale_f[0], c2 = (x * self.point_to_unit_factor * scale_geo[0],
y * self.point_to_unit_factor * scale_geo[1] * c_scale_f[1]) y * self.point_to_unit_factor * scale_geo[1])
x = float(match.group(5)) + offset_geo[0] x = float(match.group(5)) + offset_geo[0]
y = float(match.group(6)) + offset_geo[1] y = float(match.group(6)) + offset_geo[1]
stop = (x * self.point_to_unit_factor * scale_geo[0] * c_scale_f[0], stop = (x * self.point_to_unit_factor * scale_geo[0],
y * self.point_to_unit_factor * scale_geo[1] * c_scale_f[1]) y * self.point_to_unit_factor * scale_geo[1])
subpath['bezier'].append([start, c1, c2, stop]) subpath['bezier'].append([start, c1, c2, stop])
current_point = stop current_point = stop
@ -347,12 +375,12 @@ class ToolPDF(FlatCAMTool):
start = current_point start = current_point
x = float(match.group(1)) + offset_geo[0] x = float(match.group(1)) + offset_geo[0]
y = float(match.group(2)) + offset_geo[1] y = float(match.group(2)) + offset_geo[1]
c2 = (x * self.point_to_unit_factor * scale_geo[0] * c_scale_f[0], c2 = (x * self.point_to_unit_factor * scale_geo[0],
y * self.point_to_unit_factor * scale_geo[1] * c_scale_f[1]) y * self.point_to_unit_factor * scale_geo[1])
x = float(match.group(3)) + offset_geo[0] x = float(match.group(3)) + offset_geo[0]
y = float(match.group(4)) + offset_geo[1] y = float(match.group(4)) + offset_geo[1]
stop = (x * self.point_to_unit_factor * scale_geo[0] * c_scale_f[0], stop = (x * self.point_to_unit_factor * scale_geo[0],
y * self.point_to_unit_factor * scale_geo[1] * c_scale_f[1]) y * self.point_to_unit_factor * scale_geo[1])
subpath['bezier'].append([start, start, c2, stop]) subpath['bezier'].append([start, start, c2, stop])
current_point = stop current_point = stop
@ -364,33 +392,33 @@ class ToolPDF(FlatCAMTool):
start = current_point start = current_point
x = float(match.group(1)) + offset_geo[0] x = float(match.group(1)) + offset_geo[0]
y = float(match.group(2)) + offset_geo[1] y = float(match.group(2)) + offset_geo[1]
c1 = (x * self.point_to_unit_factor * scale_geo[0] * c_scale_f[0], c1 = (x * self.point_to_unit_factor * scale_geo[0],
y * self.point_to_unit_factor * scale_geo[1] * c_scale_f[1]) y * self.point_to_unit_factor * scale_geo[1])
x = float(match.group(3)) + offset_geo[0] x = float(match.group(3)) + offset_geo[0]
y = float(match.group(4)) + offset_geo[1] y = float(match.group(4)) + offset_geo[1]
stop = (x * self.point_to_unit_factor * scale_geo[0] * c_scale_f[0], stop = (x * self.point_to_unit_factor * scale_geo[0],
y * self.point_to_unit_factor * scale_geo[1] * c_scale_f[1]) y * self.point_to_unit_factor * scale_geo[1])
subpath['bezier'].append([start, c1, stop, stop]) subpath['bezier'].append([start, c1, stop, stop])
print(subpath['bezier']) print(subpath['bezier'])
current_point = stop current_point = stop
continue continue
# Draw RECTANGLE # Draw Rectangle 're
match = self.rect_re.search(pline) match = self.rect_re.search(pline)
if match: if match:
current_subpath = 'rectangle' current_subpath = 'rectangle'
x = (float(match.group(1)) + offset_geo[0]) * self.point_to_unit_factor * scale_geo[0] * c_scale_f[0] x = (float(match.group(1)) + offset_geo[0]) * self.point_to_unit_factor * scale_geo[0]
y = (float(match.group(2)) + offset_geo[1]) * self.point_to_unit_factor * scale_geo[1] * c_scale_f[1] y = (float(match.group(2)) + offset_geo[1]) * self.point_to_unit_factor * scale_geo[1]
width = (float(match.group(3)) + offset_geo[0]) * \ width = (float(match.group(3)) + offset_geo[0]) * \
self.point_to_unit_factor * scale_geo[0] * c_scale_f[0] self.point_to_unit_factor * scale_geo[0]
height = (float(match.group(4)) + offset_geo[1]) * \ height = (float(match.group(4)) + offset_geo[1]) * \
self.point_to_unit_factor * scale_geo[1] * c_scale_f[1] self.point_to_unit_factor * scale_geo[1]
pt1 = (x, y) pt1 = (x, y)
pt2 = (x+width, y) pt2 = (x+width, y)
pt3 = (x+width, y+height) pt3 = (x+width, y+height)
pt4 = (x, y+height) pt4 = (x, y+height)
# TODO: I'm not sure if rectangles are a subpath in themselves that autoclose # TODO: I'm not sure if rectangles are a type of subpath that close by itself
subpath['rectangle'] += [pt1, pt2, pt3, pt4, pt1] subpath['rectangle'] += [pt1, pt2, pt3, pt4, pt1]
current_point = pt1 current_point = pt1
continue continue
@ -404,8 +432,8 @@ class ToolPDF(FlatCAMTool):
subpath['rectangle'] = [] subpath['rectangle'] = []
# it measns that we've already added the subpath to path and we need to delete it # it measns that we've already added the subpath to path and we need to delete it
# clipping path is usually either rectangle or lines # clipping path is usually either rectangle or lines
if close_path is True: if close_subpath is True:
close_path = False close_subpath = False
if current_subpath == 'lines': if current_subpath == 'lines':
path['lines'].pop(-1) path['lines'].pop(-1)
if current_subpath == 'rectangle': if current_subpath == 'rectangle':
@ -415,7 +443,7 @@ class ToolPDF(FlatCAMTool):
# Close SUBPATH # Close SUBPATH
match = self.end_subpath_re.search(pline) match = self.end_subpath_re.search(pline)
if match: if match:
close_path = True close_subpath = True
if current_subpath == 'lines': if current_subpath == 'lines':
subpath['lines'].append(start_point) subpath['lines'].append(start_point)
# since we are closing the subpath add it to the path, a path may have chained subpaths # since we are closing the subpath add it to the path, a path may have chained subpaths
@ -439,24 +467,6 @@ class ToolPDF(FlatCAMTool):
match = self.strokewidth_re.search(pline) match = self.strokewidth_re.search(pline)
if match: if match:
size = float(match.group(1)) size = float(match.group(1))
# flag = 0
#
# if not apertures_dict:
# apertures_dict[str(aperture)] = dict()
# apertures_dict[str(aperture)]['size'] = size
# apertures_dict[str(aperture)]['type'] = 'C'
# apertures_dict[str(aperture)]['solid_geometry'] = []
# else:
# for k in apertures_dict:
# if size == apertures_dict[k]['size']:
# flag = 1
# break
# if flag == 0:
# aperture += 1
# apertures_dict[str(aperture)] = dict()
# apertures_dict[str(aperture)]['size'] = size
# apertures_dict[str(aperture)]['type'] = 'C'
# apertures_dict[str(aperture)]['solid_geometry'] = []
continue continue
# Detect No_Op command, ignore the current subpath # Detect No_Op command, ignore the current subpath
@ -471,7 +481,7 @@ class ToolPDF(FlatCAMTool):
match = self.stroke_path__re.search(pline) match = self.stroke_path__re.search(pline)
if match: if match:
# scale the size here; some PDF printers apply transformation after the size is declared # scale the size here; some PDF printers apply transformation after the size is declared
applied_size = size * scale_geo[0] * c_scale_f[0] * self.point_to_unit_factor applied_size = size * scale_geo[0] * self.point_to_unit_factor
path_geo = list() path_geo = list()
if current_subpath == 'lines': if current_subpath == 'lines':
@ -536,7 +546,7 @@ class ToolPDF(FlatCAMTool):
match = self.fill_path_re.search(pline) match = self.fill_path_re.search(pline)
if match: if match:
# scale the size here; some PDF printers apply transformation after the size is declared # scale the size here; some PDF printers apply transformation after the size is declared
applied_size = size * scale_geo[0] * c_scale_f[0] * self.point_to_unit_factor applied_size = size * scale_geo[0] * self.point_to_unit_factor
path_geo = list() path_geo = list()
if current_subpath == 'lines': if current_subpath == 'lines':
@ -544,7 +554,7 @@ class ToolPDF(FlatCAMTool):
for subp in path['lines']: for subp in path['lines']:
geo = copy(subp) geo = copy(subp)
# close the subpath if it was not closed already # close the subpath if it was not closed already
if close_path is False: if close_subpath is False:
geo.append(geo[0]) geo.append(geo[0])
geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles) geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles)
path_geo.append(geo_el) path_geo.append(geo_el)
@ -553,7 +563,7 @@ class ToolPDF(FlatCAMTool):
else: else:
geo = copy(subpath['lines']) geo = copy(subpath['lines'])
# close the subpath if it was not closed already # close the subpath if it was not closed already
if close_path is False: if close_subpath is False:
geo.append(start_point) geo.append(start_point)
geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles) geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles)
path_geo.append(geo_el) path_geo.append(geo_el)
@ -566,7 +576,7 @@ class ToolPDF(FlatCAMTool):
for b in subp: for b in subp:
geo += self.bezier_to_points(start=b[0], c1=b[1], c2=b[2], stop=b[3]) geo += self.bezier_to_points(start=b[0], c1=b[1], c2=b[2], stop=b[3])
# close the subpath if it was not closed already # close the subpath if it was not closed already
if close_path is False: if close_subpath is False:
geo.append(geo[0]) geo.append(geo[0])
geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles) geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles)
path_geo.append(geo_el) path_geo.append(geo_el)
@ -575,7 +585,7 @@ class ToolPDF(FlatCAMTool):
else: else:
for b in subpath['bezier']: for b in subpath['bezier']:
geo += self.bezier_to_points(start=b[0], c1=b[1], c2=b[2], stop=b[3]) geo += self.bezier_to_points(start=b[0], c1=b[1], c2=b[2], stop=b[3])
if close_path is False: if close_subpath is False:
geo.append(start_point) geo.append(start_point)
geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles) geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles)
path_geo.append(geo_el) path_geo.append(geo_el)
@ -586,7 +596,7 @@ class ToolPDF(FlatCAMTool):
for subp in path['rectangle']: for subp in path['rectangle']:
geo = copy(subp) geo = copy(subp)
# close the subpath if it was not closed already # close the subpath if it was not closed already
if close_path is False: if close_subpath is False:
geo.append(geo[0]) geo.append(geo[0])
geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles) geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles)
path_geo.append(geo_el) path_geo.append(geo_el)
@ -595,14 +605,14 @@ class ToolPDF(FlatCAMTool):
else: else:
geo = copy(subpath['rectangle']) geo = copy(subpath['rectangle'])
# close the subpath if it was not closed already # close the subpath if it was not closed already
if close_path is False: if close_subpath is False:
geo.append(start_point) geo.append(start_point)
geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles) geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles)
path_geo.append(geo_el) path_geo.append(geo_el)
subpath['rectangle'] = [] subpath['rectangle'] = []
# we finished painting and also closed the path if it was the case # we finished painting and also closed the path if it was the case
close_path = True close_subpath = True
try: try:
apertures_dict['0']['solid_geometry'] += path_geo apertures_dict['0']['solid_geometry'] += path_geo
@ -619,7 +629,7 @@ class ToolPDF(FlatCAMTool):
match = self.fill_stroke_path_re.search(pline) match = self.fill_stroke_path_re.search(pline)
if match: if match:
# scale the size here; some PDF printers apply transformation after the size is declared # scale the size here; some PDF printers apply transformation after the size is declared
applied_size = size * scale_geo[0] * c_scale_f[0] * self.point_to_unit_factor applied_size = size * scale_geo[0] * self.point_to_unit_factor
path_geo = list() path_geo = list()
if current_subpath == 'lines': if current_subpath == 'lines':
@ -628,7 +638,7 @@ class ToolPDF(FlatCAMTool):
for subp in path['lines']: for subp in path['lines']:
geo = copy(subp) geo = copy(subp)
# close the subpath if it was not closed already # close the subpath if it was not closed already
if close_path is False: if close_subpath is False:
geo.append(geo[0]) geo.append(geo[0])
geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles) geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles)
path_geo.append(geo_el) path_geo.append(geo_el)
@ -643,7 +653,7 @@ class ToolPDF(FlatCAMTool):
# fill # fill
geo = copy(subpath['lines']) geo = copy(subpath['lines'])
# close the subpath if it was not closed already # close the subpath if it was not closed already
if close_path is False: if close_subpath is False:
geo.append(start_point) geo.append(start_point)
geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles) geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles)
path_geo.append(geo_el) path_geo.append(geo_el)
@ -662,7 +672,7 @@ class ToolPDF(FlatCAMTool):
for b in subp: for b in subp:
geo += self.bezier_to_points(start=b[0], c1=b[1], c2=b[2], stop=b[3]) geo += self.bezier_to_points(start=b[0], c1=b[1], c2=b[2], stop=b[3])
# close the subpath if it was not closed already # close the subpath if it was not closed already
if close_path is False: if close_subpath is False:
geo.append(geo[0]) geo.append(geo[0])
geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles) geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles)
path_geo.append(geo_el) path_geo.append(geo_el)
@ -679,7 +689,7 @@ class ToolPDF(FlatCAMTool):
# fill # fill
for b in subpath['bezier']: for b in subpath['bezier']:
geo += self.bezier_to_points(start=b[0], c1=b[1], c2=b[2], stop=b[3]) geo += self.bezier_to_points(start=b[0], c1=b[1], c2=b[2], stop=b[3])
if close_path is False: if close_subpath is False:
geo.append(start_point) geo.append(start_point)
geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles) geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles)
path_geo.append(geo_el) path_geo.append(geo_el)
@ -697,7 +707,7 @@ class ToolPDF(FlatCAMTool):
for subp in path['rectangle']: for subp in path['rectangle']:
geo = copy(subp) geo = copy(subp)
# close the subpath if it was not closed already # close the subpath if it was not closed already
if close_path is False: if close_subpath is False:
geo.append(geo[0]) geo.append(geo[0])
geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles) geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles)
path_geo.append(geo_el) path_geo.append(geo_el)
@ -712,7 +722,7 @@ class ToolPDF(FlatCAMTool):
# fill # fill
geo = copy(subpath['rectangle']) geo = copy(subpath['rectangle'])
# close the subpath if it was not closed already # close the subpath if it was not closed already
if close_path is False: if close_subpath is False:
geo.append(start_point) geo.append(start_point)
geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles) geo_el = Polygon(geo).buffer(0.0000001, resolution=self.step_per_circles)
path_geo.append(geo_el) path_geo.append(geo_el)
@ -723,7 +733,7 @@ class ToolPDF(FlatCAMTool):
subpath['rectangle'] = [] subpath['rectangle'] = []
# we finished painting and also closed the path if it was the case # we finished painting and also closed the path if it was the case
close_path = True close_subpath = True
try: try:
apertures_dict['0']['solid_geometry'] += path_geo apertures_dict['0']['solid_geometry'] += path_geo