feat(v4.3): BOM (bill of materials) — flat merged, name-sorted
- 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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user