Ejemplo n.º 1
0
    def test_interpolate_1(self):
        "NURBS interpolation in 3D"
        points = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0]], dtype=np.float64)
        degree = 2
        curve = interpolate_nurbs_curve(SvNativeNurbsCurve, degree, points)
        ts = np.array([0, 0.5, 1])
        result = curve.evaluate_array(ts)
        self.assert_numpy_arrays_equal(result, points, precision=6)

        ctrlpts = curve.get_control_points()
        expected_ctrlpts = np.array([[0.0, 0.0, 0.0], [1.5, -0.5, 0.0],
                                     [1.0, 1.0, 0.0]])
        self.assert_numpy_arrays_equal(ctrlpts, expected_ctrlpts, precision=6)
Ejemplo n.º 2
0
    def test_interpolate_2(self):
        "NURBS Interpolation in homogenous coordinates"
        points = np.array([[0, 0, 0, 1], [1, 0, 0, 2], [1, 1, 0, 1]],
                          dtype=np.float64)
        degree = 2
        curve = interpolate_nurbs_curve(SvNativeNurbsCurve, degree, points)
        ts = np.array([0, 0.5, 1])
        result = curve.evaluate_array(ts)
        expected = np.array([[0, 0, 0], [0.5, 0, 0], [1, 1, 0]])
        self.assert_numpy_arrays_equal(result, expected, precision=6)

        ctrlpts = curve.get_control_points()
        expected_ctrlpts = np.array([[0.0, 0.0, 0.0], [0.5, -0.16666667, 0.0],
                                     [1.0, 1.0, 0.0]])
        self.assert_numpy_arrays_equal(ctrlpts, expected_ctrlpts, precision=6)

        weights = curve.get_weights()
        expected_weights = np.array([1, 3, 1])
        self.assert_numpy_arrays_equal(weights, expected_weights, precision=6)
Ejemplo n.º 3
0
 def interpolate(cls, degree, points, metric='DISTANCE'):
     return interpolate_nurbs_curve(cls, degree, points, metric)
Ejemplo n.º 4
0
def simple_loft(curves,
                degree_v=None,
                knots_u='UNIFY',
                metric='DISTANCE',
                tknots=None,
                implementation=SvNurbsSurface.NATIVE):
    """
    Loft between given NURBS curves (a.k.a skinning).

    inputs:
    * degree_v - degree of resulting surface along V parameter; by default - use the same degree as provided curves
    * knots_u - one of:
        - 'UNIFY' - unify knotvectors of given curves by inserting additional knots
        - 'AVERAGE' - average knotvectors of given curves; this will work only if all curves have the same number of control points
    * metric - metric for interpolation; most useful are 'DISTANCE' and 'CENTRIPETAL'
    * implementation - NURBS maths implementation

    output: tuple:
        * list of curves - input curves after unification
        * list of NURBS curves along V direction
        * generated NURBS surface.
    """
    if knots_u not in {'UNIFY', 'AVERAGE'}:
        raise Exception(f"Unsupported knots_u option: {knots_u}")
    curve_class = type(curves[0])
    curves = unify_curves_degree(curves)
    if knots_u == 'UNIFY':
        curves = unify_curves(curves)
    else:
        kvs = [len(curve.get_control_points()) for curve in curves]
        max_kv, min_kv = max(kvs), min(kvs)
        if max_kv != min_kv:
            raise Exception(
                f"U knotvector averaging is not applicable: Curves have different number of control points: {kvs}"
            )

    degree_u = curves[0].get_degree()
    if degree_v is None:
        degree_v = degree_u

    if degree_v > len(curves):
        raise Exception(
            f"V degree ({degree_v}) must be not greater than number of curves ({len(curves)}) minus 1"
        )

    src_points = [curve.get_homogenous_control_points() for curve in curves]
    #     lens = [len(pts) for pts in src_points]
    #     max_len, min_len = max(lens), min(lens)
    #     if max_len != min_len:
    #         raise Exception(f"Unify error: curves have different number of control points: {lens}")

    src_points = np.array(src_points)
    #print("Src:", src_points)
    src_points = np.transpose(src_points, axes=(1, 0, 2))

    v_curves = [
        interpolate_nurbs_curve(curve_class,
                                degree_v,
                                points,
                                metric=metric,
                                tknots=tknots) for points in src_points
    ]
    control_points = [
        curve.get_homogenous_control_points() for curve in v_curves
    ]
    control_points = np.array(control_points)
    #weights = [curve.get_weights() for curve in v_curves]
    #weights = np.array([curve.get_weights() for curve in curves]).T
    n, m, ndim = control_points.shape
    control_points = control_points.reshape((n * m, ndim))
    control_points, weights = from_homogenous(control_points)
    control_points = control_points.reshape((n, m, 3))
    weights = weights.reshape((n, m))

    mean_v_vector = control_points.mean(axis=0)
    tknots_v = Spline.create_knots(mean_v_vector, metric=metric)
    knotvector_v = sv_knotvector.from_tknots(degree_v, tknots_v)
    if knots_u == 'UNIFY':
        knotvector_u = curves[0].get_knotvector()
    else:
        knotvectors = np.array([curve.get_knotvector() for curve in curves])
        knotvector_u = knotvectors.mean(axis=0)

    surface = SvNurbsSurface.build(implementation, degree_u, degree_v,
                                   knotvector_u, knotvector_v, control_points,
                                   weights)
    surface.u_bounds = curves[0].get_u_bounds()
    return curves, v_curves, surface