Read one sample of a stream.
Fields the format does not carry for the stream's topology are empty: ids and velocities for a curves stream, vertex_counts_per_curve for points, and ids or velocities a points stream was written without.
396{
397 if (!
m_impl->archive.valid()) {
398 set_error(
"read_sample: no archive open");
399 return std::nullopt;
400 }
401
402 const auto it =
m_impl->records.find(stream_name);
403 if (it ==
m_impl->records.end()) {
404 set_error(
"read_sample: no stream named '" + stream_name +
"'");
405 return std::nullopt;
406 }
407
408 auto& record = it->second;
409 if (
index >= record.sample_count) {
410 set_error(
"read_sample: index " + std::to_string(
index) +
" out of range for '"
411 + stream_name + "' (" + std::to_string(record.sample_count) + " samples)");
412 return std::nullopt;
413 }
414
415 try {
416 const ISampleSelector selector(
static_cast<index_t
>(
index));
417 SampleStorage fresh;
418 ICompoundProperty arb;
419
420 if (
auto*
points = std::get_if<IPoints>(&record.object)) {
421 auto& schema =
points->getSchema();
422 IPointsSchema::Sample sample;
423 schema.get(sample, selector);
424
425 fresh.positions = copy_array<glm::vec3>(sample.getPositions());
426 fresh.ids = copy_array<uint64_t>(sample.getIds());
427 fresh.velocities = copy_array<glm::vec3>(sample.getVelocities());
428 arb = schema.getArbGeomParams();
429 } else if (auto* curves = std::get_if<ICurves>(&record.object)) {
430 auto& schema = curves->getSchema();
431 ICurvesSchema::Sample sample;
432 schema.get(sample, selector);
433
434 fresh.positions = copy_array<glm::vec3>(sample.getPositions());
435 fresh.vertex_counts_per_curve = copy_array<int32_t>(sample.getCurvesNumVertices());
436 arb = schema.getArbGeomParams();
437
438 if (!record.warned_curve_type
439 && (sample.getType() != kLinear || sample.getWrap() != kNonPeriodic)) {
440 record.warned_curve_type = true;
442 "SpatialReader: '{}' is not linear and non periodic, its control points are "
443 "returned as plain polylines",
444 stream_name);
445 }
446 }
447
448 if (arb.valid()) {
450 auto attribute = read_attribute(arb, decl, selector);
451 if (!attribute) {
453 "SpatialReader: '{}' sample {}: attribute '{}' has an unsupported scope or "
454 "no values, skipped",
455 stream_name,
index, decl.name);
456 continue;
457 }
458 fresh.attributes.push_back(std::move(*attribute));
459 }
460 }
461
462 record.storage = std::move(fresh);
463 return SpatialSample {
464 .topology = record.topology,
465 .positions = record.storage.positions,
466 .vertex_counts_per_curve = record.storage.vertex_counts_per_curve,
467 .ids = record.storage.ids,
468 .velocities = record.storage.velocities,
469 .attributes = record.storage.attributes,
470 };
471 } catch (const std::exception& e) {
472 set_error(std::string(
"read_sample: ") + e.what());
474 "SpatialReader::read_sample: '{}' sample {}: {}", stream_name,
index, e.what());
475 return std::nullopt;
476 }
477}
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
std::vector< glm::vec2 > * points
std::vector< SpatialAttribute > attributes
void set_error(std::string msg) const
std::unique_ptr< Impl > m_impl
@ FileIO
Filesystem I/O operations.
@ IO
Networking, file handling, streaming.