Files

121 lines
3.9 KiB
C++
Raw Permalink Normal View History

#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