From aa9d85958e212e9e6d1c5bd27c2e137f572a0e73 Mon Sep 17 00:00:00 2001 From: Martin Gerhardy Date: Tue, 14 Jan 2025 17:34:00 +0100 Subject: [PATCH] VOXELGENERATOR: new lua script to flatten errors by certain thresholds --- src/modules/voxelgenerator/CMakeLists.txt | 1 + .../voxelgenerator/lua/scripts/flatten.lua | 58 +++++++++++++++++++ .../voxelgenerator/tests/LUAApiTest.cpp | 5 ++ 3 files changed, 64 insertions(+) create mode 100644 src/modules/voxelgenerator/lua/scripts/flatten.lua diff --git a/src/modules/voxelgenerator/CMakeLists.txt b/src/modules/voxelgenerator/CMakeLists.txt index e659e994f..9f6111fed 100644 --- a/src/modules/voxelgenerator/CMakeLists.txt +++ b/src/modules/voxelgenerator/CMakeLists.txt @@ -19,6 +19,7 @@ set(LUA_SRCS scripts/delete-rgb.lua scripts/erode.lua scripts/fillhollow.lua + scripts/flatten.lua scripts/gameoflife.lua scripts/gradient.lua scripts/grass.lua diff --git a/src/modules/voxelgenerator/lua/scripts/flatten.lua b/src/modules/voxelgenerator/lua/scripts/flatten.lua new file mode 100644 index 000000000..8c107071d --- /dev/null +++ b/src/modules/voxelgenerator/lua/scripts/flatten.lua @@ -0,0 +1,58 @@ +-- +-- flatten a model by filling minor gaps between voxels or by removing voxels are not well connected +-- + +local vol = require "modules.volume" + +function arguments() + return { + { name = 'empty', desc = 'The amount of empty voxels that will lead to a removal.', type = 'int', default = '24', min = '1', max = '26' }, + { name = 'nonempty', desc = 'The amount of non-empty voxels that will lead to a new voxel.', type = 'int', default = '16', min = '1', max = '25' } + } +end + +function main(node, region, color, empty, nonempty) + local visitor = function (volume, x, y, z) + local emptyVoxels = vol.countEmptyAround(volume, x, y, z, 1) + local mins = region:mins() + local maxs = region:maxs() + local edges = 0 + if (mins.x == x or maxs.x == x) then + edges = edges + 1 + end + if (mins.y == y or maxs.y == y) then + edges = edges + 1 + end + if (mins.z == z or maxs.z == z) then + edges = edges + 1 + end + if (edges == 3) then + emptyVoxels = emptyVoxels - 19 + end + if (edges == 2) then + emptyVoxels = emptyVoxels - 15 + end + if (edges == 1) then + emptyVoxels = emptyVoxels - 9 + end + local voxel = volume:voxel(x, y, z) + if (emptyVoxels >= empty) then + if (voxel == -1) then + return + end + g_log.debug("remove voxel at " .. x .. ", " .. y .. ", " .. z .. " because of " .. emptyVoxels .. " empty voxels threshold of: " .. empty) + volume:setVoxel(x, y, z, -1) + else + local occupiedVoxels = 26 - emptyVoxels + if (occupiedVoxels >= nonempty) then + if (voxel ~= -1) then + return + end + -- TODO: find the best color + g_log.debug("add voxel at " .. x .. ", " .. y .. ", " .. z .. " because of " .. occupiedVoxels .. " occupied voxels threshold of: " .. nonempty) + volume:setVoxel(x, y, z, color) + end + end + end + vol.visitYXZ(node:volume(), region, visitor) +end diff --git a/src/modules/voxelgenerator/tests/LUAApiTest.cpp b/src/modules/voxelgenerator/tests/LUAApiTest.cpp index a3f392e95..dddbe24e1 100644 --- a/src/modules/voxelgenerator/tests/LUAApiTest.cpp +++ b/src/modules/voxelgenerator/tests/LUAApiTest.cpp @@ -327,6 +327,11 @@ TEST_F(LUAApiTest, testScriptReplaceColor) { runFile(sceneGraph, "replacecolor.lua"); } +TEST_F(LUAApiTest, testScriptFlatten) { + scenegraph::SceneGraph sceneGraph; + runFile(sceneGraph, "flatten.lua"); +} + TEST_F(LUAApiTest, testScriptReplacePalette) { scenegraph::SceneGraph sceneGraph; runFile(sceneGraph, "replacepalette.lua", {"built-in:minecraft"});