Graph Processing Tutorial¶
This tutorial covers working with spatial graphs in PyGEL3D.
Creating Graphs¶
From Scratch¶
import pygel3d.graph as graph
# Create empty graph
g = graph.Graph()
# Add nodes
n0 = g.add_node([0, 0, 0])
n1 = g.add_node([1, 0, 0])
n2 = g.add_node([0.5, 1, 0])
# Connect nodes
g.connect_nodes(n0, n1)
g.connect_nodes(n1, n2)
g.connect_nodes(n2, n0)
print(f"Created graph with {len(g.nodes())} nodes")
From Mesh¶
import pygel3d.hmesh as hmesh
import pygel3d.graph as graph
# Load mesh
m = hmesh.load("model.obj")
# Extract skeleton graph
g = graph.from_mesh(m)
Graph Queries¶
Node Information¶
# Get all node IDs
nodes = g.nodes()
# Get node positions
positions = g.positions() # Flat array: [x0,y0,z0, x1,y1,z1, ...]
# Get neighbors
neighbors = g.neighbors(node_id, mode='n')
# Check if node exists
if g.node_in_use(node_id):
print("Node exists")
Graph Statistics¶
Graph Processing¶
Smoothing¶
Pruning¶
Edge Contraction¶
# Contract edges shorter than threshold
num_contracted = graph.edge_contract(g, threshold=0.1)
print(f"Contracted {num_contracted} edges")
Graph to Mesh Conversion¶
Cylindrical Mesh¶
import pygel3d.hmesh as hmesh
import pygel3d.graph as graph
# Load graph
g = graph.load("skeleton.graph")
# Convert to cylindrical mesh
m = hmesh.graph_to_cylinders(g, fudge=0.5)
# Save result
hmesh.save("skeleton_mesh.obj", m)
Complete Workflow¶
import pygel3d.hmesh as hmesh
import pygel3d.graph as graph
import pygel3d.gl_display as gl
# 1. Load mesh
m = hmesh.load("model.obj")
# 2. Extract skeleton
g = graph.from_mesh(m)
print(f"Initial: {len(g.nodes())} nodes")
# 3. Process graph
graph.smooth(g, num_iter=10, alpha=0.5)
graph.prune(g)
contracted = graph.edge_contract(g, dist_thresh=0.01)
print(f"After processing: {len(g.nodes())} nodes")
# 4. Save graph
graph.save("skeleton.graph", g)
# 5. Convert to mesh for visualization
skeleton_mesh = hmesh.graph_to_cylinders(g, fudge=0.5)
# 6. Visualize
viewer = gl.Viewer()
viewer.display(skeleton_mesh, mode='w')
See the Graph API Reference for complete documentation.