DeleteVoxelCommand::DeleteVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditPacketSender* packetSender, QUndoCommand* parent) : QUndoCommand("Delete Voxel", parent), _tree(tree), _packetSender(packetSender), _voxel(voxel), _oldTree(NULL) { _tree->lockForRead(); VoxelTreeElement* element = _tree->getEnclosingVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); if (element->getScale() == _voxel.s) { if (!element->hasContent() && !element->isLeaf()) { _oldTree = new VoxelTree(); _tree->copySubTreeIntoNewTree(element, _oldTree, false); } else { _voxel.red = element->getColor()[0]; _voxel.green = element->getColor()[1]; _voxel.blue = element->getColor()[2]; } } else if (element->hasContent() && element->isLeaf()) { _voxel.red = element->getColor()[0]; _voxel.green = element->getColor()[1]; _voxel.blue = element->getColor()[2]; } else { _voxel.s = 0.0f; } _tree->unlock(); }
bool VoxelTree::nudgeCheck(OctreeElement* element, void* extraData) { VoxelTreeElement* voxel = (VoxelTreeElement*)element; if (voxel->isLeaf()) { // we have reached the deepest level of elements/voxels // now there are two scenarios // 1) this element's size is <= the minNudgeAmount // in which case we will simply call nudgeLeaf on this leaf // 2) this element's size is still not <= the minNudgeAmount // in which case we need to break this leaf down until the leaf sizes are <= minNudgeAmount NodeChunkArgs* args = (NodeChunkArgs*)extraData; // get octal code of this element const unsigned char* octalCode = element->getOctalCode(); // get voxel position/size VoxelPositionSize unNudgedDetails; voxelDetailsForCode(octalCode, unNudgedDetails); // find necessary leaf size float newLeafSize = findNewLeafSize(args->nudgeVec, unNudgedDetails.s); // check to see if this unNudged element can be nudged if (unNudgedDetails.s <= newLeafSize) { args->thisVoxelTree->nudgeLeaf(voxel, extraData); return false; } else { // break the current leaf into smaller chunks args->thisVoxelTree->chunkifyLeaf(voxel); } } return true; }
bool copyAndFillOperation(OctreeElement* element, void* extraData) { VoxelTreeElement* voxel = (VoxelTreeElement*)element; copyAndFillArgs* args = (copyAndFillArgs*)extraData; char outputMessage[128]; args->inCount++; int percentDone = (100*args->inCount/args->originalCount); // For each leaf node... if (voxel->isLeaf()) { // create a copy of the leaf in the copy destination float x = voxel->getCorner().x; float y = voxel->getCorner().y; float z = voxel->getCorner().z; float s = voxel->getScale(); unsigned char red = voxel->getTrueColor()[RED_INDEX]; unsigned char green = voxel->getTrueColor()[GREEN_INDEX]; unsigned char blue = voxel->getTrueColor()[BLUE_INDEX]; bool destructive = true; args->destinationTree->createVoxel(x, y, z, s, red, green, blue, destructive); args->outCount++; sprintf(outputMessage,"Completed: %d%% (%lu of %lu) - Creating voxel %lu at [%f,%f,%f,%f]", percentDone,args->inCount,args->originalCount,args->outCount,x,y,z,s); printf("%s",outputMessage); for (int b = 0; b < strlen(outputMessage); b++) { printf("\b"); } // and create same sized leafs from this leaf voxel down to zero in the destination tree for (float yFill = y-s; yFill >= 0.0f; yFill -= s) { args->destinationTree->createVoxel(x, yFill, z, s, red, green, blue, destructive); args->outCount++; sprintf(outputMessage,"Completed: %d%% (%lu of %lu) - Creating fill voxel %lu at [%f,%f,%f,%f]", percentDone,args->inCount,args->originalCount,args->outCount,x,y,z,s); printf("%s",outputMessage); for (int b = 0; b < strlen(outputMessage); b++) { printf("\b"); } } } return true; }
// will detect if children are leaves AND the same color // and in that case will delete the children and make this node // a leaf, returns TRUE if all the leaves are collapsed into a // single node bool VoxelTreeElement::collapseChildren() { // scan children, verify that they are ALL present and accounted for bool allChildrenMatch = true; // assume the best (ottimista) int red,green,blue; for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { VoxelTreeElement* childAt = getChildAtIndex(i); // if no child, child isn't a leaf, or child doesn't have a color if (!childAt || !childAt->isLeaf() || !childAt->isColored()) { allChildrenMatch=false; //qDebug("SADNESS child missing or not colored! i=%d\n",i); break; } else { if (i==0) { red = childAt->getColor()[0]; green = childAt->getColor()[1]; blue = childAt->getColor()[2]; } else if (red != childAt->getColor()[0] || green != childAt->getColor()[1] || blue != childAt->getColor()[2]) { allChildrenMatch=false; break; } } } if (allChildrenMatch) { //qDebug("allChildrenMatch: pruning tree\n"); for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { OctreeElement* childAt = getChildAtIndex(i); delete childAt; // delete all the child nodes setChildAtIndex(i, NULL); // set it to NULL } nodeColor collapsedColor; collapsedColor[0]=red; collapsedColor[1]=green; collapsedColor[2]=blue; collapsedColor[3]=1; // color is set setColor(collapsedColor); } return allChildrenMatch; }