コード例 #1
0
    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)

        blade_path.cubicTo(*params)
コード例 #2
0
ファイル: models.py プロジェクト: yangbiaocn/inkcut
    def _create_copy(self):
        """ Creates a copy of the original graphic applying the given
        transforms

        """
        optimized_path = self.optimized_path
        bbox = optimized_path.boundingRect()

        # Create the base copy
        t = QTransform()

        t.scale(
            self.scale[0] * (self.mirror[0] and -1 or 1),
            self.scale[1] * (self.mirror[1] and -1 or 1),
        )

        # Rotate about center
        if self.rotation != 0:
            c = bbox.center()
            t.translate(-c.x(), -c.y())
            t.rotate(self.rotation)
            t.translate(c.x(), c.y())

        # Apply transform
        path = optimized_path * t

        # Add weedline to copy
        if self.copy_weedline:
            self._add_weedline(path, self.copy_weedline_padding)

        # If it's too big we have to scale it
        w, h = path.boundingRect().width(), path.boundingRect().height()
        available_area = self.material.available_area

        #: This screws stuff up!
        if w > available_area.width() or h > available_area.height():

            # If it's too big an auto scale is enabled, resize it to fit
            if self.auto_scale:
                sx, sy = 1, 1
                if w > available_area.width():
                    sx = available_area.width() / w
                if h > available_area.height():
                    sy = available_area.height() / h
                s = min(sx, sy)  # Fit to the smaller of the two
                path = optimized_path * QTransform.fromScale(s, s)

        # Move to bottom left
        p = path.boundingRect().bottomRight()

        path = path * QTransform.fromTranslate(-p.x(), -p.y())

        return path
コード例 #3
0
ファイル: models.py プロジェクト: yangbiaocn/inkcut
    def create(self, swap_xy=False, scale=None):
        """ Create a path model that is rotated and scaled

        """
        model = QPainterPath()

        if not self.path:
            return

        path = self._create_copy()

        # Update size
        bbox = path.boundingRect()
        self.size = [bbox.width(), bbox.height()]

        # Create copies
        c = 0
        points = self._copy_positions_iter(path)

        if self.auto_copies:
            self.stack_size = self._compute_stack_sizes(path)
            if self.stack_size[0]:
                copies_left = self.copies % self.stack_size[0]
                if copies_left:  # not a full stack
                    with self.events_suppressed():
                        self.copies = self._desired_copies
                        self.add_stack()

        while c < self.copies:
            x, y = next(points)
            model.addPath(path * QTransform.fromTranslate(x, -y))
            c += 1

        # Create weedline
        if self.plot_weedline:
            self._add_weedline(model, self.plot_weedline_padding)

        # Determine padding
        bbox = model.boundingRect()
        if self.align_center[0]:
            px = (self.material.width() - bbox.width()) / 2.0
        else:
            px = self.material.padding_left

        if self.align_center[1]:
            py = -(self.material.height() - bbox.height()) / 2.0
        else:
            py = -self.material.padding_bottom

        # Scale and rotate
        if scale:
            model *= QTransform.fromScale(*scale)
            px, py = px * abs(scale[0]), py * abs(scale[1])

        if swap_xy:
            t = QTransform()
            t.rotate(90)
            model *= t

        # Move to 0,0
        bbox = model.boundingRect()
        p = bbox.bottomLeft()
        tx, ty = -p.x(), -p.y()

        # If swapped, make sure padding is still correct
        if swap_xy:
            px, py = -py, -px
        tx += px
        ty += py

        model = model * QTransform.fromTranslate(tx, ty)

        end_point = (QPointF(0, -self.feed_after + model.boundingRect().top())
                     if self.feed_to_end else QPointF(0, 0))
        model.moveTo(end_point)

        return model
コード例 #4
0
from atom.api import Float, Enum, Instance
from enaml.qt.QtCore import QPointF
from enaml.qt.QtGui import QPainterPath, QTransform, QVector2D

from inkcut.device.plugin import DeviceFilter, Model
from inkcut.core.utils import unit_conversions, log


# Element types
MoveToElement = QPainterPath.MoveToElement
LineToElement = QPainterPath.LineToElement
CurveToElement = QPainterPath.CurveToElement
CurveToDataElement = QPainterPath.CurveToDataElement


IDENITY_MATRIX = QTransform.fromScale(1, 1)


def fp(point):
    return "({}, {})".format(round(point.x(), 3), round(point.y(), 3))


class BladeOffsetConfig(Model):
    #: BladeOffset in user units
    offset = Float(strict=False).tag(config=True)

    #: Units for display
    offset_units = Enum(*unit_conversions.keys()).tag(config=True)

    #: If the angle is less than this, consider it continuous
    cutoff = Float(5.0, strict=False).tag(config=True)
コード例 #5
0
ファイル: blade_offset.py プロジェクト: frmdstryr/Inkcut
Distributed under the terms of the GPL v3 License.

The full license is in the file LICENSE, distributed with this software.

Created on Dec 14, 2018

@author: jrm
"""
from math import sqrt, cos, radians, isinf
from atom.api import Float, Enum, Instance
from inkcut.device.plugin import DeviceFilter, Model
from inkcut.core.utils import unit_conversions
from enaml.qt.QtGui import QPainterPath, QTransform, QVector2D


IDENITY_MATRIX = QTransform.fromScale(1, 1)


class BladeOffsetConfig(Model):
    #: BladeOffset in user units
    offset = Float(strict=False).tag(config=True)
    
    #: Units for display 
    offset_units = Enum(*unit_conversions.keys()).tag(config=True)
    
    #: Cutoff angle
    cutoff = Float(20.0, strict=False).tag(config=True)
    
    def _default_offset_units(self):
        return 'mm'