flatcam/flatcamTools/ToolPDF.py
2019-04-19 17:12:10 +03:00

179 lines
6.4 KiB
Python

############################################################
# FlatCAM: 2D Post-processing for Manufacturing #
# http://flatcam.org #
# File Author: Marius Adrian Stanciu (c) #
# Date: 3/10/2019 #
# MIT Licence #
############################################################
from FlatCAMTool import FlatCAMTool
from FlatCAMObj import *
import math
import numpy as np
import scipy.interpolate
import zlib
import re
import gettext
import FlatCAMTranslation as fcTranslate
fcTranslate.apply_language('strings')
import builtins
if '_' not in builtins.__dict__:
_ = gettext.gettext
class ToolPDF(FlatCAMTool):
'''
Parse a PDF file.
Reference here: https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/pdf_reference_archives/PDFReference.pdf
Return a list of geometries
'''
toolName = _("PDF Import Tool")
def __init__(self, app):
FlatCAMTool.__init__(self, app)
self.app = app
self.step_per_circles = self.app.defaults["gerber_circle_steps"]
self.stream_re = re.compile(b'.*?FlateDecode.*?stream(.*?)endstream', re.S)
# detect 'w' command
self.strokewidth_re = re.compile(r'^(\d+\.?\d*)\s*w$')
# detect 're' command
self.rect_re = re.compile(r'^(-?\d+\.?\d*)\s(-?\d+\.?\d*)\s(-?\d+\.?\d*)\s(-?\d+\.?\d*)\sre$')
# detect 'm' command
self.start_path_re = re.compile(r'(-?\d+\.?\d*)\s(-?\d+\.?\d*)\sm$')
# detect 'l' command
self.draw_line_re = re.compile(r'(-?\d+\.?\d*)\s(-?\d+\.?\d*)\sl')
# detect 'c' command
self.draw_arc_3pt_re = re.compile(r'(-?\d+\.?\d*)\s(-?\d+\.?\d*)\s(-?\d+\.?\d*)\s(-?\d+\.?\d*)\s(-?\d+\.?\d*)\s(-?\d+\.?\d*)\sc$')
# detect 'v' command
self.draw_arc_2pt_23_re = re.compile(r'(-?\d+\.?\d*)\s(-?\d+\.?\d*)\s(-?\d+\.?\d*)\s(-?\d+\.?\d*)\sv$')
# detect 'y' command
self.draw_arc_2pt_13_re = re.compile(r'(-?\d+\.?\d*)\s(-?\d+\.?\d*)\s(-?\d+\.?\d*)\s(-?\d+\.?\d*)\sy$')
# detect 'h' command
self.end_path_re = re.compile(r'^h$')
self.pdf_parsed = ''
def run(self, toggle=True):
self.app.report_usage("ToolPDF()")
# if toggle:
# # if the splitter is hidden, display it, else hide it but only if the current widget is the same
# if self.app.ui.splitter.sizes()[0] == 0:
# self.app.ui.splitter.setSizes([1, 1])
# else:
# try:
# if self.app.ui.tool_scroll_area.widget().objectName() == self.toolName:
# self.app.ui.splitter.setSizes([0, 1])
# except AttributeError:
# pass
# else:
# if self.app.ui.splitter.sizes()[0] == 0:
# self.app.ui.splitter.setSizes([1, 1])
#
# FlatCAMTool.run(self)
self.set_tool_ui()
self.on_open_pdf_click()
# self.app.ui.notebook.setTabText(2, "PDF Tool")
def install(self, icon=None, separator=None, **kwargs):
FlatCAMTool.install(self, icon, separator, shortcut='ALT+Q', **kwargs)
def set_tool_ui(self):
pass
def on_open_pdf_click(self):
"""
File menu callback for opening an PDF file.
:return: None
"""
self.app.report_usage("ToolPDF.on_open_pdf_click()")
self.app.log.debug("ToolPDF.on_open_pdf_click()")
_filter_ = "Adobe PDF Files (*.pdf);;" \
"All Files (*.*)"
try:
filenames, _f = QtWidgets.QFileDialog.getOpenFileNames(caption=_("Open PDF"),
directory=self.app.get_last_folder(), filter=_filter_)
except TypeError:
filenames, _f = QtWidgets.QFileDialog.getOpenFileNames(caption=_("Open PDF"), filter=_filter_)
filenames = [str(filename) for filename in filenames]
if len(filenames) == 0:
self.app.inform.emit(_("[WARNING_NOTCL] Open PDF cancelled."))
else:
for filename in filenames:
if filename != '':
self.app.worker_task.emit({'fcn': self.open_pdf,
'params': [filename]})
def open_pdf(self, filename):
def obj_init(grb_obj, app_obj):
with open(filename, "rb") as f:
pdf = f.read()
for s in re.findall(self.stream_re, pdf):
s = s.strip(b'\r\n')
try:
self.pdf_parsed += zlib.decompress(s).decode('UTF-8')
except:
pass
grb_obj.solid_geometry = [self.bezier_to_linestring(0, 0, 0, 0)]
with self.app.proc_container.new(_("Opening PDF.")):
# obj_init()
self.parse_pdf()
ret = self.app.new_object("geometry", "bla", obj_init, autoselected=False)
# Register recent file
self.app.file_opened.emit("geometry", "bla")
# # Object name
# name = outname or filename.split('/')[-1].split('\\')[-1]
#
# ret = self.new_object("excellon", name, obj_init, autoselected=False)
# if ret == 'fail':
# self.inform.emit(_('[ERROR_NOTCL] Open Excellon file failed. Probable not an Excellon file.'))
# return
#
# # Register recent file
# self.file_opened.emit("excellon", filename)
#
# # GUI feedback
# self.inform.emit(_("[success] Opened: %s") % filename)
# # self.progress.emit(100)
def parse_pdf(self):
for pline in self.pdf_parsed:
pass
def bezier_to_linestring(self, start, stop, c1, c2):
"""
From here: https://gis.stackexchange.com/questions/106937/python-library-or-algorithm-to-generate-arc-geometry-from-three-coordinate-pairs
:return: LineString geometry
"""
coords = np.array([[0, 0], [25, 10], [33, 39], [53, 53]])
# equation Bezier, page 184 PDF 1.4 reference
# https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/pdf_reference_archives/PDFReference.pdf
# R(t) = P0*(1 - t) ** 3 + P1*3*t*(1 - 5) ** 2 + P2 * 3*(1 - t) * t ** 2 + P3*t ** 3
domain = []
i = 0
while i <=1:
domain.append(i)
for i in domain:
return even_line