Пример #1
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        curve_s = self.inputs['Curve'].sv_get()
        t_before_s = self.inputs['StartExt'].sv_get()
        t_after_s = self.inputs['EndExt'].sv_get()

        t_before_s = ensure_nesting_level(t_before_s, 2)
        t_after_s = ensure_nesting_level(t_after_s, 2)
        curve_s = ensure_nesting_level(curve_s, 2, data_types=(SvCurve, ))

        start_out = []
        end_out = []
        curve_out = []
        for curves, t_before_i, t_after_i in zip_long_repeat(
                curve_s, t_before_s, t_after_s):
            for curve, t_before, t_after in zip_long_repeat(
                    curves, t_before_i, t_after_i):
                start_extent, end_extent = self.extend_curve(
                    curve, t_before, t_after)
                start_out.append(start_extent)
                end_out.append(end_extent)
                curves = []
                if start_extent is not None:
                    curves.append(start_extent)
                curves.append(curve)
                if end_extent is not None:
                    curves.append(end_extent)
                new_curve = SvConcatCurve(curves)
                curve_out.append(new_curve)

        self.outputs['StartExtent'].sv_set(start_out)
        self.outputs['EndExtent'].sv_set(end_out)
        self.outputs['ExtendedCurve'].sv_set(curve_out)
Пример #2
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        surface_s = self.inputs['Surface'].sv_get()
        if isinstance(surface_s[0], SvSurface):
            surface_s = [surface_s]

        curves_out = []
        for surfaces in surface_s:
            for surface in surfaces:
                u_min, u_max = surface.get_u_min(), surface.get_u_max()
                v_min, v_max = surface.get_v_min(), surface.get_v_max()
                if self.cyclic_mode == 'NO':
                    curve1 = SvIsoUvCurve(surface, 'V', v_min, flip=False)
                    curve2 = SvIsoUvCurve(surface, 'U', u_max, flip=False)
                    curve3 = SvIsoUvCurve(surface, 'V', v_max, flip=True)
                    curve4 = SvIsoUvCurve(surface, 'U', u_min, flip=True)
                    new_curves = [
                        SvConcatCurve([curve1, curve2, curve3, curve4])
                    ]
                elif self.cyclic_mode == 'U':
                    curve1 = SvIsoUvCurve(surface, 'V', v_max, flip=False)
                    curve2 = SvIsoUvCurve(surface, 'V', v_min, flip=False)
                    new_curves = [curve1, curve2]
                elif self.cyclic_mode == 'V':
                    curve1 = SvIsoUvCurve(surface, 'U', u_max, flip=False)
                    curve2 = SvIsoUvCurve(surface, 'U', u_min, flip=False)
                    new_curves = [curve1, curve2]
                else:
                    raise Exception("Unsupported mode")
                curves_out.append(new_curves)

        self.outputs['Boundary'].sv_set(curves_out)
Пример #3
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        verts_s = self.inputs['Vertices'].sv_get()
        tangent_s = self.inputs['Tangent'].sv_get(default=[[[]]])
        have_tangent = self.inputs['Tangent'].is_linked

        verts_s = ensure_nesting_level(verts_s, 3)
        tangent_s = ensure_nesting_level(tangent_s, 3)
        tangent_s = tangent_s[
            0]  # We can use only one tangent per curve, but let's support a spare pair of []

        curve_out = []
        center_out = []
        radius_out = []
        angle_out = []
        for verts, tangent in zip_long_repeat(verts_s, tangent_s):
            new_curves = []
            new_centers = []
            new_radius = []
            new_angles = []

            if not have_tangent:
                tangent = self.calc_tangent(verts)
            elif not isinstance(tangent, Vector):
                tangent = Vector(tangent)

            if self.is_cyclic:
                verts = verts + [verts[0]]

            for start, end in zip(verts, verts[1:]):
                start = Vector(start)
                end = Vector(end)
                diff = end - start
                if diff.angle(tangent) < 1e-8:
                    curve = SvLine.from_two_points(start, end)
                else:
                    eq = circle_by_start_end_tangent(start, end, tangent)
                    curve = SvCircle.from_equation(eq)
                    _, angle = curve.get_u_bounds()
                    tangent = Vector(curve.tangent(angle))
                    new_centers.append(curve.matrix)
                    new_radius.append(curve.radius)
                    new_angles.append(angle)
                new_curves.append(curve)

            if self.concat:
                new_curves = [SvConcatCurve(new_curves)]
            curve_out.append(new_curves)
            center_out.append(new_centers)
            radius_out.append(new_radius)
            angle_out.append(new_angles)

        self.outputs['Curve'].sv_set(curve_out)
        self.outputs['Center'].sv_set(center_out)
        self.outputs['Radius'].sv_set(radius_out)
        self.outputs['Angle'].sv_set(angle_out)
