Skip to content

Instantly share code, notes, and snippets.

@jmpinit
Created March 10, 2024 19:13
Show Gist options
  • Save jmpinit/07ef7820840fdb1e80aa685169d15f7a to your computer and use it in GitHub Desktop.
Save jmpinit/07ef7820840fdb1e80aa685169d15f7a to your computer and use it in GitHub Desktop.
Visit all Houdini points while trying to only follow edges in the input geometry. For Houdini Python node.
import numpy as np
from python_tsp.heuristics import solve_tsp_simulated_annealing
node = hou.pwd()
geo = node.geometry()
def construct_distance_matrix(edges):
# Find the maximum index to determine the size of the matrix
max_index = max(max(edge) for edge in edges)
# Initialize the distance matrix with a large value to discourage leaving existing edges
distance_matrix = np.zeros((max_index + 1, max_index + 1))
distance_matrix.fill(1e9)
# Give the existing edges a low distance
for pt1, pt2 in edges:
# Bidirectional edges
distance_matrix[pt1, pt2] = 1
distance_matrix[pt2, pt1] = 1
# "Trick" the solver to not have to go back to the origin
distance_matrix[:, 0] = 0
return distance_matrix
def find_path(edges):
dist_matrix = construct_distance_matrix(edges)
# Solve the TSP using dynamic programming
path_indices, d = solve_tsp_simulated_annealing(
dist_matrix,
alpha=0.995, # Better solutions, but slower
max_processing_time=3, # Seconds
)
return path_indices
def get_edges(geo):
"""Return 2-tuples describing edges in the input geometry"""
edges = []
for prim in geo.prims():
edge = [pt.number() for pt in list(prim.points())]
assert len(edge) == 2
edges += [edge]
return edges
edges = get_edges(geo)
path = find_path(edges)
# Erase the edges in the input and replace them with a polygon representing our solved path
geo.deletePrims(geo.prims(), True)
line = geo.createPolygon()
for pt_idx in path:
line.addVertex(geo.point(pt_idx))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment