#include #include #include #include #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_(m, "Point3") .def(py::init()) .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_(m, "Vector3") .def(py::init()) .def("norm", &Vector3D::norm) .def("normalized", &Vector3D::normalized) .def("dot", &Vector3D::dot) .def("cross", &Vector3D::cross); py::class_(m, "Triangle") .def(py::init()) .def("area", &Triangle3D::area) .def("normal", &Triangle3D::normal) .def("centroid", &Triangle3D::centroid) .def("contains", &Triangle3D::contains); py::class_(m, "AABB") .def(py::init<>()) .def("expand", py::overload_cast(&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_(m, "BezierCurve") .def(py::init>()) .def("evaluate", &curves::BezierCurve::evaluate) .def("degree", &curves::BezierCurve::degree); py::class_(m, "NurbsCurve") .def(py::init,std::vector,std::vector,int>()) .def("evaluate", &curves::NurbsCurve::evaluate) .def("degree", &curves::NurbsCurve::degree); // ── Mesh ── py::class_(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_(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> 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(i)); data.faces.push_back(vis); } foundation::write_obj(path, data); }, "Save OBJ mesh"); // ── Tolerance ── py::class_(m, "Tolerance") .def(py::init(), 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"; }