-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.py
More file actions
163 lines (134 loc) · 5.21 KB
/
config.py
File metadata and controls
163 lines (134 loc) · 5.21 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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
"""
KiRender Configuration Module
"""
import os
import json
CONFIG_FILE = os.path.join(os.path.dirname(__file__), 'kirender_config.json')
# Reference resolution for benchmark scaling (1080p)
REFERENCE_MEGAPIXELS = (1920 * 1080) / 1_000_000 # 2.07 MP
# Default render times (sec/frame at 1080p)
DEFAULT_RENDER_TIMES = {
'high': 11.0, # Raytracing - slower
'basic': 2.0, # OpenGL - faster
'user': 8.0, # User settings - assume medium
'job_settings': 8.0
}
DEFAULT_CONFIG = {
'window_width': 550,
'window_height': 700,
'log_splitter_pos': -150, # Negative = from bottom (150px for log panel)
'anim_json_splitter_pos': 150, # JSON preview height in Animation tab
'static_json_splitter_pos': 150, # JSON preview height in Static tab
'pinout_json_splitter_pos': 150, # JSON preview height in Pinout tab
'parallel_workers': 0, # 0 = auto (cpu_count - 1), or specify 1-16
'anim_width': 1080,
'anim_height': 1080,
'anim_zoom': 0.7,
'anim_frames': 120,
'anim_fps': 30,
'anim_component_height': 10, # Max component height in mm (connectors, caps, heatsinks)
'anim_safety_margin': 5, # Safety margin % for safe zoom calculation
'static_width': 2000,
'static_height': 2000,
# Render benchmarks (sec/frame at reference 1080p resolution)
'render_benchmarks': {
'high': {'sec_per_frame': 11.0, 'samples': 0},
'basic': {'sec_per_frame': 2.0, 'samples': 0},
'user': {'sec_per_frame': 8.0, 'samples': 0},
'job_settings': {'sec_per_frame': 8.0, 'samples': 0}
}
}
def load_config():
"""Load saved configuration."""
config = DEFAULT_CONFIG.copy()
try:
if os.path.exists(CONFIG_FILE):
with open(CONFIG_FILE, 'r') as f:
saved = json.load(f)
config.update(saved)
except Exception:
pass
return config
def save_config(config):
"""Save configuration to file."""
try:
with open(CONFIG_FILE, 'w') as f:
json.dump(config, f, indent=2)
except Exception:
pass
def estimate_render_time(width: int, height: int, frames: int, quality: str = 'high') -> float:
"""
Estimate total render time in seconds.
Args:
width: Image width in pixels
height: Image height in pixels
frames: Number of frames to render
quality: Render quality ('basic', 'high', 'user', 'job_settings')
Returns:
Estimated time in seconds
"""
config = load_config()
benchmarks = config.get('render_benchmarks', DEFAULT_CONFIG['render_benchmarks'])
# Get benchmark for this quality
quality_key = quality.lower() if quality else 'high'
benchmark = benchmarks.get(quality_key, {'sec_per_frame': DEFAULT_RENDER_TIMES.get(quality_key, 11.0)})
sec_per_frame_ref = benchmark.get('sec_per_frame', 11.0)
# Scale by resolution (relative to reference 1080p)
megapixels = (width * height) / 1_000_000
scale_factor = megapixels / REFERENCE_MEGAPIXELS
sec_per_frame = sec_per_frame_ref * scale_factor
total_time = sec_per_frame * frames
return total_time
def format_time_estimate(seconds: float) -> str:
"""
Format seconds into human-readable time.
Args:
seconds: Time in seconds
Returns:
Formatted string like "5 min 30 sec" or "1 hr 23 min"
"""
if seconds < 60:
return f"{seconds:.0f} sec"
elif seconds < 3600:
mins = int(seconds // 60)
secs = int(seconds % 60)
return f"{mins} min {secs} sec"
else:
hrs = int(seconds // 3600)
mins = int((seconds % 3600) // 60)
return f"{hrs} hr {mins} min"
def update_benchmark(quality: str, actual_sec_per_frame: float, width: int, height: int):
"""
Update benchmark data with actual measured render time.
Args:
quality: Render quality
actual_sec_per_frame: Measured seconds per frame
width: Render width
height: Render height
"""
config = load_config()
benchmarks = config.get('render_benchmarks', DEFAULT_CONFIG['render_benchmarks'].copy())
# Scale to reference resolution
megapixels = (width * height) / 1_000_000
scale_factor = megapixels / REFERENCE_MEGAPIXELS
sec_per_frame_ref = actual_sec_per_frame / scale_factor if scale_factor > 0 else actual_sec_per_frame
quality_key = quality.lower() if quality else 'high'
if quality_key not in benchmarks:
benchmarks[quality_key] = {'sec_per_frame': sec_per_frame_ref, 'samples': 1}
else:
old = benchmarks[quality_key]
samples = old.get('samples', 0)
old_avg = old.get('sec_per_frame', sec_per_frame_ref)
# Running average (cap at 20 samples to adapt to changes)
max_samples = 20
if samples >= max_samples:
# Weighted average favoring recent
new_avg = old_avg * 0.9 + sec_per_frame_ref * 0.1
else:
new_avg = (old_avg * samples + sec_per_frame_ref) / (samples + 1)
benchmarks[quality_key] = {
'sec_per_frame': new_avg,
'samples': min(samples + 1, max_samples)
}
config['render_benchmarks'] = benchmarks
save_config(config)