2026-07-26 22:54:46 +08:00
|
|
|
|
#pragma once
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @file cam_advanced.h
|
|
|
|
|
|
* @brief CAM 高级加工策略 — 自适应清除、摆线铣削、残料加工、清根、碰撞检测、刀路优化
|
|
|
|
|
|
*
|
|
|
|
|
|
* 在 cam_strategies.h 的 3 轴基础策略之上提供:
|
|
|
|
|
|
* - adaptive_clearing — 自适应清除(摆线刀路),根据材料负载动态调整步距
|
|
|
|
|
|
* - trochoidal_milling — 摆线铣削,使用圆形/圆弧切入避免全刃切削
|
|
|
|
|
|
* - rest_machining — 残料加工,检测前序刀具未切削区域
|
|
|
|
|
|
* - pencil_tracing — 清根加工,沿角落/交线生成清根刀路
|
|
|
|
|
|
* - tool_holder_collision_check — 刀柄/刀杆碰撞检测
|
|
|
|
|
|
* - toolpath_optimization — 刀路重排序减少空行程
|
|
|
|
|
|
* - feed_rate_optimization — 基于材料去除率的进给优化
|
|
|
|
|
|
*
|
|
|
|
|
|
* @ingroup core
|
|
|
|
|
|
*/
|
|
|
|
|
|
#include "vde/core/point.h"
|
|
|
|
|
|
#include "vde/core/aabb.h"
|
|
|
|
|
|
#include "vde/core/cam_toolpath.h"
|
|
|
|
|
|
#include "vde/core/cam_strategies.h"
|
|
|
|
|
|
#include "vde/mesh/halfedge_mesh.h"
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
|
#include <optional>
|
|
|
|
|
|
#include <functional>
|
|
|
|
|
|
|
|
|
|
|
|
namespace vde::brep {
|
|
|
|
|
|
class BrepModel;
|
|
|
|
|
|
} // namespace vde::brep
|
|
|
|
|
|
|
|
|
|
|
|
namespace vde::core {
|
|
|
|
|
|
|
|
|
|
|
|
using core::Point3D;
|
|
|
|
|
|
using core::Vector3D;
|
|
|
|
|
|
using core::AABB3D;
|
|
|
|
|
|
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
|
|
// 高级 CAM 参数类型
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
|
|
|
|
|
|
|
|
/// 自适应清除参数
|
|
|
|
|
|
struct AdaptiveClearingParams {
|
|
|
|
|
|
double step_down = 1.0; ///< 每层切深 (mm)
|
|
|
|
|
|
double min_step_over = 0.5; ///< 最小横向步距 (mm)
|
|
|
|
|
|
double max_step_over = 3.0; ///< 最大横向步距 (mm) — 低负载时扩大
|
|
|
|
|
|
double engagement_angle = 45.0; ///< 最大啮合角 (度)
|
|
|
|
|
|
double feed_rate = 800.0; ///< 进给速度 (mm/min)
|
|
|
|
|
|
double safe_z = 15.0; ///< 安全高度 (mm)
|
|
|
|
|
|
double stock_to_leave = 0.5; ///< 留量 (mm)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 摆线铣削参数
|
|
|
|
|
|
struct TrochoidalParams {
|
|
|
|
|
|
double step_down = 1.0; ///< 每层切深 (mm)
|
|
|
|
|
|
double trochoid_radius = 2.5; ///< 摆线圈半径 (mm)
|
|
|
|
|
|
double step_forward = 1.0; ///< 每圈前进量 (mm)
|
|
|
|
|
|
double feed_rate = 600.0; ///< 进给速度 (mm/min)
|
|
|
|
|
|
double safe_z = 15.0; ///< 安全高度 (mm)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 残料加工参数
|
|
|
|
|
|
struct RestMachiningParams {
|
|
|
|
|
|
double step_down = 0.5; ///< 每层切深 (mm)
|
|
|
|
|
|
double step_over = 0.3; ///< 横向步距 (mm)
|
|
|
|
|
|
double feed_rate = 500.0; ///< 进给速度 (mm/min)
|
|
|
|
|
|
double safe_z = 15.0; ///< 安全高度 (mm)
|
|
|
|
|
|
double stock_threshold = 0.1; ///< 残料检测阈值 (mm)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 清根加工参数
|
|
|
|
|
|
struct PencilTracingParams {
|
|
|
|
|
|
double step_along = 0.2; ///< 沿角落方向的步距 (mm)
|
|
|
|
|
|
double feed_rate = 400.0; ///< 进给速度 (mm/min)
|
|
|
|
|
|
double safe_z = 15.0; ///< 安全高度 (mm)
|
|
|
|
|
|
double corner_angle_min = 5.0; ///< 最小检测角度 (度)
|
|
|
|
|
|
double corner_angle_max = 170.0; ///< 最大检测角度 (度)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 刀柄/刀杆定义(用于碰撞检测)
|
|
|
|
|
|
struct ToolHolder {
|
|
|
|
|
|
double diameter = 20.0; ///< 刀杆直径 (mm)
|
|
|
|
|
|
double length = 40.0; ///< 刀杆长度 (mm)
|
|
|
|
|
|
double clearance = 3.0; ///< 安全间隙 (mm)
|
|
|
|
|
|
std::string name; ///< 刀柄名称
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 碰撞检测结果
|
|
|
|
|
|
struct CollisionResult {
|
|
|
|
|
|
bool has_collision = false; ///< 是否发生碰撞
|
|
|
|
|
|
int collision_index = -1; ///< 发生碰撞的刀位点索引 (-1 = 无碰撞)
|
|
|
|
|
|
Point3D collision_point; ///< 碰撞位置(近似)
|
|
|
|
|
|
double penetration_depth = 0.0; ///< 干涉深度 (mm)
|
|
|
|
|
|
std::string description; ///< 碰撞描述
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 刀路优化参数
|
|
|
|
|
|
struct ToolpathOptimizationParams {
|
|
|
|
|
|
bool reorder_segments = true; ///< 是否重排序以减少空行程
|
|
|
|
|
|
bool merge_collinear = true; ///< 合并共线段
|
|
|
|
|
|
double merge_tolerance = 1e-3; ///< 共线容差 (mm)
|
|
|
|
|
|
bool remove_duplicates = true; ///< 去除重复点
|
|
|
|
|
|
double duplicate_tolerance = 1e-6;///< 重点容差 (mm)
|
|
|
|
|
|
bool smooth_corners = false; ///< 圆角过渡
|
|
|
|
|
|
double corner_radius = 0.0; ///< 过渡圆角半径 (mm)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 材料定义
|
|
|
|
|
|
struct Material {
|
|
|
|
|
|
std::string name; ///< 材料名称
|
|
|
|
|
|
double hardness_brinell = 200.0; ///< 布氏硬度
|
|
|
|
|
|
double specific_cutting_force = 2000.0; ///< 比切削力 (N/mm²)
|
|
|
|
|
|
double max_chip_thickness = 0.2; ///< 最大切屑厚度 (mm)
|
|
|
|
|
|
double max_feed_per_tooth = 0.3; ///< 最大每齿进给 (mm/tooth)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
|
|
// CAM 高级加工策略函数
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
|
|
|
|
|
|
|
|
/// 自适应清除 (Adaptive Clearing)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 使用摆线/自适应刀路进行粗加工,根据材料负载动态调整步距。
|
|
|
|
|
|
/// 在低负载区域扩大步距(高速切削),在高负载/角落区域缩小步距(避免断刀)。
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @param body B-Rep 实体模型
|
|
|
|
|
|
/// @param tool 使用的刀具
|
|
|
|
|
|
/// @param params 自适应清除参数
|
|
|
|
|
|
/// @return 自适应清除刀路
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @ingroup core
|
|
|
|
|
|
[[nodiscard]] Toolpath adaptive_clearing(
|
|
|
|
|
|
const brep::BrepModel& body,
|
|
|
|
|
|
const Tool& tool,
|
|
|
|
|
|
const AdaptiveClearingParams& params);
|
|
|
|
|
|
|
|
|
|
|
|
/// 摆线铣削 (Trochoidal Milling)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 刀具沿圆形/摆线路径切入,避免全刃切削。
|
|
|
|
|
|
/// 适用于深槽、窄槽加工,减少刀具负载和振动。
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @param slot 槽/边界曲线(定义槽的走向)
|
|
|
|
|
|
/// @param tool 使用的刀具
|
|
|
|
|
|
/// @param params 摆线铣削参数
|
|
|
|
|
|
/// @return 摆线铣削刀路
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @ingroup core
|
|
|
|
|
|
[[nodiscard]] Toolpath trochoidal_milling(
|
|
|
|
|
|
const std::vector<Point3D>& slot,
|
|
|
|
|
|
const Tool& tool,
|
|
|
|
|
|
const TrochoidalParams& params);
|
|
|
|
|
|
|
|
|
|
|
|
/// 残料加工 (Rest Machining)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 检测前序大刀具未切削到的角落/窄区域,用小刀具进行残料清除。
|
|
|
|
|
|
/// 通过比较两次不同直径刀具的遍历范围,识别残料区域。
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @param body B-Rep 实体模型
|
|
|
|
|
|
/// @param prev_tool 前序(较大)刀具
|
|
|
|
|
|
/// @param next_tool 后序(较小)刀具
|
|
|
|
|
|
/// @param params 残料加工参数
|
|
|
|
|
|
/// @return 残料加工刀路
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @ingroup core
|
|
|
|
|
|
[[nodiscard]] Toolpath rest_machining(
|
|
|
|
|
|
const brep::BrepModel& body,
|
|
|
|
|
|
const Tool& prev_tool,
|
|
|
|
|
|
const Tool& next_tool,
|
|
|
|
|
|
const RestMachiningParams& params = RestMachiningParams{});
|
|
|
|
|
|
|
|
|
|
|
|
/// 清根加工 (Pencil Tracing)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 沿模型角落/交线走刀,清除前序加工无法到达的根部材料。
|
|
|
|
|
|
/// 检测曲面之间的凹角交界线(角 < corner_angle_max),
|
|
|
|
|
|
/// 沿交线生成单线刀路。
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @param body B-Rep 实体模型
|
|
|
|
|
|
/// @param tool 使用的刀具(通常为球头刀)
|
|
|
|
|
|
/// @param params 清根加工参数
|
|
|
|
|
|
/// @return 清根刀路
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @ingroup core
|
|
|
|
|
|
[[nodiscard]] Toolpath pencil_tracing(
|
|
|
|
|
|
const brep::BrepModel& body,
|
|
|
|
|
|
const Tool& tool,
|
|
|
|
|
|
const PencilTracingParams& params = PencilTracingParams{});
|
|
|
|
|
|
|
|
|
|
|
|
/// 刀柄碰撞检测 (Tool Holder Collision Check)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 沿刀路检查刀柄和刀杆是否与工件发生碰撞。
|
|
|
|
|
|
/// 使用快速包围盒预检 + 精确三角形碰撞测试。
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @param toolpath 加工刀路
|
|
|
|
|
|
/// @param holder 刀柄/刀杆定义
|
|
|
|
|
|
/// @param body B-Rep 工件模型
|
|
|
|
|
|
/// @return 碰撞检测结果列表(每个刀位点一个结果)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @ingroup core
|
|
|
|
|
|
[[nodiscard]] std::vector<CollisionResult> tool_holder_collision_check(
|
|
|
|
|
|
const Toolpath& toolpath,
|
|
|
|
|
|
const ToolHolder& holder,
|
|
|
|
|
|
const brep::BrepModel& body);
|
|
|
|
|
|
|
|
|
|
|
|
/// 刀路优化 (Toolpath Optimization)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 优化刀路以减少非切削时间:
|
|
|
|
|
|
/// - 重排序段以最小化空行程(最近邻启发式)
|
|
|
|
|
|
/// - 合并共线相邻段
|
|
|
|
|
|
/// - 去除重复/过短段
|
|
|
|
|
|
/// - 可选圆角过渡
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @param toolpath 待优化的原始刀路
|
|
|
|
|
|
/// @param params 优化参数
|
|
|
|
|
|
/// @return 优化后的刀路
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @ingroup core
|
|
|
|
|
|
[[nodiscard]] Toolpath toolpath_optimization(
|
|
|
|
|
|
const Toolpath& toolpath,
|
|
|
|
|
|
const ToolpathOptimizationParams& params = ToolpathOptimizationParams{});
|
|
|
|
|
|
|
|
|
|
|
|
/// 进给优化 (Feed Rate Optimization)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 基于材料去除率动态调整进给速度:
|
|
|
|
|
|
/// - 估算每个刀位点的材料去除率(切削截面积 × 进给)
|
|
|
|
|
|
/// - 在去除率高的区域降低进给(保护刀具)
|
|
|
|
|
|
/// - 在去除率低的区域提高进给(提高效率)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @param toolpath 待优化的刀路
|
|
|
|
|
|
/// @param material 工件材料属性
|
|
|
|
|
|
/// @return 进给优化后的刀路(各段 feed_rate 已调整)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @ingroup core
|
|
|
|
|
|
[[nodiscard]] Toolpath feed_rate_optimization(
|
|
|
|
|
|
const Toolpath& toolpath,
|
|
|
|
|
|
const Material& material);
|
|
|
|
|
|
|
2026-07-26 23:13:22 +08:00
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
|
|
// 新增后处理器
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
|
|
|
|
|
|
|
|
/// Mazak (Mazatrol) 控制器后处理器
|
|
|
|
|
|
class MazakPost : public PostProcessor {
|
|
|
|
|
|
public:
|
|
|
|
|
|
[[nodiscard]] std::string prologue(const Toolpath& tp) const override;
|
|
|
|
|
|
[[nodiscard]] std::string epilogue(const Toolpath& tp) const override;
|
|
|
|
|
|
[[nodiscard]] std::string format_gcode(const PathSegment& seg) const override;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// Okuma (OSP) 控制器后处理器
|
|
|
|
|
|
class OkumaPost : public PostProcessor {
|
|
|
|
|
|
public:
|
|
|
|
|
|
[[nodiscard]] std::string prologue(const Toolpath& tp) const override;
|
|
|
|
|
|
[[nodiscard]] std::string epilogue(const Toolpath& tp) const override;
|
|
|
|
|
|
[[nodiscard]] std::string format_gcode(const PathSegment& seg) const override;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// Haas 控制器后处理器
|
|
|
|
|
|
class HaasPost : public PostProcessor {
|
|
|
|
|
|
public:
|
|
|
|
|
|
[[nodiscard]] std::string prologue(const Toolpath& tp) const override;
|
|
|
|
|
|
[[nodiscard]] std::string epilogue(const Toolpath& tp) const override;
|
|
|
|
|
|
[[nodiscard]] std::string format_gcode(const PathSegment& seg) const override;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// DMG Mori (Siemens 840D + DMG 扩展) 控制器后处理器
|
|
|
|
|
|
class DMGPost : public PostProcessor {
|
|
|
|
|
|
public:
|
|
|
|
|
|
[[nodiscard]] std::string prologue(const Toolpath& tp) const override;
|
|
|
|
|
|
[[nodiscard]] std::string epilogue(const Toolpath& tp) const override;
|
|
|
|
|
|
[[nodiscard]] std::string format_gcode(const PathSegment& seg) const override;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
|
|
// 探测循环与螺纹铣削
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
|
|
|
|
|
|
|
|
/// 探测循环类型
|
|
|
|
|
|
enum class ProbingCycleType {
|
|
|
|
|
|
SingleSurface, ///< 单面探测
|
|
|
|
|
|
Boss, ///< 凸台中心探测
|
|
|
|
|
|
Pocket, ///< 槽/孔中心探测
|
|
|
|
|
|
Corner, ///< 角落探测
|
|
|
|
|
|
Angle ///< 角度探测
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 探测循环参数
|
|
|
|
|
|
struct ProbingParams {
|
|
|
|
|
|
ProbingCycleType cycle_type = ProbingCycleType::SingleSurface;
|
|
|
|
|
|
Point3D approach_position = Point3D::Zero(); ///< 接近位置
|
|
|
|
|
|
Point3D target_position = Point3D::Zero(); ///< 目标/期望接触位置
|
|
|
|
|
|
Vector3D probe_direction = Vector3D(0, 0, -1); ///< 探测方向
|
|
|
|
|
|
double overtravel = 5.0; ///< 超程距离 (mm)
|
|
|
|
|
|
double feed_rate = 200.0; ///< 探测进给 (mm/min)
|
|
|
|
|
|
double retract_distance = 3.0; ///< 接触后退回距离 (mm)
|
|
|
|
|
|
double safe_z = 15.0; ///< 安全高度 (mm)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 探测结果
|
|
|
|
|
|
struct ProbingResult {
|
|
|
|
|
|
Point3D contact_point; ///< 实际接触点坐标
|
|
|
|
|
|
bool contact_made = false; ///< 是否探测到接触
|
|
|
|
|
|
double deviation = 0.0; ///< 与目标位置的偏差 (mm)
|
|
|
|
|
|
std::string message; ///< 结果消息
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 螺纹铣削参数
|
|
|
|
|
|
struct ThreadMillParams {
|
|
|
|
|
|
double thread_diameter = 10.0; ///< 螺纹公称直径 (mm)
|
|
|
|
|
|
double thread_pitch = 1.5; ///< 螺距 (mm)
|
|
|
|
|
|
double thread_depth = 20.0; ///< 螺纹深度 (mm)
|
|
|
|
|
|
double major_diameter = 10.0; ///< 大径 (mm)
|
|
|
|
|
|
double minor_diameter = 8.376; ///< 小径 (mm,M10×1.5 标准)
|
|
|
|
|
|
int num_passes = 3; ///< 切削刀数(径向分层)
|
|
|
|
|
|
double feed_rate = 300.0; ///< 进给速度 (mm/min)
|
|
|
|
|
|
double safe_z = 15.0; ///< 安全高度 (mm)
|
|
|
|
|
|
bool right_hand = true; ///< 右旋螺纹
|
|
|
|
|
|
bool internal_thread = true; ///< 内螺纹 (false = 外螺纹)
|
|
|
|
|
|
Point3D hole_center = Point3D::Zero(); ///< 孔中心/螺纹起点
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 探测循环 — 生成探测刀路
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 使用接触式测头执行工件找正/测量循环。
|
|
|
|
|
|
/// 支持单面、凸台、孔/槽、角落、角度等探测类型。
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @param tool 测头(接触式探头)
|
|
|
|
|
|
/// @param params 探测参数
|
|
|
|
|
|
/// @return 探测刀路
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @ingroup core
|
|
|
|
|
|
[[nodiscard]] Toolpath probing_cycle(
|
|
|
|
|
|
const Tool& tool,
|
|
|
|
|
|
const ProbingParams& params);
|
|
|
|
|
|
|
|
|
|
|
|
/// 探测循环(含结果)— 执行探测并返回结果
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @param tool 测头
|
|
|
|
|
|
/// @param params 探测参数
|
|
|
|
|
|
/// @param body 工件模型(模拟碰撞检测)
|
|
|
|
|
|
/// @return 探测结果
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @ingroup core
|
|
|
|
|
|
[[nodiscard]] ProbingResult probing_cycle_with_result(
|
|
|
|
|
|
const Tool& tool,
|
|
|
|
|
|
const ProbingParams& params,
|
|
|
|
|
|
const brep::BrepModel& body);
|
|
|
|
|
|
|
|
|
|
|
|
/// 螺纹铣削 — 生成螺纹铣削刀路
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 使用螺纹铣刀以螺旋插补方式加工螺纹。
|
|
|
|
|
|
/// 支持内/外螺纹、右旋/左旋、多刀切削。
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 刀路策略:
|
|
|
|
|
|
/// 1. 定位到孔中心上方安全高度
|
|
|
|
|
|
/// 2. 下刀到螺纹起始深度
|
|
|
|
|
|
/// 3. 径向切入到螺纹小径
|
|
|
|
|
|
/// 4. 以螺旋方式从底向上(或从顶向下)走 360° × 圈数
|
|
|
|
|
|
/// 5. 径向退出
|
|
|
|
|
|
/// 6. 如有多次走刀 (num_passes > 1),逐步增加半径
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @param tool 螺纹铣刀
|
|
|
|
|
|
/// @param params 螺纹参数
|
|
|
|
|
|
/// @return 螺纹铣削刀路
|
|
|
|
|
|
///
|
|
|
|
|
|
/// @ingroup core
|
|
|
|
|
|
[[nodiscard]] Toolpath thread_milling(
|
|
|
|
|
|
const Tool& tool,
|
|
|
|
|
|
const ThreadMillParams& params);
|
|
|
|
|
|
|
2026-07-26 22:54:46 +08:00
|
|
|
|
} // namespace vde::core
|