示例#1
0
    def make_uv_curve(self, surface, mode, flip):
        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 mode == 'UMIN':
            u1 = u2 = u_min
            v1, v2 = v_min, v_max
        elif mode == 'UMAX':
            u1 = u2 = u_max
            v1, v2 = v_min, v_max
        elif mode == 'VMIN':
            u1, u2 = u_min, u_max
            v1 = v2 = v_min
        elif mode == 'VMAX':
            u1, u2 = u_min, u_max
            v1 = v2 = v_max
        else:
            raise Exception("unknown mode")

        p1 = (u1, v1, 0)
        p2 = (u2, v2, 0)
        if flip:
            curve = SvLine.from_two_points(p2, p1)
        else:
            curve = SvLine.from_two_points(p1, p2)
        return curve
示例#2
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        point1_s = self.inputs['Point1'].sv_get()
        point2_s = self.inputs['Point2'].sv_get()
        direction_s = self.inputs['Direction'].sv_get()
        u_min_s = self.inputs['UMin'].sv_get()
        u_max_s = self.inputs['UMax'].sv_get()

        point1_s = ensure_nesting_level(point1_s, 3)
        point2_s = ensure_nesting_level(point2_s, 3)
        direction_s = ensure_nesting_level(direction_s, 3)
        u_min_s = ensure_nesting_level(u_min_s, 2)
        u_max_s = ensure_nesting_level(u_max_s, 2)

        curves_out = []
        for point1s, point2s, directions, u_mins, u_maxs in zip_long_repeat(
                point1_s, point2_s, direction_s, u_min_s, u_max_s):
            new_curves = []
            for point1, point2, direction, u_min, u_max in zip_long_repeat(
                    point1s, point2s, directions, u_mins, u_maxs):
                point1 = np.array(point1)
                if self.mode == 'AB':
                    direction = np.array(point2) - point1

                line = SvLine(point1, direction)
                line.u_bounds = (u_min, u_max)
                new_curves.append(line)
            if self.join:
                curves_out.extend(new_curves)
            else:
                curves_out.append(new_curves)

        self.outputs['Curve'].sv_set(curves_out)
示例#3
0
 def make_line(self, point, tangent, t_ext, sign):
     if sign < 0:
         before_start = point - t_ext * tangent  # / np.linalg.norm(tangent_start)
         return SvLine.from_two_points(before_start, point)
     else:
         after_end = point + t_ext * tangent  # / np.linalg.norm(tangent_end)
         return SvLine.from_two_points(point, after_end)
示例#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(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.make_nurbs:
                new_curves = [c.to_nurbs() for c in new_curves]
            if self.concat:
                new_curves = [concatenate_curves(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)
示例#6
0
 def new_line_segment(self, v1, v2):
     if isinstance(v1, int):
         v1, v2 = self.vertices[v1], self.vertices[v2]
     v1, v2 = self.to3d(v1), self.to3d(v2)
     if (v1 - v2).length < self.close_threshold:
         return
     curve = SvLine.from_two_points(v1, v2)
     self.new_curve(curve, None)
示例#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.make_nurbs:
            if self.concat:
                curves = [
                    curve.to_nurbs().elevate_degree(target=2)
                    for curve in curves
                ]
            else:
                curves = [curve.to_nurbs() for curve in curves]
        if self.concat:
            concat = concatenate_curves(curves,
                                        scale_to_unit=self.scale_to_unit)
            return concat, centers
        else:
            return curves, centers
示例#8
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)
            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)

        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
示例#9
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)
示例#10
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 params in self.get_inputs():
            new_curves = []
            new_controls = []
            for curve1, curve2, factor1, factor2, parameter in params:
                _, 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 = self.smooth_mode

                if smooth == '0':
                    new_curve = SvLine.from_two_points(curve1_end,
                                                       curve2_begin)
                    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)
                    controls = [
                        new_curve.p0.tolist(),
                        new_curve.p1.tolist(),
                        new_curve.p2.tolist(),
                        new_curve.p3.tolist()
                    ]
                elif smooth == '1b':
                    tangent_1_end = curve1.tangent(t_max_1)
                    tangent_2_begin = curve2.tangent(t_min_2)

                    new_curve = SvBiArc.calc(
                        curve1_end,
                        curve2_begin,
                        tangent_1_end,
                        tangent_2_begin,
                        parameter,
                        planar_tolerance=self.planar_tolerance)

                    controls = [new_curve.junction.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)
                    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)
                    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:
                    new_curves.append(curve1)
                new_curves.append(new_curve)
                if self.mode == 'N' and output_src:
                    new_curves.append(curve2)
                new_controls.append(controls)

                is_first = False

                if self.concat:
                    new_curves = [concatenate_curves(new_curves)]

            if self.join:
                curves_out.extend(new_curves)
                controls_out.extend(new_controls)
            else:
                curves_out.append(new_curves)
                controls_out.append(new_controls)

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