2e004fda6d
- IncrementalUpdateEngine: dirty propagation, topological rebuild, cache hit/miss - InstanceCache: shared LOD mesh for identical parts - LargeAssemblyManager: BVH spatial index, view frustum culling, assembly stats - format_io: auto-detect STEP/IGES, batch import with error recovery - 31 tests: incremental (11), large assembly (12), format IO (8)
117 lines
3.6 KiB
C++
117 lines
3.6 KiB
C++
#pragma once
|
||
/**
|
||
* @file large_assembly.h
|
||
* @brief 大装配性能优化(10K+ 零件)
|
||
*
|
||
* 通过空间索引加速、实例共享、LOD 自动切换,
|
||
* 支持大规模装配体的高效遍历和渲染。
|
||
*
|
||
* @ingroup brep
|
||
*/
|
||
|
||
#include "vde/brep/assembly.h"
|
||
#include "vde/brep/assembly_instance.h"
|
||
#include "vde/spatial/bvh.h"
|
||
#include "vde/core/aabb.h"
|
||
#include "vde/mesh/mesh_lod.h"
|
||
#include <unordered_map>
|
||
#include <string>
|
||
|
||
namespace vde::brep {
|
||
|
||
// ═══════════════════════════════════════════════════════════
|
||
// InstanceCache — shared mesh data
|
||
// ═══════════════════════════════════════════════════════════
|
||
|
||
/**
|
||
* @brief 实例缓存:相同零件共享 mesh 数据
|
||
*
|
||
* 对同一 instance_id 的零件只存储一份 mesh,
|
||
* 不同实例通过变换矩阵区分。
|
||
*/
|
||
class InstanceCache {
|
||
public:
|
||
/// 注册实例(返回是否新实例)
|
||
bool register_instance(int instance_id, const BrepModel& model);
|
||
|
||
/// 获取实例的 LOD mesh
|
||
[[nodiscard]] const mesh::LODMesh* get_lod(int instance_id) const;
|
||
|
||
/// 获取实例的 AABB
|
||
[[nodiscard]] const core::AABB3D* get_bounds(int instance_id) const;
|
||
|
||
/// 唯一实例数
|
||
[[nodiscard]] int unique_count() const { return static_cast<int>(meshes_.size()); }
|
||
|
||
/// 总内存估算(字节)
|
||
[[nodiscard]] size_t memory_estimate() const;
|
||
|
||
private:
|
||
std::unordered_map<int, mesh::LODMesh> meshes_;
|
||
std::unordered_map<int, core::AABB3D> bounds_;
|
||
};
|
||
|
||
// ═══════════════════════════════════════════════════════════
|
||
// LargeAssemblyManager
|
||
// ═══════════════════════════════════════════════════════════
|
||
|
||
/**
|
||
* @brief 大装配管理器
|
||
*
|
||
* 提供空间索引加速的装配遍历、视锥剔除、LOD 选择。
|
||
*/
|
||
class LargeAssemblyManager {
|
||
public:
|
||
/**
|
||
* @brief 从装配体构建空间索引
|
||
*
|
||
* 遍历所有零件,将其 AABB 插入 BVH。
|
||
*
|
||
* @param assembly 装配体
|
||
*/
|
||
void build_index(const Assembly& assembly);
|
||
|
||
/**
|
||
* @brief 视锥剔除查询
|
||
*
|
||
* 返回在指定 AABB 范围内的零件名称列表。
|
||
*
|
||
* @param view_aabb 视口 AABB(世界坐标)
|
||
* @return 可见零件名称
|
||
*/
|
||
[[nodiscard]] std::vector<std::string> query_visible(
|
||
const core::AABB3D& view_aabb) const;
|
||
|
||
/**
|
||
* @brief 获取装配统计信息
|
||
*/
|
||
struct AssemblyStats {
|
||
int total_parts = 0;
|
||
int unique_parts = 0;
|
||
int subassemblies = 0;
|
||
int max_depth = 0;
|
||
core::AABB3D total_bounds;
|
||
size_t estimated_memory = 0;
|
||
};
|
||
|
||
[[nodiscard]] AssemblyStats compute_stats(const Assembly& assembly) const;
|
||
|
||
/// 零件数
|
||
[[nodiscard]] int part_count() const { return part_count_; }
|
||
|
||
/// 索引构建状态
|
||
[[nodiscard]] bool index_built() const { return index_built_; }
|
||
|
||
private:
|
||
spatial::BVH bvh_;
|
||
std::vector<core::AABB3D> part_aabbs_;
|
||
std::vector<std::string> part_names_;
|
||
int part_count_ = 0;
|
||
bool index_built_ = false;
|
||
|
||
void collect_parts(const AssemblyNode& node, const core::Transform3D& parent_tf,
|
||
int depth, AssemblyStats& stats) const;
|
||
};
|
||
|
||
} // namespace vde::brep
|