Build one grid from active cells and retain it for saving.
The lattice becomes a per-axis scale-translate transform mapping index to world as cell_size() times index plus bounds.min plus half a cell, which reproduces Lattice3D::cell_center exactly.
543{
544 const size_t width = element_width(spec.is_vector);
545 if (spec.values.size() != spec.coords.size() *
width) {
547 + "': value bytes do not match coordinate count";
548 return false;
549 }
550 if (spec.background.size() !=
width) {
552 + "': background is the wrong width";
553 return false;
554 }
555
556 static_assert(sizeof(glm::ivec3) == sizeof(tvdb_vec3i),
557 "glm::ivec3 and tvdb_vec3i must be layout compatible for the "
558 "coordinate span to be passed through without a copy");
559
560 auto& type_token =
m_state->type_tokens.emplace_back();
561 tvdb_grid_t tmpl = make_template(lattice, spec.is_vector, type_token.data());
562
563 const std::string
name(spec.name);
564
565 tvdb_grid_t grid;
566 const bool ok = tvdb_grid_from_sparse_typed_using_template(
567 &tmpl,
568 reinterpret_cast<const tvdb_vec3i*>(spec.coords.data()),
569 spec.values.data(),
570 spec.coords.size(),
571 spec.is_vector ? TVDB_VALUE_VEC3F : TVDB_VALUE_FLOAT,
574 &grid);
575
576 if (!ok) {
578 return false;
579 }
580
581 auto& list =
m_state->entries.emplace_back();
582 list.reserve(spec.metadata.size() + 1);
583
584 auto add_entry = [&](std::string_view key, std::string_view
value) {
585 std::string&
k =
m_state->strings.emplace_back(key);
586 std::string& t =
m_state->strings.emplace_back(
"string");
588
589 tvdb_meta_entry_t entry;
590 std::memset(&entry, 0, sizeof(entry));
591 entry.name =
k.data();
592 entry.type_name = t.data();
593 entry.value.type = TVDB_VALUE_STRING;
594 entry.value.u.s.str = v.data();
595 entry.value.u.s.len = v.size();
596 list.push_back(entry);
597 };
598
599
600
601 add_entry("name", spec.name);
602
603 for (
const auto& [key,
value] : spec.metadata) {
604 add_entry(key,
value);
605 }
606
607 grid.metadata.entries = list.data();
608 grid.metadata.count = list.size();
609 grid.metadata.capacity = list.size();
610 grid.metadata.alloc = nullptr;
611
612 m_state->grids.push_back(grid);
613 return true;
614}
std::string m_last_error
Set from the const read-path accessors too.
std::unique_ptr< State > m_state