Created
March 10, 2024 19:13
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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