Exemplo n.º 1
0
    def make_ruled_surface(self, curve2, vmin, vmax):
        curve = self
        curve2 = SvNurbsCurve.to_nurbs(curve2)
        if curve2 is None:
            raise UnsupportedCurveTypeException("second curve is not NURBS")
        if curve.get_degree() != curve2.get_degree():
            raise UnsupportedCurveTypeException("curves have different degrees")

        #print(f"kv1: {curve.get_knotvector().shape}, kv2: {curve2.get_knotvector().shape}")
        kv1, kv2 = curve.get_knotvector(), curve2.get_knotvector()
        if kv1.shape != kv2.shape or (kv1 != kv2).any():
            curve, curve2 = unify_curves(curve, curve2)
            #raise UnsupportedCurveTypeException("curves have different knot vectors")

        my_control_points = curve.control_points
        other_control_points = curve2.get_control_points()
        if len(my_control_points) != len(other_control_points):
            raise UnsupportedCurveTypeException("curves have different number of control points")

        if vmin != 0:
            my_control_points = (1 - vmin) * my_control_points + vmin * other_control_points
        if vmax != 0:
            other_control_points = (1 - vmax) * my_control_points + vmax * other_control_points

        control_points = np.stack((my_control_points, other_control_points))
        control_points = np.transpose(control_points, axes=(1,0,2))

        weights = np.stack((curve.weights, curve2.get_weights())).T
        knotvector_v = sv_knotvector.generate(1, 2, clamped=True)

        surface = SvNativeNurbsSurface(degree_u = curve.degree, degree_v = 1,
                        knotvector_u = curve.knotvector, knotvector_v = knotvector_v,
                        control_points = control_points,
                        weights = weights)
        return surface
Exemplo n.º 2
0
 def to_nurbs(self, implementation=SvNurbsMaths.NATIVE):
     knotvector = sv_knotvector.generate(3, 4)
     control_points = np.array([self.p0, self.p1, self.p2, self.p3])
     return SvNurbsMaths.build_curve(implementation,
                                     degree=3,
                                     knotvector=knotvector,
                                     control_points=control_points)
Exemplo n.º 3
0
    def test_split_2(self):
        points = np.array([[0, 0, 0], [1, 1, 0], [2, 0, 0]])
        kv = sv_knotvector.generate(2, 3)
        weights = [1, 1, 1]
        curve = SvNativeNurbsCurve(2, kv, points, weights)

        curve1, curve2 = curve.split_at(0.5)

        expected_kv1 = np.array([0, 0, 0, 0.5, 0.5, 0.5])
        kv1 = curve1.get_knotvector()
        self.assert_numpy_arrays_equal(kv1, expected_kv1, precision=8)

        expected_kv2 = np.array([0.5, 0.5, 0.5, 1, 1, 1])
        kv2 = curve2.get_knotvector()
        self.assert_numpy_arrays_equal(kv2, expected_kv2, precision=8)

        expected_pts1 = np.array([[0, 0, 0], [0.5, 0.5, 0], [1, 0.5, 0]])
        pts1 = curve1.get_control_points()
        #print("Pts1", pts1)
        self.assert_numpy_arrays_equal(pts1, expected_pts1, precision=8)

        expected_pts2 = np.array([[1, 0.5, 0], [1.5, 0.5, 0], [2, 0, 0]])
        pts2 = curve2.get_control_points()
        #print("Pts2", pts2)
        self.assert_numpy_arrays_equal(pts2, expected_pts2, precision=8)
Exemplo n.º 4
0
    def test_remove_geomdl_1(self):
        points = np.array([[0, 0, 0], [1, 1, 0], [2, 0, 0]])
        degree = 2
        kv = sv_knotvector.generate(degree, 3)
        weights = [1, 1, 1]
        ts = np.linspace(0.0, 1.0, num=5)

        curve = SvGeomdlCurve.build_geomdl(degree, kv, points, weights)
        orig_pts = curve.evaluate_array(ts)
        inserted = curve.insert_knot(0.5, 1)

        self.assert_numpy_arrays_equal(inserted.evaluate_array(ts),
                                       orig_pts,
                                       precision=8)

        expected_inserted_kv = np.array([0, 0, 0, 0.5, 1, 1, 1])
        self.assert_numpy_arrays_equal(inserted.get_knotvector(),
                                       expected_inserted_kv,
                                       precision=8)

        removed = inserted.remove_knot(0.5, 1)
        self.assert_numpy_arrays_equal(removed.get_knotvector(),
                                       kv,
                                       precision=8)
        #self.assert_numpy_arrays_equal(removed.evaluate_array(ts), orig_pts)

        #print("CP", removed.get_control_points())
        #print("W", removed.get_weights())
        self.assert_numpy_arrays_equal(removed.get_control_points(),
                                       points,
                                       precision=8)
