feat(v4.3): BOM (bill of materials) — flat merged, name-sorted
CI / Build & Test (push) Failing after 39s
CI / Release Build (push) Failing after 29s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled

- BomEntry struct: name, quantity, volume, total_volume
- generate_bom(): recursive assembly traversal, same-name merging
- 5 new tests, 26/26 passing
This commit is contained in:
茂之钳
2026-07-25 07:14:27 +00:00
parent 3d435a4801
commit 1e196473bc
3 changed files with 111 additions and 70 deletions
+35
View File
@@ -4,7 +4,10 @@
#include "vde/core/aabb.h"
#include "vde/mesh/halfedge_mesh.h"
#include <cmath>
#include <functional>
#include <limits>
#include <map>
#include <string>
#include <algorithm>
namespace vde::brep {
@@ -333,4 +336,36 @@ double clearance(const BrepModel& a, const BrepModel& b) {
return distance(a, b);
}
// ── generate_bom ────────────────────────────────────────────
std::vector<BomEntry> generate_bom(const AssemblyNode& node) {
std::map<std::string, BomEntry> bom_map;
std::function<void(const AssemblyNode&)> traverse =
[&](const AssemblyNode& n) {
if (n.is_part() && n.model.has_value()) {
double vol = volume(*n.model);
auto& entry = bom_map[n.name];
if (entry.quantity == 0) {
entry.name = n.name;
entry.volume = vol;
}
entry.quantity++;
entry.total_volume += vol;
}
for (const auto& child : n.children) {
traverse(*child);
}
};
traverse(node);
std::vector<BomEntry> result;
result.reserve(bom_map.size());
for (auto& [_, entry] : bom_map) result.push_back(std::move(entry));
std::sort(result.begin(), result.end(),
[](const BomEntry& a, const BomEntry& b) { return a.name < b.name; });
return result;
}
} // namespace vde::brep