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
|