2021-12-28 18:31:46 +00:00
local wea = worldeditadditions
local Vector3 = wea.Vector3
2020-06-09 20:11:34 +00:00
-- ██████ ██████ ███ ██ ██ ██ ██████ ██ ██ ██ ███████
-- ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ █████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██████ ██████ ██ ████ ████ ██████ ███████ ████ ███████
2022-05-19 21:10:09 +00:00
worldeditadditions_core.register_command ( " convolve " , {
2020-06-09 20:11:34 +00:00
params = " <kernel> [<width>[,<height>]] [<sigma>] " ,
2020-06-10 00:38:09 +00:00
description = " Advanced version of //smooth from we_env. Convolves over the defined region with the given kernel. Possible kernels: box, pascal, gaussian. The width & height (if specified) must be odd integers. If the height is not specified, it defaults to the width. gaussian should give the smoothest result, but the width & height must be identical. The sigma value is only applicable to gaussian kernels, and can be thought of as the 'smoothness' to apply. " ,
2020-06-09 20:11:34 +00:00
privs = { worldedit = true } ,
require_pos = 2 ,
parse = function ( params_text )
2020-06-10 00:06:34 +00:00
if not params_text then params_text = " " end
2020-06-09 20:11:34 +00:00
2021-12-28 18:31:46 +00:00
-- local parts = wea.split(params_text, "%s+", false)
local parts = wea.split_shell ( params_text )
2020-06-09 20:11:34 +00:00
local kernel_name = " gaussian "
local width = 5
local height = 5
local sigma = nil
2020-06-10 00:06:34 +00:00
if # parts >= 1 and # parts [ 1 ] > 0 then
2020-06-09 20:11:34 +00:00
kernel_name = parts [ 1 ]
end
if # parts >= 2 then
2021-12-28 18:31:46 +00:00
local parts_dimension = wea.split ( parts [ 2 ] , " ,%s* " , false )
2020-06-09 21:00:56 +00:00
width = tonumber ( parts_dimension [ 1 ] )
2020-06-09 20:11:34 +00:00
if not width then
return false , " Error: Invalid width (it must be a positive odd integer). "
end
if # parts_dimension >= 2 then
2020-06-10 00:06:34 +00:00
height = tonumber ( parts_dimension [ 2 ] )
2020-06-09 20:11:34 +00:00
if not height then
return false , " Error: Invalid height (it must be a positive odd integer). "
end
else
height = width
end
end
if # parts >= 3 then
sigma = tonumber ( parts [ 3 ] )
if not sigma then
return false , " Error: Invalid sigma value (it must be a valid number - floating point numbers are allowed) "
end
end
return true , kernel_name , math.floor ( width ) , math.floor ( height ) , sigma
end ,
nodes_needed = function ( name )
return worldedit.volume ( worldedit.pos1 [ name ] , worldedit.pos2 [ name ] )
end ,
2020-06-09 21:00:56 +00:00
func = function ( name , kernel_name , kernel_width , kernel_height , sigma )
2021-12-28 18:31:46 +00:00
local start_time = wea.get_ms_time ( )
2020-06-09 20:11:34 +00:00
2021-12-28 18:31:46 +00:00
local success , kernel = wea.get_conv_kernel ( kernel_name , kernel_width , kernel_height , sigma )
2020-06-09 20:11:34 +00:00
if not success then return success , kernel end
2021-12-28 18:31:46 +00:00
local kernel_size = Vector3.new (
kernel_height ,
0 ,
kernel_width
)
local pos1 , pos2 = Vector3.sort (
worldedit.pos1 [ name ] ,
worldedit.pos2 [ name ]
)
2020-06-09 20:11:34 +00:00
2021-07-30 18:58:23 +00:00
local stats
2021-12-28 18:31:46 +00:00
success , stats = wea.convolve (
pos1 , pos2 ,
2020-06-09 20:11:34 +00:00
kernel , kernel_size
)
2021-07-30 19:00:41 +00:00
if not success then return success , stats end
2020-06-09 20:11:34 +00:00
2021-12-28 18:31:46 +00:00
local time_taken = wea.get_ms_time ( ) - start_time
2020-06-09 20:11:34 +00:00
2021-12-28 18:31:46 +00:00
minetest.log ( " action " , name .. " used //convolve at " .. pos1 .. " - " .. pos2 .. " , adding " .. stats.added .. " nodes and removing " .. stats.removed .. " nodes in " .. time_taken .. " s " )
return true , " Added " .. stats.added .. " and removed " .. stats.removed .. " nodes in " .. wea.format . human_time ( time_taken )
2020-06-09 20:11:34 +00:00
end
} )