Ejemplo n.º 1
0
 def goal(ts, *xs):
     n3 = len(xs)
     n = n3 // 3
     control_points = np.array(xs).reshape((n, 3))
     curve = SvBezierCurve(control_points)
     pts = curve.evaluate_array(ts)
     return np.ravel(pts)
Ejemplo n.º 2
0
        def process(self):
            if not any(socket.is_linked for socket in self.outputs):
                return

            vertices_s = self.inputs['Vertices'].sv_get()
            degree_s = self.inputs['Degree'].sv_get()

            vertices_s = ensure_nesting_level(vertices_s, 3)
            degree_s = ensure_nesting_level(degree_s, 2)

            curve_out = []
            points_out = []
            for vertices, degree in zip_long_repeat(vertices_s, degree_s):
                if isinstance(degree, (tuple, list)):
                    degree = degree[0]

                n = len(vertices)
                npoints = degree + 1
                vertices = np.array(vertices)

                #xdata = np.linspace(0, 1, num=n)
                xdata = Spline.create_knots(vertices, metric=self.metric)
                ydata = np.ravel(vertices)

                p0 = init_guess(vertices, npoints)
                popt, pcov = curve_fit(goal, xdata, ydata, p0)
                control_points = popt.reshape((npoints, 3))
                curve = SvBezierCurve(control_points)
                curve_out.append(curve)
                points_out.append(control_points.tolist())

            self.outputs['Curve'].sv_set(curve_out)
            self.outputs['ControlPoints'].sv_set(points_out)
Ejemplo n.º 3
0
 def test_third_derivs_equal(self):
     ts = np.linspace(0.0, 1.0, num=10)
     points = cubic_control_points()
     cubic = SvCubicBezierCurve(*points)
     generic = SvBezierCurve(points)
     cubic_points = cubic.third_derivative_array(ts)
     generic_points = generic.third_derivative_array(ts)
     self.assert_numpy_arrays_equal(cubic_points, generic_points, precision=6)
Ejemplo n.º 4
0
 def test_cubic_equals_generic(self):
     ts = np.linspace(0.0, 1.0, num=10)
     points = cubic_control_points()
     cubic = SvCubicBezierCurve(*points)
     generic = SvBezierCurve(points)
     cubic_points = cubic.evaluate_array(ts)
     generic_points = generic.evaluate_array(ts)
     self.assert_numpy_arrays_equal(cubic_points, generic_points, precision=6)
Ejemplo n.º 5
0
    def interpret(self, interpreter, variables):
        vec = lambda v: Vector((v[0], v[1], 0))

        interpreter.assert_not_closed()
        interpreter.start_new_segment()

        v0 = interpreter.position
        if interpreter.has_last_vertex:
            v0_index = interpreter.get_last_vertex()
        else:
            v0_index = interpreter.new_vertex(*v0)

        knot1 = None
        for i, segment in enumerate(self.segments):
            # For first segment, knot1 is initial pen position;
            # for the following, knot1 is knot2 of previous segment.
            if knot1 is None:
                knot1 = interpreter.position
            else:
                knot1 = knot2

            handle = interpreter.calc_vertex(self.is_abs, segment.control[0],
                                             segment.control[1], variables)
            knot2 = interpreter.calc_vertex(self.is_abs, segment.knot2[0],
                                            segment.knot2[1], variables)
            interpreter.position = knot2

            if self.num_segments is not None:
                r = interpreter.eval_(self.num_segments, variables)
            else:
                r = interpreter.dflt_num_verts

            curve = SvBezierCurve([vec(knot1), vec(handle), vec(knot2)])
            interpreter.curves.append(curve)

            points = interpolate_quadratic_bezier(vec(knot1), vec(handle),
                                                  vec(knot2), r)

            interpreter.new_knot("Q#.{}.h".format(i), *handle)
            interpreter.new_knot("Q#.{}.k".format(i), *knot2)

            interpreter.prev_quad_bezier_knot = handle

            for point in points[1:]:
                v1_index = interpreter.new_vertex(point.x, point.y)
                interpreter.new_edge(v0_index, v1_index)
                v0_index = v1_index

        if self.close:
            interpreter.close_segment(v1_index)

        interpreter.has_last_vertex = True
