From 46c6f2f9b5f3add89a29fb695a53401a68c5057f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 29 May 2013 15:02:28 -0700 Subject: [PATCH] latest copy paste --- interface/src/Application.cpp | 13 +++++++- interface/src/Application.h | 2 ++ interface/src/VoxelSystem.cpp | 9 ++++++ interface/src/VoxelSystem.h | 4 +++ interface/src/main.cpp | 13 -------- libraries/shared/src/OctalCode.cpp | 16 ++++++--- libraries/shared/src/OctalCode.h | 1 + libraries/voxels/src/VoxelTree.cpp | 52 ++++++++++++++++++++++++------ libraries/voxels/src/VoxelTree.h | 26 +++++++-------- 9 files changed, 95 insertions(+), 41 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 95e3e5f1c1..7f5eeccd76 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1159,6 +1159,7 @@ void Application::copyVoxels() { printf("copyVoxels() _mouseVoxel: %f,%f,%f-%f \n", _mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); if (selectedNode) { selectedNode->printDebugDetails("selected voxel"); + _voxels.copySubTreeIntoNewTree(selectedNode, &_clipboardTree, true); } } @@ -1166,7 +1167,17 @@ void Application::pasteVoxels() { VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); printf("pasteVoxels() _mouseVoxel: %f,%f,%f-%f \n", _mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); if (selectedNode) { - selectedNode->printDebugDetails("selected voxel"); + //selectedNode->printDebugDetails("selected voxel"); + + // First, create a temporary Paste Tree + VoxelTree _temporaryPasteTree; + + // Create a destination node to paste into + _temporaryPasteTree.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s, 0, 0, 0); + + // Paste into the temporary tree + destinationNode = _temporaryPasteTree.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); + _temporaryPasteTree.copyFromTreeIntoSubTree(&_clipboardTree, destinationNode); } } diff --git a/interface/src/Application.h b/interface/src/Application.h index 57605f8cc5..85d5d7ef43 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -184,6 +184,8 @@ private: Stars _stars; VoxelSystem _voxels; + VoxelTree _clipboardTree; // if I copy/paste + QByteArray _voxelsFilename; bool _wantToKillLocalVoxels; diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 2a0a7e7a7a..359e5b77af 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -1156,3 +1156,12 @@ void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bo _tree->createSphere(r, xc, yc, zc, s, solid, mode, destructive, debug); setupNewVoxelsForDrawing(); }; + +void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinationTree, bool rebaseToRoot) { + _tree->copySubTreeIntoNewTree(startNode, destinationTree, rebaseToRoot); +} + +void VoxelSystem::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destinationNode) { + _tree->copyFromTreeIntoSubTree(sourceTree, destinationNode); +} + diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 1aeb66a7c6..c15ba53ba0 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -85,6 +85,10 @@ public: void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive = false); void createSphere(float r,float xc, float yc, float zc, float s, bool solid, creationMode mode, bool destructive = false, bool debug = false); + + void copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinationTree, bool rebaseToRoot); + void copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destinationNode); + private: // disallow copying of VoxelSystem objects VoxelSystem(const VoxelSystem&); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 5091eb9f4f..8894e5bd7c 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -21,19 +21,6 @@ #include int main(int argc, const char * argv[]) { - - unsigned char test1[2] = {2, 0xE0 }; - unsigned char test2[2] = {2, 0xFC }; - - unsigned char* result1 = chopOctalCode((unsigned char*)&test1, 1); - - printOctalCode((unsigned char*)&test1); - printOctalCode(result1); - - unsigned char* result2 = chopOctalCode((unsigned char*)&test2, 1); - printOctalCode((unsigned char*)&test2); - printOctalCode(result2); - timeval startup_time; gettimeofday(&startup_time, NULL); diff --git a/libraries/shared/src/OctalCode.cpp b/libraries/shared/src/OctalCode.cpp index b69136ddb6..f331545b33 100644 --- a/libraries/shared/src/OctalCode.cpp +++ b/libraries/shared/src/OctalCode.cpp @@ -170,14 +170,18 @@ OctalCodeComparison compareOctalCodes(unsigned char* codeA, unsigned char* codeB char getOctalCodeSectionValue(unsigned char* octalCode, int section) { - return sectionValue(octalCode + 1 + (3 * section / 8), (3 * section) % 8); + int startAtByte = 1 + (3 * section / 8); + char startIndexInByte = (3 * section) % 8; + unsigned char* startByte = octalCode + startAtByte; + + return sectionValue(startByte, startIndexInByte); } void setOctalCodeSectionValue(unsigned char* octalCode, int section, char sectionValue) { unsigned char* byteAt = octalCode + 1 + (3 * section / 8); char bitInByte = (3 * section) % 8; char shiftBy = 8 - bitInByte - 3; - const unsigned char UNSHIFTED_MASK = 0x03; + const unsigned char UNSHIFTED_MASK = 0x07; unsigned char shiftedMask; unsigned char shiftedValue; @@ -190,13 +194,17 @@ void setOctalCodeSectionValue(unsigned char* octalCode, int section, char sectio shiftedValue = sectionValue >> -shiftBy; } - byteAt[0] = byteAt[0] & (shiftedMask | shiftedValue); + unsigned char oldValue = *byteAt & ~shiftedMask; + unsigned char newValue = oldValue | shiftedValue; + *byteAt = newValue; if (bitInByte >= 6) { shiftBy = bitInByte + 1; shiftedMask = UNSHIFTED_MASK << shiftBy; shiftedValue = sectionValue << shiftBy; - byteAt[1] = byteAt[1] & (shiftedMask | shiftedValue); + oldValue = byteAt[1] & ~shiftedMask; + newValue = oldValue | shiftedValue; + byteAt[1] = newValue; } } diff --git a/libraries/shared/src/OctalCode.h b/libraries/shared/src/OctalCode.h index bce7a066b9..1849989cc3 100644 --- a/libraries/shared/src/OctalCode.h +++ b/libraries/shared/src/OctalCode.h @@ -19,6 +19,7 @@ unsigned char * childOctalCode(unsigned char * parentOctalCode, char childNumber unsigned char* chopOctalCode(unsigned char* originalOctalCode, int chopLevels); unsigned char* rebaseOctalCode(unsigned char* originalOctalCode, unsigned char* newParentOctalCode); +int numberOfThreeBitSectionsInCode(unsigned char * octalCode); // Note: copyFirstVertexForCode() is preferred because it doesn't allocate memory for the return diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index a0864964a2..562cfcc88c 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -212,10 +212,15 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, } void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes, - bool includeColor, bool includeExistsBits) { + bool includeColor, bool includeExistsBits, VoxelNode* destinationNode) { int bytesRead = 0; unsigned char* bitstreamAt = bitstream; + // If destination node is not included, set it to root + if (!destinationNode) { + destinationNode = rootNode; + } + _nodesChangedFromBitstream = 0; // Keep looping through the buffer calling readNodeData() this allows us to pack multiple root-relative Octal codes @@ -223,14 +228,14 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int // if there are more bytes after that, it's assumed to be another root relative tree while (bitstreamAt < bitstream + bufferSizeBytes) { - VoxelNode* bitstreamRootNode = nodeForOctalCode(rootNode, (unsigned char *)bitstreamAt, NULL); + VoxelNode* bitstreamRootNode = nodeForOctalCode(destinationNode, (unsigned char *)bitstreamAt, NULL); if (*bitstreamAt != *bitstreamRootNode->getOctalCode()) { // if the octal code returned is not on the same level as // the code being searched for, we have VoxelNodes to create // Note: we need to create this node relative to root, because we're assuming that the bitstream for the initial // octal code is always relative to root! - bitstreamRootNode = createMissingNode(rootNode, (unsigned char*) bitstreamAt); + bitstreamRootNode = createMissingNode(destinationNode, (unsigned char*) bitstreamAt); if (bitstreamRootNode->isDirty()) { _isDirty = true; _nodesChangedFromBitstream++; @@ -862,7 +867,7 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits, - bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const { + int chopLevels, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const { // How many bytes have we written so far at this level; int bytesWritten = 0; @@ -882,7 +887,7 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned int currentEncodeLevel = 0; int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel, node, outputBuffer, availableBytes, - bag, viewFrustum, includeColor, includeExistsBits, + bag, viewFrustum, includeColor, includeExistsBits, chopLevels, deltaViewFrustum, lastViewFrustum); // if childBytesWritten == 1 then something went wrong... that's not possible @@ -907,7 +912,7 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits, - bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const { + int chopLevels, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const { // How many bytes have we written so far at this level; int bytesAtThisLevel = 0; @@ -1062,7 +1067,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco int thisLevel = currentEncodeLevel; int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode, outputBuffer, availableBytes, bag, - viewFrustum, includeColor, includeExistsBits, + viewFrustum, includeColor, includeExistsBits, chopLevels, deltaViewFrustum, lastViewFrustum); // if the child wrote 0 bytes, it means that nothing below exists or was in view, or we ran out of space, @@ -1173,6 +1178,12 @@ void VoxelTree::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinat VoxelNodeBag nodeBag; // If we were given a specific node, start from there, otherwise start from root nodeBag.insert(startNode); + + int chopLevels = 0; + + if (rebaseToRoot) { + chopLevels = numberOfThreeBitSectionsInCode(startNode->getOctalCode()); + } static unsigned char outputBuffer[MAX_VOXEL_PACKET_SIZE - 1]; // save on allocs by making this static int bytesWritten = 0; @@ -1182,11 +1193,32 @@ void VoxelTree::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinat // ask our tree to write a bitsteam bytesWritten = encodeTreeBitstream(INT_MAX, subTree, &outputBuffer[0], - MAX_VOXEL_PACKET_SIZE - 1, nodeBag, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS); + MAX_VOXEL_PACKET_SIZE - 1, nodeBag, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS, chopLevels); // ask destination tree to read the bitstream destinationTree->readBitstreamToTree(&outputBuffer[0], bytesWritten, WANT_COLOR, NO_EXISTS_BITS); } - - } + +void VoxelTree::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destinationNode) { + printLog("copyFromTreeIntoSubTree()...\n"); + + VoxelNodeBag nodeBag; + // If we were given a specific node, start from there, otherwise start from root + nodeBag.insert(sourceTree->rootNode); + + static unsigned char outputBuffer[MAX_VOXEL_PACKET_SIZE - 1]; // save on allocs by making this static + int bytesWritten = 0; + + while (!nodeBag.isEmpty()) { + VoxelNode* subTree = nodeBag.extract(); + + // ask our tree to write a bitsteam + bytesWritten = sourceTree->encodeTreeBitstream(INT_MAX, subTree, &outputBuffer[0], + MAX_VOXEL_PACKET_SIZE - 1, nodeBag, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS); + + // ask destination tree to read the bitstream + readBitstreamToTree(&outputBuffer[0], bytesWritten, WANT_COLOR, NO_EXISTS_BITS); + } +} + diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index eccc4e0434..a2302f6cc7 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -44,19 +44,20 @@ public: VoxelTree(bool shouldReaverage = false); ~VoxelTree(); - VoxelNode *rootNode; + VoxelNode* rootNode; int leavesWrittenToBitstream; void eraseAllVoxels(); - void processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes); - void readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes, - bool includeColor = WANT_COLOR, bool includeExistsBits = WANT_EXISTS_BITS); - void readCodeColorBufferToTree(unsigned char *codeColorBuffer, bool destructive = false); - void deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage = ACTUALLY_DELETE, + void processRemoveVoxelBitstream(unsigned char* bitstream, int bufferSizeBytes); + void readBitstreamToTree(unsigned char* bitstream, unsigned long int bufferSizeBytes, + bool includeColor = WANT_COLOR, bool includeExistsBits = WANT_EXISTS_BITS, + VoxelNode* destinationNode = NULL); + void readCodeColorBufferToTree(unsigned char* codeColorBuffer, bool destructive = false); + void deleteVoxelCodeFromTree(unsigned char* codeBuffer, bool stage = ACTUALLY_DELETE, bool collapseEmptyTrees = DONT_COLLAPSE); - void printTreeForDebugging(VoxelNode *startNode); - void reaverageVoxelColors(VoxelNode *startNode); + void printTreeForDebugging(VoxelNode* startNode); + void reaverageVoxelColors(VoxelNode* startNode); void deleteVoxelAt(float x, float y, float z, float s, bool stage = false); VoxelNode* getVoxelAt(float x, float y, float z, float s) const; @@ -70,7 +71,7 @@ public: int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, const ViewFrustum* viewFrustum, - bool includeColor = WANT_COLOR, bool includeExistsBits = WANT_EXISTS_BITS, + bool includeColor = WANT_COLOR, bool includeExistsBits = WANT_EXISTS_BITS, int chopLevels = 0, bool deltaViewFrustum = false, const ViewFrustum* lastViewFrustum = NULL) const; int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag, @@ -97,20 +98,19 @@ public: unsigned long getVoxelCount(); void copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinationTree, bool rebaseToRoot); - void copyNodeIntoTree(VoxelNode* node); + void copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destinationNode); private: int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, - const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits, - bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const; + const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits, + int chopLevels, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const; int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum); static bool countVoxelsOperation(VoxelNode* node, void* extraData); - static bool copySubTreeIntoNewTreeOperation(VoxelNode* node, void* extraData); void recurseNodeWithOperation(VoxelNode* node, RecurseVoxelTreeOperation operation, void* extraData); VoxelNode* nodeForOctalCode(VoxelNode* ancestorNode, unsigned char* needleCode, VoxelNode** parentOfFoundNode) const;