Files
ViewDesignEngine/include/vde/ai/feature_learning.h
T
茂之钳 69888621cd
CI / Build & Test (push) Failing after 30s
CI / Release Build (push) Failing after 38s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled
feat(v9): distributed computing + cloud-native + KBE + WASM + digital twin
v9.1 — Distributed Computing (超越 Parasolid):
- cluster_engine: ClusterManager, TaskScheduler(DAG+Kahn), 4 load-balance strategies
- distributed_boolean, distributed_marching_cubes, distributed_ray_tracing
- grpc_service: BrepOps/MeshOps/SdfOps RPC, streaming, TLS, connection pool
- ~750 lines

v9.2 — Cloud-Native + KBE + WASM + Digital Twin (34/34 tests passing):
- cloud_native: CloudSession, OperationalTransform, DeltaSync, Serverless, ObjectStorage
- knowledge_engine: CheckMate(13 rules), RuleEngine, DesignTable, GA+Adam optimizer
- vde_wasm: WasmBridge, WebWorkerPool, SharedArrayBuffer, IndexedDB
- dt_engine: DigitalTwin, MQTT/OPC-UA, RealTimeSync, PredictiveMaintenance(RUL)
- 3950 lines, 34 tests all passing

Pending: AI/ML integration (retrying)

18 files, ~4700 lines
2026-07-26 23:44:24 +08:00

