Example #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)
Example #2
0
 def apply_blade_offset(self, poly, offset):
     """ Apply blade offset to the given polygon by appending a quadratic
     bezier to each point .
     
     """
     # Use a QPainterPath to track the distance in c++
     path = QPainterPath()
     cutoff = cos(radians(self.config.cutoff)) # Forget 
     last = None
     n = len(poly)
     for i, p in enumerate(poly):
         if i == 0:
             path.moveTo(p)
             last_path = QPainterPath()
             last_path.moveTo(p)
             last = p
             continue
         
         # Move to the point
         path.lineTo(p)
         
         if i+1 == n:
             # Done
             break
         
         # Get next point
         next = poly.at(i+1)
         
         # Make our paths
         last_path.lineTo(p)
         next_path = QPainterPath()
         next_path.moveTo(p)
         next_path.lineTo(next)
         
         # Get angle between the two components
         u, v = QVector2D(last-p), QVector2D(next-p)
         cos_theta = QVector2D.dotProduct(u.normalized(), v.normalized())
         
         # If the angle is large enough to need compensation
         if (cos_theta < cutoff and
                 last_path.length() > offset and
                 next_path.length() > offset):
             # Calculate the extended point
             t = last_path.percentAtLength(offset)
             c1 = p+(last_path.pointAtPercent(t)-last)
             c2 = p
             t = next_path.percentAtLength(offset)
             ep = next_path.pointAtPercent(t)
             if offset > 2:
                 # Can smooth it for larger offsets
                 path.cubicTo(c1, c2, ep)
             else:
                 # This works for small offsets < 0.5 mm 
                 path.lineTo(c1)
                 path.lineTo(ep)
         
         # Update last
         last_path = next_path
         last = p
     return path.toSubpathPolygons(IDENITY_MATRIX)
Example #3
0
 def splitAtPercent(self, t):
     paths = []
     path = QPainterPath()
     i = 0
     while i < self.elementCount():
         e = self.elementAt(i)
         if e.type == ElementType.MoveToElement:
             if not path.isEmpty():
                 paths.append(path)
             path = QPainterPath(QPointF(e.x, e.y))
         elif e.type == ElementType.LineToElement:
             path.lineTo(QPointF(e.x, e.y))
         elif e.type == ElementType.CurveToElement:
             e1, e2 = self.elementAt(i + 1), self.elementAt(i + 2)
             path.cubicTo(QPointF(e.x, e.y), QPointF(e1.x, e1.y),
                          QPointF(e2.x, e2.y))
             i += 2
         else:
             raise ValueError("Invalid element type %s" % (e.type, ))
         i += 1
     if not path.isEmpty():
         paths.append(path)
     return paths