Exemplo n.º 5
0
    def test_ruled_surface_1(self):
        """
        Test that
        1) SvCurveLerpSurface.build gives a NURBS surface for two NURBS curves;
        2) the resulting surface is identical to generic ruled surface.
        """
        control_points1 = np.array([[0, 0, 0], [0.5, 0, 0.5], [1, 0, 0]])
        control_points2 = np.array([[0, 2, 0], [0.5, 3, 0.5], [1, 2, 0]])
        # With non-trivial weights, this test will fail,
        # because the resulting surface will have different parametrization
        # comparing to generic ruled surface; however, the shape of the surface
        # will be correct anyway.
        weights1 = [1, 1, 1]
        weights2 = [1, 1, 1]

        knotvector = sv_knotvector.generate(degree=2, num_ctrlpts=3)
        curve1 = SvNativeNurbsCurve(2, knotvector, control_points1, weights1)
        curve2 = SvNativeNurbsCurve(2, knotvector, control_points2, weights2)

        surf1 = SvCurveLerpSurface(curve1, curve2)
        surf2 = SvCurveLerpSurface.build(curve1, curve2)

        self.assertTrue(isinstance(surf2, SvNativeNurbsSurface))

        us = np.array([0, 0, 0.5, 0.5, 1, 1])
        vs = np.array([0, 0.5, 0.5, 1, 0.5, 1])

        pts1 = surf1.evaluate_array(us, vs)
        pts2 = surf2.evaluate_array(us, vs)

        self.assert_numpy_arrays_equal(pts1,
                                       pts2,
                                       precision=8,
                                       fail_fast=False)
Exemplo n.º 6
0
    def _arc_to_nurbs(self, t_min, t_max, implementation=SvNurbsMaths.NATIVE):
        alpha = t_max - t_min
        p0_x = cos(t_min)
        p0_y = sin(t_min)
        p2_x = cos(t_max)
        p2_y = sin(t_max)
        t_mid = 0.5 * (t_max + t_min)
        theta = 0.5 * alpha
        p1_r = 1.0 / cos(theta)
        p1_x = p1_r * cos(t_mid)
        p1_y = p1_r * sin(t_mid)

        control_points = np.array([[p0_x, p0_y, 0], [p1_x, p1_y, 0],
                                   [p2_x, p2_y, 0]])
        control_points = self.radius * control_points
        control_points = np.apply_along_axis(lambda v: self.matrix @ v, 1,
                                             control_points)
        control_points = self.center + control_points

        w1 = cos(theta)
        weights = np.array([1, w1, 1])
        degree = 2
        knotvector = sv_knotvector.generate(degree, 3)
        knotvector = sv_knotvector.rescale(knotvector, t_min, t_max)

        nurbs = SvNurbsMaths.build_curve(implementation, degree, knotvector,
                                         control_points, weights)

        if alpha > 2 * pi / 3:
            nurbs = nurbs.insert_knot(t_mid)

        return nurbs
Exemplo n.º 7
0
    def extrude_to_point(self, point):
        my_control_points = self.get_control_points()
        n = len(my_control_points)
        other_control_points = np.empty((n, 3))
        other_control_points[:] = point

        control_points = np.stack((my_control_points, other_control_points))
        control_points = np.transpose(control_points, axes=(1, 0, 2))

        my_weights = self.get_weights()
        other_weights = my_weights
        #other_weights = np.ones((n,))
        weights = np.stack((my_weights, other_weights)).T

        knotvector_u = self.get_knotvector()
        knotvector_v = sv_knotvector.generate(1, 2, clamped=True)

        degree_u = self.get_degree()
        degree_v = 1

        surface = SvNurbsMaths.build_surface(self.get_nurbs_implementation(),
                                             degree_u, degree_v, knotvector_u,
                                             knotvector_v, control_points,
                                             weights)
        return surface
