예제 #1
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)
예제 #2
0
    def extend_curve(self, curve, t_before, t_after):
        u_min, u_max = curve.get_u_bounds()
        start, end = curve.evaluate(u_min), curve.evaluate(u_max)
        start_extent, end_extent = None, None
        is_nurbs = isinstance(curve, SvNurbsCurve)

        if self.mode == 'LINE':
            tangent_start = curve.tangent(u_min)
            tangent_end = curve.tangent(u_max)

            if t_before > 0:
                start_extent = self.make_line(start, tangent_start, t_before,
                                              -1)
                start_extent = self.set_length(curve, start_extent, t_before,
                                               -1)
            if t_after > 0:
                end_extent = self.make_line(end, tangent_end, t_after, +1)
                end_extent = self.set_length(curve, end_extent, t_after, +1)

        elif self.mode == 'ARC':
            tangent_start = curve.tangent(u_min)
            tangent_end = curve.tangent(u_max)
            second_start = curve.second_derivative(u_min)
            second_end = curve.second_derivative(u_max)

            if t_before > 0:
                if np.linalg.norm(second_start) > 1e-6:
                    eq1 = circle_by_two_derivatives(start, -tangent_start,
                                                    second_start)
                    start_extent = SvCircle.from_equation(eq1)
                    start_extent = self.set_length(curve, start_extent,
                                                   t_before, -1)
                    if is_nurbs:
                        start_extent = start_extent.to_nurbs()
                    start_extent = reverse_curve(start_extent)
                else:
                    start_extent = self.make_line(start, tangent_start,
                                                  t_before, -1)
                    start_extent = self.set_length(curve, start_extent,
                                                   t_before, -1)

            if t_after > 0:
                if np.linalg.norm(second_end) > 1e-6:
                    eq2 = circle_by_two_derivatives(end, tangent_end,
                                                    second_end)
                    end_extent = SvCircle.from_equation(eq2)
                else:
                    end_extent = self.make_line(end, tangent_end, t_after, +1)
                end_extent = self.set_length(curve, end_extent, t_after, +1)

        elif self.mode == 'QUAD':
            tangent_start = curve.tangent(u_min)
            tangent_end = curve.tangent(u_max)
            second_start = curve.second_derivative(u_min)
            second_end = curve.second_derivative(u_max)

            if t_before > 0:
                start_extent = SvTaylorCurve(start,
                                             [-tangent_start, second_start])
                start_extent = self.set_length(curve, start_extent, t_before)
                if is_nurbs:
                    start_extent = start_extent.to_nurbs()
                start_extent = reverse_curve(start_extent)

            if t_after > 0:
                end_extent = SvTaylorCurve(end, [tangent_end, second_end])
                end_extent = self.set_length(curve, end_extent, t_after)

        elif self.mode == 'CUBIC':
            tangent_start = curve.tangent(u_min)
            tangent_end = curve.tangent(u_max)
            second_start = curve.second_derivative(u_min)
            second_end = curve.second_derivative(u_max)
            third_start, third_end = curve.third_derivative_array(
                np.array([u_min, u_max]))

            if t_before > 0:
                start_extent = SvTaylorCurve(
                    start, [-tangent_start, second_start, -third_start])
                start_extent = self.set_length(curve, start_extent, t_before)
                if is_nurbs:
                    start_extent = start_extent.to_nurbs()
                start_extent = reverse_curve(start_extent)
            if t_after > 0:
                end_extent = SvTaylorCurve(
                    end, [tangent_end, second_end, third_end])
                end_extent = self.set_length(curve, end_extent, t_after)

        else:
            raise Exception("Unsupported mode")

        if is_nurbs:
            if start_extent is not None and not isinstance(
                    start_extent, SvNurbsCurve):
                start_extent = start_extent.to_nurbs(
                    implementation=curve.get_nurbs_implementation())
            if end_extent is not None and not isinstance(
                    end_extent, SvNurbsCurve):
                end_extent = end_extent.to_nurbs(
                    implementation=curve.get_nurbs_implementation())

        return start_extent, end_extent
예제 #3
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()
        point3_s = self.inputs['Point3'].sv_get()

        point1_s = ensure_nesting_level(point1_s, 3)
        point2_s = ensure_nesting_level(point2_s, 3)
        point3_s = ensure_nesting_level(point3_s, 3)

        arcs_out = []
        circles_out = []
        centers_out = []
        radius_out = []
        angle_out = []
        for point1s, point2s, point3s in zip_long_repeat(
                point1_s, point2_s, point3_s):
            arcs_new = []
            circles_new = []
            centers_new = []
            radius_new = []
            angle_new = []
            for point1, point2, point3 in zip_long_repeat(
                    point1s, point2s, point3s):
                circle_data = circle_by_three_points(point1, point2, point3)
                if circle_data is None:
                    raise Exception(
                        "Can't build a circle by these points: {}, {}, {}".
                        format(point1, point2, point3))
                matrix = circle_data.get_matrix()
                circle = SvCircle(matrix, circle_data.radius)
                #                 arc = SvCircle(radius=circle_data.radius,
                #                                 center=np.array(circle_data.center),
                #                                 normal=np.array(circle_data.normal),
                #                                 vectorx = np.array(circle_data.point1) - np.array(circle_data.center))
                #arc.u_bounds = (0.0, circle_data.arc_angle)
                arc = SvCircle.from_equation(circle_data)
                arcs_new.append(arc)
                circles_new.append(circle)
                centers_new.append(matrix)
                radius_new.append(circle_data.radius)
                angle_new.append(circle_data.arc_angle)

            if self.join:
                arcs_out.extend(arcs_new)
                circles_out.extend(circles_new)
                centers_out.extend(centers_new)
                radius_out.extend(radius_new)
                angle_out.extend(angle_new)
            else:
                arcs_out.append(arcs_new)
                circles_out.append(circles_new)
                centers_out.append(centers_new)
                radius_out.append(radius_new)
                angle_out.append(angle_new)

        self.outputs['Arc'].sv_set(arcs_out)
        self.outputs['Circle'].sv_set(circles_out)
        self.outputs['Center'].sv_set(centers_out)
        self.outputs['Radius'].sv_set(radius_out)
        self.outputs['Angle'].sv_set(angle_out)