Пример #4
0
    def make_curve(self, size_x, size_y, radiuses):
        r1, r2, r3, r4 = radiuses[:4]
        p1 = Vector((r1, 0, 0))
        p2 = Vector((size_x - r2, 0, 0))
        p3 = Vector((size_x, r2, 0))
        p4 = Vector((size_x, size_y - r3, 0))
        p5 = Vector((size_x - r3, size_y, 0))
        p6 = Vector((r4, size_y, 0))
        p7 = Vector((0, size_y - r4, 0))
        p8 = Vector((0, r1, 0))

        c1 = Vector((r1, r1, 0))
        c2 = Vector((size_x - r2, r2, 0))
        c3 = Vector((size_x - r3, size_y - r3, 0))
        c4 = Vector((r4, size_y - r4, 0))

        if self.center:
            center = Vector((size_x/2.0, size_y/2.0, 0))
            p1 -= center
            p2 -= center
            p3 -= center
            p4 -= center
            p5 -= center
            p6 -= center
            p7 -= center
            p8 -= center

            c1 -= center
            c2 -= center
            c3 -= center
            c4 -= center

        def make_arc(center, radius, angle):
            matrix = Matrix.Translation(center) @ Matrix.Rotation(angle, 4, 'Z')
            circle = SvCircle(matrix, radius)
            circle.u_bounds = (0, pi/2)
            return circle

        curves = []
        if r1 > 0:
            curves.append(make_arc(c1, r1, pi))
        if (p2 - p1).length > 0:
            curves.append(SvLine.from_two_points(p1, p2))
        if r2 > 0:
            curves.append(make_arc(c2, r2, 3*pi/2))
        if (p4 - p3).length > 0:
            curves.append(SvLine.from_two_points(p3, p4))
        if r3 > 0:
            curves.append(make_arc(c3, r3, 0))
        if (p6 - p5).length > 0:
            curves.append(SvLine.from_two_points(p5, p6))
        if r4 > 0:
            curves.append(make_arc(c4, r4, pi/2))
        if (p8 - p7).length > 0:
            curves.append(SvLine.from_two_points(p7, p8))

        curve = SvConcatCurve(curves, scale_to_unit = self.scale_to_unit)
        return (c1, c2, c3, c4), curve
Пример #5
0
    def process(self):
        if not any(o.is_linked for o in self.outputs):
            return

        verts_s = self.inputs['Vertices'].sv_get()
        threshold_s = self.inputs['AngneThreshold'].sv_get()

        verts_s = ensure_nesting_level(verts_s, 4)
        threshold_s = ensure_nesting_level(threshold_s, 2)

        curve_out = []
        for verts_i, threshold_i in zip_long_repeat(verts_s, threshold_s):
            for verts, threshold in zip_long_repeat(verts_i, threshold_i):
                verts = [Vector(v) for v in verts]

                if self.is_cyclic:
                    verts.append(verts[0])

                segments = [[verts[0]]]
                for v1, v2, v3 in zip(verts, verts[1:], verts[2:]):
                    dv1 = v2 - v1
                    dv2 = v2 - v3
                    angle = dv1.angle(dv2)
                    if angle < threshold:
                        segments[-1].append(v2)
                        segment = [v2]
                        segments.append(segment)
                    else:
                        segments[-1].append(v2)
                if not self.is_cyclic:
                    segments[-1].append(verts[-1])

                if self.is_cyclic:
                    v1, v2, v3 = verts[-2], verts[0], verts[1]
                    dv1 = v2 - v1
                    dv2 = v2 - v3
                    angle = dv1.angle(dv2)
                    if angle < threshold:
                        segments[-1].append(verts[-1])
                    else:
                        first_segment = segments[0]
                        segments = segments[1:]
                        segments[-1].extend(first_segment)

                new_curves = [
                    SvSplineCurve.from_points(segment, metric=self.metric)
                    for segment in segments
                ]
                if self.concat:
                    new_curves = [SvConcatCurve(new_curves)]
                curve_out.append(new_curves)

        self.outputs['Curve'].sv_set(curve_out)
