def bs_zsurface_read(z_surface_io): io = z_surface_io u_basis = bs.SplineBasis(io.u_degree, io.u_knots) v_basis = bs.SplineBasis(io.v_degree, io.v_knots) z_surf = bs.Surface((u_basis, v_basis), io.poles, io.rational) surf = bs.Z_Surface(io.orig_quad, z_surf) surf.transform(io.xy_map, io.z_map) return surf
def bilinear_surface(vtxs, overhang=0.0): """ Returns B-spline surface of a bilinear surface given by 4 corner points: uv coords: We retun also list of UV coordinates of the given points. :param vtxs: List of tuples (X,Y,Z) :return: ( Surface, vtxs_uv ) """ assert len(vtxs) == 4, "n vtx: {}".format(len(vtxs)) vtxs = np.array(vtxs) if overhang > 0.0: dv = np.roll(vtxs, -1, axis=0) - vtxs dv *= overhang vtxs += np.roll(dv, 1, axis=0) - dv def mid(*idx): return np.mean(vtxs[list(idx)], axis=0) # v - direction v0 -> v2 # u - direction v0 -> v1 poles = [[vtxs[0], mid(0, 3), vtxs[3]], [mid(0, 1), mid(0, 1, 2, 3), mid(2, 3)], [vtxs[1], mid(1, 2), vtxs[2]]] knots = 3 * [0.0 - overhang] + 3 * [1.0 + overhang] basis = bs.SplineBasis(2, knots) surface = bs.Surface((basis, basis), poles) #vtxs_uv = [ (0, 0), (1, 0), (1, 1), (0, 1) ] return surface
def curve_from_grid(points, **kwargs): """ Make a Curve (of degree 3) as an approximation of a sequence of points. :param points - N x D array, D is dimension :param nt Prescribed number of poles of the resulting spline. :return: Curve object. TODO: - Measure efficiency. Estimate how good we can be. Do it our self if we can do at leas 10 times better. - Find out which method is used. Hoschek (4.4.1) refers to several methods how to determine parametrization of the curve, i.e. Find parameters t_i to the given approximation points P_i. - Further on it is not clear what is the mening of the 's' parameter and how one cna influence tolerance and smoothness. - Some sort of adaptivity is used. """ deg = kwargs.get('degree', 3) tol = kwargs.get('tol', 0.01) weights = np.ones(points.shape[0]) weights[0] = weights[-1] = 1000.0 tck = scipy.interpolate.splprep(points.T, k=deg, s=tol, w=weights)[0] knots, poles, degree = tck curve_poles = np.array(poles).T curve_poles[0] = points[0] curve_poles[-1] = points[-1] basis = bs.SplineBasis(degree, knots) curve = bs.Curve(basis, curve_poles) return curve
def line(vtxs): ''' Return B-spline approximation of a line from two points :param vtxs: [ X0, X1 ], Xn are point coordinates in arbitrary dimension D :return: Curve2D ''' assert len(vtxs) == 2 vtxs = np.array(vtxs) mid = np.mean(vtxs, axis=0) poles = [vtxs[0], mid, vtxs[1]] knots = 3 * [0.0] + 3 * [1.0] basis = bs.SplineBasis(2, knots) return bs.Curve(basis, poles)
def curve_from_grid(points, **kwargs): """ Make a Curve (of degree 3) as an approximation of a sequence of points. :param points - N x D array, D is dimension :param nt Prescribed number of poles of the resulting spline. :return: Curve object. """ deg = kwargs.get('degree', 3) tol = kwargs.get('tol', 0.01) weights = np.ones(points.shape[0]) weights[0] = weights[-1] = 1000.0 tck = scipy.interpolate.splprep(points.T, k=deg, s=tol, w=weights)[0] knots, poles, degree = tck basis = bs.SplineBasis(degree, knots) curve = bs.Curve(basis, np.array(poles).T) return curve
def line(vtxs, overhang=0.0): ''' Return B-spline approximation of a line from two points :param vtxs: [ X0, X1 ], Xn are point coordinates in arbitrary dimension D :return: Curve2D ''' assert len(vtxs) == 2 vtxs = np.array(vtxs) if overhang > 0.0: dv = overhang * (vtxs[1] - vtxs[0]) vtxs[0] -= dv vtxs[1] += dv mid = np.mean(vtxs, axis=0) poles = [vtxs[0], mid, vtxs[1]] knots = 3 * [0.0 - overhang] + 3 * [1.0 + overhang] basis = bs.SplineBasis(2, knots) return bs.Curve(basis, poles)