def composite_option(**attrs): attrs.setdefault("help", "Mask: Composite video effect mask") return str_option("--composite", type=click.Choice( [m.name for m in ValueMask.rgb_members()]), **attrs)
def point_distrib_option(**attrs): attrs.setdefault("help", "Voronoi/DLA: Point cloud distribution") return str_option("--point-distrib", type=click.Choice( [m.name for m in PointDistribution] + [m.name for m in ValueMask.nonprocedural_members()] ), default="random", **attrs)
def convolve_option(**attrs): attrs.setdefault("help", "Convolution kernel: May be specified multiple times") return multi_str_option("--convolve", type=click.Choice([ m.name.replace('conv2d_', '') for m in ValueMask.conv2d_members() ]), **attrs)
def point_cloud(freq, distrib=PointDistribution.random, shape=None, corners=False, generations=1, drift=0.0, time=0.0, speed=1.0): """ """ if not freq: return x = [] y = [] if shape is None: width = 1.0 height = 1.0 else: width = shape[1] height = shape[0] if isinstance(distrib, int): if any(d.value == distrib for d in PointDistribution): distrib = PointDistribution(distrib) else: distrib = ValueMask(distrib) elif isinstance(distrib, str): if any(d.name == distrib for d in PointDistribution): distrib = PointDistribution[distrib] else: distrib = ValueMask[distrib] if distrib in ValueMask.procedural_members(): raise Exception( "Procedural ValueMask can't be used as a PointDistribution.") point_func = rand range_x = width * .5 range_y = height * .5 # seen = set() active_set = set() if isinstance(distrib, PointDistribution): if PointDistribution.is_grid(distrib): point_func = square_grid elif distrib == PointDistribution.spiral: point_func = spiral elif PointDistribution.is_circular(distrib): point_func = circular if PointDistribution.is_grid(distrib): active_set.add((0.0, 0.0, 1)) else: active_set.add((range_y, range_x, 1)) else: # Use a ValueMask as a PointDistribution! mask = masks.Masks[distrib] mask_shape = masks.mask_shape(distrib) x_space = shape[1] / mask_shape[1] y_space = shape[0] / mask_shape[0] x_margin = x_space * .5 y_margin = y_space * .5 for _x in range(mask_shape[1]): for _y in range(mask_shape[0]): pixel = mask[_y][_x] if isinstance(pixel, list): pixel = sum(p for p in pixel) if drift: x_drift = simplex.random( time, speed=speed) * drift / freq * shape[1] y_drift = simplex.random( time, speed=speed) * drift / freq * shape[0] else: x_drift = 0 y_drift = 0 if pixel != 0: x.append(int(x_margin + _x * x_space + x_drift)) y.append(int(y_margin + _y * y_space + y_drift)) return x, y seen.update(active_set) while active_set: x_point, y_point, generation = active_set.pop() if generation <= generations: multiplier = max(2 * (generation - 1), 1) _x, _y = point_func(freq=freq, distrib=distrib, corners=corners, center_x=x_point, center_y=y_point, range_x=range_x / multiplier, range_y=range_y / multiplier, width=width, height=height, generation=generation, time=time, speed=speed * .1) for i in range(len(_x)): x_point = _x[i] y_point = _y[i] if (x_point, y_point) in seen: continue seen.add((x_point, y_point)) active_set.add((x_point, y_point, generation + 1)) if drift: x_drift = simplex.random(time, speed=speed) * drift y_drift = simplex.random(time, speed=speed) * drift else: x_drift = 0 y_drift = 0 if shape is None: x_point = (x_point + x_drift / freq) % 1.0 y_point = (y_point + y_drift / freq) % 1.0 else: x_point = int(x_point + (x_drift / freq * shape[1])) % shape[1] y_point = int(y_point + (y_drift / freq * shape[0])) % shape[0] x.append(x_point) y.append(y_point) return (x, y)
def values(freq, shape, distrib=ValueDistribution.normal, corners=False, mask=None, mask_inverse=False, spline_order=3, wavelet=False, time=0.0, speed=1.0): """ """ initial_shape = freq + [shape[-1]] if isinstance(distrib, int): distrib = ValueDistribution(distrib) elif isinstance(distrib, str): distrib = ValueDistribution[distrib] if isinstance(mask, int): mask = ValueMask(mask) elif isinstance(mask, str): mask = ValueMask[mask] if distrib == ValueDistribution.ones: tensor = tf.ones(initial_shape) elif distrib == ValueDistribution.mids: tensor = tf.ones(initial_shape) * .5 elif distrib == ValueDistribution.normal: tensor = tf.random_normal(initial_shape) elif distrib == ValueDistribution.uniform: tensor = tf.random_uniform(initial_shape) elif distrib == ValueDistribution.exp: tensor = tf.cast(tf.stack(np.random.exponential(size=initial_shape)), tf.float32) elif distrib == ValueDistribution.laplace: tensor = tf.cast(tf.stack(np.random.laplace(size=initial_shape)), tf.float32) elif distrib == ValueDistribution.lognormal: tensor = tf.cast(tf.stack(np.random.lognormal(size=initial_shape)), tf.float32) elif distrib == ValueDistribution.column_index: tensor = tf.expand_dims( tf.cast(effects.normalize(effects.column_index(initial_shape)), tf.float32), -1) * tf.ones(initial_shape, tf.float32) elif distrib == ValueDistribution.row_index: tensor = tf.expand_dims( tf.cast(effects.normalize(effects.row_index(initial_shape)), tf.float32), -1) * tf.ones(initial_shape, tf.float32) elif distrib == ValueDistribution.simplex: tensor = simplex.simplex(initial_shape, time=time, speed=speed) elif distrib == ValueDistribution.simplex_exp: tensor = tf.pow(simplex.simplex(initial_shape, time=time, speed=speed), 4) else: raise ValueError("%s (%s) is not a ValueDistribution" % (distrib, type(distrib))) if mask: atlas = None if mask == ValueMask.truetype: from noisemaker.glyphs import load_glyphs atlas = load_glyphs([15, 15, 1]) if not atlas: mask = ValueMask.numeric # Fall back to canned values channel_shape = freq + [1] mask_values, _ = masks.mask_values(mask, channel_shape, atlas=atlas, inverse=mask_inverse, time=time, speed=speed) tensor *= mask_values if wavelet: tensor = effects.wavelet(tensor, initial_shape) tensor = effects.resample(tensor, shape, spline_order=spline_order) if (not corners and (freq[0] % 2) == 0) or (corners and (freq[0] % 2) == 1): tensor = effects.offset(tensor, shape, x=int((shape[1] / freq[1]) * .5), y=int((shape[0] / freq[0]) * .5)) return tensor