From c4c2d468477505b6dc1bbff5ac658985590c5031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hor=C3=A1=C4=8Dek?= Date: Wed, 26 Jun 2013 13:10:36 +0200 Subject: [PATCH 1/7] re #19385: first version of PNG import works for size <= 128px --- interface/src/Application.cpp | 27 +++- libraries/voxels/src/SquarePixelMap.cpp | 205 ++++++++++++++++++++++++ libraries/voxels/src/SquarePixelMap.h | 43 +++++ libraries/voxels/src/VoxelTree.cpp | 8 + libraries/voxels/src/VoxelTree.h | 2 + 5 files changed, 280 insertions(+), 5 deletions(-) create mode 100644 libraries/voxels/src/SquarePixelMap.cpp create mode 100644 libraries/voxels/src/SquarePixelMap.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8373f8f440..97698aac2c 100755 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -1252,14 +1253,30 @@ void Application::exportVoxels() { void Application::importVoxels() { QString desktopLocation = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation); QString fileNameString = QFileDialog::getOpenFileName(_glWidget, tr("Import Voxels"), desktopLocation, - tr("Sparse Voxel Octree Files (*.svo)")); + tr("Sparse Voxel Octree Files, Square PNG (*.svo *.png)")); QByteArray fileNameAscii = fileNameString.toAscii(); const char* fileName = fileNameAscii.data(); - - // Read the file into a tree + VoxelTree importVoxels; - importVoxels.readFromSVOFile(fileName); - + if (fileNameString.endsWith(".png", Qt::CaseInsensitive)) { + QImage pngImage = QImage(fileName); + if (pngImage.height() != pngImage.width()) { + return; + } + + const uint32_t* pixels; + if (pngImage.format() == QImage::Format_ARGB32) { + pixels = reinterpret_cast(pngImage.constBits()); + } else { + QImage tmp = pngImage.convertToFormat(QImage::Format_ARGB32); + pixels = reinterpret_cast(tmp.constBits()); + } + + importVoxels.readFromSquareARGB32Pixels(pixels, pngImage.height()); + } else { + importVoxels.readFromSVOFile(fileName); + } + VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); // Recurse the Import Voxels tree, where everything is root relative, and send all the colored voxels to diff --git a/libraries/voxels/src/SquarePixelMap.cpp b/libraries/voxels/src/SquarePixelMap.cpp new file mode 100644 index 0000000000..d8b4be28f3 --- /dev/null +++ b/libraries/voxels/src/SquarePixelMap.cpp @@ -0,0 +1,205 @@ +// +// SquarePixelMap.cpp +// hifi +// +// Created by Tomáš Horáček on 6/25/13. +// +// + +#include "SquarePixelMap.h" +#include +#include + + +unsigned int numberOfBitsForSize(unsigned int size) { + if (size == 0) { + return 0; + } + + size--; + + unsigned int ans = 1; + while (size >>= 1) { + ans++; + } + return ans; +} + +struct PixelQuadTreeCoordinates { + unsigned int x; + unsigned int y; + unsigned int size; +}; + +class PixelQuadTreeNode { +public: + PixelQuadTreeCoordinates _coord; + uint32_t _color; // undefined value for _allChildrenHasSameColor = false + bool _allChildrenHasSameColor; + + // 0 x -> 1 + // +---+---+ + // y | 0 | 1 | <- child index + // | +---+---+ + // v | 2 | 3 | + // +---+---+ + // 1 + PixelQuadTreeNode *_children[4]; + + PixelQuadTreeNode(PixelQuadTreeCoordinates coord, SquarePixelMap *pixelMap); + ~PixelQuadTreeNode() { + for (int i = 0; i < 4; i++) { + delete _children[i]; + } + } + +private: + void updateChildCoordinates(int i, PixelQuadTreeCoordinates &childCoord) { + childCoord.x = _coord.x; + childCoord.y = _coord.y; + + if (i & 0x1) { + childCoord.x += childCoord.size; + } + if (i & 0x2) { + childCoord.y += childCoord.size; + } + } + + bool hasAllChildrenSameColor() { + for (int i = 1; i < 4; i++) { + if (!_children[i]->_allChildrenHasSameColor) { + return false; + } + } + + uint32_t firstColor = _children[0]->_color; + + for (int i = 1; i < 4; i++) { + if (firstColor != _children[i]->_color) { + return false; + } + } + return true; + } +}; + +PixelQuadTreeNode::PixelQuadTreeNode(PixelQuadTreeCoordinates coord, SquarePixelMap *pixelMap) : _coord(coord) { + for (int i = 0; i < 4; i++) { + _children[i] = NULL; + } + + if (_coord.size == 1) { + _color = pixelMap->getPixelAt(_coord.x, _coord.y); + _allChildrenHasSameColor = true; + } else { + PixelQuadTreeCoordinates childCoord = PixelQuadTreeCoordinates(); + childCoord.size = _coord.size / 2; + + for (int i = 0; i < 4; i++) { + this->updateChildCoordinates(i, childCoord); + + + if (childCoord.x < pixelMap->dimension() && + childCoord.y < pixelMap->dimension()) { + + _children[i] = new PixelQuadTreeNode(childCoord, pixelMap); + } + } + + if (this->hasAllChildrenSameColor()) { + _allChildrenHasSameColor = true; + _color = _children[0]->_color; + + for (int i = 0; i < 4; i++) { + delete _children[i]; + _children[i] = NULL; + } + } else { + _allChildrenHasSameColor = false; + } + } +} + +SquarePixelMap::SquarePixelMap(const uint32_t *pixels, int dimension) : _rootPixelQuadTreeNode(NULL) { + _data = new SquarePixelMapData(); + _data->dimension = dimension; + _data->reference_counter = 1; + + size_t pixels_size = dimension * dimension; + _data->pixels = new uint32_t[pixels_size]; + memcpy((void *)_data->pixels, (void *)pixels, sizeof(uint32_t) * pixels_size); +} + +SquarePixelMap::SquarePixelMap(const SquarePixelMap& other) { + this->_data = other._data; + this->_data->reference_counter++; +} + +SquarePixelMap::~SquarePixelMap() { + delete _rootPixelQuadTreeNode; + + if (--_data->reference_counter == 0) { + delete _data->pixels; + delete _data; + } +} + +void SquarePixelMap::addVoxelsToVoxelTree(VoxelTree *voxelTree) { + this->generateRootPixelQuadTreeNode(); + this->createVoxelsFromPixelQuadTreeToVoxelTree(_rootPixelQuadTreeNode, voxelTree); +} + +int SquarePixelMap::dimension() { + return _data->dimension; +} + +uint32_t SquarePixelMap::getPixelAt(unsigned int x, unsigned int y) { + return _data->pixels[x + y * _data->dimension]; +} + +void SquarePixelMap::generateRootPixelQuadTreeNode() { + delete _rootPixelQuadTreeNode; + + PixelQuadTreeCoordinates rootNodeCoord = PixelQuadTreeCoordinates(); + rootNodeCoord.size = 1 << numberOfBitsForSize(_data->dimension); + rootNodeCoord.x = rootNodeCoord.y = 0; + + _rootPixelQuadTreeNode = new PixelQuadTreeNode(rootNodeCoord, this); +} + +void SquarePixelMap::createVoxelsFromPixelQuadTreeToVoxelTree(PixelQuadTreeNode *pixelQuadTreeNode, VoxelTree *voxelTree) { + if (pixelQuadTreeNode->_allChildrenHasSameColor) { + VoxelDetail voxel = this->getVoxelDetail(pixelQuadTreeNode); + + voxelTree->createVoxel(voxel.x, voxel.y, voxel.z, voxel.s, voxel.red, voxel.green, voxel.blue, true); + } else { + for (int i = 0; i < 4; i++) { + PixelQuadTreeNode *child = pixelQuadTreeNode->_children[i]; + if (child) { + this->createVoxelsFromPixelQuadTreeToVoxelTree(child, voxelTree); + } + } + } +} + +VoxelDetail SquarePixelMap::getVoxelDetail(PixelQuadTreeNode *pixelQuadTreeNode) { + VoxelDetail voxel = VoxelDetail(); + + uint32_t color = pixelQuadTreeNode->_color; + unsigned char alpha = color >> 24; + + voxel.red = color >> 16; + voxel.green = color >> 8; + voxel.blue = color; + + + float rootSize = _rootPixelQuadTreeNode->_coord.size; + + voxel.s = pixelQuadTreeNode->_coord.size / rootSize; + voxel.y = voxel.s * (floor(alpha / (256.f * voxel.s)) + 0.5); + voxel.x = pixelQuadTreeNode->_coord.x / rootSize + voxel.s / 2; + voxel.z = pixelQuadTreeNode->_coord.y / rootSize + voxel.s / 2; + + return voxel; +} diff --git a/libraries/voxels/src/SquarePixelMap.h b/libraries/voxels/src/SquarePixelMap.h new file mode 100644 index 0000000000..ae7b812651 --- /dev/null +++ b/libraries/voxels/src/SquarePixelMap.h @@ -0,0 +1,43 @@ +// +// SquarePixelMap.h +// hifi +// +// Created by Tomáš Horáček on 6/25/13. +// +// + +#ifndef __hifi__SquarePixelMap__ +#define __hifi__SquarePixelMap__ + +#include +#include "VoxelTree.h" +#include "SharedUtil.h" + +class PixelQuadTreeNode; + +struct SquarePixelMapData { + const uint32_t* pixels; + int dimension; + int reference_counter; +}; + +class SquarePixelMap { +public: + SquarePixelMap(const uint32_t *pixels, int dimension); + SquarePixelMap(const SquarePixelMap& other); + ~SquarePixelMap(); + + void addVoxelsToVoxelTree(VoxelTree *voxelTree); + + int dimension(); + uint32_t getPixelAt(unsigned int x, unsigned int y); +private: + SquarePixelMapData *_data; + PixelQuadTreeNode *_rootPixelQuadTreeNode; + + void generateRootPixelQuadTreeNode(); + void createVoxelsFromPixelQuadTreeToVoxelTree(PixelQuadTreeNode *pixelQuadTreeNode, VoxelTree *voxelTree); + VoxelDetail getVoxelDetail(PixelQuadTreeNode *pixelQuadTreeNode); +}; + +#endif /* defined(__hifi__SquarePixelMap__) */ diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index e2f66fa52b..417fdcd5d5 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -23,6 +23,8 @@ #include // to load voxels from file #include "VoxelConstants.h" #include "CoverageMap.h" +#include "SquarePixelMap.h" + #include @@ -1447,6 +1449,12 @@ bool VoxelTree::readFromSVOFile(const char* fileName) { return false; } +bool VoxelTree::readFromSquareARGB32Pixels(const uint32_t *pixels, int dimension) { + SquarePixelMap pixelMap = SquarePixelMap(pixels, dimension); + pixelMap.addVoxelsToVoxelTree(this); + return true; +} + void VoxelTree::writeToSVOFile(const char* fileName, VoxelNode* node) const { std::ofstream file(fileName, std::ios::out|std::ios::binary); diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index df721d0ba5..b7b7ef7fd8 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -133,6 +133,8 @@ public: // these will read/write files that match the wireformat, excluding the 'V' leading void writeToSVOFile(const char* filename, VoxelNode* node = NULL) const; bool readFromSVOFile(const char* filename); + // reads voxels from square image with alpha as a Z axis + bool readFromSquareARGB32Pixels(const uint32_t *pixels, int dimension); unsigned long getVoxelCount(); From b5e58069881744c0e46bfbd9b9c6ed4cb25fd497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hor=C3=A1=C4=8Dek?= Date: Sat, 29 Jun 2013 02:23:41 +0200 Subject: [PATCH 2/7] re #19385: fill gaps between neighbourhood voxels --- interface/src/Application.cpp | 1 + libraries/voxels/src/SquarePixelMap.cpp | 34 ++++++++++++++++++++++--- libraries/voxels/src/SquarePixelMap.h | 1 + 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 97698aac2c..50c3720472 100755 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1261,6 +1261,7 @@ void Application::importVoxels() { if (fileNameString.endsWith(".png", Qt::CaseInsensitive)) { QImage pngImage = QImage(fileName); if (pngImage.height() != pngImage.width()) { + printLog("ERROR: Bad PNG size: height != width.\n"); return; } diff --git a/libraries/voxels/src/SquarePixelMap.cpp b/libraries/voxels/src/SquarePixelMap.cpp index d8b4be28f3..af1d6ba24b 100644 --- a/libraries/voxels/src/SquarePixelMap.cpp +++ b/libraries/voxels/src/SquarePixelMap.cpp @@ -36,6 +36,7 @@ public: PixelQuadTreeCoordinates _coord; uint32_t _color; // undefined value for _allChildrenHasSameColor = false bool _allChildrenHasSameColor; + uint8_t _minimumNeighbourhoodAplha; // 0 x -> 1 // +---+---+ @@ -67,6 +68,8 @@ private: } bool hasAllChildrenSameColor() { + return false; //turn off import voxel grouping + for (int i = 1; i < 4; i++) { if (!_children[i]->_allChildrenHasSameColor) { return false; @@ -84,13 +87,19 @@ private: } }; -PixelQuadTreeNode::PixelQuadTreeNode(PixelQuadTreeCoordinates coord, SquarePixelMap *pixelMap) : _coord(coord) { +PixelQuadTreeNode::PixelQuadTreeNode(PixelQuadTreeCoordinates coord, SquarePixelMap *pixelMap) : _coord(coord), _minimumNeighbourhoodAplha(-1) { for (int i = 0; i < 4; i++) { _children[i] = NULL; } if (_coord.size == 1) { _color = pixelMap->getPixelAt(_coord.x, _coord.y); + + _minimumNeighbourhoodAplha = std::min(pixelMap->getAlphaAt(_coord.x - 1, _coord.y - 1), _minimumNeighbourhoodAplha); + _minimumNeighbourhoodAplha = std::min(pixelMap->getAlphaAt(_coord.x - 1, _coord.y + 1), _minimumNeighbourhoodAplha); + _minimumNeighbourhoodAplha = std::min(pixelMap->getAlphaAt(_coord.x + 1, _coord.y - 1), _minimumNeighbourhoodAplha); + _minimumNeighbourhoodAplha = std::min(pixelMap->getAlphaAt(_coord.x + 1, _coord.y + 1), _minimumNeighbourhoodAplha); + _allChildrenHasSameColor = true; } else { PixelQuadTreeCoordinates childCoord = PixelQuadTreeCoordinates(); @@ -111,7 +120,10 @@ PixelQuadTreeNode::PixelQuadTreeNode(PixelQuadTreeCoordinates coord, SquarePixel _allChildrenHasSameColor = true; _color = _children[0]->_color; + _minimumNeighbourhoodAplha = _children[0]->_minimumNeighbourhoodAplha; + for (int i = 0; i < 4; i++) { + _minimumNeighbourhoodAplha = std::min(_children[i]->_minimumNeighbourhoodAplha, _minimumNeighbourhoodAplha); delete _children[i]; _children[i] = NULL; } @@ -158,6 +170,16 @@ uint32_t SquarePixelMap::getPixelAt(unsigned int x, unsigned int y) { return _data->pixels[x + y * _data->dimension]; } +uint8_t SquarePixelMap::getAlphaAt(int x, int y) { + int max_coord = this->dimension() - 1; + + if (x < 0 || y < 0 || x > max_coord || y > max_coord) { + return -1; + } + + return this->getPixelAt(x, y) >> 24; +} + void SquarePixelMap::generateRootPixelQuadTreeNode() { delete _rootPixelQuadTreeNode; @@ -172,7 +194,13 @@ void SquarePixelMap::createVoxelsFromPixelQuadTreeToVoxelTree(PixelQuadTreeNode if (pixelQuadTreeNode->_allChildrenHasSameColor) { VoxelDetail voxel = this->getVoxelDetail(pixelQuadTreeNode); - voxelTree->createVoxel(voxel.x, voxel.y, voxel.z, voxel.s, voxel.red, voxel.green, voxel.blue, true); + unsigned char minimumNeighbourhoodAplha = std::max(0, pixelQuadTreeNode->_minimumNeighbourhoodAplha - 1); + + float minimumNeighbourhoodY = voxel.s * (floor(minimumNeighbourhoodAplha / (256.f * voxel.s)) + 0.5); + + do { + voxelTree->createVoxel(voxel.x, voxel.y, voxel.z, voxel.s, voxel.red, voxel.green, voxel.blue, false); + } while ((voxel.y -= voxel.s) > minimumNeighbourhoodY); } else { for (int i = 0; i < 4; i++) { PixelQuadTreeNode *child = pixelQuadTreeNode->_children[i]; @@ -187,7 +215,7 @@ VoxelDetail SquarePixelMap::getVoxelDetail(PixelQuadTreeNode *pixelQuadTreeNode) VoxelDetail voxel = VoxelDetail(); uint32_t color = pixelQuadTreeNode->_color; - unsigned char alpha = color >> 24; + unsigned char alpha = std::max(0, (color >> 24) - 1); voxel.red = color >> 16; voxel.green = color >> 8; diff --git a/libraries/voxels/src/SquarePixelMap.h b/libraries/voxels/src/SquarePixelMap.h index ae7b812651..9a4fb4bb04 100644 --- a/libraries/voxels/src/SquarePixelMap.h +++ b/libraries/voxels/src/SquarePixelMap.h @@ -31,6 +31,7 @@ public: int dimension(); uint32_t getPixelAt(unsigned int x, unsigned int y); + uint8_t getAlphaAt(int x, int y); private: SquarePixelMapData *_data; PixelQuadTreeNode *_rootPixelQuadTreeNode; From 71c54586ba1130a85e151a83d90071f8e13a2c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hor=C3=A1=C4=8Dek?= Date: Mon, 1 Jul 2013 15:30:31 +0200 Subject: [PATCH 3/7] re #19385: use right neighbour voxels --- libraries/voxels/src/SquarePixelMap.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/voxels/src/SquarePixelMap.cpp b/libraries/voxels/src/SquarePixelMap.cpp index af1d6ba24b..0d0fae6d15 100644 --- a/libraries/voxels/src/SquarePixelMap.cpp +++ b/libraries/voxels/src/SquarePixelMap.cpp @@ -95,10 +95,10 @@ PixelQuadTreeNode::PixelQuadTreeNode(PixelQuadTreeCoordinates coord, SquarePixel if (_coord.size == 1) { _color = pixelMap->getPixelAt(_coord.x, _coord.y); - _minimumNeighbourhoodAplha = std::min(pixelMap->getAlphaAt(_coord.x - 1, _coord.y - 1), _minimumNeighbourhoodAplha); - _minimumNeighbourhoodAplha = std::min(pixelMap->getAlphaAt(_coord.x - 1, _coord.y + 1), _minimumNeighbourhoodAplha); - _minimumNeighbourhoodAplha = std::min(pixelMap->getAlphaAt(_coord.x + 1, _coord.y - 1), _minimumNeighbourhoodAplha); - _minimumNeighbourhoodAplha = std::min(pixelMap->getAlphaAt(_coord.x + 1, _coord.y + 1), _minimumNeighbourhoodAplha); + _minimumNeighbourhoodAplha = std::min(pixelMap->getAlphaAt(_coord.x + 1, _coord.y), _minimumNeighbourhoodAplha); + _minimumNeighbourhoodAplha = std::min(pixelMap->getAlphaAt(_coord.x - 1, _coord.y), _minimumNeighbourhoodAplha); + _minimumNeighbourhoodAplha = std::min(pixelMap->getAlphaAt(_coord.x, _coord.y + 1), _minimumNeighbourhoodAplha); + _minimumNeighbourhoodAplha = std::min(pixelMap->getAlphaAt(_coord.x, _coord.y - 1), _minimumNeighbourhoodAplha); _allChildrenHasSameColor = true; } else { From 2eeb0d9bb964e953612f0f51c6c2f4c5d3d87dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hor=C3=A1=C4=8Dek?= Date: Tue, 2 Jul 2013 00:28:18 +0200 Subject: [PATCH 4/7] re #19385: importing voxels should be destructive --- libraries/voxels/src/SquarePixelMap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/voxels/src/SquarePixelMap.cpp b/libraries/voxels/src/SquarePixelMap.cpp index 0d0fae6d15..58ba51b27b 100644 --- a/libraries/voxels/src/SquarePixelMap.cpp +++ b/libraries/voxels/src/SquarePixelMap.cpp @@ -199,7 +199,7 @@ void SquarePixelMap::createVoxelsFromPixelQuadTreeToVoxelTree(PixelQuadTreeNode float minimumNeighbourhoodY = voxel.s * (floor(minimumNeighbourhoodAplha / (256.f * voxel.s)) + 0.5); do { - voxelTree->createVoxel(voxel.x, voxel.y, voxel.z, voxel.s, voxel.red, voxel.green, voxel.blue, false); + voxelTree->createVoxel(voxel.x, voxel.y, voxel.z, voxel.s, voxel.red, voxel.green, voxel.blue, true); } while ((voxel.y -= voxel.s) > minimumNeighbourhoodY); } else { for (int i = 0; i < 4; i++) { From 66de431d675ea341deea5a28f5517ed546db4776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hor=C3=A1=C4=8Dek?= Date: Tue, 2 Jul 2013 02:57:55 +0200 Subject: [PATCH 5/7] re #19385: add hot-fix to allow import of big PNGs sendVoxelsOperation() is sending data too fast, printf slows it down. Better fix is required. --- interface/src/Application.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 50c3720472..edb7b32aba 100755 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1217,6 +1217,12 @@ bool Application::sendVoxelsOperation(VoxelNode* node, void* extraData) { codeColorBuffer[bytesInCode + RED_INDEX ] = node->getColor()[RED_INDEX ]; codeColorBuffer[bytesInCode + GREEN_INDEX] = node->getColor()[GREEN_INDEX]; codeColorBuffer[bytesInCode + BLUE_INDEX ] = node->getColor()[BLUE_INDEX ]; + + // TODO: sendVoxelsOperation() is sending voxels too fast. + // This printf function accidently slowed down sending + // and hot-fixed the bug when importing + // large PNG models (256x256 px and more) + static unsigned int sendVoxelsOperationCalled = 0; printf("sending voxel #%u\n", ++sendVoxelsOperationCalled); // if we have room don't have room in the buffer, then send the previously generated message first if (args->bufferInUse + codeAndColorLength > MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE) { From 5f9f2fee71c7e36186f5d2f0f01ddda2678e000c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hor=C3=A1=C4=8Dek?= Date: Tue, 2 Jul 2013 11:47:53 +0200 Subject: [PATCH 6/7] re #19385: use righ axis name --- libraries/voxels/src/VoxelTree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index b7b7ef7fd8..42eddaecdd 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -133,7 +133,7 @@ public: // these will read/write files that match the wireformat, excluding the 'V' leading void writeToSVOFile(const char* filename, VoxelNode* node = NULL) const; bool readFromSVOFile(const char* filename); - // reads voxels from square image with alpha as a Z axis + // reads voxels from square image with alpha as a Y-axis bool readFromSquareARGB32Pixels(const uint32_t *pixels, int dimension); unsigned long getVoxelCount(); From a9f8b586ee79be90528084da85775d28f0638fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hor=C3=A1=C4=8Dek?= Date: Tue, 2 Jul 2013 23:04:06 +0200 Subject: [PATCH 7/7] re #19385: CR changes --- libraries/voxels/src/SquarePixelMap.cpp | 42 ++++++++++++++----------- libraries/voxels/src/SquarePixelMap.h | 12 +++---- libraries/voxels/src/VoxelTree.cpp | 2 +- libraries/voxels/src/VoxelTree.h | 2 +- 4 files changed, 32 insertions(+), 26 deletions(-) diff --git a/libraries/voxels/src/SquarePixelMap.cpp b/libraries/voxels/src/SquarePixelMap.cpp index 58ba51b27b..bdc97624a7 100644 --- a/libraries/voxels/src/SquarePixelMap.cpp +++ b/libraries/voxels/src/SquarePixelMap.cpp @@ -10,6 +10,12 @@ #include #include +#define CHILD_COORD_X_IS_1 0x1 +#define CHILD_COORD_Y_IS_1 0x2 +#define ALPHA_CHANNEL_RANGE_FLOAT 256.f +#define ALPHA_CHANNEL_BIT_OFFSET 24 +#define RED_CHANNEL_BIT_OFFSET 16 +#define GREEN_CHANNEL_BIT_OFFSET 8 unsigned int numberOfBitsForSize(unsigned int size) { if (size == 0) { @@ -45,9 +51,9 @@ public: // v | 2 | 3 | // +---+---+ // 1 - PixelQuadTreeNode *_children[4]; + PixelQuadTreeNode* _children[4]; - PixelQuadTreeNode(PixelQuadTreeCoordinates coord, SquarePixelMap *pixelMap); + PixelQuadTreeNode(PixelQuadTreeCoordinates coord, SquarePixelMap* pixelMap); ~PixelQuadTreeNode() { for (int i = 0; i < 4; i++) { delete _children[i]; @@ -55,14 +61,14 @@ public: } private: - void updateChildCoordinates(int i, PixelQuadTreeCoordinates &childCoord) { + void updateChildCoordinates(int i, PixelQuadTreeCoordinates& childCoord) { childCoord.x = _coord.x; childCoord.y = _coord.y; - if (i & 0x1) { + if (i & CHILD_COORD_X_IS_1) { childCoord.x += childCoord.size; } - if (i & 0x2) { + if (i & CHILD_COORD_Y_IS_1) { childCoord.y += childCoord.size; } } @@ -87,7 +93,7 @@ private: } }; -PixelQuadTreeNode::PixelQuadTreeNode(PixelQuadTreeCoordinates coord, SquarePixelMap *pixelMap) : _coord(coord), _minimumNeighbourhoodAplha(-1) { +PixelQuadTreeNode::PixelQuadTreeNode(PixelQuadTreeCoordinates coord, SquarePixelMap* pixelMap) : _coord(coord), _minimumNeighbourhoodAplha(-1) { for (int i = 0; i < 4; i++) { _children[i] = NULL; } @@ -133,14 +139,14 @@ PixelQuadTreeNode::PixelQuadTreeNode(PixelQuadTreeCoordinates coord, SquarePixel } } -SquarePixelMap::SquarePixelMap(const uint32_t *pixels, int dimension) : _rootPixelQuadTreeNode(NULL) { +SquarePixelMap::SquarePixelMap(const uint32_t* pixels, int dimension) : _rootPixelQuadTreeNode(NULL) { _data = new SquarePixelMapData(); _data->dimension = dimension; _data->reference_counter = 1; size_t pixels_size = dimension * dimension; _data->pixels = new uint32_t[pixels_size]; - memcpy((void *)_data->pixels, (void *)pixels, sizeof(uint32_t) * pixels_size); + memcpy((void*)_data->pixels, (void*)pixels, sizeof(uint32_t) * pixels_size); } SquarePixelMap::SquarePixelMap(const SquarePixelMap& other) { @@ -157,7 +163,7 @@ SquarePixelMap::~SquarePixelMap() { } } -void SquarePixelMap::addVoxelsToVoxelTree(VoxelTree *voxelTree) { +void SquarePixelMap::addVoxelsToVoxelTree(VoxelTree* voxelTree) { this->generateRootPixelQuadTreeNode(); this->createVoxelsFromPixelQuadTreeToVoxelTree(_rootPixelQuadTreeNode, voxelTree); } @@ -177,7 +183,7 @@ uint8_t SquarePixelMap::getAlphaAt(int x, int y) { return -1; } - return this->getPixelAt(x, y) >> 24; + return this->getPixelAt(x, y) >> ALPHA_CHANNEL_BIT_OFFSET; } void SquarePixelMap::generateRootPixelQuadTreeNode() { @@ -190,20 +196,20 @@ void SquarePixelMap::generateRootPixelQuadTreeNode() { _rootPixelQuadTreeNode = new PixelQuadTreeNode(rootNodeCoord, this); } -void SquarePixelMap::createVoxelsFromPixelQuadTreeToVoxelTree(PixelQuadTreeNode *pixelQuadTreeNode, VoxelTree *voxelTree) { +void SquarePixelMap::createVoxelsFromPixelQuadTreeToVoxelTree(PixelQuadTreeNode* pixelQuadTreeNode, VoxelTree* voxelTree) { if (pixelQuadTreeNode->_allChildrenHasSameColor) { VoxelDetail voxel = this->getVoxelDetail(pixelQuadTreeNode); unsigned char minimumNeighbourhoodAplha = std::max(0, pixelQuadTreeNode->_minimumNeighbourhoodAplha - 1); - float minimumNeighbourhoodY = voxel.s * (floor(minimumNeighbourhoodAplha / (256.f * voxel.s)) + 0.5); + float minimumNeighbourhoodY = voxel.s * (floor(minimumNeighbourhoodAplha / (ALPHA_CHANNEL_RANGE_FLOAT * voxel.s)) + 0.5); do { voxelTree->createVoxel(voxel.x, voxel.y, voxel.z, voxel.s, voxel.red, voxel.green, voxel.blue, true); } while ((voxel.y -= voxel.s) > minimumNeighbourhoodY); } else { for (int i = 0; i < 4; i++) { - PixelQuadTreeNode *child = pixelQuadTreeNode->_children[i]; + PixelQuadTreeNode* child = pixelQuadTreeNode->_children[i]; if (child) { this->createVoxelsFromPixelQuadTreeToVoxelTree(child, voxelTree); } @@ -211,21 +217,21 @@ void SquarePixelMap::createVoxelsFromPixelQuadTreeToVoxelTree(PixelQuadTreeNode } } -VoxelDetail SquarePixelMap::getVoxelDetail(PixelQuadTreeNode *pixelQuadTreeNode) { +VoxelDetail SquarePixelMap::getVoxelDetail(PixelQuadTreeNode* pixelQuadTreeNode) { VoxelDetail voxel = VoxelDetail(); uint32_t color = pixelQuadTreeNode->_color; - unsigned char alpha = std::max(0, (color >> 24) - 1); + unsigned char alpha = std::max(0, (color >> ALPHA_CHANNEL_BIT_OFFSET) - 1); - voxel.red = color >> 16; - voxel.green = color >> 8; + voxel.red = color >> RED_CHANNEL_BIT_OFFSET; + voxel.green = color >> GREEN_CHANNEL_BIT_OFFSET; voxel.blue = color; float rootSize = _rootPixelQuadTreeNode->_coord.size; voxel.s = pixelQuadTreeNode->_coord.size / rootSize; - voxel.y = voxel.s * (floor(alpha / (256.f * voxel.s)) + 0.5); + voxel.y = voxel.s * (floor(alpha / (ALPHA_CHANNEL_RANGE_FLOAT * voxel.s)) + 0.5); voxel.x = pixelQuadTreeNode->_coord.x / rootSize + voxel.s / 2; voxel.z = pixelQuadTreeNode->_coord.y / rootSize + voxel.s / 2; diff --git a/libraries/voxels/src/SquarePixelMap.h b/libraries/voxels/src/SquarePixelMap.h index 9a4fb4bb04..0ef6dc55ee 100644 --- a/libraries/voxels/src/SquarePixelMap.h +++ b/libraries/voxels/src/SquarePixelMap.h @@ -23,22 +23,22 @@ struct SquarePixelMapData { class SquarePixelMap { public: - SquarePixelMap(const uint32_t *pixels, int dimension); + SquarePixelMap(const uint32_t* pixels, int dimension); SquarePixelMap(const SquarePixelMap& other); ~SquarePixelMap(); - void addVoxelsToVoxelTree(VoxelTree *voxelTree); + void addVoxelsToVoxelTree(VoxelTree* voxelTree); int dimension(); uint32_t getPixelAt(unsigned int x, unsigned int y); uint8_t getAlphaAt(int x, int y); private: - SquarePixelMapData *_data; - PixelQuadTreeNode *_rootPixelQuadTreeNode; + SquarePixelMapData* _data; + PixelQuadTreeNode* _rootPixelQuadTreeNode; void generateRootPixelQuadTreeNode(); - void createVoxelsFromPixelQuadTreeToVoxelTree(PixelQuadTreeNode *pixelQuadTreeNode, VoxelTree *voxelTree); - VoxelDetail getVoxelDetail(PixelQuadTreeNode *pixelQuadTreeNode); + void createVoxelsFromPixelQuadTreeToVoxelTree(PixelQuadTreeNode* pixelQuadTreeNode, VoxelTree* voxelTree); + VoxelDetail getVoxelDetail(PixelQuadTreeNode* pixelQuadTreeNode); }; #endif /* defined(__hifi__SquarePixelMap__) */ diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 417fdcd5d5..b16425370e 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1449,7 +1449,7 @@ bool VoxelTree::readFromSVOFile(const char* fileName) { return false; } -bool VoxelTree::readFromSquareARGB32Pixels(const uint32_t *pixels, int dimension) { +bool VoxelTree::readFromSquareARGB32Pixels(const uint32_t* pixels, int dimension) { SquarePixelMap pixelMap = SquarePixelMap(pixels, dimension); pixelMap.addVoxelsToVoxelTree(this); return true; diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 42eddaecdd..72ea9e2326 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -134,7 +134,7 @@ public: void writeToSVOFile(const char* filename, VoxelNode* node = NULL) const; bool readFromSVOFile(const char* filename); // reads voxels from square image with alpha as a Y-axis - bool readFromSquareARGB32Pixels(const uint32_t *pixels, int dimension); + bool readFromSquareARGB32Pixels(const uint32_t* pixels, int dimension); unsigned long getVoxelCount();