Exemplo n.º 8
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        vertices_s = self.inputs['ControlPoints'].sv_get()
        has_weights = self.inputs['Weights'].is_linked
        weights_s = self.inputs['Weights'].sv_get(default = [[1.0]])
        knots_s = self.inputs['Knots'].sv_get(default = [[]])
        degree_s = self.inputs['Degree'].sv_get()

        curves_out = []
        knots_out = []
        for vertices, weights, knots, degree in zip_long_repeat(vertices_s, weights_s, knots_s, degree_s):
            if isinstance(degree, (tuple, list)):
                degree = degree[0]

            n_source = len(vertices)
            fullList(weights, n_source)
            if self.knot_mode == 'AUTO' and self.is_cyclic:
                vertices = vertices + vertices[:degree]
                weights = weights + weights[:degree]
            n_total = len(vertices)

            # Set degree
            curve_degree = degree

            if has_weights and self.surface_mode == 'NURBS':
                curve_weights = weights
            else:
                curve_weights = None

            # Set knot vector
            if self.knot_mode == 'AUTO':
                if self.is_cyclic:
                    self.debug("N: %s, degree: %s", n_total, degree)
                    knots = list(range(n_total + degree + 1))
                else:
                    knots = sv_knotvector.generate(curve_degree, n_total)
                self.debug('Auto knots: %s', knots)
                curve_knotvector = knots
            else:
                self.debug('Manual knots: %s', knots)
                curve_knotvector = knots

            new_curve = SvNurbsCurve.build(self.implementation, degree, curve_knotvector, vertices, curve_weights, normalize_knots = self.normalize_knots)
            curve_knotvector = new_curve.get_knotvector().tolist()
            if self.knot_mode == 'AUTO' and self.is_cyclic:
                u_min = curve_knotvector[degree]
                u_max = curve_knotvector[-degree-1]
                new_curve.u_bounds = u_min, u_max
            else:
                u_min = min(curve_knotvector)
                u_max = max(curve_knotvector)
                new_curve.u_bounds = (u_min, u_max)
            curves_out.append(new_curve)
            knots_out.append(curve_knotvector)

        self.outputs['Curve'].sv_set(curves_out)
        self.outputs['Knots'].sv_set(knots_out)
Exemplo n.º 9
0
 def to_nurbs(self, implementation=SvNurbsMaths.NATIVE):
     control_points = self.get_control_points()
     degree = self.get_degree()
     knotvector = sv_knotvector.generate(degree, len(control_points))
     nurbs = SvNurbsMaths.build_curve(implementation,
                                      degree=degree,
                                      knotvector=knotvector,
                                      control_points=control_points)
     return nurbs.cut_segment(*self.u_bounds)
Exemplo n.º 10
0
 def test_single_1(self):
     points = np.array([[0, 0, 0], [1, 1, 0], [2, 0, 0]])
     kv = sv_knotvector.generate(2, 3)
     weights = [1, 1, 1]
     curve = SvNativeNurbsCurve(2, kv, points, weights)
     t = 0.5
     result = curve.evaluate(t)
     #print(result)
     expected = np.array([1, 0.5, 0])
     self.assert_numpy_arrays_equal(result, expected, precision=6)
Exemplo n.º 11
0
 def to_nurbs(self, implementation=SvNurbsCurve.NATIVE):
     knotvector = sv_knotvector.generate(1, 2)
     u_min, u_max = self.get_u_bounds()
     p1 = self.evaluate(u_min)
     p2 = self.evaluate(u_max)
     control_points = np.array([p1, p2])
     return SvNurbsCurve.build(implementation,
                               degree=1,
                               knotvector=knotvector,
                               control_points=control_points)
Exemplo n.º 12
0
    def test_outside_sphere_3(self):
        cpts = np.array([[-2, 5, 0], [2, 5, 0]])
        degree = 1
        knotvector = sv_knotvector.generate(degree, len(cpts))
        curve = SvNurbsCurve.build(SvNurbsCurve.NATIVE, degree, knotvector,
                                   cpts)

        result = curve.is_strongly_outside_sphere(np.array([0, 0, 0]), 1)
        expected_result = True
        self.assertEquals(result, expected_result)
