From 4c1aa6c01d3b061179d228db4ec218c84506c3b9 Mon Sep 17 00:00:00 2001 From: Martin Gerhardy Date: Wed, 4 Dec 2024 19:51:14 +0100 Subject: [PATCH] SCENEGRAPH: moved function to remove unused palette color entries into the node see issue #549 --- src/modules/scenegraph/SceneGraphNode.cpp | 60 +++++++++++++++++++ src/modules/scenegraph/SceneGraphNode.h | 2 + .../modules/voxedit-util/SceneManager.cpp | 55 +---------------- 3 files changed, 64 insertions(+), 53 deletions(-) diff --git a/src/modules/scenegraph/SceneGraphNode.cpp b/src/modules/scenegraph/SceneGraphNode.cpp index 339be0f4a..1a9c398b3 100644 --- a/src/modules/scenegraph/SceneGraphNode.cpp +++ b/src/modules/scenegraph/SceneGraphNode.cpp @@ -16,6 +16,7 @@ #include "voxel/MaterialColor.h" #include "voxel/RawVolume.h" #include "voxel/Region.h" +#include "voxelutil/VolumeVisitor.h" #include "voxelutil/VoxelUtil.h" namespace scenegraph { @@ -186,6 +187,65 @@ palette::Palette &SceneGraphNode::palette() const { return *_palette.value(); } +bool SceneGraphNode::removeUnusedColors(bool updateVoxels) { + voxel::RawVolume *v = volume(); + if (v == nullptr) { + return false; + } + core::Array usedColors; + usedColors.fill(false); + + palette::Palette &pal = palette(); + voxelutil::visitVolume(*v, [&usedColors] (int x, int y, int z, const voxel::Voxel& voxel) { + usedColors[voxel.getColor()] = true; + return true; + }); + int unused = 0; + for (size_t i = 0; i < palette::PaletteMaxColors; ++i) { + if (!usedColors[i]) { + ++unused; + } + } + if (unused >= palette::PaletteMaxColors) { + Log::warn("Removing all colors from the palette is not allowed"); + return false; + } + Log::debug("Unused colors: %i", unused); + if (updateVoxels) { + int newMappingPos = 0; + core::Array newMapping; + for (size_t i = 0; i < palette::PaletteMaxColors; ++i) { + if (usedColors[i]) { + newMapping[i] = newMappingPos++; + } + } + palette::Palette newPalette; + for (size_t i = 0; i < palette::PaletteMaxColors; ++i) { + if (usedColors[i]) { + newPalette.setColor(newMapping[i], pal.color(i)); + newPalette.setMaterial(newMapping[i], pal.material(i)); + } + } + core_assert(newPalette.colorCount() > 0); + pal = newPalette; + voxelutil::visitVolume(*v, [v, &newMapping, &pal] (int x, int y, int z, const voxel::Voxel& voxel) { + v->setVoxel(x, y, z, voxel::createVoxel(pal, newMapping[voxel.getColor()])); + return true; + }); + pal.markDirty(); + pal.markSave(); + } else { + for (size_t i = 0; i < pal.size(); ++i) { + if (!usedColors[i]) { + pal.setColor(i, core::RGBA(127, 127, 127, 255)); + } + } + pal.markDirty(); + pal.markSave(); + } + return true; +} + void SceneGraphNode::fixErrors() { if (_type == SceneGraphNodeType::Model) { if (_volume == nullptr) { diff --git a/src/modules/scenegraph/SceneGraphNode.h b/src/modules/scenegraph/SceneGraphNode.h index 466d66e62..9e99fb2ea 100644 --- a/src/modules/scenegraph/SceneGraphNode.h +++ b/src/modules/scenegraph/SceneGraphNode.h @@ -148,6 +148,8 @@ class SceneGraphNode { palette::NormalPalette &normalPalette() const; void setNormalPalette(const palette::NormalPalette &normalPalette); + bool removeUnusedColors(bool updateVoxels); + // normalized pivot of [0-1] to be somewhere inside the volume region bool setPivot(const glm::vec3 &pivot); const glm::vec3 &pivot() const; diff --git a/src/tools/voxedit/modules/voxedit-util/SceneManager.cpp b/src/tools/voxedit/modules/voxedit-util/SceneManager.cpp index 2eacb5241..ff111a5ba 100644 --- a/src/tools/voxedit/modules/voxedit-util/SceneManager.cpp +++ b/src/tools/voxedit/modules/voxedit-util/SceneManager.cpp @@ -2269,63 +2269,12 @@ void SceneManager::construct() { void SceneManager::nodeRemoveUnusedColors(int nodeId, bool updateVoxels) { scenegraph::SceneGraphNode &node = _sceneGraph.node(nodeId); - voxel::RawVolume *v = node.volume(); - if (v == nullptr) { - return; - } - core::Array usedColors; - usedColors.fill(false); - - palette::Palette &pal = node.palette(); - voxelutil::visitVolume(*v, [&usedColors] (int x, int y, int z, const voxel::Voxel& voxel) { - usedColors[voxel.getColor()] = true; - return true; - }); - int unused = 0; - for (size_t i = 0; i < palette::PaletteMaxColors; ++i) { - if (!usedColors[i]) { - ++unused; - } - } - if (unused >= palette::PaletteMaxColors) { - Log::warn("Removing all colors from the palette is not allowed"); - return; - } - Log::debug("Unused colors: %i", unused); + node.removeUnusedColors(updateVoxels); if (updateVoxels) { - int newMappingPos = 0; - core::Array newMapping; - for (size_t i = 0; i < palette::PaletteMaxColors; ++i) { - if (usedColors[i]) { - newMapping[i] = newMappingPos++; - } - } - palette::Palette newPalette; - for (size_t i = 0; i < palette::PaletteMaxColors; ++i) { - if (usedColors[i]) { - newPalette.setColor(newMapping[i], pal.color(i)); - newPalette.setMaterial(newMapping[i], pal.material(i)); - } - } - core_assert(newPalette.colorCount() > 0); - pal = newPalette; - voxelutil::visitVolume(*v, [v, &newMapping, &pal] (int x, int y, int z, const voxel::Voxel& voxel) { - v->setVoxel(x, y, z, voxel::createVoxel(pal, newMapping[voxel.getColor()])); - return true; - }); - pal.markDirty(); - pal.markSave(); memento::ScopedMementoGroup mementoGroup(_mementoHandler, "removeunusedcolors"); _mementoHandler.markPaletteChange(_sceneGraph, node); - modified(nodeId, v->region()); + modified(nodeId, _sceneGraph.resolveRegion(node)); } else { - for (size_t i = 0; i < pal.size(); ++i) { - if (!usedColors[i]) { - pal.setColor(i, core::RGBA(127, 127, 127, 255)); - } - } - pal.markDirty(); - pal.markSave(); _mementoHandler.markPaletteChange(_sceneGraph, node); } }