void recursivelyMarkIf(Node* start, const NodeConditional& nc) { if (nc(&*start)) { start->mark |= MARK_KEEP | MARK_KEEP_KIDS; for (ChildIterator ci = childBegin(start); !ci.done(); ++ci) { recursivelyMarkIf(&*ci, nc); } } else { start->mark |= MARK_KEEP; } }
/*! Destroys children of nodes that are not marked, defragments the node array always keeps the root Note: invalidates all pointers to nodes of the tree, and all iterators. */ void eraseChildrenOfUnmarkedNodes() { unsigned int write = 0; nodes[root_index].mark = MARK_KEEP; assert(root_index < allocation_index); for (unsigned int read = root_index; read != allocation_index; read++) { Node *node = &nodes[read]; char mark = node->mark; if (mark) { // TODO: could handle read == write as a special case Node *write_node = &nodes[write]; *write_node = *node; // copy write_node->mark = 0; // clear mark if (mark & MARK_KEEP_KIDS) { // adjust children's parent pointers for (ChildIterator it = childBegin(write_node); !it.done(); ++it) { it->parent = write; } } else { write_node->num_children = 0; } // adjust parent's first_child "pointer" if this is its first child if (read != root_index) { Node* parent_node = getParent(node); if (write < parent_node->first_child) { parent_node->first_child = write; } } write++; } } root_index = 0; nodes[root_index].parent = 0; allocation_index = write; }