8be2f0ba0a
M1 — Draft Analysis (拔模分析): - draft_angle(face, pull_dir): compute draft angle from NURBS surface normal - analyze_draft(body, pull_dir, min_angle): full-model analysis with face classification - DraftFaceType: Positive/Negative/ZeroDraft/Undercut with area-weighted stats - draft_report(): human-readable moldability report - create_draft_face / apply_draft: face rotation stubs (needs mutable surface access) M2 — Incremental Mesh (增量网格): - IncrementalMesher: face_id → mesh fragment mapping with dirty tracking - invalidate_face / rebuild_dirty / rebuild_all: targeted remeshing - merged_mesh(): combine clean face meshes into single HalfedgeMesh - Cache statistics: hit rate + memory estimation M3 — Kinematic Chain (运动链求解): - FourBarLinkage: Grashof classification + Freudenstein position solver - GearPair/GearTrain: ratio-based transmission solver with multi-stage support - CamFollower: 5 motion types (Dwell/CV/SHM/Cycloidal/3-4-5 Polynomial) - Full-cycle analysis for all solvers 7 new files, ~1400 lines of header + implementation
151 lines
5.0 KiB
C++
151 lines
5.0 KiB
C++
#pragma once
|
|
/**
|
|
* @file draft_analysis.h
|
|
* @brief 拔模分析
|
|
*
|
|
* 模具设计中的关键分析工具:
|
|
* - 计算每个面相对于拔模方向的拔模角
|
|
* - 分类面:正拔模 / 负拔模 / 零拔模 / 倒扣
|
|
* - 生成拔模面
|
|
*
|
|
* @ingroup brep
|
|
*/
|
|
|
|
#include "vde/brep/brep.h"
|
|
#include "vde/core/point.h"
|
|
#include "vde/core/aabb.h"
|
|
#include <vector>
|
|
#include <string>
|
|
#include <map>
|
|
|
|
namespace vde::brep {
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
// Draft Result Types
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
/// 拔模面分类
|
|
enum class DraftFaceType {
|
|
Positive, ///< 正拔模:角度 > min_draft_angle
|
|
Negative, ///< 负拔模:角度 < -min_draft_angle
|
|
ZeroDraft, ///< 零拔模:|角度| ≤ min_draft_angle(平行于拔模方向)
|
|
Undercut, ///< 倒扣:面法线与拔模方向法向分量不一致(侧面障碍)
|
|
};
|
|
|
|
/// 单个面的拔模分析结果
|
|
struct DraftFaceResult {
|
|
int face_id = -1; ///< 面ID
|
|
double draft_angle = 0.0; ///< 拔模角(弧度),正值 = 向外张开
|
|
DraftFaceType classification = DraftFaceType::ZeroDraft;
|
|
core::Vector3D face_normal; ///< 面法线(近似)
|
|
double face_area = 0.0; ///< 面面积(用于加权统计)
|
|
};
|
|
|
|
/// 全模型拔模分析结果
|
|
struct DraftAnalysisResult {
|
|
/// 拔模方向(输入)
|
|
core::Vector3D pull_direction{0, 0, 1};
|
|
|
|
/// 最小允许拔模角(弧度)
|
|
double min_draft_angle = 0.0;
|
|
|
|
/// 每个面的拔模分析
|
|
std::vector<DraftFaceResult> faces;
|
|
|
|
// ─── 汇总统计 ───
|
|
|
|
/// 面分类统计
|
|
int positive_count = 0;
|
|
int negative_count = 0;
|
|
int zero_draft_count = 0;
|
|
int undercut_count = 0;
|
|
|
|
/// 面积加权平均拔模角
|
|
double area_weighted_angle = 0.0;
|
|
|
|
/// 最小/最大拔模角(正拔模面)
|
|
double min_positive_angle = std::numeric_limits<double>::max();
|
|
double max_positive_angle = -std::numeric_limits<double>::max();
|
|
|
|
/// 是否有倒扣(模具无法脱出)
|
|
[[nodiscard]] bool has_undercut() const { return undercut_count > 0; }
|
|
|
|
/// 是否全部可脱模
|
|
[[nodiscard]] bool is_moldable() const { return undercut_count == 0; }
|
|
|
|
/// 拔模角分布:角度区间 → 面数量(用于热力图)
|
|
[[nodiscard]] std::map<int, int> angle_distribution(int bins = 18) const;
|
|
};
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
// Draft Analysis Functions
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* @brief 计算单个面的近似拔模角
|
|
*
|
|
* 拔模角 = π/2 - arccos(|n·d|),其中 n 为面法线,d 为拔模方向。
|
|
* 正值表示面沿拔模方向向外张开。
|
|
*
|
|
* @param body B-Rep 实体
|
|
* @param face_id 面ID
|
|
* @param pull_dir 拔模方向(会被归一化)
|
|
* @return 拔模角(弧度),范围 [-π/2, π/2]
|
|
*/
|
|
[[nodiscard]] double draft_angle(const BrepModel& body, int face_id,
|
|
const core::Vector3D& pull_dir);
|
|
|
|
/**
|
|
* @brief 全模型拔模分析
|
|
*
|
|
* 对 B-Rep 实体的每个面计算拔模角并分类。
|
|
*
|
|
* @param body B-Rep 实体
|
|
* @param pull_dir 拔模方向
|
|
* @param min_draft_angle 最小允许拔模角(弧度),默认 1° (≈0.0175 rad)
|
|
* @return 完整分析结果
|
|
*/
|
|
[[nodiscard]] DraftAnalysisResult analyze_draft(const BrepModel& body,
|
|
const core::Vector3D& pull_dir,
|
|
double min_draft_angle = 0.0174533);
|
|
|
|
/**
|
|
* @brief 创建拔模面
|
|
*
|
|
* 沿拔模方向偏转面,使其达到指定拔模角度。
|
|
* (基础实现:沿边界旋转面法线)
|
|
*
|
|
* @param body B-Rep 实体(会被修改)
|
|
* @param face_id 面ID
|
|
* @param pull_dir 拔模方向
|
|
* @param angle 目标拔模角(弧度,正值 = 向外)
|
|
* @return 是否成功
|
|
*/
|
|
[[nodiscard]] bool create_draft_face(BrepModel& body, int face_id,
|
|
const core::Vector3D& pull_dir, double angle);
|
|
|
|
/**
|
|
* @brief 批量应用拔模
|
|
*
|
|
* 对指定面列表创建拔模面。
|
|
*
|
|
* @param body B-Rep 实体(会被修改)
|
|
* @param face_ids 面ID列表
|
|
* @param pull_dir 拔模方向
|
|
* @param angle 目标拔模角(弧度)
|
|
* @return 成功应用拔模的面数量
|
|
*/
|
|
[[nodiscard]] int apply_draft(BrepModel& body,
|
|
const std::vector<int>& face_ids,
|
|
const core::Vector3D& pull_dir, double angle);
|
|
|
|
/**
|
|
* @brief 拔模分析报告(人类可读字符串)
|
|
*
|
|
* @param result 分析结果
|
|
* @return 格式化报告
|
|
*/
|
|
[[nodiscard]] std::string draft_report(const DraftAnalysisResult& result);
|
|
|
|
} // namespace vde::brep
|