feat(v2.0.0): Sprint 10 — B-Rep完善 + STEP导入/导出 + 布尔运算 + 验证
S10-A: B-Rep modeling 补齐 - fillet: 恒定半径滚动球倒圆(NURBS 曲面构建 + 相邻面裁剪) - chamfer: 等距倒角(平面偏移 + 倒角面构建) - shell: 完整抽壳(顶点偏移 + 内外面 + 开口侧壁) S10-B: STEP AP203/AP214 导入 - ISO 10303-21 解析器(1,424 行) - 支持 14 种几何实体 → NurbsCurve/NurbsSurface 转换 - 完整拓扑链:VERTEX_POINT → EDGE_CURVE → EDGE_LOOP → ADVANCED_FACE → CLOSED_SHELL → MANIFOLD_SOLID_BREP - 装配支持:NEXT_ASSEMBLY_USAGE_OCCURRENCE + CONTEXT_DEPENDENT_SHAPE_REPRESENTATION S10-C.1: STEP AP214 导出 - export_step / export_step_file - 曲线/曲面类型自动检测简化输出 S10-C.2: B-Rep 级布尔运算 - brep_union / brep_intersection / brep_difference - 面-面求交 + 内/外分类 + 面缝合 S10-C.3: B-Rep 工程验证 - ValidationResult: 水密性/悬边/自相交/方向一致性/欧拉示性数 测试: 5 个新测试文件,47 项测试(modeling/STEP导入/导出/布尔/验证) 修改: 7 files (+576/-47) | 新增: 13 files (4,141 行) 总计: +4,670 行
This commit is contained in:
@@ -43,7 +43,10 @@ public:
|
||||
[[nodiscard]] size_t num_faces() const { return faces_.size(); }
|
||||
[[nodiscard]] size_t num_bodies() const { return bodies_.size(); }
|
||||
|
||||
// Look up vertex by array index (faster, for sequential access)
|
||||
[[nodiscard]] const TopoVertex& vertex(int id) const { return vertices_[id]; }
|
||||
// Look up vertex by unique ID (correct for ID-based references from edge data)
|
||||
[[nodiscard]] const TopoVertex& vertex_by_id(int id) const;
|
||||
[[nodiscard]] const TopoEdge& edge(int id) const { return edges_[id]; }
|
||||
[[nodiscard]] const TopoFace& face(int id) const { return faces_[id]; }
|
||||
[[nodiscard]] const curves::NurbsSurface& surface(int id) const { return surfaces_[id]; }
|
||||
@@ -56,6 +59,10 @@ public:
|
||||
[[nodiscard]] std::vector<int> edge_faces(int edge_id) const;
|
||||
[[nodiscard]] std::vector<int> vertex_edges(int vertex_id) const;
|
||||
|
||||
[[nodiscard]] size_t num_surfaces() const { return surfaces_.size(); }
|
||||
[[nodiscard]] const TopoLoop& loop_by_id(int id) const;
|
||||
[[nodiscard]] const std::vector<TopoLoop>& all_loops() const { return loops_; }
|
||||
|
||||
private:
|
||||
std::vector<TopoVertex> vertices_;
|
||||
std::vector<TopoEdge> edges_;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include "vde/brep/brep.h"
|
||||
|
||||
namespace vde::brep {
|
||||
|
||||
/// B-Rep level boolean union: A ∪ B
|
||||
[[nodiscard]] BrepModel brep_union(const BrepModel& a, const BrepModel& b);
|
||||
|
||||
/// B-Rep level boolean intersection: A ∩ B
|
||||
[[nodiscard]] BrepModel brep_intersection(const BrepModel& a, const BrepModel& b);
|
||||
|
||||
/// B-Rep level boolean difference: A \ B
|
||||
[[nodiscard]] BrepModel brep_difference(const BrepModel& a, const BrepModel& b);
|
||||
|
||||
} // namespace vde::brep
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
#include "vde/brep/brep.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
|
||||
namespace vde::brep {
|
||||
|
||||
/// Comprehensive validation result for B-Rep models.
|
||||
struct ValidationResult {
|
||||
bool valid = true;
|
||||
std::vector<std::string> errors;
|
||||
std::vector<std::string> warnings;
|
||||
|
||||
/// Fraction of edges with exactly 2 adjacent faces (1.0 = perfect)
|
||||
double watertightness = 1.0;
|
||||
|
||||
/// Fraction of face pairs that don't intersect except at shared edges
|
||||
double self_intersection_free = 1.0;
|
||||
|
||||
double min_edge_length = std::numeric_limits<double>::max();
|
||||
double max_edge_length = 0.0;
|
||||
size_t non_manifold_edges = 0;
|
||||
size_t dangling_edges = 0;
|
||||
size_t inconsistent_orientations = 0;
|
||||
size_t total_edges = 0;
|
||||
size_t total_faces = 0;
|
||||
};
|
||||
|
||||
/// Perform comprehensive validation on a BrepModel.
|
||||
/// Checks watertightness, orientation consistency, self-intersection,
|
||||
/// edge length bounds, Euler characteristic, and closed shells.
|
||||
[[nodiscard]] ValidationResult validate(const BrepModel& body);
|
||||
|
||||
} // namespace vde::brep
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include "vde/brep/brep.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace vde::brep {
|
||||
|
||||
/// Export bodies to STEP AP214 (ISO 10303-214) format string.
|
||||
/// Handles planes, cylinders, B-spline surfaces, lines, circles, and B-spline curves.
|
||||
[[nodiscard]] std::string export_step(const std::vector<BrepModel>& bodies);
|
||||
|
||||
/// Export and write to file (AP214 compliant).
|
||||
void export_step_file(const std::string& filepath, const std::vector<BrepModel>& bodies);
|
||||
|
||||
} // namespace vde::brep
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include "vde/brep/brep.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace vde::brep {
|
||||
|
||||
/// STEP import error codes
|
||||
enum class StepError {
|
||||
Ok = 0,
|
||||
FileNotFound,
|
||||
ParseError,
|
||||
InvalidHeader,
|
||||
UnsupportedSchema,
|
||||
MissingEntity,
|
||||
EntityTypeError,
|
||||
};
|
||||
|
||||
/// Parse a STEP file (AP203/AP214) and return B-Rep bodies
|
||||
/// @param filepath Path to .step/.stp file
|
||||
/// @return Vector of BrepModel bodies (one per PRODUCT in the file)
|
||||
[[nodiscard]] std::vector<BrepModel> import_step(const std::string& filepath);
|
||||
|
||||
/// Parse STEP data from a string (for testing)
|
||||
[[nodiscard]] std::vector<BrepModel> import_step_from_string(const std::string& step_data);
|
||||
|
||||
/// Get the last error from import_step / import_step_from_string
|
||||
[[nodiscard]] StepError step_last_error();
|
||||
|
||||
/// Get a human-readable description of the last error
|
||||
[[nodiscard]] const std::string& step_last_error_message();
|
||||
|
||||
} // namespace vde::brep
|
||||
Reference in New Issue
Block a user