Exemplo n.º 13
0
 def test_insert_2(self):
     points = np.array([[0, 0, 0], [1, 1, 0], [2, 0, 0]])
     degree = 2
     kv = sv_knotvector.generate(degree, 3)
     weights = [1, 1, 1]
     curve = SvNativeNurbsCurve(degree, kv, points, weights)
     inserted = curve.insert_knot(0.5, 2)
     ts = np.array([0, 0.25, 0.5, 0.75, 1.0])
     expected = curve.evaluate_array(ts)
     result = inserted.evaluate_array(ts)
     self.assert_numpy_arrays_equal(result, expected, precision=8)
Exemplo n.º 14
0
    def test_insert_1(self):
        points = np.array([[0, 0, 0], [1, 0, 0]])
        kv = sv_knotvector.generate(1, 2)
        weights = [1, 1]
        curve = SvNativeNurbsCurve(1, kv, points, weights)
        curve = curve.insert_knot(0.5)

        ts = np.array([0, 0.25, 0.5, 0.75, 1.0])
        expected = np.array([[0, 0, 0], [0.25, 0, 0], [0.5, 0, 0],
                             [0.75, 0, 0], [1, 0, 0]])
        result = curve.evaluate_array(ts)
        self.assert_numpy_arrays_equal(result, expected, precision=8)
Exemplo n.º 15
0
 def extrude_along_vector(self, vector):
     vector = np.array(vector)
     other_control_points = self.control_points + vector
     control_points = np.stack((self.control_points, other_control_points))
     control_points = np.transpose(control_points, axes=(1,0,2))
     weights = np.stack((self.weights, self.weights)).T
     knotvector_v = sv_knotvector.generate(1, 2, clamped=True)
     surface = SvNativeNurbsSurface(degree_u = self.degree, degree_v = 1,
                     knotvector_u = self.knotvector, knotvector_v = knotvector_v,
                     control_points = control_points,
                     weights = weights)
     return surface
Exemplo n.º 16
0
    def to_nurbs(self, implementation=SvNurbsCurve.NATIVE):
        control_points = self.spline.get_control_points()
        degree = self.spline.get_degree()
        n_points = degree + 1
        knotvector = sv_knotvector.generate(degree, n_points)
        t_segments = self.spline.get_t_segments()
        segments = [SvNurbsCurve.build(implementation,
                        degree, knotvector, points) for points in control_points]
        segments = [reparametrize_curve(segment, t_min, t_max) for segment, (t_min, t_max) in zip(segments, t_segments)]
#         pairs = [f"#{i}: {t_min}-{t_max}: {segment.evaluate(t_min)} -- {segment.evaluate(t_max)}" for i, (segment, (t_min, t_max)) in enumerate(zip(segments, t_segments))]
#         pairs = ", ".join(pairs)
#         print(f"S: {pairs}")
        return concatenate_nurbs_curves(segments)
Exemplo n.º 17
0
    def test_bezier_to_taylor_2(self):
        cpts = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [2, 1, 0]],
                        dtype=np.float64)
        degree = 3
        knotvector = sv_knotvector.generate(degree, len(cpts))
        knotvector += 1.0
        curve = SvNurbsCurve.build(SvNurbsCurve.NATIVE, degree, knotvector,
                                   cpts)

        taylor = curve.bezier_to_taylor()
        nurbs = taylor.to_nurbs()

        self.assert_numpy_arrays_equal(nurbs.get_control_points(),
                                       cpts,
                                       precision=8)
Exemplo n.º 18
0
 def extrude_along_vector(self, vector):
     vector = np.array(vector)
     my_control_points = self.get_control_points()
     my_weights = self.get_weights()
     other_control_points = my_control_points + vector
     control_points = np.stack((my_control_points, other_control_points))
     control_points = np.transpose(control_points, axes=(1,0,2)).tolist()
     weights = np.stack((my_weights, my_weights)).T.tolist()
     my_knotvector = self.get_knotvector()
     my_degree = self.get_degree()
     knotvector_v = sv_knotvector.generate(1, 2, clamped=True)
     surface = SvGeomdlSurface.build(degree_u = my_degree, degree_v = 1,
                     knotvector_u = my_knotvector, knotvector_v = knotvector_v,
                     control_points = control_points,
                     weights = weights)
     return surface
