Skip to content

Commit

Permalink
SCENEGRAPH: moved function to remove unused palette color entries int…
Browse files Browse the repository at this point in the history
…o the node

see issue #549
  • Loading branch information
mgerhardy committed Dec 4, 2024
1 parent 71151b1 commit 4c1aa6c
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 53 deletions.
60 changes: 60 additions & 0 deletions src/modules/scenegraph/SceneGraphNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<bool, palette::PaletteMaxColors> 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<uint8_t, palette::PaletteMaxColors> 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) {
Expand Down
2 changes: 2 additions & 0 deletions src/modules/scenegraph/SceneGraphNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
55 changes: 2 additions & 53 deletions src/tools/voxedit/modules/voxedit-util/SceneManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<bool, palette::PaletteMaxColors> 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<uint8_t, palette::PaletteMaxColors> 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);
}
}
Expand Down

0 comments on commit 4c1aa6c

Please sign in to comment.