mascaf.skeleton¶
Graph-based skeleton handler.
Provides a SkeletonGraph class that inherits from networkx.Graph to: - Represent skeleton as a graph with xyz coordinates on each node - Load from polylines array or polylines text format: N x1 y1 z1 x2 y2 z2 … - Identify terminal nodes (degree 1) and branch nodes (degree 3+) - Every point from input polylines becomes a node in the SkeletonGraph
Note: This class represents skeleton topology as a graph where: - Nodes have ‘pos’ attribute with (x, y, z) coordinates - Edges connect consecutive nodes along polylines - Terminal nodes have degree 1 - Branch nodes have degree 3+ - Continuation nodes have degree 2
- class mascaf.skeleton.SkeletonGraph(tolerance=1e-06, **attr)[source]¶
Bases:
Graph3DGraph-based skeleton representation with xyz coordinates on nodes.
Inherits from networkx.Graph. Each node has a ‘pos’ attribute storing (x, y, z) coordinates. Edges represent connections between consecutive points along polylines data.
Every point from input polylines file becomes a node. Endpoints within tolerance are merged into single nodes.
Terminal nodes (degree 1) are isolated endpoints. Branch nodes (degree 3+) are where multiple branches meet. Continuation nodes (degree 2) are intermediate points along branches.
- Parameters:
tolerance (float)
- __init__(tolerance=1e-06, **attr)[source]¶
Initialize a SkeletonGraph.
- Parameters:
tolerance (
float) – Distance threshold below which two endpoints are merged into a single node.**attr – Additional keyword arguments forwarded to the networkx graph constructor as graph-level attributes.
- position_attr = 'pos'¶
- classmethod from_polylines(polylines, tolerance=1e-06)[source]¶
Create a
SkeletonGraphfrom a sequence of polyline arrays.Every point in every polyline becomes a node. Consecutive points within a polyline are connected by edges. Endpoints whose Euclidean distance is less than tolerance are merged into a single node.
- Parameters:
- Returns:
Graph with node positions stored under the
'pos'attribute and edge'length'attributes populated.- Return type:
- classmethod from_txt(path, tolerance=1e-06)[source]¶
Load a SkeletonGraph from a file.
Supports two formats: 1. GraphML format (.graphml or .xml extension) - native graph format 2. Legacy polylines format (.polylines.txt) - for backward compatibility
- Return type:
- Parameters:
- Args:
path: Path to the skeleton file tolerance: Distance threshold for merging nearby endpoints (polylines format only)
- Returns:
SkeletonGraph instance
- detect_branch_points(tolerance=1e-06)[source]¶
Detect branch points and endpoints in the skeleton.
- Note:
SkeletonGraph already merges endpoints within tolerance on import. The tolerance argument is accepted for API compatibility.
- Args:
tolerance: Unused; kept for compatibility.
- Returns:
- Dictionary containing:
‘branch_points’: List of node IDs for branch nodes
‘endpoints’: List of node IDs for terminal nodes
‘branch_locations’: List of 3D coordinates of branch nodes
‘endpoint_locations’: List of 3D coordinates of terminal nodes
- get_branch_point_indices(tolerance=1e-06)[source]¶
Return the set of branch node IDs.
- Args:
tolerance: Unused; kept for compatibility.
- Returns:
Set of node IDs.
- get_true_endpoint_indices(tolerance=1e-06)[source]¶
Return the set of terminal node IDs.
- Args:
tolerance: Unused; kept for compatibility.
- Returns:
Set of node IDs.
- build_graph(tolerance=1e-06)[source]¶
Build a networkx graph representation with node type annotations.
This is primarily a compatibility helper for tests. The returned graph is a plain nx.Graph (not a SkeletonGraph).
- Args:
tolerance: Unused; kept for compatibility.
- Returns:
- A nx.Graph with nodes annotated with:
‘pos’: (x, y, z)
‘type’: ‘endpoint’ | ‘branch’ | ‘continuation’
- prune_short_branches(min_length=None, min_length_fraction=None, tolerance=1e-06, iterative=True, verbose=False)[source]¶
Remove short terminal branches.
A terminal branch is a path from a terminal node (degree 1) to the next non-continuation node (degree != 2). If the path ends at a branch node (degree 3+) and its geometric length is below the threshold, it is removed. Isolated components that connect terminal-to-terminal with no branch nodes are removed regardless of length.
Length is computed from edge lengths (or node coordinates if missing), so “short” refers to geometric length, not node count.
- prune_short_branches_inplace(min_length=None, min_length_fraction=None, tolerance=1e-06, iterative=True, verbose=False)[source]¶
In-place version of prune_short_branches.
- Return type:
- Parameters:
- Returns:
Number of nodes removed.
- to_polylines()[source]¶
Convert the graph back to a list of polyline arrays.
Reconstructs polylines by grouping edges with the same polyline_idx and ordering them by segment_idx, properly handling branch points.
- Returns:
List of (N_i, 3) arrays representing polylines
- to_txt(path)[source]¶
Save the skeleton to a file.
Saves in GraphML format (.graphml) which preserves all graph structure, node positions, and edge metadata. This is the native format for SkeletonGraph.
For legacy polylines format, use to_polylines() and save manually.
- Args:
path: Output file path (will use .graphml extension if not provided)
- copy()[source]¶
Create a deep copy of the skeleton graph.
- Return type:
- Returns:
New SkeletonGraph instance with copied data
- get_statistics()[source]¶
Get statistics about the skeleton graph.
- Return type:
- Returns:
Dictionary with various statistics
- resample(spacing)[source]¶
Resample the skeleton to have approximately uniform spacing between nodes.
Works directly on graph edges, subdividing long edges and preserving topology.
- Return type:
- Parameters:
spacing (float)
- Args:
spacing: Target distance between consecutive nodes
- Returns:
New SkeletonGraph with resampled nodes
- snap_to_mesh_surface(mesh, project_outside_only=True, max_distance=None)[source]¶
Project node positions to the nearest surface point on mesh.
- Args:
mesh: trimesh.Trimesh object project_outside_only: If True, only project points outside the mesh max_distance: If provided, only move points beyond this distance from surface
- Returns:
(n_moved, mean_move_distance) tuple