Update & de-duplicate skeleton builder by C-Achard · Pull Request #3258 · DeepLabCut/DeepLabCut
Switch YAML usage to YAML(typ="rt") with explicit UTF-8 encoding for read/write to avoid encoding issues and make config I/O consistent. Replace scipy.spatial.cKDTree alias with KDTree import and adjust on_pick to correctly identify and discard the clicked segment and its sorted index pair, update the LineCollection and trigger a canvas redraw. Ensure skeleton pairs are written in a consistent order by sorting indices before saving. Minor cleanup: comment out unused path/verts assignments in on_select and add a TODO note about duplicate config functions.
Extract and decouple skeleton-building logic into deeplabcut.utils.skeleton.SkeletonBuilder and adapt the GUI to reuse it. The widgets.SkeletonBuilder now subclasses the new BaseSkeletonBuilder and Qt dialog, delegating setup to BaseSkeletonBuilder.__init__ and providing GUI-specific build_ui/display implementations. The core builder no longer calls plt.show() directly; it exposes build_ui() and display() so different frontends (matplotlib or Qt) can control presentation. Also fixed/clarified pick_labeled_frame grouping logic for 'individuals' columns and replaced immediate show() calls with canvas.draw_idle() in the Qt UI. Minor cleanup and UI wiring changes to support the refactor.
Introduce tests/utils/test_skeleton.py containing unit tests for the skeleton builder utilities. Covers pick_labeled_frame (multi-animal drop and no-individual fallback), clear (resetting indices, segments, and LineCollection), export (sorting pairs, writing config, and warning on unconnected bodyparts), on_select (adding pairs/segments, ignoring duplicate hits), on_pick (removing segments on right-click only), and lightweight SkeletonBuilder.__init__ integration (loading dataframe/image and error when no labeled data). Tests use KDTree, LineCollection, pandas/numpy, and monkeypatching to isolate I/O and rendering.
Add read_config/write_config hooks to GUI and core SkeletonBuilder to centralize config IO and ensure skeleton pairs are normalized to plain lists before writing. Update export to call the instance write_config, and make clear() reset the LineCollection to an empty list and trigger a canvas redraw to avoid stale drawing state. Add a simple dev test script (dev/test_skeleton.py) and adjust the unit test to attach a fake canvas before calling clear().
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters