def _BezierInterpolate(pts, n, cache, npts, steps, scale): """Interpolate points cache to bezier curve pts: numpy.ndarray([x, y, 3], dtype='f') array for bezier interpolated control points n: int position in pts array cache: ctypes.POINTER(_ParticleCacheKey) points cache npts: int points number in cache. scale: float interpolation scale factor """ #TODO: First Render -> Cache is Empty, causes Hair only to appear in subsequent renders. #try: for i in range(npts): #print(npts) if cache: c = cache[i] a = _NDARRAY([steps, 3], dtype='f') for j in range(steps): a[j] = c[j].co s = a[1:-1] t = a[2:] - a[:-2] t *= scale / _NORM(t, axis=1)[_S] # tangents m = _NORM(a[1:] - a[:-1], axis=1)[_S] # magnitudes pts[n, ::3] = a pts[n, 1] = a[0] + (a[1] - a[0]) * scale pts[n, -2] = a[-1] - (a[-1] - a[-2]) * scale pts[n, 2:-3:3] = s - t * m[:-1] pts[n, 4::3] = s + t * m[1:] n += 1 # else: # cache = [] # for i in range(npts): # cache.append(i) return n
def _BezierInterpolate(pts, n, cache, npts, steps, scale): """Interpolate points cache to bezier curve pts: numpy.ndarray([x, y, 3], dtype='f') array for bezier interpolated control points n: int position in pts array cache: ctypes.POINTER(_ParticleCacheKey) points cache npts: int points number in cache. scale: float interpolation scale factor """ for i in range(npts): c = cache[i] a = _NDARRAY([steps, 3], dtype='f') for j in range(steps): a[j] = c[j].co s = a[1:-1] t = a[2:] - a[:-2] t *= scale / _NORM(t, axis=1)[_S] # tangents m = _NORM(a[1:] - a[:-1], axis=1)[_S] # magnitudes pts[n, ::3] = a pts[n, 1] = a[0] + (a[1] - a[0]) * scale pts[n, -2] = a[-1] - (a[-1] - a[-2]) * scale pts[n, 2:-3:3] = s - t * m[:-1] pts[n, 4::3] = s + t * m[1:] n += 1 return n
def psys_get_curves(ps, steps, use_parent_particles, props): nch = len(ps.child_particles) if nch == 0 or use_parent_particles: np = len(ps.particles) tot = np + nch if tot <= 0: return None use_parent_particles = True elif nch > 0: tot = nch use_parent_particles = False else: return None _ps = _ParticleSystem.from_address(ps.as_pointer()) n = 0 if props.basis == 'bezier': nsteps = steps * 3 - 2 points = _NDARRAY([tot, nsteps, 3], dtype=numpy.float32) #print(points) scale = props.bezier_scale if use_parent_particles: n = _BezierInterpolate(points, n, _ps.pathcache, np, steps, scale) _BezierInterpolate(points, n, _ps.childcache, nch, steps, scale) radius = numpy.linspace(props.radius_root, props.radius_tip, steps, dtype=numpy.float32) return (points.reshape(-1, 3), numpy.tile(radius, tot), nsteps) if props.basis in {'b-spline', 'catmull-rom'}: points = _NDARRAY([tot * (steps + 4), 3], dtype=numpy.float32) if use_parent_particles: _cache = _ps.pathcache for i in range(np): if _cache: c = _cache[i] points[n:n + 2] = c[0].co n += 2 for j in range(steps): points[n] = c[j].co n += 1 points[n:n + 2] = points[n - 1] n += 2 _cache = _ps.childcache for i in range(nch): if _cache: c = _cache[i] points[n:n + 2] = c[0].co n += 2 for j in range(steps): points[n] = c[j].co n += 1 points[n:n + 2] = points[n - 1] n += 2 radius = numpy.ndarray(steps + 2, dtype=numpy.float32) radius[1:-1] = numpy.linspace(props.radius_root, props.radius_tip, steps, dtype=numpy.float32) radius[0] = 0 radius[-1] = 0 return (points, numpy.tile(radius, tot), steps + 4) if props.basis == 'linear': points = _NDARRAY([tot * steps, 3], dtype=numpy.float32) if use_parent_particles: _cache = _ps.pathcache for i in range(np): if _cache: c = _cache[i] for j in range(steps): points[n] = c[j].co n += 1 _cache = _ps.childcache for i in range(nch): if _cache: c = _cache[i] for j in range(steps): points[n] = c[j].co n += 1 radius = numpy.linspace(props.radius_root, props.radius_tip, steps, dtype=numpy.float32) return (points, numpy.tile(radius, tot), steps) return None
def psys_get_curves(ps, steps, use_parent_particles, props): nch = len(ps.child_particles) if nch == 0 or use_parent_particles: np = len(ps.particles) tot = np + nch if tot <= 0: return None use_parent_particles = True elif nch > 0: tot = nch use_parent_particles = False else: return None _ps = _ParticleSystem.from_address(ps.as_pointer()) n = 0 if props.basis == 'bezier': nsteps = steps * 3 - 2 points = _NDARRAY([tot, nsteps, 3], dtype=numpy.float32) scale = props.bezier_scale if use_parent_particles: n = _BezierInterpolate(points, n, _ps.pathcache, np, steps, scale) _BezierInterpolate(points, n, _ps.childcache, nch, steps, scale) radius = numpy.linspace(props.radius_root, props.radius_tip, steps, dtype=numpy.float32) return (points.reshape(-1, 3), numpy.tile(radius, tot), nsteps) if props.basis in {'b-spline', 'catmull-rom'}: points = _NDARRAY([tot * (steps + 4), 3], dtype=numpy.float32) if use_parent_particles: _cache = _ps.pathcache for i in range(np): c = _cache[i] points[n:n + 2] = c[0].co n += 2 for j in range(steps): points[n] = c[j].co n += 1 points[n:n + 2] = points[n - 1] n += 2 _cache = _ps.childcache for i in range(nch): c = _cache[i] points[n:n + 2] = c[0].co n += 2 for j in range(steps): points[n] = c[j].co n += 1 points[n: n + 2] = points[n - 1] n += 2 radius = numpy.ndarray(steps + 2, dtype=numpy.float32) radius[1:-1] = numpy.linspace(props.radius_root, props.radius_tip, steps, dtype=numpy.float32) radius[0] = 0 radius[-1] = 0 return (points, numpy.tile(radius, tot), steps + 4) if props.basis == 'linear': points = _NDARRAY([tot * steps, 3], dtype=numpy.float32) if use_parent_particles: _cache = _ps.pathcache for i in range(np): c = _cache[i] for j in range(steps): points[n] = c[j].co n += 1 _cache = _ps.childcache for i in range(nch): c = _cache[i] for j in range(steps): points[n] = c[j].co n += 1 radius = numpy.linspace(props.radius_root, props.radius_tip, steps, dtype=numpy.float32) return (points, numpy.tile(radius, tot), steps) return None