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)
121 lines
3.9 KiB
C++
121 lines
3.9 KiB
C++
#pragma once
|
||
/**
|
||
* @file incremental_update.h
|
||
* @brief 增量更新引擎
|
||
*
|
||
* 特征参数修改后,仅重建受影响的脏节点,避免全量重算。
|
||
* 支持脏标记传播、缓存管理和增量重建。
|
||
*
|
||
* @ingroup brep
|
||
*/
|
||
|
||
#include "vde/brep/feature_tree.h"
|
||
#include "vde/brep/brep.h"
|
||
#include "vde/mesh/halfedge_mesh.h"
|
||
#include "vde/core/aabb.h"
|
||
#include <unordered_map>
|
||
#include <unordered_set>
|
||
#include <functional>
|
||
#include <optional>
|
||
|
||
namespace vde::brep {
|
||
|
||
// ═══════════════════════════════════════════════════════════
|
||
// Cached data
|
||
// ═══════════════════════════════════════════════════════════
|
||
|
||
/// 节点缓存数据
|
||
struct NodeCache {
|
||
std::optional<BrepModel> model; ///< 缓存模型
|
||
std::optional<mesh::HalfedgeMesh> mesh; ///< 缓存网格
|
||
std::optional<core::AABB3D> bounds; ///< 缓存包围盒
|
||
bool dirty = false; ///< 是否脏
|
||
};
|
||
|
||
// ═══════════════════════════════════════════════════════════
|
||
// IncrementalUpdateEngine
|
||
// ═══════════════════════════════════════════════════════════
|
||
|
||
/**
|
||
* @brief 增量更新引擎
|
||
*
|
||
* 管理特征树节点的缓存和脏标记。
|
||
* 参数修改时,沿依赖链标脏,仅重建受影响节点。
|
||
*
|
||
* @ingroup brep
|
||
*/
|
||
class IncrementalUpdateEngine {
|
||
public:
|
||
/// 回调:节点重建完成通知
|
||
using RebuildCallback = std::function<void(int node_id, const BrepModel&)>;
|
||
|
||
/**
|
||
* @brief 注册特征树节点
|
||
*
|
||
* @param node_id 节点 ID
|
||
* @param deps 依赖节点 ID 列表(上游节点)
|
||
*/
|
||
void register_node(int node_id, const std::vector<int>& deps = {});
|
||
|
||
/**
|
||
* @brief 标记节点为脏(参数已修改)
|
||
*
|
||
* 自动将脏标记传播到所有下游节点。
|
||
*
|
||
* @param node_id 修改的节点 ID
|
||
*/
|
||
void mark_dirty(int node_id);
|
||
|
||
/**
|
||
* @brief 增量重建
|
||
*
|
||
* 仅重建脏节点,按拓扑顺序(先上游后下游)。
|
||
*
|
||
* @param feature_history 特征历史(含 FeatureNode)
|
||
* @param callback 每个节点重建后的回调
|
||
* @return 重建的节点数
|
||
*/
|
||
[[nodiscard]] int incremental_rebuild(
|
||
FeatureHistory& feature_history,
|
||
RebuildCallback callback = nullptr);
|
||
|
||
/**
|
||
* @brief 全量重建(清除所有缓存后重建)
|
||
*/
|
||
[[nodiscard]] int full_rebuild(
|
||
FeatureHistory& feature_history,
|
||
RebuildCallback callback = nullptr);
|
||
|
||
/// 获取缓存
|
||
[[nodiscard]] const NodeCache* get_cache(int node_id) const;
|
||
|
||
/// 清除指定节点缓存
|
||
void invalidate_cache(int node_id);
|
||
|
||
/// 清除所有缓存
|
||
void clear_all();
|
||
|
||
/// 脏节点数
|
||
[[nodiscard]] int dirty_count() const;
|
||
|
||
/// 总节点数
|
||
[[nodiscard]] int total_nodes() const { return static_cast<int>(caches_.size()); }
|
||
|
||
/// 缓存命中统计
|
||
[[nodiscard]] int cache_hits() const { return cache_hits_; }
|
||
[[nodiscard]] int cache_misses() const { return cache_misses_; }
|
||
[[nodiscard]] double hit_rate() const;
|
||
|
||
private:
|
||
std::unordered_map<int, NodeCache> caches_; ///< node_id → cache
|
||
std::unordered_map<int, std::vector<int>> deps_; ///< node_id → upstream deps
|
||
std::unordered_set<int> dirty_set_; ///< 脏节点集合
|
||
int cache_hits_ = 0;
|
||
int cache_misses_ = 0;
|
||
|
||
/// 拓扑排序:脏节点按依赖顺序排列
|
||
std::vector<int> topological_sort_dirty();
|
||
};
|
||
|
||
} // namespace vde::brep
|