Esempio n. 1
0
 def __init__(self,
              degree_u,
              degree_v,
              knotvector_u,
              knotvector_v,
              control_points,
              weights,
              normalize_knots=False):
     self.degree_u = degree_u
     self.degree_v = degree_v
     self.knotvector_u = np.array(knotvector_u)
     self.knotvector_v = np.array(knotvector_v)
     if normalize_knots:
         self.knotvector_u = sv_knotvector.normalize(self.knotvector_u)
         self.knotvector_v = sv_knotvector.normalize(self.knotvector_v)
     self.control_points = np.array(control_points)
     c_ku, c_kv, _ = self.control_points.shape
     if weights is None:
         self.weights = weights = np.ones((c_ku, c_kv))
     else:
         self.weights = np.array(weights)
         w_ku, w_kv = self.weights.shape
         if c_ku != w_ku or c_kv != w_kv:
             raise Exception(
                 f"Shape of control_points ({c_ku}, {c_kv}) does not match to shape of weights ({w_ku}, {w_kv})"
             )
     self.basis_u = SvNurbsBasisFunctions(knotvector_u)
     self.basis_v = SvNurbsBasisFunctions(knotvector_v)
     self.u_bounds = (self.knotvector_u.min(), self.knotvector_u.max())
     self.v_bounds = (self.knotvector_v.min(), self.knotvector_v.max())
     self.normal_delta = 0.0001
     self.__description__ = f"Native NURBS (degree={degree_u}x{degree_v}, pts={self.control_points.shape[0]}x{self.control_points.shape[1]})"
Esempio n. 2
0
def interpolate_nurbs_curve(cls,
                            degree,
                            points,
                            metric='DISTANCE',
                            tknots=None):
    n = len(points)
    if points.ndim != 2:
        raise Exception(
            f"Array of points was expected, but got {points.shape}: {points}")
    ndim = points.shape[1]  # 3 or 4
    if ndim not in {3, 4}:
        raise Exception(
            f"Only 3D and 4D points are supported, but ndim={ndim}")
    #points3d = points[:,:3]
    #print("pts:", points)
    if tknots is None:
        tknots = Spline.create_knots(
            points, metric=metric)  # In 3D or in 4D, in general?
    knotvector = sv_knotvector.from_tknots(degree, tknots)
    functions = SvNurbsBasisFunctions(knotvector)
    coeffs_by_row = [
        functions.function(idx, degree)(tknots) for idx in range(n)
    ]
    A = np.zeros((ndim * n, ndim * n))
    for equation_idx, t in enumerate(tknots):
        for unknown_idx in range(n):
            coeff = coeffs_by_row[unknown_idx][equation_idx]
            row = ndim * equation_idx
            col = ndim * unknown_idx
            for d in range(ndim):
                A[row + d, col + d] = coeff
    B = np.zeros((ndim * n, 1))
    for point_idx, point in enumerate(points):
        row = ndim * point_idx
        B[row:row + ndim] = point[:, np.newaxis]

    x = np.linalg.solve(A, B)

    control_points = []
    for i in range(n):
        row = i * ndim
        control = x[row:row + ndim, 0].T
        control_points.append(control)
    control_points = np.array(control_points)
    if ndim == 3:
        weights = np.ones((n, ))
    else:  # 4
        control_points, weights = from_homogenous(control_points)

    if type(cls) == type:
        return cls.build(cls.get_nurbs_implementation(), degree, knotvector,
                         control_points, weights)
    elif isinstance(cls, str):
        return SvNurbsMaths.build_curve(cls, degree, knotvector,
                                        control_points, weights)
    else:
        raise TypeError(f"Unsupported type of `cls` parameter: {type(cls)}")
Esempio n. 3
0
 def __init__(self, degree_u, degree_v, knotvector_u, knotvector_v,
              control_points, weights):
     self.degree_u = degree_u
     self.degree_v = degree_v
     self.knotvector_u = np.array(knotvector_u)
     self.knotvector_v = np.array(knotvector_v)
     self.control_points = np.array(control_points)
     self.weights = np.array(weights)
     c_ku, c_kv, _ = self.control_points.shape
     w_ku, w_kv = self.weights.shape
     if c_ku != w_ku or c_kv != w_kv:
         raise Exception(
             f"Shape of control_points ({c_ku}, {c_kv}) does not match to shape of weights ({w_ku}, {w_kv})"
         )
     self.basis_u = SvNurbsBasisFunctions(knotvector_u)
     self.basis_v = SvNurbsBasisFunctions(knotvector_v)
     self.u_bounds = (self.knotvector_u.min(), self.knotvector_u.max())
     self.v_bounds = (self.knotvector_v.min(), self.knotvector_v.max())
     self.normal_delta = 0.0001
Esempio n. 4
0
    def interpolate_list(cls, degree, points, metric='DISTANCE'):
        n_curves, n_points, _ = points.shape
        tknots = [
            Spline.create_knots(points[i], metric=metric)
            for i in range(n_curves)
        ]
        knotvectors = [
            sv_knotvector.from_tknots(degree, tknots[i])
            for i in range(n_curves)
        ]
        functions = [
            SvNurbsBasisFunctions(knotvectors[i]) for i in range(n_curves)
        ]
        coeffs_by_row = [[
            functions[curve_idx].function(idx, degree)(tknots[curve_idx])
            for idx in range(n_points)
        ] for curve_idx in range(n_curves)]
        coeffs_by_row = np.array(coeffs_by_row)
        A = np.zeros((n_curves, 3 * n_points, 3 * n_points))
        for curve_idx in range(n_curves):
            for equation_idx, t in enumerate(tknots[curve_idx]):
                for unknown_idx in range(n_points):
                    coeff = coeffs_by_row[curve_idx][unknown_idx][equation_idx]
                    row = 3 * equation_idx
                    col = 3 * unknown_idx
                    A[curve_idx, row, col] = A[curve_idx, row + 1,
                                               col + 1] = A[curve_idx, row + 2,
                                                            col + 2] = coeff

        B = np.zeros((n_curves, 3 * n_points, 1))
        for curve_idx in range(n_curves):
            for point_idx, point in enumerate(points[curve_idx]):
                row = 3 * point_idx
                B[curve_idx, row:row + 3] = point[:, np.newaxis]

        x = np.linalg.solve(A, B)

        curves = []
        weights = np.ones((n_points, ))
        for curve_idx in range(n_curves):
            control_points = []
            for i in range(n_points):
                row = i * 3
                control = x[curve_idx][row:row + 3, 0].T
                control_points.append(control)
            control_points = np.array(control_points)

            curve = SvNurbsCurve.build(cls.get_nurbs_implementation(), degree,
                                       knotvectors[curve_idx], control_points,
                                       weights)
            curves.append(curve)

        return curves
Esempio n. 5
0
 def __init__(self, degree, knotvector, control_points, weights=None):
     self.control_points = np.array(control_points) # (k, 3)
     k = len(control_points)
     if weights is not None:
         self.weights = np.array(weights) # (k, )
     else:
         self.weights = np.ones((k,))
     self.knotvector = np.array(knotvector)
     self.degree = degree
     self.basis = SvNurbsBasisFunctions(knotvector)
     self.tangent_delta = 0.001
     self.__description__ = f"Native NURBS (degree={degree}, pts={k})"