Exemplo n.º 19
0
 def to_nurbs(self, implementation=SvNurbsMaths.NATIVE):
     control_points = self.get_control_points()
     if control_points.shape[1] == 4:
         control_points, weights = from_homogenous(control_points)
     else:
         weights = None
     degree = self.get_degree()
     knotvector = sv_knotvector.generate(degree, len(control_points))
     u1, u2 = self.get_u_bounds()
     knotvector = (u2 - u1) * knotvector + u1
     nurbs = SvNurbsMaths.build_curve(implementation,
                                      degree=degree,
                                      knotvector=knotvector,
                                      control_points=control_points,
                                      weights=weights)
     #return nurbs.reparametrize(*self.get_u_bounds())
     return nurbs
Exemplo n.º 20
0
    def to_nurbs(self, implementation = SvNurbsMaths.NATIVE):
        u_min, u_max = self.u_bounds
        v_min, v_max = self.v_bounds
        pt1 = self.evaluate(u_min, v_min)
        pt2 = self.evaluate(u_min, v_max)
        pt3 = self.evaluate(u_max, v_min)
        pt4 = self.evaluate(u_max, v_max)

        control_points = np.array([[pt1, pt2], [pt3, pt4]])
        weights = np.array([[1,1], [1, 1]])
        degree_u = degree_v = 1
        knotvector_u = knotvector_v = sv_knotvector.generate(1, 2)

        return SvNurbsMaths.build_surface(implementation,
                degree_u, degree_v,
                knotvector_u, knotvector_v,
                control_points, weights)
Exemplo n.º 21
0
    def test_insert_3(self):
        points = np.array([[0, 0, 0], [1, 1, 0], [2, 1, 0], [3, 0, 0]])
        degree = 2
        kv = sv_knotvector.generate(degree, 4)
        weights = [1, 1, 1, 1]

        #print("test_insert_3: Kv:", kv)
        curve = SvNativeNurbsCurve(degree, kv, points, weights)
        inserted = curve.insert_knot(0.5)

        #print("Ins.kv:", inserted.knotvector)
        #print("Ins.cp:", inserted.control_points)

        ts = np.array([0, 0.25, 0.5, 0.75, 1.0])
        expected = curve.evaluate_array(ts)
        result = inserted.evaluate_array(ts)
        self.assert_numpy_arrays_equal(result, expected, precision=8)
Exemplo n.º 22
0
    def test_split_3(self):
        points = np.array([[0, 0, 0], [1, 1, 0], [2, 1, 0], [3, 0, 0]])
        weights = [1, 1, 1, 1]
        degree = 2
        knotvector = sv_knotvector.generate(degree, 4)
        curve = SvNativeNurbsCurve(degree, knotvector, points, weights)

        t0 = 0.5
        curve1, curve2 = curve.split_at(t0)
        #print("Kv1:", curve1.get_knotvector())
        #print("Kv2:", curve2.get_knotvector())

        pt1 = curve1.evaluate(0.25)
        expected_pt1 = curve.evaluate(0.25)
        self.assert_numpy_arrays_equal(pt1, expected_pt1, precision=4)

        pt2 = curve2.evaluate(0.75)
        expected_pt2 = curve.evaluate(0.75)
        self.assert_numpy_arrays_equal(pt2, expected_pt2, precision=4)
