diff --git a/darkdraw/load_dur.py b/darkdraw/load_dur.py index f36eb97..bbd3dbf 100644 --- a/darkdraw/load_dur.py +++ b/darkdraw/load_dur.py @@ -78,6 +78,72 @@ def open_dur(vd, p): ) rows.append(d) + frame_ids = {r['id'] for r in rows if r.get('type') == 'frame'} + frame_rows = [r for r in rows if r.get('type') == 'frame'] + + # Merge duplicate elements across frames + merged = {} # (x, y, text, color) -> set of frame ids + for r in rows: + if r.get('type') == 'frame': + continue + key = (r['x'], r['y'], r['text'], r['color']) + merged.setdefault(key, set()).add(r['frame']) + + element_rows = [] + for (x, y, text, color), frames in merged.items(): + d = dict(x=x, y=y, text=text, color=color) + if frames != frame_ids: + d['frame'] = ' '.join(sorted(frames, key=int)) + element_rows.append(d) + + rows = frame_rows + element_rows + + rows = _combine_duplicate_frames(rows) + ddwoutput = '\n'.join(json.dumps(r) for r in rows) + '\n' return DrawingSheet(p.name, source=Path(str(p.with_suffix('.ddw')), fptext=io.StringIO(ddwoutput))).drawing + + +def _combine_duplicate_frames(rows): + 'Replace later duplicate frames with another instance of the first matching frame.' + def sig(fid): + return frozenset( + (r['x'], r['y'], r['text'], r['color']) + for r in rows + if not r.get('type') and fid in r.get('frame', '').split() + ) + + sigs = {} + rename_map = {} # dup_id -> first_id + for r in rows: + if r.get('type') != 'frame': continue + s = sig(r['id']) + if not s: continue + if s in sigs: + rename_map[r['id']] = sigs[s] + else: + sigs[s] = r['id'] + + if not rename_map: return rows + + out = [] + dup_ids = set(rename_map) + for r in rows: + if r.get('type') == 'frame': + if r['id'] in dup_ids: + r = {**r, 'id': rename_map[r['id']]} + out.append(r) + else: + ids = r.get('frame', '').split() + if not ids: + out.append(r) + continue + new_ids = [x for x in ids if x not in dup_ids] + if not new_ids: + continue + if new_ids == ids: + out.append(r) + else: + out.append({**r, 'frame': ' '.join(new_ids)}) + return out