367 lines
14 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
/**
* @file feature_learning.h
* @brief 基于 AI/ML 的特征学习:图神经网络特征分类 + 3D 形状相似度搜索
*
* ## 主要功能
*
* | 功能 | 说明 |
* |-----------------------|----------------------------------------------|
* | FeatureClassifier | 基于 GNN 的 B-Rep 面邻接图特征分类 |
* | SimilaritySearch | 3D 形状描述子(ESF/FPFH) + 历史模型相似度检索 |
*
* ## 使用模式
*
* @code{.cpp}
* // 特征分类
* vde::ai::FeatureClassifier classifier;
* classifier.load_model("models/feature_gnn.onnx");
* auto result = classifier.classify_features(body);
* for (auto& f : result.features) { ... }
*
* // 相似度搜索
* vde::ai::SimilaritySearch search;
* search.build_index(model_database);
* auto matches = search.query(target_body, 5); // top-5
* @endcode
*
* @ingroup ai
*/
#include "vde/brep/brep.h"
#include "vde/core/point.h"
#include "vde/core/aabb.h"
#include "vde/mesh/halfedge_mesh.h"
#include <vector>
#include <string>
#include <memory>
#include <unordered_map>
#include <functional>
#include <array>
#include <optional>
namespace vde::ai {
using core::Point3D;
using core::Vector3D;
using core::AABB3D;
using mesh::HalfedgeMesh;
// ═══════════════════════════════════════════════════════════
// 通用类型定义
// ═══════════════════════════════════════════════════════════
/** @brief 特征类型枚举 */
enum class FeatureType {
Unknown, Hole, Slot, Pocket, Boss, Fillet, Chamfer, Rib, Step, Groove
};
/** @brief 单个已分类特征 */
struct ClassifiedFeature {
FeatureType type = FeatureType::Unknown;
std::vector<int> face_ids; ///< 构成该特征的面 ID
std::string label; ///< 特征标签
double confidence = 0.0; ///< 分类置信度 [0,1]
Point3D centroid{0,0,0}; ///< 特征形心
Vector3D orientation{0,0,1}; ///< 特征方向
std::unordered_map<std::string, double> params; ///< 几何参数(半径、深度等)
};
/** @brief 特征分类结果 */
struct FeatureClassificationResult {
std::vector<ClassifiedFeature> features;
int hole_count = 0, slot_count = 0, pocket_count = 0;
int boss_count = 0, fillet_count = 0, chamfer_count = 0;
int rib_count = 0, step_count = 0, groove_count = 0;
double inference_time_ms = 0.0;
bool success = false;
std::string error_message;
};
// ═══════════════════════════════════════════════════════════
// 面邻接图 (Face Adjacency Graph) — GNN 输入
// ═══════════════════════════════════════════════════════════
/** @brief 面邻接图的节点(对应一个 B-Rep 面) */
struct FAGNode {
int face_id; ///< B-Rep 面 ID
std::vector<double> node_features; ///< 节点特征向量
int surface_type; ///< 曲面类型(0=平面,1=圆柱,2=圆锥,3=球面,...)
double area; ///< 面面积
Point3D centroid; ///< 面形心
Vector3D normal; ///< 面平均法向
};
/** @brief 面邻接图 */
struct FaceAdjacencyGraph {
std::vector<FAGNode> nodes; ///< 节点列表
std::vector<std::pair<int,int>> edges;///< 边列表(face_id 对)
std::vector<double> edge_features; ///< 边特征(凹/凸角、边长比等), 每个 edge 一个标量
};
// ═══════════════════════════════════════════════════════════
// 3D 形状描述子
// ═══════════════════════════════════════════════════════════
/** @brief Ensemble of Shape Functions (ESF) 描述子 — 640维直方图 */
struct ESFDescriptor {
static constexpr int kDim = 640;
std::array<double, kDim> histogram{};
};
/** @brief FPFH (Fast Point Feature Histograms) 描述子 — 33维 */
struct FPFHDescriptor {
static constexpr int kDim = 33;
std::array<double, kDim> histogram{};
};
/** @brief 联合 3D 形状描述子(ESF + FPFH */
struct ShapeDescriptor {
ESFDescriptor esf;
FPFHDescriptor fpfh;
std::string model_id; ///< 关联的模型 ID
std::string model_path; ///< 模型文件路径
};
// ═══════════════════════════════════════════════════════════
// FeatureClassifier — 基于 GNN 的特征分类器
// ═══════════════════════════════════════════════════════════
/**
* @brief 基于图神经网络的特征分类器
*
* 从 B-Rep 模型的面邻接图出发,通过 GNN(加载预训练 ONNX 模型)
* 对每个面进行分类,再将相邻同类面聚合为高层特征。
*
* ## 算法流水线
*
* 1. B-Rep 模型 → FaceAdjacencyGraph(面邻接图)
* 2. 节点特征编码:曲面类型、面积、曲率、法向
* 3. 边特征编码:二面角(凹/凸)、公共边长比
* 4. GNN 前向传播(ONNX Runtime)→ 每个面的分类概率
* 5. 相邻同类面聚合 → 特征实例(Hole/Slot/Pocket/...
* 6. 几何参数估计(半径、深度、方向等)
*/
class FeatureClassifier {
public:
FeatureClassifier();
~FeatureClassifier();
// ── 模型管理 ──────────────────────────────────
/** @brief 从文件加载预训练 ONNX 模型 */
bool load_model(const std::string& model_path);
/** @brief 检查模型是否已加载 */
[[nodiscard]] bool is_model_loaded() const noexcept { return model_loaded_; }
/** @brief 获取模型版本信息 */
[[nodiscard]] const std::string& model_version() const noexcept { return model_version_; }
// ── 图构建 ────────────────────────────────────
/**
* @brief 从 B-Rep 模型构建面邻接图
* @param body 输入的 B-Rep 模型
* @return 面邻接图(节点=面,边=拓扑邻接关系)
*/
[[nodiscard]] FaceAdjacencyGraph build_face_graph(const brep::BrepModel& body) const;
// ── 特征分类 ──────────────────────────────────
/**
* @brief 对 B-Rep 模型进行特征分类
* @param body 输入的 B-Rep 模型
* @return 分类结果(含特征列表和统计信息)
*/
[[nodiscard]] FeatureClassificationResult classify_features(const brep::BrepModel& body);
// ── 特征编码(可独立使用) ─────────────────────
/**
* @brief 计算面的节点特征向量
* @param body B-Rep 模型
* @param face_id 面索引
* @return 节点特征向量(曲面类型、面积、曲率等)
*/
[[nodiscard]] std::vector<double> encode_face_node(
const brep::BrepModel& body, int face_id) const;
/**
* @brief 计算面邻接边的特征
* @param body B-Rep 模型
* @param face_id_a 面 A
* @param face_id_b 面 B
* @return 边特征标量(二面角类型:凹/凸)
*/
[[nodiscard]] double encode_edge_feature(
const brep::BrepModel& body, int face_id_a, int face_id_b) const;
/**
* @brief 聚合相邻同类面为高层特征
* @param graph 面邻接图
* @param face_labels 每个面的分类标签
* @param body B-Rep 模型
* @return 聚合后的特征列表
*/
[[nodiscard]] std::vector<ClassifiedFeature> aggregate_features(
const FaceAdjacencyGraph& graph,
const std::vector<std::pair<FeatureType, double>>& face_labels,
const brep::BrepModel& body) const;
private:
struct Impl;
std::unique_ptr<Impl> impl_;
bool model_loaded_ = false;
std::string model_version_;
};
// ═══════════════════════════════════════════════════════════
// SimilaritySearch — 3D 形状相似度搜索
// ═══════════════════════════════════════════════════════════
/** @brief 单个相似度搜索结果 */
struct SimilarityMatch {
std::string model_id; ///< 匹配的模型 ID
std::string model_path; ///< 模型文件路径
double similarity = 0.0; ///< 相似度 [0,1],越高越相似
double esf_distance = 0.0; ///< ESF 描述子距离
double fpfh_distance = 0.0; ///< FPFH 描述子距离
};
/**
* @brief 基于 3D 形状描述子(ESF + FPFH)的相似度搜索引擎
*
* 构建模型数据库的索引,支持查询与目标模型最相似的历史模型。
*
* ## 使用流程
*
* 1. 对每个历史模型计算 ShapeDescriptorESF + FPFH
* 2. build_index(descriptors) 建立搜索索引
* 3. query(target_body, k) 找到 top-k 最相似模型
*/
class SimilaritySearch {
public:
SimilaritySearch();
~SimilaritySearch();
// ── 描述子计算 ────────────────────────────────
/**
* @brief 从 B-Rep 模型计算 ESF 描述子
*
* Ensemble of Shape Functions 使用三种形状函数
* (A3: 三点夹角, D2: 两点距离, D3: 三点面积) 的直方图。
*
* @param body B-Rep 模型
* @param samples 表面采样点数
* @return 640 维 ESF 直方图
*/
[[nodiscard]] ESFDescriptor compute_esf(const brep::BrepModel& body, int samples = 10000) const;
/**
* @brief 从 B-Rep 模型计算 FPFH 描述子
*
* Fast Point Feature Histograms 使用点对之间的角度关系。
*
* @param body B-Rep 模型
* @param samples 表面采样点数
* @return 33 维 FPFH 直方图
*/
[[nodiscard]] FPFHDescriptor compute_fpfh(const brep::BrepModel& body, int samples = 5000) const;
/**
* @brief 计算完整联合描述子 (ESF + FPFH)
* @param body B-Rep 模型
* @param model_id 模型标识符
* @param model_path 模型文件路径
* @param esf_samples ESF 采样数
* @param fpfh_samples FPFH 采样数
* @return 联合形状描述子
*/
[[nodiscard]] ShapeDescriptor compute_shape_descriptor(
const brep::BrepModel& body,
const std::string& model_id = "",
const std::string& model_path = "",
int esf_samples = 10000,
int fpfh_samples = 5000) const;
// ── 索引管理 ──────────────────────────────────
/**
* @brief 构建相似度搜索索引
* @param descriptors 历史模型的描述子集合
*/
void build_index(const std::vector<ShapeDescriptor>& descriptors);
/**
* @brief 向索引追加一个模型描述子
* @param desc 描述子
*/
void add_to_index(const ShapeDescriptor& desc);
/** @brief 索引中的模型数量 */
[[nodiscard]] size_t index_size() const noexcept;
/** @brief 清空索引 */
void clear_index();
// ── 搜索 ──────────────────────────────────────
/**
* @brief 搜索与目标模型最相似的历史模型
* @param body 目标 B-Rep 模型
* @param k 返回的 top-k 数量
* @return 按相似度降序排列的匹配结果
*/
[[nodiscard]] std::vector<SimilarityMatch> query(
const brep::BrepModel& body, int k = 5) const;
/**
* @brief 使用已有描述子搜索
* @param desc 目标描述子
* @param k 返回的 top-k 数量
* @return 按相似度降序排列的匹配结果
*/
[[nodiscard]] std::vector<SimilarityMatch> query_by_descriptor(
const ShapeDescriptor& desc, int k = 5) const;
// ── 距离度量 ──────────────────────────────────
/** @brief 计算两个 ESF 描述子之间的 L1 距离 */
[[nodiscard]] static double esf_distance(const ESFDescriptor& a, const ESFDescriptor& b);
/** @brief 计算两个 FPFH 描述子之间的 L2 距离 */
[[nodiscard]] static double fpfh_distance(const FPFHDescriptor& a, const FPFHDescriptor& b);
/** @brief 计算融合相似度 (ESF + FPFH 加权平均),返回 [0,1] */
[[nodiscard]] static double combined_similarity(
const ShapeDescriptor& a, const ShapeDescriptor& b,
double esf_weight = 0.5);
private:
struct Impl;
std::unique_ptr<Impl> impl_;
};
// ═══════════════════════════════════════════════════════════
// 辅助函数
// ═══════════════════════════════════════════════════════════
/**
* @brief 在 B-Rep 模型表面上随机采样点
* @param body B-Rep 模型
* @param num_samples 采样点数
* @return 表面上的随机点集合
*/
[[nodiscard]] std::vector<Point3D> sample_surface_points(
const brep::BrepModel& body, int num_samples);
/**
* @brief 从 B-Rep 模型中提取所有面的形心
* @param body B-Rep 模型
* @return 面的形心列表(按面 ID 索引)
*/
[[nodiscard]] std::vector<Point3D> face_centroids(const brep::BrepModel& body);
} // namespace vde::ai