-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbatch_pingpong.py
More file actions
65 lines (52 loc) · 1.72 KB
/
batch_pingpong.py
File metadata and controls
65 lines (52 loc) · 1.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import torch
class BatchPingPong:
"""
Classic ping-pong (reverse) playback for IMAGE batches.
- No smoothing
- No easing
- No turnaround slowdown
- Pure index reversal
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"images": ("IMAGE",),
},
"optional": {
"loop_count": ("INT", {"default": 0, "min": 0, "max": 100, "step": 1}),
}
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "process"
CATEGORY = "🟢 3DVidTools"
def _pingpong_once(self, N: int):
if N <= 1:
return list(range(N))
return list(range(0, N)) + list(range(N - 2, 0, -1))
def _pingpong_loopable(self, N: int):
if N <= 1:
return list(range(N))
return list(range(0, N)) + list(range(N - 2, -1, -1))
def process(self, images, loop_count=0):
if not isinstance(images, torch.Tensor):
raise TypeError("images must be a torch.Tensor")
if images.dim() != 4:
raise ValueError(f"Expected images [N,H,W,C], got {tuple(images.shape)}")
N = int(images.shape[0])
if N <= 1:
return (images,)
loops = max(0, int(loop_count))
if loops == 0:
idx = self._pingpong_once(N)
else:
unit = self._pingpong_loopable(N)
idx = []
for i in range(loops + 1):
if i == 0:
idx.extend(unit)
else:
idx.extend(unit[1:] if len(unit) > 1 else unit)
idx_t = torch.tensor(idx, device=images.device, dtype=torch.long)
out = images.index_select(0, idx_t)
return (out,)