| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- ############################################################
- # 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
|