Skip to content

Skeleton Operations

Euler order conversion

# Change all joints at once
bvh_xyz = bvh.change_euler_order("XYZ")

# Change a single joint only
bvh_single = bvh.change_euler_order("XYZ", joint="Hips")

Skeleton scaling

bvh_scaled = bvh.scale(0.01)         # uniform — scales offsets AND root translation
bvh_scaled = bvh.scale([1, 2, 1])    # per-axis

Retargeting

reference = pybvh.read_bvh_file("reference_skeleton.bvh")
bvh_retarget = bvh.retarget(reference)

# With name mapping (when joint names differ)
bvh_retarget = bvh.retarget(reference, name_mapping={
    "Hips": "pelvis", "Spine": "spine_01"
})

Joint extraction

upper = bvh.extract_joints(["Hips", "Spine", "Neck", "Head"])

Frame operations

clip = bvh.slice_frames(10, 50)
combined = bvh.concat(other_bvh)
bvh_30fps = bvh.resample(30)

Pandas integration

import pandas as pd

df = pd.DataFrame(bvh.to_df_dict(mode="euler"))

from pybvh import df_to_bvh
bvh_from_df = df_to_bvh(bvh.nodes, df)

Inplace convention

All mutation methods default to inplace=False (return a new Bvh):

bvh2 = bvh.scale(0.01)                     # new object
bvh.scale(0.01, inplace=True)              # modifies self, returns None