Exemple #1
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        surface1_s = self.inputs['Surface1'].sv_get()
        surface2_s = self.inputs['Surface2'].sv_get()
        uv_curve1_s = self.inputs['UVCurve1'].sv_get(default=[[None]])
        uv_curve2_s = self.inputs['UVCurve2'].sv_get(default=[[None]])
        bulge1_s = self.inputs['Bulge1'].sv_get()
        bulge2_s = self.inputs['Bulge2'].sv_get()

        surface1_s = ensure_nesting_level(surface1_s,
                                          2,
                                          data_types=(SvSurface, ))
        if self.inputs['UVCurve1'].is_linked:
            uv_curve1_s = ensure_nesting_level(uv_curve1_s,
                                               2,
                                               data_types=(SvCurve, ))
        surface2_s = ensure_nesting_level(surface2_s,
                                          2,
                                          data_types=(SvSurface, ))
        if self.inputs['UVCurve2'].is_linked:
            uv_curve2_s = ensure_nesting_level(uv_curve2_s,
                                               2,
                                               data_types=(SvCurve, ))
        bulge1_s = ensure_nesting_level(bulge1_s, 2)
        bulge2_s = ensure_nesting_level(bulge2_s, 2)

        surfaces_out = []
        for surface1_i, curve1_i, bulge1_i, surface2_i, curve2_i, bulge2_i in zip_long_repeat(
                surface1_s, uv_curve1_s, bulge1_s, surface2_s, uv_curve2_s,
                bulge2_s):
            new_surfaces = []
            for surface1, curve1, bulge1, surface2, curve2, bulge2 in zip_long_repeat(
                    surface1_i, curve1_i, bulge1_i, surface2_i, curve2_i,
                    bulge2_i):
                if self.curve1_mode != 'USER':
                    curve1 = self.make_uv_curve(surface1, self.curve1_mode,
                                                self.flip1)
                elif self.flip1:
                    curve1 = reverse_curve(curve1)
                if self.curve2_mode != 'USER':
                    curve2 = self.make_uv_curve(surface2, self.curve2_mode,
                                                self.flip2)
                elif self.flip2:
                    curve2 = reverse_curve(curve2)

                surface = SvBlendSurface(surface1, surface2, curve1, curve2,
                                         bulge1, bulge2)
                new_surfaces.append(surface)
            surfaces_out.append(new_surfaces)

        self.outputs['Surface'].sv_set(surfaces_out)
Exemple #2
0
    def __init__(self, curve1, curve2, curve3, curve4):
        curve1 = reparametrize_curve(curve1)
        curve2 = reparametrize_curve(curve2)
        curve3 = reparametrize_curve(curve3)
        curve4 = reparametrize_curve(curve4)
        self.curve1 = curve1
        self.curve2 = curve2
        self.curve3 = curve3
        self.curve4 = curve4
        self.linear1 = SvCurveLerpSurface.build(curve1, reverse_curve(curve3))
        self.linear2 = SvCurveLerpSurface.build(curve2, reverse_curve(curve4))
        self.c1_t_min, self.c1_t_max = curve1.get_u_bounds()
        self.c3_t_min, self.c3_t_max = curve3.get_u_bounds()

        self.corner1 = self.curve1.evaluate(self.c1_t_min)
        self.corner2 = self.curve1.evaluate(self.c1_t_max)
        self.corner3 = self.curve3.evaluate(self.c3_t_max)
        self.corner4 = self.curve3.evaluate(self.c3_t_min)

        self.normal_delta = 0.001
Exemple #3
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        curve_s = self.inputs['Curve'].sv_get()
        if isinstance(curve_s[0], SvCurve):
            out_level = 1
            curve_s = [curve_s]
        else:
            out_level = 2

        curves_out = []
        for curves in curve_s:
            new_curves = []
            for curve in curves:
                new_curve = reverse_curve(curve)
                new_curves.append(new_curve)
            if out_level == 1:
                curves_out.extend(new_curves)
            else:
                curves_out.append(new_curves)

        self.outputs['Curve'].sv_set(curves_out)
