FME Geometry, PythonCaller, GenerativeArt

#main_script import fmeobjects import numpy as np from fmeobjects import FMELine, FMEPoint, FMEPolygon import math from sklearn.decomposition import PCA from sklearn.metrics.pairwise import rbf_kernel STEP = 1 """ Generate a noisyline using scikit learn make sliding windows """ def smooth_polyline(n=200, scale=10, seed=0): rng = np.random.RandomState(seed) # parameter along the line t = np.linspace(0, 5, n)[:, None] # random noise in higher dimensions noise = rng.randn(n, 4) # smooth the noise using a Gaussian kernel (Perlin-like) K = rbf_kernel(t, t, gamma=1/scale) smooth_noise = np.dot(K, noise) # combine structure + smooth noise data = np.column_stack([t.ravel(), smooth_noise]) # project to 2D pts = PCA(n_components=2).fit_transform(data) return pts class FeatureProcessor(object): def __init__(self): pass def input(self, feature: fmeobjects.FMEFeature): lines = smooth_polyline(n=200, scale=10, seed=0) pline_input = list(map(tuple, lines)) # output the star boundary tri_line = FMELine(pline_input) out_feat = fmeobjects.FMEFeature(feature) out_feat.setGeometry(tri_line) self.pyoutput(out_feat) _geom = out_feat.getGeometry() length = int(_geom.getLength(False)) _step = STEP _sequence = [(i, min(i + _step, length)) for i in range(0, length, _step)] group_size =5 for i, j in enumerate(_sequence): # crucial step to workaround # inplace geom modification _clone = out_feat.clone() end = j[-1] start = j[0] seq_group_floating = end // group_size _clone.setAttribute('end',end) _clone.setAttribute('start',start) _clone.setAttribute('seq_num',i) _clone.setAttribute('seq_group2',seq_group_floating) _clone.performFunction(f"@Snip({start}, {end}, 1)") _clone_geom = _clone.getGeometry() _clone_start_point = _clone_geom.getStartPoint() _clone.getGeometry().rotate2D(_clone_start_point, 10.0) self.pyoutput(_clone) # little barrie here n = round(length) sequence = list(range(n)) window_size = 5 step = 4 result = [ sequence[i:i + window_size] for i in range(0, n, step) ]