void MetavoxelData::expand() { for (QHash<AttributePointer, MetavoxelNode*>::iterator it = _roots.begin(); it != _roots.end(); it++) { MetavoxelNode* newParent = new MetavoxelNode(it.key()); for (int i = 0; i < MetavoxelNode::CHILD_COUNT; i++) { MetavoxelNode* newChild = new MetavoxelNode(it.key()); newParent->setChild(i, newChild); int index = getOppositeIndex(i); if (it.value()->isLeaf()) { newChild->setChild(index, new MetavoxelNode(it.value()->getAttributeValue(it.key()))); } else { MetavoxelNode* grandchild = it.value()->getChild(i); grandchild->incrementReferenceCount(); newChild->setChild(index, grandchild); } for (int j = 1; j < MetavoxelNode::CHILD_COUNT; j++) { MetavoxelNode* newGrandchild = new MetavoxelNode(it.key()); newChild->setChild((index + j) % MetavoxelNode::CHILD_COUNT, newGrandchild); } newChild->mergeChildren(it.key()); } newParent->mergeChildren(it.key()); it.value()->decrementReferenceCount(it.key()); it.value() = newParent; } _size *= 2.0f; }
MetavoxelNode* Attribute::expandMetavoxelRoot(const MetavoxelNode& root) { AttributePointer attribute(this); MetavoxelNode* newParent = new MetavoxelNode(attribute); for (int i = 0; i < MetavoxelNode::CHILD_COUNT; i++) { MetavoxelNode* newChild = new MetavoxelNode(attribute); newParent->setChild(i, newChild); int index = MetavoxelNode::getOppositeChildIndex(i); if (root.isLeaf()) { newChild->setChild(index, new MetavoxelNode(root.getAttributeValue(attribute))); } else { MetavoxelNode* grandchild = root.getChild(i); grandchild->incrementReferenceCount(); newChild->setChild(index, grandchild); } for (int j = 1; j < MetavoxelNode::CHILD_COUNT; j++) { MetavoxelNode* newGrandchild = new MetavoxelNode(attribute); newChild->setChild((index + j) % MetavoxelNode::CHILD_COUNT, newGrandchild); } newChild->mergeChildren(attribute); } newParent->mergeChildren(attribute); return newParent; }
void DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) { visitation.info.isLeaf = visitation.allInputNodesLeaves(); bool keepGoing = visitation.visitor.visit(visitation.info); for (int i = 0; i < visitation.outputNodes.size(); i++) { AttributeValue& value = visitation.info.outputValues[i]; if (!value.getAttribute()) { continue; } MetavoxelNode*& node = visitation.outputNodes[i]; if (node && node->isLeaf() && value.getAttribute()->equal(value.getValue(), node->getAttributeValue())) { // "set" to same value; disregard value = AttributeValue(); } else { node = new MetavoxelNode(value); } } if (!keepGoing) { return; } MetavoxelVisitation nextVisitation = { &visitation, visitation.visitor, QVector<MetavoxelNode*>(visitation.inputNodes.size()), QVector<MetavoxelNode*>(visitation.outputNodes.size()), { glm::vec3(), visitation.info.size * 0.5f, QVector<AttributeValue>(visitation.inputNodes.size()), QVector<AttributeValue>(visitation.outputNodes.size()) } }; for (int i = 0; i < MetavoxelNode::CHILD_COUNT; i++) { for (int j = 0; j < visitation.inputNodes.size(); j++) { MetavoxelNode* node = visitation.inputNodes.at(j); MetavoxelNode* child = node ? node->getChild(i) : NULL; nextVisitation.info.inputValues[j] = ((nextVisitation.inputNodes[j] = child)) ? child->getAttributeValue(visitation.info.inputValues[j].getAttribute()) : visitation.info.inputValues[j]; } for (int j = 0; j < visitation.outputNodes.size(); j++) { MetavoxelNode* node = visitation.outputNodes.at(j); MetavoxelNode* child = node ? node->getChild(i) : NULL; nextVisitation.outputNodes[j] = child; } nextVisitation.info.minimum = visitation.info.minimum + glm::vec3( (i & X_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f, (i & Y_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f, (i & Z_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f); static_cast<MetavoxelGuide*>(nextVisitation.info.inputValues.last().getInlineValue< PolymorphicDataPointer>().data())->guide(nextVisitation); for (int j = 0; j < nextVisitation.outputNodes.size(); j++) { AttributeValue& value = nextVisitation.info.outputValues[j]; if (!value.getAttribute()) { continue; } // replace the child AttributeValue& parentValue = visitation.info.outputValues[j]; if (!parentValue.getAttribute()) { // shallow-copy the parent node on first change parentValue = value; MetavoxelNode*& node = visitation.outputNodes[j]; if (node) { node = new MetavoxelNode(value.getAttribute(), node); } else { // create leaf with inherited value node = new MetavoxelNode(visitation.getInheritedOutputValue(j)); } } MetavoxelNode* node = visitation.outputNodes.at(j); MetavoxelNode* child = node->getChild(i); if (child) { child->decrementReferenceCount(value.getAttribute()); } else { // it's a leaf; we need to split it up AttributeValue nodeValue = node->getAttributeValue(value.getAttribute()); for (int k = 1; k < MetavoxelNode::CHILD_COUNT; k++) { node->setChild((i + k) % MetavoxelNode::CHILD_COUNT, new MetavoxelNode(nodeValue)); } } node->setChild(i, nextVisitation.outputNodes.at(j)); value = AttributeValue(); } } for (int i = 0; i < visitation.outputNodes.size(); i++) { AttributeValue& value = visitation.info.outputValues[i]; if (value.getAttribute()) { MetavoxelNode* node = visitation.outputNodes.at(i); node->mergeChildren(value.getAttribute()); value = node->getAttributeValue(value.getAttribute()); } } }