Skip to content

Commit

Permalink
Fix rounding errors breaking buffer sizes of large gltf models (#810)
Browse files Browse the repository at this point in the history
- Add uint64_t/int64_t types to the JsonObj class so that sizes never
touch floats
- In match graph diagrams, color nodes with obs-crossing boundary edges
in red instead of in black
  • Loading branch information
Strilanc authored Aug 3, 2024
1 parent f66de61 commit 51b29e3
Show file tree
Hide file tree
Showing 26 changed files with 194 additions and 139 deletions.
2 changes: 1 addition & 1 deletion src/stim/diagram/basic_3d_diagram.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ GltfScene Basic3dDiagram::to_gltf_scene() const {
});

auto buf_purple_scattered_lines = std::shared_ptr<GltfBuffer<3>>(new GltfBuffer<3>{
{"buf_blue_scattered_lines"},
{"buf_purple_scattered_lines"},
purple_line_data,
});

Expand Down
27 changes: 14 additions & 13 deletions src/stim/diagram/gate_data_3d.cc
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ std::pair<std::string_view, std::shared_ptr<GltfMesh>> make_z_control_mesh() {
return {"Z_CONTROL", mesh};
}

std::pair<std::string_view, std::shared_ptr<GltfMesh>> make_detector_mesh() {
std::pair<std::string_view, std::shared_ptr<GltfMesh>> make_detector_mesh(bool excited) {
auto circle = make_circle_loop(8, CONTROL_RADIUS, true);
auto circle2 = make_circle_loop(8, CONTROL_RADIUS, true);
auto circle3 = make_circle_loop(8, CONTROL_RADIUS, true);
Expand All @@ -354,44 +354,44 @@ std::pair<std::string_view, std::shared_ptr<GltfMesh>> make_detector_mesh() {
std::swap(e.xyz[0], e.xyz[1]);
std::swap(e.xyz[1], e.xyz[2]);
}
auto black_material = std::shared_ptr<GltfMaterial>(new GltfMaterial{
{"black"},
{0, 0, 0, 1},
auto material = std::shared_ptr<GltfMaterial>(new GltfMaterial{
{excited ? "det_red" : "det_black"},
{excited ? 1.0f : 0.0f, excited ? 0.5f : 0.0f, excited ? 0.5f : 0.0f, 1},
1,
1,
true,
nullptr,
});
auto disc_interior = std::shared_ptr<GltfPrimitive>(new GltfPrimitive{
{"detector_primitive_circle_interior"},
{excited ? "excited_detector_primitive_circle_interior" : "detector_primitive_circle_interior"},
GL_TRIANGLE_FAN,
circle,
nullptr,
black_material,
material,
});
auto disc_interior2 = std::shared_ptr<GltfPrimitive>(new GltfPrimitive{
{"detector_primitive_circle_interior_2"},
{excited ? "excited_detector_primitive_circle_interior_2" : "detector_primitive_circle_interior_2"},
GL_TRIANGLE_FAN,
circle2,
nullptr,
black_material,
material,
});
auto disc_interior3 = std::shared_ptr<GltfPrimitive>(new GltfPrimitive{
{"detector_primitive_circle_interior_3"},
{excited ? "excited_detector_primitive_circle_interior_3" : "detector_primitive_circle_interior_3"},
GL_TRIANGLE_FAN,
circle3,
nullptr,
black_material,
material,
});
auto mesh = std::shared_ptr<GltfMesh>(new GltfMesh{
{"mesh_DETECTOR"},
{excited ? "mesh_EXCITED_DETECTOR" : "mesh_DETECTOR"},
{
disc_interior,
disc_interior2,
disc_interior3,
},
});
return {"DETECTOR", mesh};
return {excited ? "EXCITED_DETECTOR" : "DETECTOR", mesh};
}

std::map<std::string_view, std::shared_ptr<GltfMesh>> stim_draw_internal::make_gate_primitives() {
Expand Down Expand Up @@ -516,6 +516,7 @@ std::map<std::string_view, std::shared_ptr<GltfMesh>> stim_draw_internal::make_g
make_z_control_mesh(),
make_xswap_control_mesh(),
make_zswap_control_mesh(),
make_detector_mesh(),
make_detector_mesh(false),
make_detector_mesh(true),
};
}
12 changes: 7 additions & 5 deletions src/stim/diagram/gltf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ JsonObj GltfScene::_to_json_local() const {
JsonObj GltfScene::to_json() {
// Clear indices.
visit([&](GltfId &item_id, const char *type, const std::function<JsonObj(void)> &to_json, uintptr_t abs_id) {
item_id.index = SIZE_MAX;
item_id.index = UINT64_MAX;
});

// Re-index.
std::map<std::string, size_t> counts;
visit([&](GltfId &item_id, const char *type, const std::function<JsonObj(void)> &to_json, uintptr_t abs_id) {
auto &c = counts[type];
if (item_id.index == SIZE_MAX || item_id.index == c) {
if (item_id.index == UINT64_MAX || item_id.index == c) {
item_id.index = c;
c++;
} else if (item_id.index > c) {
Expand Down Expand Up @@ -97,7 +97,8 @@ void GltfImage::visit(const gltf_visit_callback &callback) {

JsonObj GltfImage::to_json() const {
return std::map<std::string, JsonObj>{
{"name", id.name},
// Note: saving space by not including names.
//{"name", id.name},
{"uri", uri},
};
}
Expand All @@ -116,7 +117,8 @@ void GltfTexture::visit(const gltf_visit_callback &callback) {

JsonObj GltfTexture::to_json() const {
return std::map<std::string, JsonObj>{
{"name", id.name},
// Note: saving space by not including names.
// {"name", id.name},
{"sampler", 0},
{"source", 0},
};
Expand All @@ -137,7 +139,7 @@ void GltfMaterial::visit(const gltf_visit_callback &callback) {

JsonObj GltfMaterial::to_json() const {
JsonObj result = std::map<std::string, JsonObj>{
{"name", id.name},
// {"name", id.name},
{"pbrMetallicRoughness",
std::map<std::string, JsonObj>{
{"baseColorFactor",
Expand Down
49 changes: 21 additions & 28 deletions src/stim/diagram/gltf.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,23 @@

namespace stim_draw_internal {

constexpr size_t GL_FLOAT = 5126;
constexpr size_t GL_ARRAY_BUFFER = 34962;
constexpr size_t GL_UNSIGNED_SHORT = 5123;
constexpr size_t GL_ELEMENT_ARRAY_BUFFER = 34963;
constexpr size_t GL_TRIANGLE_STRIP = 5;
constexpr size_t GL_TRIANGLES = 4;
constexpr size_t GL_TRIANGLE_FAN = 6;

constexpr size_t GL_LINES = 1;
constexpr size_t GL_LINE_STRIP = 3;
constexpr size_t GL_LINE_LOOP = 2;

constexpr size_t GL_REPEAT = 10497;
constexpr size_t GL_CLAMP = 10496;
constexpr size_t GL_CLAMP_TO_EDGE = 33071;
constexpr size_t GL_LINEAR = 9729;
constexpr size_t GL_LINEAR_MIPMAP_NEAREST = 9987;
constexpr size_t GL_NEAREST = 9728;
constexpr uint64_t GL_FLOAT = 5126;
constexpr uint64_t GL_ARRAY_BUFFER = 34962;
constexpr uint64_t GL_TRIANGLES = 4;
constexpr uint64_t GL_TRIANGLE_FAN = 6;

constexpr uint64_t GL_LINES = 1;
constexpr uint64_t GL_LINE_STRIP = 3;
constexpr uint64_t GL_LINE_LOOP = 2;

constexpr uint64_t GL_CLAMP_TO_EDGE = 33071;
constexpr uint64_t GL_NEAREST = 9728;

struct GltfId {
std::string name;
size_t index;
uint64_t index;

GltfId(std::string name) : name(name), index(SIZE_MAX) {
GltfId(std::string name) : name(name), index(UINT64_MAX) {
}
GltfId() = delete;
};
Expand Down Expand Up @@ -81,7 +74,7 @@ struct GltfBuffer {
return std::map<std::string, JsonObj>{
{"name", id.name},
{"uri", ss.str()},
{"byteLength", vertex_data_size},
{"byteLength", (uint64_t)vertex_data_size},
};
}

Expand All @@ -90,7 +83,7 @@ struct GltfBuffer {
{"name", id.name},
{"buffer", id.index},
{"byteOffset", 0},
{"byteLength", vertices.size() * sizeof(Coord<DIM>)},
{"byteLength", (uint64_t)(vertices.size() * sizeof(Coord<DIM>))},
{"target", GL_ARRAY_BUFFER},
};
}
Expand All @@ -115,7 +108,7 @@ struct GltfBuffer {
{"bufferView", id.index},
{"byteOffset", 0},
{"componentType", GL_FLOAT},
{"count", vertices.size()},
{"count", (uint64_t)vertices.size()},
{"type", "VEC" + std::to_string(DIM)},
{"min", std::move(min_v)},
{"max", std::move(max_v)},
Expand All @@ -125,10 +118,10 @@ struct GltfBuffer {

struct GltfSampler {
GltfId id;
size_t magFilter;
size_t minFilter;
size_t wrapS;
size_t wrapT;
uint64_t magFilter;
uint64_t minFilter;
uint64_t wrapS;
uint64_t wrapT;

void visit(const gltf_visit_callback &callback);
JsonObj to_json() const;
Expand Down Expand Up @@ -165,7 +158,7 @@ struct GltfMaterial {

struct GltfPrimitive {
GltfId id;
size_t element_type;
uint64_t element_type;
std::shared_ptr<GltfBuffer<3>> position_buffer;
std::shared_ptr<GltfBuffer<2>> tex_coords_buffer;
std::shared_ptr<GltfMaterial> material;
Expand Down
17 changes: 13 additions & 4 deletions src/stim/diagram/graph/match_graph_3d_drawer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Basic3dDiagram stim_draw_internal::dem_match_graph_to_basic_3d_diagram(const sti
auto minmax = Coord<3>::min_max(coords);
auto center = (minmax.first + minmax.second) * 0.5;

std::set<uint64_t> boundary_observable_detectors;
std::vector<Coord<3>> det_coords;
auto handle_contiguous_targets = [&](SpanRef<const DemTarget> targets) {
bool has_observables = false;
Expand All @@ -102,6 +103,13 @@ Basic3dDiagram stim_draw_internal::dem_match_graph_to_basic_3d_diagram(const sti
}
auto a = det_coords[0];
det_coords.push_back(a + d * 10);
if (has_observables) {
for (auto t : targets) {
if (t.is_relative_detector_id()) {
boundary_observable_detectors.insert(t.val());
}
}
}
}
if (det_coords.size() == 2) {
if (has_observables) {
Expand Down Expand Up @@ -129,10 +137,6 @@ Basic3dDiagram stim_draw_internal::dem_match_graph_to_basic_3d_diagram(const sti
}
};

for (const auto &c : coords) {
out.elements.push_back({"DETECTOR", c});
}

dem.iter_flatten_error_instructions([&](const DemInstruction &op) {
if (op.type != DemInstructionType::DEM_ERROR) {
return;
Expand All @@ -148,5 +152,10 @@ Basic3dDiagram stim_draw_internal::dem_match_graph_to_basic_3d_diagram(const sti
handle_contiguous_targets({p + start, op.target_data.ptr_end});
});

for (size_t k = 0; k < coords.size(); k++) {
bool excited = boundary_observable_detectors.find(k) != boundary_observable_detectors.end();
out.elements.push_back({excited ? "EXCITED_DETECTOR" : "DETECTOR", coords[k]});
}

return out;
}
Loading

0 comments on commit 51b29e3

Please sign in to comment.