Exemplo n.º 23
0
    def get_curve(self, spline, matrix):
        curve_degree = spline.order_u - 1
        if self.apply_matrix:
            vertices = [
                tuple(matrix @ Vector(p.co[:3])) for p in spline.points
            ]
        else:
            vertices = [tuple(p.co)[:3] for p in spline.points]
        weights = [tuple(p.co)[3] for p in spline.points]
        if spline.use_cyclic_u:
            vertices = vertices + vertices[:curve_degree + 1]
            weights = weights + weights[:curve_degree + 1]
        n_total = len(vertices)
        curve_ctrlpts = vertices
        curve_weights = weights
        if spline.use_cyclic_u:
            knots = list(range(n_total + curve_degree + 1))
        else:
            knots = sv_knotvector.generate(curve_degree,
                                           n_total,
                                           clamped=spline.use_endpoint_u)
        self.debug('Auto knots: %s', knots)
        curve_knotvector = knots

        new_curve = SvNurbsCurve.build(self.implementation, curve_degree,
                                       curve_knotvector, curve_ctrlpts,
                                       curve_weights)
        if spline.use_cyclic_u:
            u_min = curve_knotvector[curve_degree]
            u_max = curve_knotvector[-curve_degree - 2]
            new_curve = new_curve.cut_segment(u_min, u_max)
            #new_curve.u_bounds = u_min, u_max
        else:
            if spline.use_endpoint_u:
                u_min = min(curve_knotvector)
                u_max = max(curve_knotvector)
            else:
                u_min = curve_knotvector[curve_degree]
                u_max = curve_knotvector[-curve_degree - 1]
            new_curve.u_bounds = (u_min, u_max)

        return new_curve
Exemplo n.º 24
0
def build_from_curves(curves,
                      degree_u=None,
                      implementation=SvNurbsSurface.NATIVE):
    curves = unify_curves(curves)
    degree_v = curves[0].get_degree()
    if degree_u is None:
        degree_u = degree_v
    control_points = [curve.get_control_points() for curve in curves]
    control_points = np.array(control_points)
    weights = np.array([curve.get_weights() for curve in curves])
    knotvector_u = sv_knotvector.generate(degree_u, len(curves))
    #knotvector_v = curves[0].get_knotvector()
    knotvector_v = sv_knotvector.average(
        [curve.get_knotvector() for curve in curves])

    surface = SvNurbsSurface.build(implementation, degree_u, degree_v,
                                   knotvector_u, knotvector_v, control_points,
                                   weights)

    return curves, surface
Exemplo n.º 25
0
    def test_split_4(self):
        points = np.array([[0, 0, 0], [1, 1, 0], [2, 0, 0], [3, 1, 0],
                           [4, 0, 0]])
        degree = 3
        knotvector = sv_knotvector.generate(degree, 5)
        weights = [0.25, 1, 4.9, 2.35, 1]
        #weights = [1, 1, 1, 1, 1]
        curve = SvNativeNurbsCurve(degree, knotvector, points, weights)

        curve1, curve2 = curve.split_at(0.501)
        #print("Kv1:", curve1.get_knotvector())
        #print("Kv2:", curve2.get_knotvector())

        pt1 = curve1.evaluate(0.25)
        expected_pt1 = curve.evaluate(0.25)
        self.assert_numpy_arrays_equal(pt1, expected_pt1, precision=4)

        pt2 = curve2.evaluate(0.75)
        expected_pt2 = curve.evaluate(0.75)
        self.assert_numpy_arrays_equal(pt2, expected_pt2, precision=4)
Exemplo n.º 26
0
    def test_split_1(self):
        points = np.array([[0, 0, 0], [1, 0, 0]])
        kv = sv_knotvector.generate(1, 2)
        weights = [1, 1]
        curve = SvNativeNurbsCurve(1, kv, points, weights)

        curve1, curve2 = curve.split_at(0.5)

        expected_pts1 = np.array([[0, 0, 0], [0.5, 0, 0]])
        pts1 = curve1.get_control_points()
        self.assert_numpy_arrays_equal(pts1, expected_pts1)

        expected_pts2 = np.array([[0.5, 0, 0.0], [1, 0, 0]])
        pts2 = curve2.get_control_points()
        self.assert_numpy_arrays_equal(pts2, expected_pts2)

        expected_kv1 = np.array([0, 0, 0.5, 0.5])
        kv1 = curve1.get_knotvector()
        self.assert_numpy_arrays_equal(kv1, expected_kv1)

        expected_kv2 = np.array([0.5, 0.5, 1, 1])
        kv2 = curve2.get_knotvector()
        self.assert_numpy_arrays_equal(kv2, expected_kv2)
