Skip to content

Commit

Permalink
Add C bindings for Triangulate() (#1034)
Browse files Browse the repository at this point in the history
* Adds C bindings for Triangulate()

* Triangulate() returns a std::vector<ivec3>, which I tried to respect.
  Since ivec3 is 3 int's, I have
  manifold_triangulation_tri_verts(void *mem, ...)
  copy assuming mem has space for 3 * num_tri int's

* NOTE: manifoldc.cpp now includes "manifold/polygon.h"

* NOTE: I couldn't figure out manifold_destruct_triangulation(...)
  Also, I don't understand the use case(s) of the destruct functions
  (literally don't understand; I am sure they exist)

* Usage code:

  ```
  ManifoldTriangulation *triangulation = manifold_triangulate(manifold_alloc_triangulation(), polygons, epsilon);
  size_t num_tri = manifold_triangulation_num_tri(triangulation);
  int *tri_verts = (int *) manifold_triangulation_tri_verts(malloc(num_tri * 3 * sizeof(int)), triangulation);
  manifold_delete_triangulation(triangulation);
  ```

* fixing formatting

* fix destruct

* add triangulation CBIND test

---------

Co-authored-by: pca006132 <[email protected]>
  • Loading branch information
james-bern and pca006132 authored Nov 16, 2024
1 parent e7e0780 commit ee32b30
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 0 deletions.
8 changes: 8 additions & 0 deletions bindings/c/conv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ ManifoldVec3 to_c(vec3 v) { return {v.x, v.y, v.z}; }

ManifoldIVec3 to_c(ivec3 v) { return {v.x, v.y, v.z}; }

ManifoldTriangulation *to_c(std::vector<ivec3> *m) {
return reinterpret_cast<ManifoldTriangulation *>(m);
}

const manifold::Manifold *from_c(ManifoldManifold *m) {
return reinterpret_cast<manifold::Manifold const *>(m);
}
Expand Down Expand Up @@ -220,6 +224,10 @@ ivec3 from_c(ManifoldIVec3 v) { return ivec3(v.x, v.y, v.z); }

vec4 from_c(ManifoldVec4 v) { return vec4(v.x, v.y, v.z, v.w); }

const std::vector<ivec3> *from_c(ManifoldTriangulation *m) {
return reinterpret_cast<std::vector<ivec3> const *>(m);
}

std::vector<vec3> vector_of_vec_array(ManifoldVec3 *vs, size_t length) {
auto vec = std::vector<vec3>();
for (size_t i = 0; i < length; ++i) {
Expand Down
2 changes: 2 additions & 0 deletions bindings/c/conv.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ ManifoldError to_c(manifold::Manifold::Error error);
ManifoldVec2 to_c(vec2 v);
ManifoldVec3 to_c(vec3 v);
ManifoldIVec3 to_c(ivec3 v);
ManifoldTriangulation *to_c(std::vector<ivec3> *m);

const manifold::Manifold *from_c(ManifoldManifold *m);
ManifoldVec *from_c(ManifoldManifoldVec *ms);
Expand All @@ -57,6 +58,7 @@ vec2 from_c(ManifoldVec2 v);
vec3 from_c(ManifoldVec3 v);
ivec3 from_c(ManifoldIVec3 v);
vec4 from_c(ManifoldVec4 v);
const std::vector<ivec3> *from_c(ManifoldTriangulation *m);

std::vector<vec3> vector_of_vec_array(ManifoldVec3 *vs, size_t length);
std::vector<ivec3> vector_of_vec_array(ManifoldIVec3 *vs, size_t length);
Expand Down
11 changes: 11 additions & 0 deletions bindings/c/include/manifold/manifoldc.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,13 @@ double *manifold_meshgl64_run_transform(void *mem, ManifoldMeshGL64 *m);
uint64_t *manifold_meshgl64_face_id(void *mem, ManifoldMeshGL64 *m);
double *manifold_meshgl64_halfedge_tangent(void *mem, ManifoldMeshGL64 *m);

// Triangulation

ManifoldTriangulation *manifold_triangulate(void *mem, ManifoldPolygons *ps,
double epsilon);
size_t manifold_triangulation_num_tri(ManifoldTriangulation *m);
int *manifold_triangulation_tri_verts(void *mem, ManifoldTriangulation *m);

// memory size

size_t manifold_manifold_size();
Expand All @@ -430,6 +437,7 @@ size_t manifold_meshgl64_size();
size_t manifold_box_size();
size_t manifold_rect_size();
size_t manifold_curvature_size();
size_t manifold_triangulation_size();

// allocation

Expand All @@ -443,6 +451,7 @@ ManifoldMeshGL *manifold_alloc_meshgl();
ManifoldMeshGL64 *manifold_alloc_meshgl64();
ManifoldBox *manifold_alloc_box();
ManifoldRect *manifold_alloc_rect();
ManifoldTriangulation *manifold_alloc_triangulation();

// destruction

Expand All @@ -456,6 +465,7 @@ void manifold_destruct_meshgl(ManifoldMeshGL *m);
void manifold_destruct_meshgl64(ManifoldMeshGL64 *m);
void manifold_destruct_box(ManifoldBox *b);
void manifold_destruct_rect(ManifoldRect *b);
void manifold_destruct_triangulation(ManifoldTriangulation *M);

// pointer free + destruction

Expand All @@ -469,6 +479,7 @@ void manifold_delete_meshgl(ManifoldMeshGL *m);
void manifold_delete_meshgl64(ManifoldMeshGL64 *m);
void manifold_delete_box(ManifoldBox *b);
void manifold_delete_rect(ManifoldRect *b);
void manifold_delete_triangulation(ManifoldTriangulation *m);

// MeshIO / Export

Expand Down
1 change: 1 addition & 0 deletions bindings/c/include/manifold/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ typedef struct ManifoldMeshGL ManifoldMeshGL;
typedef struct ManifoldMeshGL64 ManifoldMeshGL64;
typedef struct ManifoldBox ManifoldBox;
typedef struct ManifoldRect ManifoldRect;
typedef struct ManifoldTriangulation ManifoldTriangulation;

#ifdef MANIFOLD_EXPORT
typedef struct ManifoldMaterial ManifoldMaterial;
Expand Down
25 changes: 25 additions & 0 deletions bindings/c/manifoldc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "manifold/common.h"
#include "manifold/cross_section.h"
#include "manifold/manifold.h"
#include "manifold/polygon.h"
#include "manifold/types.h"

using namespace manifold;
Expand Down Expand Up @@ -703,6 +704,20 @@ int manifold_get_circular_segments(double radius) {

void manifold_reset_to_circular_defaults() { Quality::ResetToDefaults(); }

ManifoldTriangulation *manifold_triangulate(void *mem, ManifoldPolygons *ps,
double epsilon) {
auto triangulation = manifold::Triangulate(*from_c(ps), epsilon);
return to_c(new (mem) std::vector<ivec3>(triangulation));
}

size_t manifold_triangulation_num_tri(ManifoldTriangulation *m) {
return from_c(m)->size();
}

int *manifold_triangulation_tri_verts(void *mem, ManifoldTriangulation *m) {
return reinterpret_cast<int *>(copy_data<ivec3>(mem, *from_c(m)));
}

// memory size
size_t manifold_cross_section_size() { return sizeof(CrossSection); }
size_t manifold_cross_section_vec_size() {
Expand All @@ -717,6 +732,7 @@ size_t manifold_meshgl_size() { return sizeof(MeshGL); }
size_t manifold_meshgl64_size() { return sizeof(MeshGL64); }
size_t manifold_box_size() { return sizeof(Box); }
size_t manifold_rect_size() { return sizeof(Rect); }
size_t manifold_triangulation_size() { return sizeof(std::vector<ivec3>); }

// allocation
ManifoldManifold *manifold_alloc_manifold() {
Expand All @@ -741,6 +757,9 @@ ManifoldMeshGL *manifold_alloc_meshgl() { return to_c(new MeshGL); }
ManifoldMeshGL64 *manifold_alloc_meshgl64() { return to_c(new MeshGL64); }
ManifoldBox *manifold_alloc_box() { return to_c(new Box); }
ManifoldRect *manifold_alloc_rect() { return to_c(new Rect); }
ManifoldTriangulation *manifold_alloc_triangulation() {
return to_c(new std::vector<ivec3>);
}

// pointer free + destruction
void manifold_delete_cross_section(ManifoldCrossSection *c) {
Expand All @@ -761,6 +780,9 @@ void manifold_delete_meshgl(ManifoldMeshGL *m) { delete from_c(m); }
void manifold_delete_meshgl64(ManifoldMeshGL64 *m) { delete from_c(m); }
void manifold_delete_box(ManifoldBox *b) { delete from_c(b); }
void manifold_delete_rect(ManifoldRect *r) { delete from_c(r); }
void manifold_delete_triangulation(ManifoldTriangulation *m) {
delete from_c(m);
}

// destruction
void manifold_destruct_cross_section(ManifoldCrossSection *cs) {
Expand All @@ -781,6 +803,9 @@ void manifold_destruct_meshgl(ManifoldMeshGL *m) { from_c(m)->~MeshGL(); }
void manifold_destruct_meshgl64(ManifoldMeshGL64 *m) { from_c(m)->~MeshGL64(); }
void manifold_destruct_box(ManifoldBox *b) { from_c(b)->~Box(); }
void manifold_destruct_rect(ManifoldRect *r) { from_c(r)->~Rect(); }
void manifold_destruct_triangulation(ManifoldTriangulation *m) {
from_c(m)->~vector<ivec3>();
}

#ifdef __cplusplus
}
Expand Down
24 changes: 24 additions & 0 deletions test/manifoldc_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,3 +383,27 @@ TEST(CBIND, polygons) {
free(sp);
free(ps);
}

TEST(CBIND, triangulation) {
ManifoldVec2 vs[] = {{0, 0}, {1, 1}, {1, 2}};
ManifoldSimplePolygon *sp =
manifold_simple_polygon(manifold_alloc_simple_polygon(), vs, 3);
ManifoldSimplePolygon *sps[] = {sp};
ManifoldPolygons *ps = manifold_polygons(manifold_alloc_polygons(), sps, 1);
ManifoldTriangulation *triangulation =
manifold_triangulate(manifold_alloc_triangulation(), ps, 1e-6);

manifold_delete_simple_polygon(sp);
manifold_delete_polygons(ps);

size_t num_tri = manifold_triangulation_num_tri(triangulation);
int *tri_verts = (int *)manifold_triangulation_tri_verts(
malloc(num_tri * 3 * sizeof(int)), triangulation);

EXPECT_EQ(num_tri, 1);
EXPECT_EQ(tri_verts[0], 0);
EXPECT_EQ(tri_verts[1], 1);
EXPECT_EQ(tri_verts[2], 2);
manifold_delete_triangulation(triangulation);
free(tri_verts);
}

0 comments on commit ee32b30

Please sign in to comment.