mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-09 18:43:51 +00:00
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.
51 lines
1.9 KiB
C++
51 lines
1.9 KiB
C++
#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 /
|
|
// --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`.
|
|
//
|
|
// 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);
|
|
|
|
// 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);
|
|
|
|
} // namespace cli
|
|
} // namespace editor
|
|
} // namespace wowee
|