| 63 | |
| 64 | |
| 65 | size_t BuPyramid::queueWork(CellManager& cells) |
| 66 | { |
| 67 | std::set<VoxelKey> needed; |
| 68 | std::set<VoxelKey> parentsToProcess; |
| 69 | std::vector<OctantInfo> have; |
| 70 | const VoxelKey root; |
| 71 | |
| 72 | for (auto& kv : cells) |
| 73 | { |
| 74 | VoxelKey k = kv.first; |
| 75 | PointViewPtr v = kv.second; |
| 76 | |
| 77 | // Stick an OctantInfo for this cell in the 'have' list. |
| 78 | OctantInfo o(k); |
| 79 | o.source() = v; |
| 80 | have.push_back(o); |
| 81 | |
| 82 | // Walk up the tree and make sure that we're populated for all children necessary |
| 83 | // to process to the top level. We do this in order to facilitate processing -- |
| 84 | // a parent node is ready to be processed when all its children have been processed, |
| 85 | // so making sure a parent has all 8 children makes this easy. |
| 86 | while (k != root) |
| 87 | { |
| 88 | k = k.parent(); |
| 89 | parentsToProcess.insert(k); |
| 90 | for (int i = 0; i < 8; ++i) |
| 91 | needed.insert(k.child(i)); |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | // Now remove entries for the cells we have and their parents. |
| 96 | for (const OctantInfo& o : have) |
| 97 | { |
| 98 | VoxelKey k = o.key(); |
| 99 | while (k != root) |
| 100 | { |
| 101 | needed.erase(k); |
| 102 | k = k.parent(); |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | // Queue what we have. |
| 107 | for (const OctantInfo& o : have) |
| 108 | m_manager.queue(o); |
| 109 | |
| 110 | // Queue what we need but have no data for. |
| 111 | for (const VoxelKey& k : needed) |
| 112 | m_manager.queue(OctantInfo(k)); |
| 113 | return parentsToProcess.size(); |
| 114 | } |
| 115 | |
| 116 | } // namespace copcwriter |
| 117 | } // namespace pdal |