Ejemplo n.º 6
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return
        start_s = self.inputs['Start'].sv_get()
        end_s = self.inputs['End'].sv_get()
        knot1_s = self.inputs[CONTROL1_SOCKET].sv_get()
        knot2_s = self.inputs[CONTROL2_SOCKET].sv_get()
        controls_s = self.inputs['ControlPoints'].sv_get(default=[[[[]]]])

        start_s = ensure_nesting_level(start_s, 3)
        end_s = ensure_nesting_level(end_s, 3)
        knot1_s = ensure_nesting_level(knot1_s, 3)
        knot2_s = ensure_nesting_level(knot2_s, 3)
        controls_s = ensure_nesting_level(controls_s, 4)

        curves_out = []
        controls_out = []
        for starts, ends, knot1s, knot2s, controls_i in zip_long_repeat(
                start_s, end_s, knot1_s, knot2_s, controls_s):
            new_curves = []
            new_controls = []
            for start, end, knot1, knot2, controls in zip_long_repeat(
                    starts, ends, knot1s, knot2s, controls_i):
                start, end = np.array(start), np.array(end)
                knot1, knot2 = np.array(knot1), np.array(knot2)
                if self.mode == CUBIC:
                    curve = SvCubicBezierCurve(start, knot1, knot2, end)
                    curve_controls = [
                        start.tolist(),
                        knot1.tolist(),
                        knot2.tolist(),
                        end.tolist()
                    ]
                elif self.mode == CUBIC_TANGENT:
                    curve = SvBezierCurve.from_points_and_tangents(
                        start, knot1, knot2, end)
                    curve_controls = [
                        curve.p0.tolist(),
                        curve.p1.tolist(),
                        curve.p2.tolist(),
                        curve.p3.tolist()
                    ]
                elif self.mode == CUBIC_4PT:
                    curve = SvCubicBezierCurve.from_four_points(
                        start, knot1, knot2, end)
                    curve_controls = [
                        curve.p0.tolist(),
                        curve.p1.tolist(),
                        curve.p2.tolist(),
                        curve.p3.tolist()
                    ]
                elif self.mode == QUADRATIC:
                    curve = SvBezierCurve([start, knot1, end])
                    curve_controls = [p.tolist() for p in curve.points]
                else:  # GENERIC
                    if not controls:
                        raise SvNoDataError(
                            socket=self.inputs['ControlPoints'], node=self)
                    if len(controls) < 2:
                        raise Exception(
                            "At least two control points are required to build a Bezier spline!"
                        )
                    if self.is_cyclic:
                        controls = controls + [controls[0]]
                    curve = SvBezierCurve(controls)
                    curve_controls = controls
                new_curves.append(curve)
                new_controls.extend(curve_controls)
            curves_out.append(new_curves)
            controls_out.append(new_controls)

        self.outputs['Curve'].sv_set(curves_out)
        self.outputs['ControlPoints'].sv_set(controls_out)
Ejemplo n.º 7
0
    def interpret(self, interpreter, variables):
        vec = lambda v: Vector((v[0], v[1], 0))

        interpreter.assert_not_closed()
        interpreter.start_new_segment()

        v0 = interpreter.position
        if interpreter.has_last_vertex:
            v0_index = interpreter.get_last_vertex()
        else:
            v0_index = interpreter.new_vertex(*v0)

        knot1 = None
        for i, segment in enumerate(self.segments):
            # For first segment, knot1 is initial pen position;
            # for the following, knot1 is knot2 of previous segment.
            if knot1 is None:
                knot1 = interpreter.position
            else:
                knot1 = knot2

            if interpreter.prev_quad_bezier_knot is None:
                # If there is no previous command or if the previous command was
                # not a Q, q, T or t, assume the control point is coincident with
                # the current point.
                handle = knot1
            else:
                # The first control point is assumed to be the reflection of the
                # second control point on the previous command relative to the
                # current point. 
                prev_knot_x, prev_knot_y = interpreter.prev_quad_bezier_knot
                x0, y0 = knot1
                dx, dy = x0 - prev_knot_x, y0 - prev_knot_y
                handle = x0 + dx, y0 + dy

            knot2 = interpreter.calc_vertex(self.is_abs, segment.knot2[0], segment.knot2[1], variables)
            interpreter.position = knot2

            if self.num_segments is not None:
                r = interpreter.eval_(self.num_segments, variables)
            else:
                r = interpreter.dflt_num_verts

            curve = SvBezierCurve([vec(knot1), vec(handle), vec(knot2)])
            interpreter.new_curve(curve, self)

            points = interpolate_quadratic_bezier(vec(knot1), vec(handle), vec(knot2), r)

            interpreter.new_knot("T#.{}.h".format(i), *handle)
            interpreter.new_knot("T#.{}.k".format(i), *knot2)

            interpreter.prev_quad_bezier_knot = handle

            for point in points[1:]:
                v1_index = interpreter.new_vertex(point.x, point.y)
                interpreter.new_edge(v0_index, v1_index)
                v0_index = v1_index

        if self.close:
            interpreter.close_segment(v1_index)

        interpreter.has_last_vertex = True