def factorize_nurbs_handles(handles):
    """
    Factorize (n,m,3) handles into a skeleton, radii and relative normalized profiles.

    IE, profiles output will all face x axis, and have mean radius ~= 1
    """

    skeleton_polyline = handles.mean(axis=1)
    tangents = skeleton_to_tangents(skeleton_polyline)

    forward = np.zeros_like(tangents)
    forward[:, 0] = 1
    rot_mats = rotate_match_directions(tangents, forward)

    profiles = handles - skeleton_polyline[:, None]
    profiles = np.einsum("bij,bvj->bvi", rot_mats, profiles)

    ts = np.linspace(0, 1, handles.shape[0])

    return skeleton_polyline, ts, profiles

    Factorize (n,m,3) handles into a skeleton, radii and relative normalized profiles.

    IE, profiles output will all face x axis, and have mean radius ~= 1
    
infinigen/assets/utils/geometry/lofting.py