Exemple #4
0
def coons_surface(curve1, curve2, curve3, curve4):
    curves = [curve1, curve2, curve3, curve4]
    nurbs_curves = [SvNurbsCurve.to_nurbs(c) for c in curves]
    if any(c is None for c in nurbs_curves):
        return SvCoonsSurface(*curves)
    try:
        nurbs_curves = [c.reparametrize(0, 1) for c in nurbs_curves]
        degrees = [c.get_degree() for c in nurbs_curves]
        implementation = nurbs_curves[0].get_nurbs_implementation()

        if degrees[0] > degrees[2]:
            nurbs_curves[2] = nurbs_curves[2].elevate_degree(delta=degrees[0] -
                                                             degrees[2])
        if degrees[2] > degrees[0]:
            nurbs_curves[0] = nurbs_curves[0].elevate_degree(delta=degrees[2] -
                                                             degrees[0])
        if degrees[1] > degrees[3]:
            nurbs_curves[3] = nurbs_curves[3].elevate_degree(delta=degrees[1] -
                                                             degrees[3])
        if degrees[3] > degrees[1]:
            nurbs_curves[1] = nurbs_curves[1].elevate_degree(delta=degrees[3] -
                                                             degrees[1])

        degree_u = nurbs_curves[0].get_degree()
        degree_v = nurbs_curves[1].get_degree()

        knotvectors = [c.get_knotvector() for c in nurbs_curves]
        if not sv_knotvector.equal(knotvectors[0], knotvectors[2]):
            nurbs_curves[0], nurbs_curves[2] = unify_two_curves(
                nurbs_curves[0], nurbs_curves[2])
        if not sv_knotvector.equal(knotvectors[1], knotvectors[3]):
            nurbs_curves[1], nurbs_curves[3] = unify_two_curves(
                nurbs_curves[1], nurbs_curves[3])

        nurbs_curves[0] = reverse_curve(nurbs_curves[0])
        nurbs_curves[3] = reverse_curve(nurbs_curves[3])

        ruled1 = nurbs_curves[0].make_ruled_surface(nurbs_curves[2], 0, 1)
        ruled2 = nurbs_curves[1].make_ruled_surface(nurbs_curves[3], 0,
                                                    1).swap_uv()
        ruled1 = ruled1.elevate_degree(SvNurbsSurface.V, target=degree_v)
        ruled2 = ruled2.elevate_degree(SvNurbsSurface.U, target=degree_u)

        diff_1to2 = sv_knotvector.difference(ruled1.get_knotvector_v(),
                                             ruled2.get_knotvector_v())
        diff_2to1 = sv_knotvector.difference(ruled2.get_knotvector_u(),
                                             ruled1.get_knotvector_u())

        for v, count in diff_1to2:
            #print(f"R1: insert V={v} {count} times")
            ruled1 = ruled1.insert_knot(SvNurbsSurface.V, v, count)
        for u, count in diff_2to1:
            #print(f"R2: insert U={u} {count} times")
            ruled2 = ruled2.insert_knot(SvNurbsSurface.U, u, count)
        #print(f"R1: {ruled1.get_control_points().shape}, R2: {ruled2.get_control_points().shape}")

        linear_kv = sv_knotvector.generate(1, 2)

        c1_t_min, c1_t_max = nurbs_curves[0].get_u_bounds()
        c3_t_min, c3_t_max = nurbs_curves[2].get_u_bounds()

        pt1 = nurbs_curves[0].evaluate(c1_t_min)
        pt2 = nurbs_curves[0].evaluate(c1_t_max)
        pt3 = nurbs_curves[2].evaluate(c3_t_min)
        pt4 = nurbs_curves[2].evaluate(c3_t_max)

        w1 = nurbs_curves[0].get_weights()[0]
        w2 = nurbs_curves[0].get_weights()[-1]
        w3 = nurbs_curves[2].get_weights()[0]
        w4 = nurbs_curves[2].get_weights()[-1]

        linear_pts = np.array([[pt1, pt3], [pt2, pt4]])
        linear_weights = np.array([[w1, w3], [w2, w4]])
        #linear_weights = np.array([[1,1], [1,1]])
        bilinear = SvNurbsSurface.build(implementation, 1, 1, linear_kv,
                                        linear_kv, linear_pts, linear_weights)

        bilinear = bilinear.elevate_degree(SvNurbsSurface.U, target=degree_u)
        bilinear = bilinear.elevate_degree(SvNurbsSurface.V, target=degree_v)

        knotvector_u = ruled1.get_knotvector_u()
        knotvector_v = ruled2.get_knotvector_v()
        for u, count in sv_knotvector.get_internal_knots(
                knotvector_u, output_multiplicity=True):
            #print(f"B: insert U={u} {count} times")
            bilinear = bilinear.insert_knot(SvNurbsSurface.U, u, count)
        for v, count in sv_knotvector.get_internal_knots(
                knotvector_v, output_multiplicity=True):
            #print(f"B: insert V={v} {count} times")
            bilinear = bilinear.insert_knot(SvNurbsSurface.V, v, count)

        control_points = ruled1.get_control_points(
        ) + ruled2.get_control_points() - bilinear.get_control_points()
        weights = ruled1.get_weights() + ruled2.get_weights(
        ) - bilinear.get_weights()
        result = SvNurbsSurface.build(implementation, degree_u, degree_v,
                                      knotvector_u, knotvector_v,
                                      control_points, weights)
        return result
    except UnsupportedCurveTypeException as e:
        info("Can't create a native Coons surface from curves %s: %s", curves,
             e)
        return SvCoonsSurface(*curves)