Example #4
0
    def request_relayout(self):
        # y = 0.0

        # for child in self.children():
        #     if not isinstance(child, QtContainer):
        #         continue
        #     scene_proxy = self._proxies[child]
        #     width, height = child._layout_manager.best_size()
        #     scene_proxy.setPos(0.0, y)
        #     y += height + 25.0

        for p in self._edge_paths:
            self.scene.removeItem(p)
        self._edge_paths = []

        g = pygraphviz.AGraph(directed=True)
        g.graph_attr['nodesep'] = 100
        g.graph_attr['ranksep'] = 50
        g.node_attr['shape'] = 'rect'

        children_names = {child.declaration.name for child in self.children() if isinstance(child, QtContainer)}

        if any(from_ not in children_names or to not in children_names for (from_, to) in self.declaration.edges):
            # hasn't finished being set up yet
            return

        for child in self.children():
            if not isinstance(child, QtContainer):
                continue
            scene_proxy = self._proxy(child)
            width, height = child._layout_manager.best_size()
            scene_proxy.setGeometry(QRectF(0.0, 0.0, width, height))
            g.add_node(child.declaration.name, width=width, height=height)

        for from_, to in self.declaration.edges:
            g.add_edge(from_, to)

        g.layout(prog='dot')

        for child in self.children():
            if not isinstance(child, QtContainer):
                continue
            scene_proxy = self._proxies[child]
            node = g.get_node(child.declaration.name)
            center_x, center_y = (-float(v)/72.0 for v in node.attr['pos'].split(','))
            width, height = child._layout_manager.best_size()
            x = center_x - (width / 2.0)
            y = center_y - (height / 2.0)
            scene_proxy.setPos(x, y)

        for from_, to in self.declaration.edges:
            if from_ not in children_names or to not in children_names:
                continue
            edge = g.get_edge(from_, to)
            # TODO: look at below code
            all_points = [tuple(-float(v)/72.0 for v in t.strip('e,').split(',')) for t in edge.attr['pos'].split(' ')]
            arrow = all_points[0]
            start_point = all_points[1]

            painter = QPainterPath(QPointF(*start_point))
            for c1, c2, end in grouper(all_points[2:], 3):
                painter.cubicTo(QPointF(*c1), QPointF(*c2), QPointF(*end))

            self._edge_paths.append(self.scene.addPath(painter))

        rect = self.scene.itemsBoundingRect()
        # Enlarge the rect so there is enough room at right and bottom
        rect.setX(rect.x() - self.LEFT_PADDING)
        rect.setY(rect.y() - self.TOP_PADDING)
        rect.setWidth(rect.width() + 2 * self.LEFT_PADDING)
        rect.setHeight(rect.height() + 2 * self.TOP_PADDING)

        self.scene.setSceneRect(rect)
        self.widget.viewport().update()

        self.show_selected()
Example #5
0
    def request_relayout(self):
        # y = 0.0

        # for child in self.children():
        #     if not isinstance(child, QtContainer):
        #         continue
        #     scene_proxy = self._proxies[child]
        #     width, height = child._layout_manager.best_size()
        #     scene_proxy.setPos(0.0, y)
        #     y += height + 25.0

        for p in self._edge_paths:
            self.scene.removeItem(p)
        self._edge_paths = []

        g = pygraphviz.AGraph(directed=True)
        g.graph_attr['nodesep'] = 100
        g.graph_attr['ranksep'] = 50
        g.node_attr['shape'] = 'rect'

        children_names = {child.declaration.name for child in self.children() if isinstance(child, QtContainer)}

        if any(from_ not in children_names or to not in children_names for (from_, to) in self.declaration.edges):
            # hasn't finished being set up yet
            return

        for child in self.children():
            if not isinstance(child, QtContainer):
                continue
            scene_proxy = self._proxy(child)
            width, height = child._layout_manager.best_size()
            scene_proxy.setGeometry(QRectF(0.0, 0.0, width, height))
            g.add_node(child.declaration.name, width=width, height=height)

        for from_, to in self.declaration.edges:
            g.add_edge(from_, to)

        before = time.time()
        g.layout(prog='dot')
        after = time.time()

        for child in self.children():
            if not isinstance(child, QtContainer):
                continue
            scene_proxy = self._proxies[child]
            node = g.get_node(child.declaration.name)
            center_x, center_y = (-float(v)/72.0 for v in node.attr['pos'].split(','))
            width, height = child._layout_manager.best_size()
            x = center_x - (width / 2.0)
            y = center_y - (height / 2.0)
            scene_proxy.setPos(x, y)

        for from_, to in self.declaration.edges:
            if from_ not in children_names or to not in children_names:
                continue
            edge = g.get_edge(from_, to)
            # TODO: look at below code
            all_points = [tuple(-float(v)/72.0 for v in t.strip('e,').split(',')) for t in edge.attr['pos'].split(' ')]
            arrow = all_points[0]
            start_point = all_points[1]

            painter = QPainterPath(QPointF(*start_point))
            for c1, c2, end in grouper(all_points[2:], 3):
                painter.cubicTo(QPointF(*c1), QPointF(*c2), QPointF(*end))

            self._edge_paths.append(self.scene.addPath(painter))

        self.show_selected()