Пример #6
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        curve_s = self.inputs['Curves'].sv_get()
        if isinstance(curve_s[0], SvCurve):
            curve_s = [curve_s]

        curves_out = []
        for curves in curve_s:
            if self.check:
                self.run_check(curves)
            new_curve = SvConcatCurve(curves)
            curves_out.append(new_curve)

        self.outputs['Curve'].sv_set(curves_out)
Пример #7
0
    def make_curve(self, vertices, radiuses):
        if self.cyclic:
            last_fillet = calc_fillet(vertices[-1], vertices[0], vertices[1], radiuses[0])
            prev_edge_start = last_fillet.p2
            radiuses = radiuses[1:] + [radiuses[0]]
            corners = list(zip(vertices, vertices[1:], vertices[2:], radiuses))
            corners.append((vertices[-2], vertices[-1], vertices[0], radiuses[-1]))
            corners.append((vertices[-1], vertices[0], vertices[1], radiuses[0]))
        else:
            prev_edge_start = vertices[0]
            corners = zip(vertices, vertices[1:], vertices[2:], radiuses)

        curves = []
        centers = []
        for v1, v2, v3, radius in corners:
            fillet = calc_fillet(v1, v2, v3, radius)
            if fillet is not None:
                edge_direction = np.array(fillet.p1) - np.array(prev_edge_start)
                edge_len = np.linalg.norm(edge_direction)
                edge = SvLine(prev_edge_start, edge_direction / edge_len)
                edge.u_bounds = (0.0, edge_len)
                arc = fillet.get_curve()
                prev_edge_start = fillet.p2
                curves.append(edge)
                curves.append(arc)
                centers.append(fillet.matrix)
            else:
                edge = SvLine.from_two_points(prev_edge_start, v2)
                prev_edge_start = v2
                curves.append(edge)

        if not self.cyclic:
            edge_direction = np.array(vertices[-1]) - np.array(prev_edge_start)
            edge_len = np.linalg.norm(edge_direction)
            edge = SvLine(prev_edge_start, edge_direction / edge_len)
            edge.u_bounds = (0.0, edge_len)
            curves.append(edge)

        if self.concat:
            concat = SvConcatCurve(curves, scale_to_unit = self.scale_to_unit)
            return concat, centers
        else:
            return curves, centers
Пример #8
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        points_s = self.inputs['Points'].sv_get()
        tangents_s = self.inputs['Tangents'].sv_get()

        points_s = ensure_nesting_level(points_s, 3)
        tangents_s = ensure_nesting_level(tangents_s, 3)

        curve_out = []
        controls_out = []
        for points, tangents in zip_long_repeat(points_s, tangents_s):
            new_curves = []
            new_controls = []
            control_points = []
            pairs = list(zip_long_repeat(points, tangents))
            segments = list(zip(pairs, pairs[1:]))
            if self.cyclic:
                segments.append((pairs[-1], pairs[0]))
            for pair1, pair2 in segments:
                point1, tangent1 = pair1
                point2, tangent2 = pair2
                point1, tangent1 = np.array(point1), np.array(tangent1)
                point2, tangent2 = np.array(point2), np.array(tangent2)
                tangent1, tangent2 = tangent1 / 2.0, tangent2 / 2.0
                curve = SvCubicBezierCurve(point1, point1 + tangent1,
                                           point2 - tangent2, point2)
                curve_controls = [
                    curve.p0.tolist(),
                    curve.p1.tolist(),
                    curve.p2.tolist(),
                    curve.p3.tolist()
                ]
                new_curves.append(curve)
                new_controls.append(curve_controls)
            if self.concat:
                new_curves = [SvConcatCurve(new_curves)]
            curve_out.append(new_curves)
            controls_out.append(new_controls)

        self.outputs['Curve'].sv_set(curve_out)
        self.outputs['ControlPoints'].sv_set(controls_out)
