示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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()); 
        }
    }
}