Skip to content

Skel: Slice D — Skin weight painting #558

@fernandotonon

Description

@fernandotonon

Parent epic: #554
Depends on: Slice A (#555). Best-with: Paint v2 Slice C (#546).

Goal

Paint skin weights with a proper brush — radius, strength, falloff, symmetry, pressure — plus the standard weight-paint utility ops: normalize, mirror, smooth, lock per-bone. Today's BoneWeightOverlay is read-only; this slice makes it interactive.

Scope

  • New singleton SkinWeightController (src/SkinWeightController.{h,cpp}).
  • Brush integration:
  • Tools:
    • Paint (add to active bone's weight, ramping with strength).
    • Smear / blur (low-pass filter the weights under the brush).
    • Erase (paint zero — bone influence drops to zero, weight redistributed to remaining bones to keep normalized).
    • Fill connected (flood-fill a UV-connected island at the active bone, with falloff from the click point).
  • Utility ops (no brush — applied to selection or whole mesh):
    • Normalize — every vertex's bone weights sum to 1.0.
    • Mirror weights — depends on Slice E's bone naming; mirror weights across an axis using _l/_r (or any configured naming) bone pairs.
    • Smooth weights — Laplacian smoothing over the mesh's vertex adjacency (via HalfEdgeMesh).
    • Lock bone — selected bones can't be modified by paint ops (their weights are frozen; other bones absorb redistributions).
    • Limit weights — clamp each vertex to at most N influences (default 4 — game-engine constraint).
  • Live visualization: extends BoneWeightOverlay to show active bone weight under the cursor (number readout + heatmap toggle).
  • Per-vertex weight inspector: select a vertex (Edit Mode integration), see its bone-weight list, edit a single value numerically.
  • Undo: PaintWeightStrokeCommand (per-stroke, like Paint v2), WeightOpCommand (utility ops). Both mergeable for drags.

Acceptance Criteria

  • Paint weights on a fixture skinned mesh and see immediate deformation change when posing.
  • Normalize, mirror, smooth, lock all work on a fixture and produce expected weight distributions.
  • Limit-weights (4 influences) preserves the largest weights and renormalizes.
  • Per-vertex inspector shows live values and edits round-trip.
  • Active-bone-weight overlay updates as the cursor moves.
  • Mirror requires Slice E plumbing — fall back to "axis-position mirror" if Slice E hasn't landed.
  • All operations undoable.
  • Sentry breadcrumbs scene.skel.weight.*.
  • Headless-CI tests cover normalize, mirror, smooth, lock, limit on a fixture.

Effort

~10 days, plus 2 buffer if BrushEngine integration needs prototype-then-migrate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpaintPaint tools (vertex, texture, projection, layers, brushes)skeletonSkeleton & rigging: bones, weights, IK, constraints, envelopes

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions