Files
ViewDesignEngine/python/bindings.cpp
T
ViewDesignEngine cf13496ff6
CI / Build & Test (push) Failing after 1m31s
CI / Release Build (push) Failing after 16m55s
feat: v0.5.0 P1 + 差异化功能 — Voronoi, Marching Cubes, 曲率, 序列化, Python绑定
新增功能:
- core: 2D Voronoi 图(Delaunay 对偶图)
- mesh: Marching Cubes(完整256项三角表 + SDF 辅助函数)
- mesh: 离散曲率(Gaussian/Mean, Cotan 公式)
- foundation: 二进制序列化(版本化格式,Little-Endian)
- python: pybind11 绑定(30+ API 暴露)
- marching_cubes.h: SDF 基本体(球/盒)+ 光滑布尔
2026-07-23 06:27:43 +00:00

150 lines
6.3 KiB
C++

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/eigen.h>
#include <pybind11/functional.h>
#include "vde/core/point.h"
#include "vde/core/triangle.h"
#include "vde/core/aabb.h"
#include "vde/core/convex_hull.h"
#include "vde/core/distance.h"
#include "vde/core/voronoi.h"
#include "vde/curves/bezier_curve.h"
#include "vde/curves/nurbs_curve.h"
#include "vde/mesh/halfedge_mesh.h"
#include "vde/mesh/delaunay_2d.h"
#include "vde/mesh/marching_cubes.h"
#include "vde/mesh/mesh_curvature.h"
#include "vde/mesh/mesh_simplify.h"
#include "vde/mesh/mesh_smooth.h"
#include "vde/mesh/mesh_quality.h"
#include "vde/mesh/mesh_repair.h"
#include "vde/mesh/mesh_boolean.h"
#include "vde/spatial/bvh.h"
#include "vde/collision/gjk.h"
#include "vde/collision/ray_intersect.h"
#include "vde/boolean/boolean_2d.h"
#include "vde/foundation/tolerance.h"
#include "vde/foundation/serializer.h"
#include "vde/foundation/io_obj.h"
#include "vde/foundation/io_stl.h"
namespace py = pybind11;
using namespace vde;
PYBIND11_MODULE(_vde, m) {
m.doc() = "ViewDesignEngine — High-performance CAD geometry engine";
// ── Core ──
py::class_<Point3D>(m, "Point3")
.def(py::init<double,double,double>())
.def_property("x", [](const Point3D& p){ return p.x(); }, [](Point3D& p, double v){ p.x()=v; })
.def_property("y", [](const Point3D& p){ return p.y(); }, [](Point3D& p, double v){ p.y()=v; })
.def_property("z", [](const Point3D& p){ return p.z(); }, [](Point3D& p, double v){ p.z()=v; })
.def("__repr__", [](const Point3D& p){ return "("+std::to_string(p.x())+","+std::to_string(p.y())+","+std::to_string(p.z())+")"; })
.def("distance", [](const Point3D& a, const Point3D& b){ return core::distance(a,b); });
py::class_<Vector3D>(m, "Vector3")
.def(py::init<double,double,double>())
.def("norm", &Vector3D::norm)
.def("normalized", &Vector3D::normalized)
.def("dot", &Vector3D::dot)
.def("cross", &Vector3D::cross);
py::class_<Triangle3D>(m, "Triangle")
.def(py::init<Point3D,Point3D,Point3D>())
.def("area", &Triangle3D::area)
.def("normal", &Triangle3D::normal)
.def("centroid", &Triangle3D::centroid)
.def("contains", &Triangle3D::contains);
py::class_<core::AABB3D>(m, "AABB")
.def(py::init<>())
.def("expand", py::overload_cast<const Point3D&>(&core::AABB3D::expand))
.def("center", &core::AABB3D::center)
.def("extent", &core::AABB3D::extent)
.def("contains", &core::AABB3D::contains)
.def("intersects", &core::AABB3D::intersects);
m.def("convex_hull_2d", &core::convex_hull_2d, "2D convex hull (Graham scan)");
m.def("voronoi_2d", &core::voronoi_2d, "2D Voronoi diagram");
// ── Curves ──
py::class_<curves::BezierCurve>(m, "BezierCurve")
.def(py::init<std::vector<Point3D>>())
.def("evaluate", &curves::BezierCurve::evaluate)
.def("degree", &curves::BezierCurve::degree);
py::class_<curves::NurbsCurve>(m, "NurbsCurve")
.def(py::init<std::vector<Point3D>,std::vector<double>,std::vector<double>,int>())
.def("evaluate", &curves::NurbsCurve::evaluate)
.def("degree", &curves::NurbsCurve::degree);
// ── Mesh ──
py::class_<mesh::HalfedgeMesh>(m, "Mesh")
.def(py::init<>())
.def("num_vertices", &mesh::HalfedgeMesh::num_vertices)
.def("num_faces", &mesh::HalfedgeMesh::num_faces)
.def("vertex", &mesh::HalfedgeMesh::vertex)
.def("add_vertex", &mesh::HalfedgeMesh::add_vertex)
.def("add_face", &mesh::HalfedgeMesh::add_face)
.def("bounds", &mesh::HalfedgeMesh::bounds)
.def("update_normals", &mesh::HalfedgeMesh::update_normals);
m.def("delaunay_2d", &mesh::delaunay_2d, "2D Delaunay triangulation");
m.def("simplify_mesh", &mesh::simplify_mesh, "QEM mesh simplification");
m.def("smooth_mesh", &mesh::smooth_mesh, "Laplacian/Taubin mesh smoothing");
m.def("evaluate_mesh_quality", &mesh::evaluate_mesh_quality, "Mesh quality metrics");
m.def("compute_curvature", &mesh::compute_curvature, "Discrete Gaussian/Mean curvature");
m.def("marching_cubes", &mesh::marching_cubes, "Marching Cubes isosurface extraction");
// ── Spatial ──
py::class_<spatial::BVH>(m, "BVH")
.def(py::init<>())
.def("build", &spatial::BVH::build)
.def("size", &spatial::BVH::size)
.def("query_ray_nearest", &spatial::BVH::query_ray_nearest);
// ── Collision ──
m.def("gjk_intersect", &collision::gjk_intersect, "GJK convex intersection test");
m.def("gjk_distance", &collision::gjk_distance, "GJK minimum distance");
m.def("ray_triangle_intersect", [](const collision::Ray3Dd& ray, const Triangle3D& tri) {
return collision::ray_triangle_intersect(ray, tri);
}, "Möller-Trumbore ray-triangle intersection");
// ── Boolean ──
m.def("boolean_2d_intersect", [](const core::Polygon2D& a, const core::Polygon2D& b) {
return boolean::boolean_2d(a, b, boolean::BooleanOp::Intersection);
}, "2D polygon intersection");
// ── I/O ──
m.def("read_obj", [](const std::string& path) {
auto data = foundation::read_obj(path);
mesh::HalfedgeMesh m;
std::vector<std::array<int,3>> tris;
for (const auto& f : data.faces) {
if (f.size() >= 3) tris.push_back({f[0],f[1],f[2]});
}
m.build_from_triangles(data.vertices, tris);
return m;
}, "Load OBJ mesh");
m.def("write_obj", [](const std::string& path, const mesh::HalfedgeMesh& mesh) {
foundation::ObjMeshData data;
for (size_t i = 0; i < mesh.num_vertices(); ++i) data.vertices.push_back(mesh.vertex(i));
for (size_t i = 0; i < mesh.num_faces(); ++i) {
auto vis = mesh.face_vertices(static_cast<int>(i));
data.faces.push_back(vis);
}
foundation::write_obj(path, data);
}, "Save OBJ mesh");
// ── Tolerance ──
py::class_<foundation::Tolerance>(m, "Tolerance")
.def(py::init<double,double,double,double>(),
py::arg("absolute")=1e-6, py::arg("relative")=1e-8,
py::arg("angular")=1e-8, py::arg("snapping")=1e-4);
// ── Version ──
m.attr("__version__") = "0.3.0";
}