2026-05-09 11:05:54 -07:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <glm/glm.hpp>
|
|
|
|
|
#include <cstddef>
|
|
|
|
|
#include <cstdint>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
namespace wowee {
|
|
|
|
|
namespace editor {
|
|
|
|
|
namespace cli {
|
|
|
|
|
|
|
|
|
|
// Vertex weld pass shared by --info-mesh-stats / --info-wob-stats /
|
refactor(editor): extract edge classification into cli_weld
The "loop over triangles, key edges by canonical-vertex pair,
count uses, classify boundary/manifold/non-manifold" pass was
duplicated across cli_mesh_info, cli_world_info, and the new
cli_audits watertight check. Hoist it into cli_weld as
classifyEdges(indices, canon) returning an EdgeStats struct
with boundary / manifold / nonManifold counters and a
watertight() convenience method.
All three callers verified byte-identical:
• --info-mesh-stats firepit: 180 edges, watertight YES
• --info-wob-stats cube: 18 manifold, watertight YES
• --audit-watertight /tmp/...: 61 meshes, 12 failures, rc=12
About 60 more lines of duplication removed; classifyEdges +
buildWeldMap together form the complete reusable surface for
new weld/topology audit commands.
2026-05-09 11:15:31 -07:00
|
|
|
// --bake-wom-collision / --audit-watertight. Positions are quantized
|
|
|
|
|
// onto a 1/eps grid; every vertex sharing a cell with a previously-
|
|
|
|
|
// seen vertex is remapped to that vertex's index. Returns canon[v]
|
|
|
|
|
// giving the canonical (lowest-index) representative of v's
|
|
|
|
|
// equivalence class and writes the count of distinct cells to
|
|
|
|
|
// `uniqueOut`.
|
2026-05-09 11:05:54 -07:00
|
|
|
//
|
|
|
|
|
// Implementation uses std::map<tuple<int64,int64,int64>, uint32_t>
|
|
|
|
|
// for exact equality on the quantized key — a hash-based key would
|
|
|
|
|
// risk false-positive collisions that incorrectly merge distinct
|
|
|
|
|
// corners (e.g. a unit cube's 8 corners all hashing to 2 buckets).
|
|
|
|
|
std::vector<uint32_t> buildWeldMap(
|
|
|
|
|
const std::vector<glm::vec3>& positions,
|
|
|
|
|
float eps,
|
|
|
|
|
std::size_t& uniqueOut);
|
|
|
|
|
|
refactor(editor): extract edge classification into cli_weld
The "loop over triangles, key edges by canonical-vertex pair,
count uses, classify boundary/manifold/non-manifold" pass was
duplicated across cli_mesh_info, cli_world_info, and the new
cli_audits watertight check. Hoist it into cli_weld as
classifyEdges(indices, canon) returning an EdgeStats struct
with boundary / manifold / nonManifold counters and a
watertight() convenience method.
All three callers verified byte-identical:
• --info-mesh-stats firepit: 180 edges, watertight YES
• --info-wob-stats cube: 18 manifold, watertight YES
• --audit-watertight /tmp/...: 61 meshes, 12 failures, rc=12
About 60 more lines of duplication removed; classifyEdges +
buildWeldMap together form the complete reusable surface for
new weld/topology audit commands.
2026-05-09 11:15:31 -07:00
|
|
|
// Edge classification result from walking a triangle list with a
|
|
|
|
|
// canon[] map (typically built by buildWeldMap above, but the
|
|
|
|
|
// identity mapping also works for "as-authored" edge counts).
|
|
|
|
|
struct EdgeStats {
|
|
|
|
|
std::size_t total = 0; // distinct edges seen
|
|
|
|
|
std::size_t boundary = 0; // shared by exactly 1 triangle (open seam)
|
|
|
|
|
std::size_t manifold = 0; // shared by exactly 2 (closed surface)
|
|
|
|
|
std::size_t nonManifold = 0; // shared by 3+ (branching surface)
|
|
|
|
|
bool watertight() const {
|
|
|
|
|
return boundary == 0 && nonManifold == 0;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Walk every triangle in `indices` (must be a multiple of 3),
|
|
|
|
|
// remap each corner through canon[], and count edge uses. An
|
|
|
|
|
// edge whose two canonical endpoints are equal is dropped (it
|
|
|
|
|
// became a self-loop after welding and isn't a real edge).
|
|
|
|
|
EdgeStats classifyEdges(const std::vector<uint32_t>& indices,
|
|
|
|
|
const std::vector<uint32_t>& canon);
|
|
|
|
|
|
2026-05-09 11:05:54 -07:00
|
|
|
} // namespace cli
|
|
|
|
|
} // namespace editor
|
|
|
|
|
} // namespace wowee
|