FME Geometry, PythonCaller, GenerativeArt

#main_script import fmeobjects import numpy as np from fmeobjects import FMELine, FMEPoint, FMEPolygon from scipy.ndimage import gaussian_filter def zigzag(poly, n, amp = 1.0): """Return zigzag polyline with n equal-length steps. poly: (N,2) input polyline, amp: zigzag amplitude.""" seg = np.diff(poly, axis=0) dist = np.r_[0, np.linalg.norm(seg, axis=1).cumsum()] t = np.linspace(0, dist[-1], n + 1) pts = np.column_stack([np.interp(t, dist, poly[:, i]) for i in (0, 1)]) d = np.diff(pts, axis=0) nrm = np.column_stack([-d[:,1], d[:,0]]) nrm /= np.linalg.norm(nrm, axis=1, keepdims=True) pts[1:] += amp * ((-1)**np.arange(n))[:, None] * nrm return pts def organic_polyline(size=100, sigma=5, steps=200): f = gaussian_filter(np.random.rand(size, size), sigma) x = y = size//2; pts=[] for _ in range(steps): if not (0 = int(x) size and 0 = int(y) size): break a = f[int(y), int(x)] * 10*np.pi x += np.cos(a); y += np.sin(a) pts.append((x, y)) return np.array(pts) class FeatureProcessor(object): def __init__(self): pass def input(self, feature: fmeobjects.FMEFeature): # svg_body = create_svg_no_deps(datastructure,'foo') pline = organic_polyline(size=100, sigma=5) pline_input = list(map(tuple, pline)) line1 = FMELine(pline_input) feature.setGeometry(line1) self.pyoutput(feature) _z = zigzag(pline, 100, amp= 3.0) _z_input = list(map(tuple, _z)) line2 = FMELine(_z_input) feature.setGeometry(line2) self.pyoutput(feature)