69888621cd
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
367 lines
14 KiB
C++
367 lines
14 KiB
C++
#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. 对每个历史模型计算 ShapeDescriptor(ESF + 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
|