Shape descriptors (element_shape.comp) and nearest-neighbour distances (nearest_neighbor.comp) over fe.boxes, filled in place.
No-op when fe.boxes is empty.
205{
206 const auto n = fe.boxes.size();
207 fe.shapes.assign(n, {});
208 fe.nearest_neighbor_distance_px.assign(n, 0.0F);
209 if (n == 0)
210 return;
211
212 const auto fw = static_cast<float>(w);
213 const auto fh =
static_cast<float>(
h);
214
215 std::vector<float> element_data;
216 element_data.reserve(n * 4);
217 std::vector<float> centroid_data;
218 centroid_data.reserve(n * 2);
219
220 for (
const auto&
b : fe.boxes) {
221 const auto it = std::ranges::find_if(fe.contours,
222 [&](const auto& c) { return c.label_id == b.label_id; });
223 const float area_px = (it != fe.contours.end()) ? it->area * fw * fh : 0.0F;
224 const float perimeter_px = (it != fe.contours.end()) ? it->perimeter : 0.0F;
225 element_data.push_back(area_px);
226 element_data.push_back(perimeter_px);
227 element_data.push_back(
b.w * fw);
228 element_data.push_back(
b.h * fh);
229
230 centroid_data.push_back((
b.x +
b.w * 0.5F) * fw);
231 centroid_data.push_back((
b.y +
b.h * 0.5F) * fh);
232 }
233
235 m_shape_ctx = std::make_shared<ShaderExecutionContext<>>(
238 .workgroup_size = { 256, 1, 1 },
239 .push_constant_size = sizeof(TrackReducePC) });
240 }
242 .output(1, n * sizeof(glm::vec2))
243 .push(TrackReducePC { .count = static_cast<uint32_t>(n) });
244
245 const auto shape_output =
m_shape_ctx->execute(Datum<std::vector<Kakshya::DataVariant>> {}, ExecutionContext {});
246 const auto shape_raw = ShaderExecutionContext<>::read_output<float>(shape_output, 1);
247 for (size_t i = 0; i < n && (i + 1) * 2 <= shape_raw.size(); ++i) {
248 fe.shapes[i].compactness = shape_raw[i * 2];
249 fe.shapes[i].aspect_ratio = shape_raw[i * 2 + 1];
250 }
251
252 if (n < 2)
253 return;
254
259 .workgroup_size = { 256, 1, 1 },
260 .push_constant_size = sizeof(TrackReducePC) });
261 }
263 .output(1, n * sizeof(float))
264 .push(TrackReducePC { .count = static_cast<uint32_t>(n) });
265
266 const auto dist_output =
m_neighbor_ctx->execute(Datum<std::vector<Kakshya::DataVariant>> {}, ExecutionContext {});
267 const auto dist_raw = ShaderExecutionContext<>::read_output<float>(dist_output, 1);
268 for (size_t i = 0; i < n && i < dist_raw.size(); ++i)
269 fe.nearest_neighbor_distance_px[i] = dist_raw[i];
270}
std::shared_ptr< ShaderExecutionContext<> > m_shape_ctx
std::shared_ptr< ShaderExecutionContext<> > m_neighbor_ctx
Portal::Graphics::GpuComputeConfig GpuComputeConfig