scene/tables/plans.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // SPDX-License-Identifier: BSD-3-Clause | ||
| 2 | #include "chrono_batch_render/scene/tables/plans.h" | ||
| 3 | |||
| 4 | #include <algorithm> | ||
| 5 | #include <optional> | ||
| 6 | |||
| 7 | #include "chrono_batch_render/scene/scene.h" | ||
| 8 | #include "chrono_batch_render/util/error.h" | ||
| 9 | #include "chrono_batch_render/util/profiler.h" | ||
| 10 | |||
| 11 | namespace chrono::batch_render { | ||
| 12 | |||
| 13 | 3541 | std::shared_ptr<const ProductPlan> ProductPlans::Plan(std::span<const std::string> paths) { | |
| 14 | 3541 | std::vector<std::string> sorted(paths.begin(), paths.end()); | |
| 15 | 3541 | std::ranges::sort(sorted); | |
| 16 | 3541 | sorted.erase(std::ranges::unique(sorted).begin(), sorted.end()); | |
| 17 | 3541 | const std::lock_guard lock(m_mutex); | |
| 18 | 3541 | const auto cached = | |
| 19 | 6930 | std::ranges::find_if(m_plans, [&](const auto& plan) { return plan->paths == sorted; }); | |
| 20 | 3541 | if (cached != m_plans.end()) { | |
| 21 | 3383 | const bool current = std::ranges::all_of((*cached)->products, [&](const auto& product) { | |
| 22 | 3386 | const std::shared_ptr<const ResolvedProduct> now = m_products.Find(product->prim); | |
| 23 | 3404 | return now && now->version == product->version; | |
| 24 | 3386 | }); | |
| 25 | 3383 | if (current) { | |
| 26 | 3365 | m_plans.splice(m_plans.begin(), m_plans, cached); | |
| 27 | 6899 | return m_plans.front(); | |
| 28 | } | ||
| 29 | 18 | m_plans.erase(cached); | |
| 30 | } | ||
| 31 | |||
| 32 | 176 | CHRONO_BATCH_RENDER_ZONE("Products/Plan"); | |
| 33 | 176 | auto plan = std::make_shared<ProductPlan>(); | |
| 34 | 176 | plan->id = ++m_ids; | |
| 35 | 354 | for (const std::string& path : sorted) { | |
| 36 | 185 | const std::optional<Prim> prim = m_scene.Find(path); | |
| 37 | 185 | if (!prim || !prim->IsA<RenderProduct>()) { | |
| 38 | 2 | throw Error("\"{}\" isn't a RenderProduct", path); | |
| 39 | } | ||
| 40 | 183 | std::shared_ptr<const ResolvedProduct> product = m_products.Find(prim->Index()); | |
| 41 | 183 | if (!product) { | |
| 42 | ✗ | throw Error("{} isn't published yet", path); | |
| 43 | } | ||
| 44 | 183 | if (!product->error.empty()) { | |
| 45 | 5 | throw Error("{}", product->error); | |
| 46 | } | ||
| 47 | 178 | PlannedCapture capture{.product = product->prim, | |
| 48 | 178 | .width = product->width, | |
| 49 | 178 | .height = product->height, | |
| 50 | .taxonomy = 0, | ||
| 51 | 178 | .missDistance = product->missDistance, | |
| 52 | 178 | .returns = std::max(product->returns, 1u)}; | |
| 53 | 178 | if (product->semantic) { | |
| 54 | 3 | const auto found = std::ranges::find(plan->taxonomies, product->taxonomy); | |
| 55 | 3 | capture.taxonomy = uint32_t(found - plan->taxonomies.begin()); | |
| 56 | 3 | if (found == plan->taxonomies.end()) { | |
| 57 | 3 | plan->taxonomies.push_back(product->taxonomy); | |
| 58 | } | ||
| 59 | } | ||
| 60 | 178 | const auto entry = uint32_t(product->entry); | |
| 61 | 178 | uint64_t& pixels = plan->pixelCounts[entry]; | |
| 62 | 383 | for (capture.layer = 0; capture.layer < product->sensors.size(); ++capture.layer) { | |
| 63 | 205 | capture.sensor = product->sensors[capture.layer]; | |
| 64 | 205 | capture.firstPixel = pixels; | |
| 65 | 205 | plan->captures[entry].push_back(capture); | |
| 66 | 205 | pixels += uint64_t(capture.width) * capture.height; | |
| 67 | } | ||
| 68 | 178 | const auto index = uint32_t(plan->products.size()); | |
| 69 | 178 | plan->products.push_back(product); | |
| 70 | 178 | if (product->pipeline != kNoPrim) { | |
| 71 | 67 | for (const uint32_t sensor : product->sensors) { | |
| 72 | 34 | const auto found = | |
| 73 | 34 | std::ranges::find_if(plan->pipelines, [&](const PlannedSensorPipeline& run) { | |
| 74 | 9 | const ResolvedProduct& first = *plan->products[run.products.front()]; | |
| 75 | 5 | return run.pipeline == product->pipeline && run.sensor == sensor && | |
| 76 | 13 | first.width == product->width && first.height == product->height; | |
| 77 | }); | ||
| 78 | 34 | PlannedSensorPipeline& run = | |
| 79 | 34 | found != plan->pipelines.end() | |
| 80 | 34 | ? *found | |
| 81 | 31 | : plan->pipelines.emplace_back( | |
| 82 | 36 | PlannedSensorPipeline{product->pipeline, sensor, {}}); | |
| 83 | 34 | run.products.push_back(index); | |
| 84 | } | ||
| 85 | } | ||
| 86 | 178 | plan->captureCount += uint32_t(product->sensors.size()); | |
| 87 | 178 | plan->pixelCount += uint64_t(product->width) * product->height * product->sensors.size(); | |
| 88 | 183 | } | |
| 89 | 169 | plan->paths = std::move(sorted); | |
| 90 | 345 | m_plans.push_front(plan); | |
| 91 | 169 | if (m_plans.size() > kCachedPlans) { | |
| 92 | ✗ | m_plans.pop_back(); | |
| 93 | } | ||
| 94 | 169 | return plan; | |
| 95 | 3717 | } | |
| 96 | |||
| 97 | } | ||
| 98 |