-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathk_easy_track.py
More file actions
106 lines (89 loc) · 3.74 KB
/
Copy pathk_easy_track.py
File metadata and controls
106 lines (89 loc) · 3.74 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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
from __future__ import annotations
from pathlib import Path
from typing import List
COLUMN_COUNT = 19
DEFAULT_POSE_WIDTH = 1280.0
DEFAULT_POSE_HEIGHT = 720.0
def _parse_pose_line(line: str, line_number: int) -> List[float]:
tokens = line.strip().split()
if len(tokens) != COLUMN_COUNT:
raise ValueError(
f"Line {line_number} expected {COLUMN_COUNT} values but found {len(tokens)}."
)
try:
return [float(token) for token in tokens]
except ValueError as exc:
raise ValueError(f"Line {line_number} contains a non-numeric value.") from exc
class KoolookLoadCameraPosesAbsolute:
"""
Loads RealEstate10k-style camera pose TXT files from any absolute path without ComfyUI's
built-in strip_path restrictions. The file format matches the AnimateDiff CameraCtrl loader:
line 1 is metadata, and each following line contains 19 space-separated floats describing
timestamp, intrinsics, original width/height placeholders, and the flattened 3x4 pose.
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"file_path": (
"STRING",
{
"default": "input/poses/example_track.txt",
"multiline": False,
"tooltip": "Absolute or user-expanded path to a RealEstate10k-style CameraCtrl pose TXT file.",
},
),
},
"optional": {
"pose_width": (
"FLOAT",
{
"default": DEFAULT_POSE_WIDTH,
"min": 1.0,
"max": 16384.0,
"step": 1.0,
"tooltip": "Width value written into each pose row before returning CAMERACTRL_POSES.",
},
),
"pose_height": (
"FLOAT",
{
"default": DEFAULT_POSE_HEIGHT,
"min": 1.0,
"max": 16384.0,
"step": 1.0,
"tooltip": "Height value written into each pose row before returning CAMERACTRL_POSES.",
},
),
},
}
RETURN_TYPES = ("CAMERACTRL_POSES",)
FUNCTION = "load_camera_poses"
CATEGORY = "Koolook/Camera"
DESCRIPTION = "Load CameraCtrl poses from a RealEstate10k-style TXT file located anywhere on disk."
def load_camera_poses(self, file_path: str, pose_width: float = DEFAULT_POSE_WIDTH, pose_height: float = DEFAULT_POSE_HEIGHT):
normalized_path = Path(file_path).expanduser()
if not normalized_path.is_file():
raise FileNotFoundError(f"Pose file not found: {normalized_path}")
with normalized_path.open("r", encoding="utf-8") as fh:
lines = fh.read().splitlines()
if len(lines) < 2:
raise ValueError("Pose file is missing data rows below the header/metadata line.")
pose_rows = []
for idx, raw_line in enumerate(lines[1:], start=2):
stripped = raw_line.strip()
if not stripped:
continue # allow blank separator lines
values = _parse_pose_line(stripped, idx)
values[5] = pose_width
values[6] = pose_height
pose_rows.append(values)
if not pose_rows:
raise ValueError("Pose file did not contain any valid pose rows.")
return (pose_rows,)
NODE_CLASS_MAPPINGS = {
"KoolookLoadCameraPosesAbsolute": KoolookLoadCameraPosesAbsolute,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"KoolookLoadCameraPosesAbsolute": "Koolook Load Camera Poses (Absolute Path)",
}