Exemplo n.º 27
0
    def test_bezier_to_taylor_1(self):
        cpts = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [2, 1, 0]],
                        dtype=np.float64)
        degree = 3
        knotvector = sv_knotvector.generate(degree, len(cpts))
        curve = SvNurbsCurve.build(SvNurbsCurve.NATIVE, degree, knotvector,
                                   cpts)

        taylor = curve.bezier_to_taylor()
        coeffs = taylor.get_coefficients()

        self.assert_numpy_arrays_equal(coeffs[0],
                                       np.array([0, 0, 0, 1]),
                                       precision=8)
        self.assert_numpy_arrays_equal(coeffs[1],
                                       np.array([3, 0, 0, 0]),
                                       precision=8)
        self.assert_numpy_arrays_equal(coeffs[2],
                                       np.array([-3, 3, 0, 0]),
                                       precision=8)
        self.assert_numpy_arrays_equal(coeffs[3],
                                       np.array([2, -2, 0, 0]),
                                       precision=8)
Exemplo n.º 28
0
    def get_surface(self, spline, matrix):
        surface_degree_u = spline.order_u - 1
        surface_degree_v = spline.order_v - 1

        spline_points = split_by_count(spline.points, spline.point_count_u)
        if self.apply_matrix:
            control_points = [[list(matrix @ Vector(p.co[:3])) for p in row]
                              for row in spline_points]
        else:
            control_points = [[tuple(p.co) for p in row]
                              for row in spline_points]
        surface_weights = [[p.co[3] for p in row] for row in spline_points]
        if spline.use_cyclic_v:
            for row_idx in range(len(control_points)):
                control_points[row_idx].extend(
                    control_points[row_idx][:spline.order_v])
        if spline.use_cyclic_u:
            control_points.extend(control_points[:spline.order_u])

        # Control points
        n_u_total = len(control_points)
        n_v_total = len(control_points[0])
        if spline.use_cyclic_u:
            knots_u = list(range(n_u_total + spline.order_u))
        else:
            knots_u = sv_knotvector.generate(surface_degree_u,
                                             n_u_total,
                                             clamped=spline.use_endpoint_u)
        self.debug("Auto knots U: %s", knots_u)

        if spline.use_cyclic_v:
            knots_v = list(range(n_v_total + spline.order_v))
        else:
            knots_v = sv_knotvector.generate(surface_degree_v,
                                             n_v_total,
                                             clamped=spline.use_endpoint_v)
        self.debug("Auto knots V: %s", knots_v)

        surface_knotvector_u = knots_u
        surface_knotvector_v = knots_v

        new_surf = SvNurbsSurface.build(self.implementation,
                                        surface_degree_u,
                                        surface_degree_v,
                                        surface_knotvector_u,
                                        surface_knotvector_v,
                                        control_points,
                                        surface_weights,
                                        normalize_knots=True)

        if spline.use_cyclic_u:
            u_min = surface_knotvector_u[surface_degree_u]
            u_max = surface_knotvector_u[-surface_degree_u - 2]
        else:
            if spline.use_endpoint_u:
                u_min = min(surface_knotvector_u)
                u_max = max(surface_knotvector_u)
            else:
                u_min = surface_knotvector_u[surface_degree_u]
                u_max = surface_knotvector_u[-surface_degree_u - 1]
        if spline.use_cyclic_v:
            v_min = surface_knotvector_v[surface_degree_v]
            v_max = surface_knotvector_v[-surface_degree_v - 2]
        else:
            if spline.use_endpoint_v:
                v_min = min(surface_knotvector_v)
                v_max = max(surface_knotvector_v)
            else:
                v_min = surface_knotvector_v[surface_degree_v]
                v_max = surface_knotvector_v[-surface_degree_v - 1]

        new_surf.u_bounds = u_min, u_max
        new_surf.v_bounds = v_min, v_max

        return new_surf
