diff --git a/docs/roadmap/streaming-and-tiling.md b/docs/roadmap/streaming-and-tiling.md index b0dd9d6..819e2da 100644 --- a/docs/roadmap/streaming-and-tiling.md +++ b/docs/roadmap/streaming-and-tiling.md @@ -46,8 +46,13 @@ usdCopc_runtime_streaming_probe C:\path\to\sample.copc --level 3 ``` This measures the source-side portion of the runtime-streaming question. -Host LOD policy, OpenUSD payload composition, and renderer loading remain -outside the probe and are still research work. +The TSV summary also includes `selected_tile_ids` and +`selected_tile_ranges`. The comma-separated values are aligned by position: +tile identities use `L///`, while ranges use +`:`. This makes a deterministic source-read selection +available for comparison with host observations. Host LOD policy, OpenUSD +payload composition, and renderer loading remain outside the probe and are +still research work. ## 1. Problem statement diff --git a/libs/usd-copc/benchmarks/runtime_streaming_probe.cpp b/libs/usd-copc/benchmarks/runtime_streaming_probe.cpp index 5f5cf59..2846325 100644 --- a/libs/usd-copc/benchmarks/runtime_streaming_probe.cpp +++ b/libs/usd-copc/benchmarks/runtime_streaming_probe.cpp @@ -100,6 +100,17 @@ bool MakeEntry(const usdcopc::CopcPointTile& tile, return entry.IsValid() && entry.IsPointData(); } +std::string TileIdentity(const usdcopc::CopcPointTile& tile) { + const auto& id = tile.tile.id; + return "L" + std::to_string(id.level) + "/" + std::to_string(id.x) + + "/" + std::to_string(id.y) + "/" + std::to_string(id.z); +} + +std::string TileRange(const usdcopc::CopcPointTile& tile) { + return std::to_string(tile.pointDataOffset) + ":" + + std::to_string(tile.pointDataSize); +} + } // namespace int main(int argc, char** argv) { @@ -154,6 +165,8 @@ int main(int argc, char** argv) { std::uint64_t selectedPointRangeBytes = 0; std::uint64_t decodedPoints = 0; + std::vector selectedTileIds; + std::vector selectedTileRanges; for (const auto* tile : selectedTiles) { usdcopc::CopcHierarchyEntry entry; if (!MakeEntry(*tile, entry)) { @@ -167,14 +180,26 @@ int main(int argc, char** argv) { } selectedPointRangeBytes += tile->pointDataSize; decodedPoints += static_cast(points.size()); + selectedTileIds.push_back(TileIdentity(*tile)); + selectedTileRanges.push_back(TileRange(*tile)); } std::cout << "input\tlevel\thierarchy_nodes\tpoint_tiles\tselected_tiles\t" - "decoded_points\tselected_point_range_bytes\tsource_bytes_read\n" + "decoded_points\tselected_point_range_bytes\tsource_bytes_read\t" + "selected_tile_ids\tselected_tile_ranges\n" << options.inputPath << '\t' << options.level << '\t' << hierarchy.nodes.size() << '\t' << tiles.size() << '\t' << selectedTiles.size() << '\t' << decodedPoints << '\t' - << selectedPointRangeBytes << '\t' << source->BytesRead() - << '\n'; + << selectedPointRangeBytes << '\t' << source->BytesRead() << '\t'; + for (std::size_t index = 0; index < selectedTileIds.size(); ++index) { + if (index != 0) std::cout << ','; + std::cout << selectedTileIds[index]; + } + std::cout << '\t'; + for (std::size_t index = 0; index < selectedTileRanges.size(); ++index) { + if (index != 0) std::cout << ','; + std::cout << selectedTileRanges[index]; + } + std::cout << '\n'; return 0; } \ No newline at end of file diff --git a/libs/usd-copc/benchmarks/test_runtime_streaming_probe.cmake b/libs/usd-copc/benchmarks/test_runtime_streaming_probe.cmake index d3a925f..c5904ab 100644 --- a/libs/usd-copc/benchmarks/test_runtime_streaming_probe.cmake +++ b/libs/usd-copc/benchmarks/test_runtime_streaming_probe.cmake @@ -30,7 +30,46 @@ endif() if(NOT probe_output MATCHES "selected_point_range_bytes") message(FATAL_ERROR "probe output is missing range accounting: ${probe_output}") endif() -if(NOT probe_output MATCHES "\\t0\\t[0-9]+\\t1\\t1\\t3\\t[1-9][0-9]*\\t[1-9][0-9]*") +if(NOT probe_output MATCHES "selected_tile_ids") + message(FATAL_ERROR "probe output is missing tile identities: ${probe_output}") +endif() +if(NOT probe_output MATCHES "selected_tile_ranges") + message(FATAL_ERROR "probe output is missing tile ranges: ${probe_output}") +endif() +string(REPLACE "\r\n" "\n" normalized_probe_output "${probe_output}") +string(STRIP "${normalized_probe_output}" normalized_probe_output) +string(REPLACE "\n" ";" probe_lines "${normalized_probe_output}") +list(GET probe_lines -1 probe_row) +string(REPLACE "\t" ";" probe_fields "${probe_row}") +list(LENGTH probe_fields probe_field_count) +if(NOT probe_field_count EQUAL 10) + message(FATAL_ERROR + "probe output has unexpected field count: ${probe_row}") +endif() +list(GET probe_fields 1 reported_level) +list(GET probe_fields 2 reported_hierarchy_nodes) +list(GET probe_fields 3 reported_point_tiles) +list(GET probe_fields 4 reported_selected_tiles) +list(GET probe_fields 5 reported_decoded_points) +list(GET probe_fields 6 reported_range_bytes) +list(GET probe_fields 7 reported_source_bytes) +list(GET probe_fields 8 reported_tile_ids) +list(GET probe_fields 9 reported_tile_ranges) +string(REPLACE "," ";" reported_tile_id_list "${reported_tile_ids}") +string(REPLACE "," ";" reported_tile_range_list "${reported_tile_ranges}") +list(LENGTH reported_tile_id_list reported_tile_id_count) +list(LENGTH reported_tile_range_list reported_tile_range_count) +if(NOT reported_level STREQUAL "0" OR + NOT reported_hierarchy_nodes MATCHES "^[0-9]+$" OR + NOT reported_point_tiles STREQUAL "1" OR + NOT reported_selected_tiles STREQUAL "1" OR + NOT reported_tile_id_count EQUAL reported_selected_tiles OR + NOT reported_tile_range_count EQUAL reported_selected_tiles OR + NOT reported_decoded_points STREQUAL "3" OR + NOT reported_range_bytes MATCHES "^[1-9][0-9]*$" OR + NOT reported_source_bytes MATCHES "^[1-9][0-9]*$" OR + NOT reported_tile_ids STREQUAL "L0/0/0/0" OR + NOT reported_tile_ranges MATCHES "^[1-9][0-9]*:[1-9][0-9]*$") message(FATAL_ERROR - "probe output has unexpected level-0 results: ${probe_output}") + "probe output has unexpected level-0 results: ${probe_row}") endif() \ No newline at end of file