Пример #9
0
    def make_curve(self, control_points):
        curves = []
        for series in control_points:
            xs = [p.x for p in series]
            min_x = xs[0]
            max_x = xs[-1]
            series = np.array([p.to_tuple() for p in series])
            xs = np.array(xs)

            if self.mode == 'SPL':
                spline = CubicSpline(series, tknots=xs, is_cyclic=False)
            else:
                spline = LinearSpline(series, tknots=xs, is_cyclic=False)
            curve = SvSplineCurve(spline)
            curve.u_bounds = (series[0][0], series[-1][0])
            curves.append(curve)

        if len(curves) == 1:
            return curves[0]
        else:
            return SvConcatCurve(curves)
Пример #10
0
 def get_curve(self, spline, matrix):
     segments = []
     pairs = zip(spline.bezier_points, spline.bezier_points[1:])
     if spline.use_cyclic_u:
         pairs = list(pairs) + [
             (spline.bezier_points[-1], spline.bezier_points[0])
         ]
     points = []
     is_first = True
     for p1, p2 in pairs:
         c0 = p1.co
         c1 = p1.handle_right
         c2 = p2.handle_left
         c3 = p2.co
         if self.apply_matrix:
             c0, c1, c2, c3 = [tuple(matrix @ c) for c in [c0, c1, c2, c3]]
         else:
             c0, c1, c2, c3 = [tuple(c) for c in [c0, c1, c2, c3]]
         points.append([c0, c1, c2, c3])
         segment = SvCubicBezierCurve(c0, c1, c2, c3)
         segments.append(segment)
     return points, SvConcatCurve(segments)
Пример #11
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        output_src = self.output_src or self.concat

        curves_out = []
        controls_out = []
        is_first = True
        for curve1, curve2, factor1, factor2 in self.get_inputs():
            _, t_max_1 = curve1.get_u_bounds()
            t_min_2, _ = curve2.get_u_bounds()

            curve1_end = curve1.evaluate(t_max_1)
            curve2_begin = curve2.evaluate(t_min_2)

            smooth = int(self.smooth_mode)

            if smooth == 0:
                new_curve = SvLine.from_two_points(curve1_end, curve2_begin)
                new_controls = [curve1_end, curve2_begin]
            elif smooth == 1:
                tangent_1_end = curve1.tangent(t_max_1)
                tangent_2_begin = curve2.tangent(t_min_2)

                tangent1 = factor1 * tangent_1_end
                tangent2 = factor2 * tangent_2_begin

                new_curve = SvCubicBezierCurve(
                        curve1_end,
                        curve1_end + tangent1 / 3.0,
                        curve2_begin - tangent2 / 3.0,
                        curve2_begin
                    )
                new_controls = [new_curve.p0.tolist(), new_curve.p1.tolist(),
                                new_curve.p2.tolist(), new_curve.p3.tolist()]
            elif smooth == 2:
                tangent_1_end = curve1.tangent(t_max_1)
                tangent_2_begin = curve2.tangent(t_min_2)
                second_1_end = curve1.second_derivative(t_max_1)
                second_2_begin = curve2.second_derivative(t_min_2)

                new_curve = SvBezierCurve.blend_second_derivatives(
                                curve1_end, tangent_1_end, second_1_end,
                                curve2_begin, tangent_2_begin, second_2_begin)
                new_controls = [p.tolist() for p in new_curve.points]
            elif smooth == 3:
                tangent_1_end = curve1.tangent(t_max_1)
                tangent_2_begin = curve2.tangent(t_min_2)
                second_1_end = curve1.second_derivative(t_max_1)
                second_2_begin = curve2.second_derivative(t_min_2)
                third_1_end = curve1.third_derivative_array(np.array([t_max_1]))[0]
                third_2_begin = curve2.third_derivative_array(np.array([t_min_2]))[0]

                new_curve = SvBezierCurve.blend_third_derivatives(
                                curve1_end, tangent_1_end, second_1_end, third_1_end,
                                curve2_begin, tangent_2_begin, second_2_begin, third_2_begin)
                new_controls = [p.tolist() for p in new_curve.points]
            else:
                raise Exception("Unsupported smooth level")

            if self.mode == 'N' and not self.cyclic and output_src and is_first:
                curves_out.append(curve1)
            curves_out.append(new_curve)
            if self.mode == 'N' and output_src:
                curves_out.append(curve2)
            controls_out.append(new_controls)

            is_first = False

        if self.concat:
            curves_out = [SvConcatCurve(curves_out)]

        self.outputs['Curve'].sv_set(curves_out)
        self.outputs['ControlPoints'].sv_set(controls_out)