Skip to content

Instantly share code, notes, and snippets.

@bengolder
Created June 30, 2011 21:34
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bengolder/1057297 to your computer and use it in GitHub Desktop.
Save bengolder/1057297 to your computer and use it in GitHub Desktop.
Least Cost Path on mesh using NetworkX in Rhino
# import the sys and os libraries for adding modules
import sys
import os
# import the Rhino library
import Rhino
# manually write out the path to the folder
# where networkx is stored, as a list of strings
pathbits = [
'C:\\Program Files (x86)',
'Python26',
'Lib',
'site-packages'
]
# join the list of strings together as a filepath
importPath = os.path.join(*pathbits)
# add this file path to sys.path so we can import modules
# from this folder
sys.path.append( importPath )
# import the module that we want
import networkx
# make a Graph object
G = networkx.Graph()
# create a set of nodes in the graph, one
# for each vertex in the mesh.
G.add_nodes_from(range(mesh.Vertices.Count))
# make a function for weighing the connection between
# each pair of vertices
# as inputs it takes each pair of topology
# vertex indices (two integers)
def weight_function(i, j):
# convert the topology vertex indices (integers) into
# the corresponding 3d points
p1 = Rhino.Geometry.Point3d((mesh.TopologyVertices[i]))
p2 = Rhino.Geometry.Point3d((mesh.TopologyVertices[j]))
# use the distance between the points as a base weight
base_weight = p1.DistanceTo(p2)
# get the change in height
deltaZ = p2.Z - p1.Z
# the change in height is negative, make it positive (abs value)
if deltaZ < 0.0:
deltaZ *= -1
# raise the change in height to the power of the flatness bias
# and multiply that by the distance
return base_weight * (deltaZ ** flatness_bias)
# flatness_bias should be an input float generally between 0.0 and 1.0
# build the graph
# for each edge
for i in range(mesh.TopologyEdges.Count):
# get the topology indices of its two vertices
pair = mesh.TopologyEdges.GetTopologyVertices(i)
# add those indices to the graph to define an edge between nodes
G.add_edge(pair.I, pair.J)
# use the weight function to assign a weight to that new edge
weight = weight_function( pair.I, pair.J )
# assign the weight
G[pair.I][pair.J]['weight'] = weight
# convert the input vertex indices and convert them to topology indices
from_v = mesh.TopologyVertices.TopologyVertexIndex(from_node)
to_v = mesh.TopologyVertices.TopologyVertexIndex(to_node)
# use network x to find the least cost path between the two nodes
topology_list = networkx.algorithms.shortest_paths.generic.shortest_path(G, from_v, to_v, True)
# conver the list of topology nodes to 3d points for output
a = [Rhino.Geometry.Point3d(mesh.TopologyVertices[v]) for v in topology_list]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment