-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAuto Rename.lua
309 lines (231 loc) · 8.32 KB
/
Auto Rename.lua
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
--[[
Auto Rename
created by Nizar / version 1.1
contact: http://twitter.com/nizarneezR
Usage:
- Open the Fusion page
- Run this script from DaVinci Resolve's dropdown menu (Workspace > Scripts)
- This will automatically rename all unnamed "MediaIn", "Background", "Text+" and "Text 3D" nodes to logical display names
- This will also rename all layers in the LayerList of a "MultiMerge" node to the names of their input nodes
- This works best if bound to a hotkey! (open hotkey settings with CTRL+ALT+K)
Install:
- Copy this .lua-file into the folder "%appdata%\Blackmagic Design\DaVinci Resolve\Support\Fusion\Scripts\Comp"
--]]
-- Subprocesses
-- [Media In-Nodes]
function rename_mediain_node(tool)
if tool:GetAttrs("TOOLS_RegID") == "MediaIn" then
new_node_name = tool:GetAttrs().TOOLS_Clip_Name
new_node_name = string.gsub(new_node_name, " ", "_") --remove white spaces
if string.find(new_node_name, "%.") then --remove file extensions
local final_dot_index = (new_node_name:reverse()):find("%.")
new_node_name = string.sub(new_node_name,1,#new_node_name-final_dot_index)
end
if new_node_name:match("^%d+$") then --add prefix to purely numeric file names
new_node_name = "_" .. new_node_name
end
tool:SetAttrs({TOOLS_Name = new_node_name})
end
end
-- [Background Nodes]
BG_NODE_PREFIX = ""
BG_NODE_SUFFIX = ""
-- Change these if you want to add prefixes or suffixes to the way Background nodes are renamed
--
-- If you want names like "bg_Red_node", "bg_Blue_node", ...
-- change BG_NODE_PREFIX = "bg_" and BG_NODE_SUFFIX = "_node"
--
-- or keep them empty for names like "Red","Blue",...
COLORS = {White={1.0,1.0,1.0}, Silver={0.75,0.75,0.75}, Gray={0.5,0.5,0.5}, Black={0.0,0.0,0.0}, Red={1.0,0.0,0.0}, Maroon={0.5,0.0,0.0}, Yellow={1.0,1.0,0.0}, Olive={0.5,0.5,0}, Lime={0.0,1.0,0.0}, Green={0.0,0.5,0.0}, Cyan={0.0,1.0,1.0}, Teal={0.0,0.5,0.5}, Blue={0.0,0.0,1.0}, Navy={0.0,0.0,0.5}, Magenta={1.0,0.0,1.0}, Purple={0.5,0.0,0.5}, Pink={1.0,0.75,0.8}, OrangeRed={1.0,0.27,0.0}, Orange={1.0,0.55,0.0},Gold={1.0,0.84,0.0}, Brown={0.55,0.27,0.07}}
-- Colors are based on CSS4 colors (core colors + some extras)
-- https://en.wikipedia.org/wiki/Web_colors
function rename_background_node(tool)
if tool:GetAttrs("TOOLS_RegID") == "Background" then
--todo handle BG.Type (solid, gradient)?
local r,g,b,a = tool.TopLeftRed[comp.CurrentTime], tool.TopLeftGreen[comp.CurrentTime], tool.TopLeftBlue[comp.CurrentTime], tool.TopLeftAlpha[comp.CurrentTime]
local est_color = guess_color(r,g,b,a)
local new_node_name = BG_NODE_PREFIX .. est_color .. BG_NODE_SUFFIX
tool:SetAttrs({TOOLS_Name = new_node_name})
end
end
function guess_color(r,g,b,a)
if a == 0 then
return "Transparent"
end
similarity_table = {} --color_name:similarity_to_input_color
for color_name, color_rgb_table in pairs(COLORS) do
similarity_table[color_name] = similarity(color_rgb_table[1], color_rgb_table[2], color_rgb_table[3], r,g,b)
end
local est_color = get_best_match_from_sim_table(similarity_table)
if a < 1 then
return est_color .. "_Transparent"
else
return est_color
end
end
function get_best_match_from_sim_table(t)
local key = next(t)
local minv = t[key]
for k, v in pairs(t) do
if t[k] < minv then
key, minv = k, v
end
end
return key
end
function similarity(r1,g1,b1,r2,g2,b2)
--1 is color in COLORS, 2 is color in bg node
return _cielab_similarity(r1,g1,b1,r2,g2,b2)
end
function _cielab_similarity(r1,g1,b1,r2,g2,b2)
local x1,y1,z1 = sRGBtoLab(r1,g1,b1)
local x2,y2,z2 = sRGBtoLab(r2,g2,b2)
--taxi-cab distance of chroma+L
return math.sqrt((y1-y2)^2 + (z1-z2)^2) + math.abs(x1-x2)
end
-- some other similarity measurements that were tested earlier, but were not as accurate as CIELAB
--[[
function _cosinesimilarity(r1,g1,b1,r2,g2,b2)
--apply weights for human perception
r1 = r1 * 0.3
r2 = r2 * 0.3
g1 = g1 * 0.59
g2 = g2 * 0.59
b1 = b1 * 0.11
b2 = b2 * 0.11
--cosine similarity
local dp = (r1*r2) + (g1*g2) + (b1*b2)
local len_a = math.sqrt(r1^2 + g1^2 + b1^2)
local len_b = math.sqrt(r2^2 + g2^2 + b2^2)
return dp/(len_a*len_b)
end
function _euclidiandistance(r1,g1,b1,r2,g2,b2)
return math.sqrt(0.3*(r1-r2)^2 + 0.59*(g1-g2)^2 + 0.11*(b1-b2)^2)
end
function _hue_similarity(r1,g1,b1,r2,g2,b2)
local vivid = require('vivid')
local h1,_s1,_v1, _a1 = vivid.RGBtoHSV(r1,g1,b1, 1.0)
local h2,_s2,_v2, _a2 = vivid.RGBtoHSV(r2,g2,b2, 1.0)
return math.min(math.abs(h1-h2), 1-math.abs(h1-h2))
end
]]--
function sRGBtoLab(r,g,b)
-- adapted from vivid.lua
-- https://github.com/WetDesertRock/vivid
--(Observer = 2°, Illuminant = D65)
if r > 0.04045 then
r = ((r+0.055)/1.055)^2.4
else
r = r/12.92
end
if g > 0.04045 then
g = ((g+0.055)/1.055)^2.4
else
g = g/12.92
end
if b > 0.04045 then
b = ((b+0.055)/1.055)^2.4
else
b = b/12.92
end
r = r*100
g = g*100
b = b*100
local x = r * 0.4124 + g * 0.3576 + b * 0.1805
local y = r * 0.2126 + g * 0.7152 + b * 0.0722
local z = r * 0.0193 + g * 0.1192 + b * 0.9505
local refx,refy,refz = 95.047,100.000,108.883
x,y,z = x/refx,y/refy,z/refz
if x > 0.008856 then
x = x^(1/3)
else
x = (7.787*x) + (16/116)
end
if y > 0.008856 then
y = y^(1/3)
else
y = (7.787*y) + (16/116)
end
if z > 0.008856 then
z = z^(1/3)
else
z = (7.787*z) + (16/116)
end
L = (116*y) - 16
a = 500*(x-y)
b = 200*(y-z)
return L,a,b
end
-- [Text Nodes]
NODE_PREFIX_TEXTPLUS = "Text_"
NODE_PREFIX_TEXT3D = "Text3D_"
-- Change these if you want to change the prefixes or suffixes added to the way Text nodes are renamed
function rename_textplus_node(tool)
if tool:GetAttrs("TOOLS_RegID") == "TextPlus" or tool:GetAttrs("TOOLS_RegID") == "Text3D" then
local styledtext = tool.StyledText[comp.CurrentTime]
if styledtext ~= "" then
local new_node_name = shorten_text_node_name(styledtext)
if tool:GetAttrs("TOOLS_RegID") == "TextPlus" then
new_node_name = NODE_PREFIX_TEXTPLUS .. new_node_name
elseif tool:GetAttrs("TOOLS_RegID") == "Text3D" then
new_node_name = NODE_PREFIX_TEXT3D .. new_node_name
end
tool:SetAttrs({TOOLS_Name = new_node_name})
end
end
end
function shorten_text_node_name(styledtext)
local words = {}
for matchgroup in string.gmatch(styledtext, "%S+") do
words[#words+1] = matchgroup
end
if(#words == 1) then
return styledtext
end
if(#words >= 2) then
return(words[1] .. "_" .. words[2])
end
end
-- [MultiMerge nodes]
function number_of_connected_layers(mmrg)
local res = 0
while(mmrg["Layer"..tostring(res+1)] ~= nil) do
res = res+1
end
--[[for some reason, an invisible n+1th layer is always added to a MultiMerge. Calling the GetTool() method on it will throw an error.
res-1 ignores that additional, falsely added layer
]]--
return res-1
end
function rename_multimerge_node(tool)
if(tool:GetAttrs("TOOLS_RegID") == "MultiMerge") then
--[[
print(tool.LayerName1[0]) -- = Name of layer n in layer list ("Layer 1") at frame 0
print(tool["Layer1"].Foreground:GetConnectedOutput():GetTool()) -- = get connected tool
print(number_of_connected_layers(tool)) -- number of connected foreground layers in Layer List
]]--
for i=1,number_of_connected_layers(tool) do
tool["LayerName"..tostring(i)][0] = tool["Layer"..tostring(i)].Foreground:GetConnectedOutput():GetTool():GetAttrs("TOOLS_Name")
end
end
end
-- [main loop]
function main()
tools = fusion:GetCurrentComp():GetToolList()
for _,tool in ipairs(tools) do
local _tool_id = tool:GetAttrs("TOOLS_RegID")
local _tool_name_changed_by_user = tool:GetAttrs("TOOLB_NameSet")
if((_tool_id == "MediaIn") and (not _tool_name_changed_by_user)) then
pcall(rename_mediain_node, tool)
elseif(_tool_id == "Background" and (not _tool_name_changed_by_user)) then
pcall(rename_background_node, tool)
elseif((_tool_id == "TextPlus") or (_tool_id == "Text3D")) then
if(not _tool_name_changed_by_user) then
pcall(rename_textplus_node, tool)
end
elseif(_tool_id == "MultiMerge") then
pcall(rename_multimerge_node, tool)
end
end
end
main()