From bc78c832e98bb8e9b36a4d236d5ad9ce36de66c5 Mon Sep 17 00:00:00 2001 From: Jakub Marcowski <01158831@pw.edu.pl> Date: Sat, 14 Oct 2023 15:18:14 +0200 Subject: [PATCH] Expose 3D Delaunay tetrahedralization in `Geometry3D` --- core/core_bind.cpp | 5 +++++ core/core_bind.h | 1 + core/math/geometry_3d.h | 16 ++++++++++++++++ doc/classes/Geometry3D.xml | 7 +++++++ 4 files changed, 29 insertions(+) diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 981d9b00251..281c8278407 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -1039,6 +1039,10 @@ Vector Geometry3D::clip_polygon(const Vector &p_points, const return ::Geometry3D::clip_polygon(p_points, p_plane); } +Vector Geometry3D::tetrahedralize_delaunay(const Vector &p_points) { + return ::Geometry3D::tetrahedralize_delaunay(p_points); +} + void Geometry3D::_bind_methods() { ClassDB::bind_method(D_METHOD("compute_convex_mesh_points", "planes"), &Geometry3D::compute_convex_mesh_points); ClassDB::bind_method(D_METHOD("build_box_planes", "extents"), &Geometry3D::build_box_planes); @@ -1060,6 +1064,7 @@ void Geometry3D::_bind_methods() { ClassDB::bind_method(D_METHOD("segment_intersects_convex", "from", "to", "planes"), &Geometry3D::segment_intersects_convex); ClassDB::bind_method(D_METHOD("clip_polygon", "points", "plane"), &Geometry3D::clip_polygon); + ClassDB::bind_method(D_METHOD("tetrahedralize_delaunay", "points"), &Geometry3D::tetrahedralize_delaunay); } ////// Marshalls ////// diff --git a/core/core_bind.h b/core/core_bind.h index 5f51b64eb74..40b3d16cf4b 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -336,6 +336,7 @@ public: Vector segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const TypedArray &p_planes); Vector clip_polygon(const Vector &p_points, const Plane &p_plane); + Vector tetrahedralize_delaunay(const Vector &p_points); Geometry3D() { singleton = this; } }; diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index 99c554fe05f..305a64e39cb 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -31,6 +31,7 @@ #ifndef GEOMETRY_3D_H #define GEOMETRY_3D_H +#include "core/math/delaunay_3d.h" #include "core/math/face3.h" #include "core/object/object.h" #include "core/templates/local_vector.h" @@ -532,6 +533,21 @@ public: return clipped; } + static Vector tetrahedralize_delaunay(const Vector &p_points) { + Vector tetr = Delaunay3D::tetrahedralize(p_points); + Vector tetrahedrons; + + tetrahedrons.resize(4 * tetr.size()); + int32_t *ptr = tetrahedrons.ptrw(); + for (int i = 0; i < tetr.size(); i++) { + *ptr++ = tetr[i].points[0]; + *ptr++ = tetr[i].points[1]; + *ptr++ = tetr[i].points[2]; + *ptr++ = tetr[i].points[3]; + } + return tetrahedrons; + } + // Create a "wrap" that encloses the given geometry. static Vector wrap_geometry(Vector p_array, real_t *p_error = nullptr); diff --git a/doc/classes/Geometry3D.xml b/doc/classes/Geometry3D.xml index a85d17d9250..9f876829830 100644 --- a/doc/classes/Geometry3D.xml +++ b/doc/classes/Geometry3D.xml @@ -142,5 +142,12 @@ Tests if the segment ([param from], [param to]) intersects the triangle [param a], [param b], [param c]. If yes, returns the point of intersection as [Vector3]. If no intersection takes place, returns [code]null[/code]. + + + + + Tetrahedralizes the volume specified by a discrete set of [param points] in 3D space, ensuring that no point lies within the circumsphere of any resulting tetrahedron. The method returns a [PackedInt32Array] where each tetrahedron consists of four consecutive point indices into the [param points] array (resulting in an array with [code]n * 4[/code] elements, where [code]n[/code] is the number of tetrahedra found). If the tetrahedralization is unsuccessful, an empty [PackedInt32Array] is returned. + +