Exemplo n.º 29
0
    def process(self):
        vertices_s = self.inputs['ControlPoints'].sv_get()
        has_weights = self.inputs['Weights'].is_linked
        weights_s = self.inputs['Weights'].sv_get(default=[[1.0]])
        u_size_s = self.inputs['USize'].sv_get()
        knots_u_s = self.inputs['KnotsU'].sv_get(default=[[]])
        knots_v_s = self.inputs['KnotsV'].sv_get(default=[[]])
        degree_u_s = self.inputs['DegreeU'].sv_get()
        degree_v_s = self.inputs['DegreeV'].sv_get()

        if self.input_mode == '1D':
            vertices_s = ensure_nesting_level(vertices_s, 3)
        else:
            vertices_s = ensure_nesting_level(vertices_s, 4)

        surfaces_out = []
        inputs = zip_long_repeat(vertices_s, weights_s, knots_u_s, knots_v_s,
                                 degree_u_s, degree_v_s, u_size_s)
        for vertices, weights, knots_u, knots_v, degree_u, degree_v, u_size in inputs:
            if isinstance(degree_u, (tuple, list)):
                degree_u = degree_u[0]
            if isinstance(degree_v, (tuple, list)):
                degree_v = degree_v[0]
            if isinstance(u_size, (list, tuple)):
                u_size = u_size[0]

            if self.surface_mode != 'NURBS':
                weights = None

            if self.surface_mode == 'NURBS':
                if self.input_mode == '1D':
                    weights = repeat_last_for_length(weights,
                                                     len(vertices),
                                                     deepcopy=True)
                else:
                    if isinstance(weights[0], (int, float)):
                        weights = [weights]
                    weights = repeat_last_for_length(weights,
                                                     len(vertices),
                                                     deepcopy=True)
                    for verts_u, weights_u in zip(vertices, weights):
                        fullList_deep_copy(weights_u, len(verts_u))

            if self.input_mode == '1D':
                n_v = u_size
                n_u = len(vertices) // n_v

                vertices = split_by_count(vertices, n_u)
                if self.surface_mode == 'NURBS':
                    weights = split_by_count(weights, n_u)

            if self.knot_mode == 'AUTO':
                if self.is_cyclic_v:
                    for row_idx in range(len(vertices)):
                        vertices[row_idx].extend(vertices[row_idx][:degree_v +
                                                                   1])
                        if self.surface_mode == 'NURBS':
                            weights[row_idx].extend(
                                weights[row_idx][:degree_v + 1])
                if self.is_cyclic_u:
                    vertices.extend(vertices[:degree_u + 1])
                    if self.surface_mode == 'NURBS':
                        weights.extend(weights[:degree_u + 1])
                self.debug("UxV: %s x %s", len(vertices), len(vertices[0]))

            n_u_total = len(vertices)
            n_v_total = len(vertices[0])

            if self.knot_mode == 'AUTO':
                if self.is_cyclic_u:
                    knots_u = list(range(n_u_total + degree_u + 1))
                else:
                    knots_u = sv_knotvector.generate(degree_u, n_u_total)
                self.debug("Auto knots U: %s", knots_u)
                surf_knotvector_u = knots_u

                if self.is_cyclic_v:
                    knots_v = list(range(n_v_total + degree_v + 1))
                else:
                    knots_v = sv_knotvector.generate(degree_v, n_v_total)
                self.debug("Auto knots V: %s", knots_v)
                surf_knotvector_v = knots_v
            else:
                surf_knotvector_u = knots_u
                surf_knotvector_v = knots_v

            new_surf = SvNurbsSurface.build(self.implementation, degree_u,
                                            degree_v, surf_knotvector_u,
                                            surf_knotvector_v, vertices,
                                            weights, self.normalize_knots)
            surf_knotvector_u = new_surf.get_knotvector_u().tolist()
            surf_knotvector_v = new_surf.get_knotvector_v().tolist()
            if self.is_cyclic_u:
                u_min = surf_knotvector_u[degree_u]
                u_max = surf_knotvector_u[-degree_u - 2]
                new_surf.u_bounds = u_min, u_max
                #print("U:",new_surf.u_bounds)
            else:
                u_min = min(surf_knotvector_u)
                u_max = max(surf_knotvector_u)
                new_surf.u_bounds = u_min, u_max
            if self.is_cyclic_v:
                v_min = surf_knotvector_v[degree_v]
                v_max = surf_knotvector_v[-degree_v - 2]
                new_surf.v_bounds = v_min, v_max
                #print("V:",new_surf.v_bounds)
            else:
                v_min = min(surf_knotvector_v)
                v_max = max(surf_knotvector_v)
                new_surf.v_bounds = v_min, v_max
            surfaces_out.append(new_surf)

        self.outputs['Surface'].sv_set(surfaces_out)
Exemplo n.º 30
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)