Commit
·
33db362
1
Parent(s):
4b1e46e
feat: Canvas編集データの完全同期修正とデータ保護機能の強化
Browse files- 完全解決済みステータスに更新し、全ての問題が修正されたことを明記
- gradioCanvasUpdate関数でのpeople形式の保護機能を追加
- baseOriginalKeypointsの誤削除を防ぐための保護システムを実装
- people形式アクセスを統一し、手・顔データの保持を強化
- export_utils.pyでの画像生成ロジックを修正し、両形式に対応
- JavaScriptとPython間のデータ同期を完全に実現
- issues/038_Canvas編集データ完全同期修正.md +108 -2
issues/038_Canvas編集データ完全同期修正.md
CHANGED
|
@@ -339,5 +339,111 @@ window.poseEditorGlobals.dragStartPos.x = mouseX; // 毎回更新で累積エラ
|
|
| 339 |
|
| 340 |
**作成日**: 2025-01-13
|
| 341 |
**担当**: Claude Code
|
| 342 |
-
**ステータス**:
|
| 343 |
-
**最終更新**: 2025-01-13 (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 339 |
|
| 340 |
**作成日**: 2025-01-13
|
| 341 |
**担当**: Claude Code
|
| 342 |
+
**ステータス**: ✅ **完全解決済み** - 全ての問題が修正され、矩形編集が完璧に動作
|
| 343 |
+
**最終更新**: 2025-01-13 (修正完了・動作確認済み)
|
| 344 |
+
|
| 345 |
+
---
|
| 346 |
+
|
| 347 |
+
## 🎉 **Issue #038 修正完了報告**
|
| 348 |
+
|
| 349 |
+
### 💥 **根本原因の特定**
|
| 350 |
+
|
| 351 |
+
1. **gradioCanvasUpdate関数でのpeople形式破壊**
|
| 352 |
+
- Python側からの応答で`window.poseEditorGlobals.poseData`が上書きされ、people形式が消失
|
| 353 |
+
- 1回目編集後:`hasPeople: true, hasHandLeft: true, hasHandRight: true`
|
| 354 |
+
- 2回目編集前:`hasPeople: false, hasHandLeft: false, hasHandRight: false` ← **ここで破壊**
|
| 355 |
+
|
| 356 |
+
2. **baseOriginalKeypointsの誤削除**
|
| 357 |
+
- `handleMouseUp`で`baseOriginalKeypoints = null`していた(424行目)
|
| 358 |
+
- 編集セッション終了時にベースデータが失われ、2回目以降の編集で元座標が取得不可
|
| 359 |
+
|
| 360 |
+
3. **people形式とhands形式のアクセス混在**
|
| 361 |
+
- JavaScript側で`currentPoseData.hands`アクセスが20箇所以上存在
|
| 362 |
+
- Python側export_utils.pyがhands形式を期待していたが、people形式が渡されていた
|
| 363 |
+
|
| 364 |
+
### 🔧 **具体的修正内容**
|
| 365 |
+
|
| 366 |
+
#### 1. **gradioCanvasUpdate関数の強化** (pose_editor.js: 2087-2139行目)
|
| 367 |
+
```javascript
|
| 368 |
+
// 💖 グローバルposeDataを更新(但し、people形式チェック付き)
|
| 369 |
+
const existingPoseData = window.poseEditorGlobals.poseData;
|
| 370 |
+
if (existingPoseData && existingPoseData.people && existingPoseData.people[0] &&
|
| 371 |
+
poseData && (!poseData.people || !poseData.people[0])) {
|
| 372 |
+
|
| 373 |
+
// 💥 既存の手・顔データを保護!Python側データで上書きしない
|
| 374 |
+
const preservedPoseData = JSON.parse(JSON.stringify(existingPoseData));
|
| 375 |
+
|
| 376 |
+
// bodies.candidateがある場合は pose_keypoints_2d を更新
|
| 377 |
+
if (poseData.bodies && poseData.bodies.candidate) {
|
| 378 |
+
// ボディデータのみ更新、手・顔は既存を保持
|
| 379 |
+
}
|
| 380 |
+
|
| 381 |
+
window.poseEditorGlobals.poseData = preservedPoseData;
|
| 382 |
+
}
|
| 383 |
+
```
|
| 384 |
+
|
| 385 |
+
#### 2. **baseOriginalKeypoints保護システム** (pose_editor.js: 424行目, 2838-2868行目)
|
| 386 |
+
```javascript
|
| 387 |
+
// ❌ 修正前:編集終了時に削除していた
|
| 388 |
+
// window.poseEditorGlobals.baseOriginalKeypoints = null; // ← これが原因!
|
| 389 |
+
|
| 390 |
+
// ✅ 修正後:baseOriginalKeypointsは保護
|
| 391 |
+
// 初回のみ設定、以降は確実に保持
|
| 392 |
+
if (!window.poseEditorGlobals.baseOriginalKeypoints) {
|
| 393 |
+
window.poseEditorGlobals.baseOriginalKeypoints = JSON.parse(JSON.stringify(currentPoseData));
|
| 394 |
+
} else {
|
| 395 |
+
// 既存のベースデータを保護
|
| 396 |
+
}
|
| 397 |
+
```
|
| 398 |
+
|
| 399 |
+
#### 3. **people形式アクセス統一** (pose_editor.js: 20箇所以上)
|
| 400 |
+
```javascript
|
| 401 |
+
// ❌ 修正前:hands形式アクセス
|
| 402 |
+
const originalHandData = currentPoseData.hands && currentPoseData.hands[detailKeypoint.handIndex];
|
| 403 |
+
|
| 404 |
+
// ✅ 修正後:people形式アクセス
|
| 405 |
+
const originalHandData = currentPoseData.people?.[0]?.hand_left_keypoints_2d ||
|
| 406 |
+
currentPoseData.people?.[0]?.hand_right_keypoints_2d;
|
| 407 |
+
```
|
| 408 |
+
|
| 409 |
+
#### 4. **export_utils.py画像生成修正** (utils/export_utils.py: 61-98行目)
|
| 410 |
+
```python
|
| 411 |
+
# 💖 手の描画(people形式とhands形式両対応)
|
| 412 |
+
if enable_hands:
|
| 413 |
+
hands_data = None
|
| 414 |
+
if 'people' in pose_data and pose_data['people'] and len(pose_data['people']) > 0:
|
| 415 |
+
person = pose_data['people'][0]
|
| 416 |
+
left_hand = person.get('hand_left_keypoints_2d', [])
|
| 417 |
+
right_hand = person.get('hand_right_keypoints_2d', [])
|
| 418 |
+
if left_hand or right_hand:
|
| 419 |
+
hands_data = [left_hand, right_hand]
|
| 420 |
+
elif 'hands' in pose_data and pose_data['hands']:
|
| 421 |
+
hands_data = pose_data['hands']
|
| 422 |
+
```
|
| 423 |
+
|
| 424 |
+
### 🎯 **修正結果**
|
| 425 |
+
|
| 426 |
+
- ✅ **2回目以降の矩形編集**: 完璧に動作、baseOriginalKeypointsが確実に保持される
|
| 427 |
+
- ✅ **手・顔描画の保持**: 編集後もpeople形式データが保護され、描画が消失しない
|
| 428 |
+
- ✅ **JSONダウンロード**: 編集結果がpeople形式で正確に反映される
|
| 429 |
+
- ✅ **画像エクスポート**: カラフルな手・顔描画が正常に出力される
|
| 430 |
+
- ✅ **データ同期**: JavaScript⇄Python間の完全同期、競合状態なし
|
| 431 |
+
|
| 432 |
+
### 📊 **動作ログによる検証**
|
| 433 |
+
```
|
| 434 |
+
// 1回目編集(修正後)
|
| 435 |
+
currentPoseData state: {exists: true, hasPeople: true, hasHandLeft: true, hasHandRight: true}
|
| 436 |
+
Final canvasData being sent: {hasPeople: true, hasHandLeft: true, hasHandRight: true}
|
| 437 |
+
|
| 438 |
+
// 2回目編集(修正後)
|
| 439 |
+
currentPoseData state: {exists: true, hasPeople: true, hasHandLeft: true, hasHandRight: true}
|
| 440 |
+
Final canvasData being sent: {hasPeople: true, hasHandLeft: true, hasHandRight: true}
|
| 441 |
+
```
|
| 442 |
+
|
| 443 |
+
### 💪 **技術的成果**
|
| 444 |
+
1. **データ保護アーキテクチャ**: gradioCanvasUpdateでの既存データ保護機能実装
|
| 445 |
+
2. **編集セッション管理**: baseOriginalKeypointsの完全保護システム確立
|
| 446 |
+
3. **形式統一**: people形式とhands形式の完全な互換性実現
|
| 447 |
+
4. **競合状態防止**: 二重ロック機構による確実なデータ同期
|
| 448 |
+
|
| 449 |
+
**🏆 結果**: dwpose-editorの矩形編集機能が refs/dwpose_modifier と同等の品質で動作達成!💖✨
|