FME Geometry, PythonCaller, GenerativeArt
#main_script
import fmeobjects
import numpy as np
from fmeobjects import FMELine, FMEPoint, FMEPolygon
import math
from sklearn.cluster import KMeans
from sklearn.neighbors import KDTree
from sklearn.manifold import TSNE
def generate_tsne_network(n_points=200, n_clusters=5, n_neighbors=3,
n_dims_raw=7, perplexity=30, seed=42):
rng = np.random.RandomState(seed)
raw_points = rng.randn(n_points, n_dims_raw)
labels = KMeans(n_clusters=n_clusters, random_state=seed, n_init=4)\
.fit_predict(raw_points)
tree = KDTree(raw_points)
_, indices = tree.query(raw_points, k=n_neighbors + 1)
edges_idx = set()
for i, neighbors in enumerate(indices):
for j in neighbors[1:]:
edges_idx.add((min(i, j), max(i, j)))
tsne = TSNE(n_components=2, perplexity=perplexity, random_state=seed)
points_2d = tsne.fit_transform(raw_points)
edges = []
for i, j in edges_idx:
x1, y1 = points_2d[i]
x2, y2 = points_2d[j]
# orthogonal routing
mid = (x2, y1)
edges.append(((float(x1), float(y1)), (float(mid[0]), float(mid[1]))))
edges.append(((float(mid[0]), float(mid[1])), (float(x2), float(y2))))
return edges
class FeatureProcessor(object):
def __init__(self):
pass
def input(self, feature: fmeobjects.FMEFeature):
lines = generate_tsne_network(n_points=133, n_clusters=5, n_neighbors=3,
n_dims_raw=2, perplexity=3, seed=42)
# output the star boundary
for i,line in enumerate(lines):
tri_ring = (list(map(tuple, line)))
tri_line = FMELine([tuple(p) for p in tri_ring])
out_feat = fmeobjects.FMEFeature(feature)
out_feat.setGeometry(tri_line)
self.pyoutput(out_feat)