Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _view_changed(self,change):
view_items = []
t=QtGui.QTransform.fromScale(1,-1)
self.path = QtGui.QPainterPath()#[#],QtGui.QPainterPath()]
x,y,z = self.device.position
r= max(10,self.device.blade_offset)#,self.device.blade_offset
self.path.addEllipse(QtCore.QPointF(x,-y),r,r)
#view_items.append(PainterPathPlotItem(self.paths[0],pen=self.pen_down))
view_items.append(PainterPathPlotItem(self.path,pen=self.pen_down))
if self.device:
# Also observe any change to job.media and job.device
view_items.append(PainterPathPlotItem(self.device.path*t,pen=self.pen_media,skip_autorange=True))
view_items.append(PainterPathPlotItem(self.device.padding_path*t,pen=self.pen_media_padding,skip_autorange=True))
self.plot = view_items
return view_items
elif len(params) == 3:
p.cubicTo(*params)
else:
raise ValueError("Invalid curve parameters: {}".format(params))
for i in range(path.elementCount()):
e = path.elementAt(i)
# Finish the previous curve (if there was one)
if params and e.type != CurveToDataElement:
finish_curve(p, params)
params = []
# Reconstruct the path
if e.type == MoveToElement:
p = QPainterPath()
p.moveTo(e.x, e.y)
subpaths.append(p)
elif e.type == LineToElement:
p.lineTo(e.x, e.y)
elif e.type == CurveToElement:
params = [QPointF(e.x, e.y)]
elif e.type == CurveToDataElement:
params.append(QPointF(e.x, e.y))
# Finish the previous curve (if there was one)
if params and e and e.type != CurveToDataElement:
finish_curve(p, params)
return subpaths
def _default_path(self):
p = QtGui.QPainterPath()
p.addRect(self.area)
return p
def apply_blade_offset(self, path, job):
""" Apply blade offset to the given path.
"""
params = []
e = None
cmd = None
qf = getattr(job.config, 'quality_factor', 1)
# Holds the blade path
blade_path = QPainterPath()
offset_path = QPainterPath()
for i in range(path.elementCount()):
e = path.elementAt(i)
# Finish the previous curve (if there was one)
if cmd == CurveToElement and e.type != CurveToDataElement:
n = len(params)
if n == 2:
self.process_quad(offset_path, blade_path, params, qf)
elif n == 3:
self.process_cubic(offset_path, blade_path, params, qf)
else:
raise ValueError("Unexpected curve data length %s" % n)
params = []
# Reconstruct the path
def process_cubic(self, offset_path, blade_path, params, quality):
""" Add offset correction to a cubic bezier.
"""
r = self.config.offset
p0 = blade_path.currentPosition()
p1, p2, p3 = params
self.add_continuity_correction(offset_path, blade_path, p1)
curve = QPainterPath()
curve.moveTo(p0)
curve.cubicTo(*params)
p = QPainterPath()
p.moveTo(p0)
if quality == 1:
polygon = curve.toSubpathPolygons(IDENITY_MATRIX)[0]
else:
m = QTransform.fromScale(quality, quality)
m_inv = QTransform.fromScale(1/quality, 1/quality)
polygon = m_inv.map(curve.toSubpathPolygons(m)[0])
for point in polygon:
p.lineTo(point)
t = curve.percentAtLength(p.length())
angle = curve.angleAtPercent(t)
a = radians(angle)
dx, dy = r*cos(a), -r*sin(a)
offset_path.lineTo(point.x()+dx, point.y()+dy)
def add_continuity_correction(self, offset_path, blade_path, point):
""" Adds if the upcoming angle and previous angle are not the same
we need to correct for that difference by "arcing back" about the
current blade point with a radius equal to the offset.
"""
# Current blade position
cur = blade_path.currentPosition()
# Determine direction of next move
sp = QPainterPath()
sp.moveTo(cur)
sp.lineTo(point)
next_angle = sp.angleAtPercent(1)
# Direction of last move
angle = blade_path.angleAtPercent(1)
# If not continuous it needs corrected with an arc
if isnan(angle) or isnan(next_angle):
return
if abs(angle - next_angle) > self.config.cutoff:
r = self.config.offset
a = radians(next_angle)
dx, dy = r*cos(a), -r*sin(a)
po = QPointF(cur.x()+dx, cur.y()+dy)
Parses an SVG document into a QPainterPath. Adapted from inkscape's path
parsers written by Aaron Spike.
Created on Jan 5, 2015
@author: Jairus Martin, frmdstryr@gmail.com
@author: Aaron Spike, aaron@ekips.org
"""
import re
import math
from math import sqrt, tan, atan, atan2, cos, acos, sin, pi
from lxml import etree
from copy import deepcopy
from enaml.qt import QtGui, QtCore
ElementType = QtGui.QPainterPath.ElementType
EtreeElement = etree._Element
class QtSvgItem(QtGui.QPainterPath):
tag = None
_nodes = None
_uuconv = {'in': 90.0, 'pt': 1.25, 'px': 1, 'mm': 3.5433070866,
'cm': 35.433070866, 'm': 3543.3070866,
'km': 3543307.0866, 'pc': 15.0, 'yd': 3240, 'ft': 1080}
def __init__(self, e, nodes=None, **kwargs):
if not isinstance(e, EtreeElement):
raise TypeError("%s only works with etree Elements, "
"given %s" % (self, type(e)))
elif e.tag != self.tag:
raise ValueError("%s only works with %s elements, "
def apply_blade_offset(self, path, job):
""" Apply blade offset to the given path.
"""
params = []
e = None
cmd = None
qf = getattr(job.config, 'quality_factor', 1)
# Holds the blade path
blade_path = QPainterPath()
offset_path = QPainterPath()
for i in range(path.elementCount()):
e = path.elementAt(i)
# Finish the previous curve (if there was one)
if cmd == CurveToElement and e.type != CurveToDataElement:
n = len(params)
if n == 2:
self.process_quad(offset_path, blade_path, params, qf)
elif n == 3:
self.process_cubic(offset_path, blade_path, params, qf)
else:
raise ValueError("Unexpected curve data length %s" % n)
params = []
for f in self.filters:
log.debug(" filter | Running {} on polypath".format(f))
polypath = f.apply_to_polypath(polypath)
for path in polypath:
#: And then each point within the path
#: this is a polygon
for i, p in enumerate(path):
#: Head state
# 0 move, 1 cut
z = 0 if i == 0 else 1
#: Make a subpath
subpath = QtGui.QPainterPath()
subpath.moveTo(_p)
subpath.lineTo(p)
#: Update the last point
_p = p
#: Total length
l = subpath.length()
#: If the device does not support streaming
#: the path interpolation is skipped entirely
if skip_interpolation:
x, y = p.x(), p.y()
yield (l, self.move, ([x, y, z],), {})
continue
'''
Created on Jul 20, 2015
@author: jrm
'''
from atom.api import observe,ContainerList,Float,Instance
from enaml.qt import QtCore,QtGui
from inkcut.workbench.preferences.plugin import Model
class AreaBase(Model):
model = Instance(QtCore.QRectF) # Qt model representing this area
size = ContainerList(Float(),default=[1800,2700]).tag(config=True)
padding = ContainerList(Float(),default=[10,10,10,10]).tag(config=True) # Left, Top, Right, Bottom
area = Instance(QtCore.QRectF)
path = Instance(QtGui.QPainterPath)
padding_path = Instance(QtGui.QPainterPath)
def _default_area(self):
return QtCore.QRectF(0,0,self.size[0],self.size[1])
def _default_path(self):
p = QtGui.QPainterPath()
p.addRect(self.area)
return p
def _default_padding_path(self):
p = QtGui.QPainterPath()
p.addRect(self.available_area)
return p
@observe('size','padding')