feat: P2 B-Rep 内核 + 建模操作
- brep: 完整 B-Rep 数据结构(Vertex/Edge/Loop/Face/Shell/Body) - brep: 实体工厂(box/cylinder/sphere) - brep: 建模操作(extrude/revolve/sweep/loft) - brep: 拓扑查询(face_edges/edge_faces/vertex_edges) - brep: 网格转换(to_mesh) - 新增 vde_brep 模块,更新聚合库
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
#include "vde/core/point.h"
|
||||
#include "vde/core/aabb.h"
|
||||
#include "vde/curves/nurbs_curve.h"
|
||||
#include "vde/curves/nurbs_surface.h"
|
||||
#include "vde/mesh/halfedge_mesh.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace vde::brep {
|
||||
|
||||
enum class CurveType { Line, Circle, Bezier, BSpline, Nurbs };
|
||||
|
||||
struct TopoVertex { int id; Point3D point; double tolerance = 1e-6; };
|
||||
struct TopoEdge {
|
||||
int id, v_start, v_end;
|
||||
std::shared_ptr<curves::NurbsCurve> curve;
|
||||
bool reversed = false;
|
||||
};
|
||||
struct TopoLoop { int id; std::vector<int> edges; bool is_outer = true; };
|
||||
struct TopoFace { int id, surface_id; std::vector<int> loops; bool reversed = false; };
|
||||
struct TopoShell { int id; std::vector<int> faces; bool closed = true; };
|
||||
struct TopoBody { int id; std::vector<int> shells; std::string name; };
|
||||
|
||||
class BrepModel {
|
||||
public:
|
||||
BrepModel() = default;
|
||||
int add_vertex(const Point3D& p);
|
||||
int add_edge(int v0, int v1);
|
||||
int add_edge(int v0, int v1, const curves::NurbsCurve& curve);
|
||||
int add_loop(const std::vector<int>& edges, bool outer = true);
|
||||
int add_face(int surface_id, const std::vector<int>& loops);
|
||||
int add_shell(const std::vector<int>& faces, bool closed = true);
|
||||
int add_body(const std::vector<int>& shells, const std::string& name = "");
|
||||
int add_surface(const curves::NurbsSurface& surf);
|
||||
|
||||
[[nodiscard]] size_t num_vertices() const { return vertices_.size(); }
|
||||
[[nodiscard]] size_t num_edges() const { return edges_.size(); }
|
||||
[[nodiscard]] size_t num_faces() const { return faces_.size(); }
|
||||
[[nodiscard]] size_t num_bodies() const { return bodies_.size(); }
|
||||
|
||||
[[nodiscard]] const TopoVertex& vertex(int id) const { return vertices_[id]; }
|
||||
[[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]; }
|
||||
|
||||
[[nodiscard]] core::AABB3D bounds() const;
|
||||
[[nodiscard]] bool is_valid() const;
|
||||
[[nodiscard]] mesh::HalfedgeMesh to_mesh(double deflection = 0.01) const;
|
||||
|
||||
[[nodiscard]] std::vector<int> face_edges(int face_id) const;
|
||||
[[nodiscard]] std::vector<int> edge_faces(int edge_id) const;
|
||||
[[nodiscard]] std::vector<int> vertex_edges(int vertex_id) const;
|
||||
|
||||
private:
|
||||
std::vector<TopoVertex> vertices_;
|
||||
std::vector<TopoEdge> edges_;
|
||||
std::vector<TopoLoop> loops_;
|
||||
std::vector<TopoFace> faces_;
|
||||
std::vector<TopoShell> shells_;
|
||||
std::vector<TopoBody> bodies_;
|
||||
std::vector<curves::NurbsSurface> surfaces_;
|
||||
int next_id_ = 0;
|
||||
};
|
||||
|
||||
} // namespace vde::brep
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
#include "vde/brep/brep.h"
|
||||
|
||||
namespace vde::brep {
|
||||
|
||||
/// Extrude a planar face/wire along a direction
|
||||
/// @param profile Profile curve (must be planar)
|
||||
/// @param dir Extrusion direction (length = distance)
|
||||
[[nodiscard]] BrepModel extrude(const curves::NurbsCurve& profile, const Vector3D& dir);
|
||||
|
||||
/// Revolve a profile around an axis
|
||||
[[nodiscard]] BrepModel revolve(const curves::NurbsCurve& profile,
|
||||
const Point3D& axis_origin,
|
||||
const Vector3D& axis_dir,
|
||||
double angle_rad = 2.0 * M_PI);
|
||||
|
||||
/// Sweep a profile along a path curve
|
||||
[[nodiscard]] BrepModel sweep(const curves::NurbsCurve& profile,
|
||||
const curves::NurbsCurve& path);
|
||||
|
||||
/// Loft between two or more profile curves
|
||||
[[nodiscard]] BrepModel loft(const std::vector<curves::NurbsCurve>& profiles);
|
||||
|
||||
/// Create a solid box
|
||||
[[nodiscard]] BrepModel make_box(double w, double h, double d);
|
||||
|
||||
/// Create a solid cylinder
|
||||
[[nodiscard]] BrepModel make_cylinder(double radius, double height, int segments = 32);
|
||||
|
||||
/// Create a solid sphere
|
||||
[[nodiscard]] BrepModel make_sphere(double radius, int segments_u = 32, int segments_v = 16);
|
||||
|
||||
/// Fillet an edge (constant radius)
|
||||
/// @param body Input body
|
||||
/// @param edge_id Edge to fillet
|
||||
/// @param radius Fillet radius
|
||||
[[nodiscard]] BrepModel fillet(const BrepModel& body, int edge_id, double radius);
|
||||
|
||||
/// Chamfer an edge
|
||||
[[nodiscard]] BrepModel chamfer(const BrepModel& body, int edge_id, double distance);
|
||||
|
||||
/// Shell a solid body (hollow it out)
|
||||
/// @param body Input solid body
|
||||
/// @param face_id Face to remove (opening), -1 for closed shell
|
||||
/// @param thickness Wall thickness (positive = outward offset)
|
||||
[[nodiscard]] BrepModel shell(const BrepModel& body, int face_id, double thickness);
|
||||
|
||||
} // namespace vde::brep
|
||||
Reference in New Issue
Block a user