Exemple #5
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
Exemple #6
0
def extend_curve(curve,
                 t_before,
                 t_after,
                 mode='LINE',
                 len_mode='T',
                 len_resolution=50):
    def make_line(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)

    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 mode == 'LINE':
        tangent_start = curve.tangent(u_min)
        tangent_end = curve.tangent(u_max)

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

    elif 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 = set_length(curve,
                                          start_extent,
                                          t_before,
                                          -1,
                                          len_mode=len_mode,
                                          len_resolution=len_resolution)
                if is_nurbs:
                    start_extent = start_extent.to_nurbs()
                start_extent = reverse_curve(start_extent)
            else:
                start_extent = make_line(start, tangent_start, t_before, -1)
                start_extent = set_length(curve,
                                          start_extent,
                                          t_before,
                                          -1,
                                          len_mode=len_mode,
                                          len_resolution=len_resolution)

        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 = make_line(end, tangent_end, t_after, +1)
            end_extent = set_length(curve,
                                    end_extent,
                                    t_after,
                                    +1,
                                    len_mode=len_mode,
                                    len_resolution=len_resolution)

    elif 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 = set_length(curve,
                                      start_extent,
                                      t_before,
                                      len_mode=len_mode,
                                      len_resolution=len_resolution)
            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 = set_length(curve,
                                    end_extent,
                                    t_after,
                                    len_mode=len_mode,
                                    len_resolution=len_resolution)

    elif 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 = set_length(curve,
                                      start_extent,
                                      t_before,
                                      len_mode=len_mode,
                                      len_resolution=len_resolution)
            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 = set_length(curve,
                                    end_extent,
                                    t_after,
                                    len_mode=len_mode,
                                    len_resolution=len_resolution)

    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
Exemple #7
0
def coons_surface(curve1, curve2, curve3, curve4, use_nurbs=NURBS_IF_POSSIBLE):
    curves = [curve1, curve2, curve3, curve4]
    nurbs_curves = [SvNurbsCurve.to_nurbs(c) for c in curves]
    if use_nurbs == GENERIC:
        return SvCoonsSurface(*curves)
    if any(c is None for c in nurbs_curves):
        if use_nurbs == NURBS_ONLY:
            raise UnsupportedCurveTypeException("Some of curves are not NURBS")
        else:
            return SvCoonsSurface(*curves)
    try:
        nurbs_curves = [c.reparametrize(0, 1) for c in nurbs_curves]
        degrees = [c.get_degree() for c in nurbs_curves]
        implementation = nurbs_curves[0].get_nurbs_implementation()

        nurbs_curves[0], nurbs_curves[2] = unify_curves(
            [nurbs_curves[0], nurbs_curves[2]])
        nurbs_curves[1], nurbs_curves[3] = unify_curves(
            [nurbs_curves[1], nurbs_curves[3]])

        degree_u = nurbs_curves[0].get_degree()
        degree_v = nurbs_curves[1].get_degree()

        nurbs_curves[0] = reverse_curve(nurbs_curves[0])
        nurbs_curves[3] = reverse_curve(nurbs_curves[3])

        ruled1 = nurbs_curves[0].make_ruled_surface(nurbs_curves[2], 0, 1)
        ruled2 = nurbs_curves[1].make_ruled_surface(nurbs_curves[3], 0,
                                                    1).swap_uv()

        linear_kv = sv_knotvector.generate(1, 2)

        c1_t_min, c1_t_max = nurbs_curves[0].get_u_bounds()
        c3_t_min, c3_t_max = nurbs_curves[2].get_u_bounds()

        pt1 = nurbs_curves[0].evaluate(c1_t_min)
        pt2 = nurbs_curves[0].evaluate(c1_t_max)
        pt3 = nurbs_curves[2].evaluate(c3_t_min)
        pt4 = nurbs_curves[2].evaluate(c3_t_max)

        w1 = nurbs_curves[0].get_weights()[0]
        w2 = nurbs_curves[0].get_weights()[-1]
        w3 = nurbs_curves[2].get_weights()[0]
        w4 = nurbs_curves[2].get_weights()[-1]

        linear_pts = np.array([[pt1, pt3], [pt2, pt4]])
        linear_weights = np.array([[w1, w3], [w2, w4]])
        #linear_weights = np.array([[1,1], [1,1]])
        bilinear = SvNurbsSurface.build(implementation, 1, 1, linear_kv,
                                        linear_kv, linear_pts, linear_weights)

        ruled1, ruled2, bilinear = unify_nurbs_surfaces(
            [ruled1, ruled2, bilinear])
        knotvector_u = ruled1.get_knotvector_u()
        knotvector_v = ruled1.get_knotvector_v()

        control_points = ruled1.get_control_points(
        ) + ruled2.get_control_points() - bilinear.get_control_points()
        weights = ruled1.get_weights() + ruled2.get_weights(
        ) - bilinear.get_weights()
        result = SvNurbsSurface.build(implementation, degree_u, degree_v,
                                      knotvector_u, knotvector_v,
                                      control_points, weights)
        return result
    except UnsupportedCurveTypeException as e:
        if use_nurbs == NURBS_ONLY:
            raise
        else:
            info("Can't create a native Coons surface from curves %s: %s",
                 curves, e)
            return SvCoonsSurface(*curves)