star-cpr

Clip 2D meshes with 2D polygons
git clone git://git.meso-star.fr/star-cpr.git
Log | Files | Refs | README | LICENSE

commit af9932bc8558765f879ee1419a9cd76aaa7abf4e
parent 52cf42776c31ac70e3ea9c6ed84d94607dda7a5a
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Thu, 27 Oct 2022 10:30:35 +0200

Change copy API to include polygon creation

Diffstat:
Msrc/scpr.h | 11++++++-----
Msrc/scpr_c.h | 2++
Msrc/scpr_mesh.c | 48++++++++++++++++++------------------------------
Msrc/scpr_polygon.c | 26+++++++++++++++++---------
Msrc/test_scpr_polygon.c | 9+++++----
5 files changed, 48 insertions(+), 48 deletions(-)

diff --git a/src/scpr.h b/src/scpr.h @@ -68,6 +68,12 @@ scpr_polygon_create struct scpr_polygon** polygon); SCPR_API res_T +scpr_polygon_create_copy + (struct mem_allocator* allocator, /* May be NULL <=> Use default allocator */ + const struct scpr_polygon* src_polygon, + struct scpr_polygon** polygon); + +SCPR_API res_T scpr_polygon_ref_get (struct scpr_polygon* polygon); @@ -85,11 +91,6 @@ scpr_polygon_setup_indexed_vertices void* data); /* Client data set as the last param of the callbacks */ SCPR_API res_T -scpr_polygon_copy - (const struct scpr_polygon* polygon, - struct scpr_polygon* copy); - -SCPR_API res_T scpr_offset_polygon (struct scpr_polygon* polygon, const double offset, /* Can be either positive or negative */ diff --git a/src/scpr_c.h b/src/scpr_c.h @@ -28,6 +28,8 @@ #undef PI #include <clipper2/clipper.h> +#define ERR(Expr) { if((res = (Expr)) != RES_OK) goto error; } (void)0 + struct mem_allocator; struct vertex { double pos[2]; }; diff --git a/src/scpr_mesh.c b/src/scpr_mesh.c @@ -100,17 +100,14 @@ register_vertex } else { const size_t ivert = darray_double_size_get(coords); - res = darray_double_resize(coords, ivert+2/*#coords*/); - if(res != RES_OK) goto error; + ERR(darray_double_resize(coords, ivert+2/*#coords*/)); d2_set(darray_double_data_get(coords)+ivert, pos); id = ivert / 2; - res = htable_vertex_set(vertices, &v, &id); - if(res != RES_OK) goto error; + ERR(htable_vertex_set(vertices, &v, &id)); } - res = darray_size_t_push_back(indices, &id); - if(res != RES_OK) goto error; + ERR(darray_size_t_push_back(indices, &id)); exit: return res; @@ -129,10 +126,12 @@ register_triangle res_T res = RES_OK; ASSERT(tri && coords && indices && vertices); FOR_EACH(ivert, 0, 3) { - res = register_vertex(tri[ivert], coords, indices, vertices); - if(res != RES_OK) return res; + ERR(register_vertex(tri[ivert], coords, indices, vertices)); } +exit: return RES_OK; +error: + goto exit; } @@ -155,8 +154,7 @@ register_paths double pos[2]; pos[0] = paths[ipath][ivert].x; pos[1] = paths[ipath][ivert].y; - res = register_vertex(pos, coords, indices, vertices); - if(res != RES_OK) goto error; + ERR(register_vertex(pos, coords, indices, vertices)); } } else { /* Triangulate the clipped primitive */ @@ -173,11 +171,9 @@ register_paths pos[1] = paths[ipath][ivert].y; fpos[0] = (float)pos[0], fpos[1] = (float)pos[1]; - res = polygon_vertex_add(polygon, fpos); - if(res != RES_OK) goto error; + ERR(polygon_vertex_add(polygon, fpos)); } - res = polygon_triangulate(polygon, &ids, &nids); - if(res != RES_OK) goto error; + ERR(polygon_triangulate(polygon, &ids, &nids)); FOR_EACH(ivert, 0, nids) { float fpos[3]; @@ -185,8 +181,7 @@ register_paths POLYGON(vertex_get(polygon, ids[ivert], fpos)); pos[0] = (float)fpos[0]; pos[1] = (float)fpos[1]; - res = register_vertex(pos, coords, indices, vertices); - if(res != RES_OK) goto error; + ERR(register_vertex(pos, coords, indices, vertices)); } } } @@ -302,10 +297,8 @@ scpr_mesh_setup_indexed_vertices goto error; } - res = darray_double_resize(&mesh->coords, nverts*2/*#coords per vertex*/); - if(res != RES_OK) goto error; - res = darray_size_t_resize(&mesh->indices, ntris*3/*#vertices per triangle*/); - if(res != RES_OK) goto error; + ERR(darray_double_resize(&mesh->coords, nverts*2/*#coords per vertex*/)); + ERR(darray_size_t_resize(&mesh->indices, ntris*3/*#vertices per triangle*/)); /* Fetch mesh positions */ pos = darray_double_data_get(&mesh->coords); @@ -421,8 +414,7 @@ scpr_mesh_clip d2_max(upper, upper, poly_desc->upper); /* Create the polygon structure used to triangulate the clipped polygons */ - res = polygon_create(mesh->allocator, &polygon); - if(res != RES_OK) goto error; + ERR(polygon_create(mesh->allocator, &polygon)); /* Clip the triangles of the mesh */ SCPR(mesh_get_triangles_count(mesh, &ntris)); @@ -440,8 +432,7 @@ scpr_mesh_clip /* Do not clip triangles that do not intersect the clip AABB */ if(!aabb_intersect(lower, upper, poly_desc->lower, poly_desc->upper)) { if(op != SCPR_AND) { - res = register_triangle(tri, &coords, &indices, &vertices); - if(res != RES_OK) goto error; + ERR(register_triangle(tri, &coords, &indices, &vertices)); } continue; } @@ -464,14 +455,11 @@ scpr_mesh_clip clipper.Execute(clip_type, Clipper2Lib::FillRule::EvenOdd, output); /* Register the resulting clipped polygons */ - res = register_paths (output, &coords, &indices, &vertices, polygon); - if(res != RES_OK) goto error; + ERR(register_paths (output, &coords, &indices, &vertices, polygon)); } - res = darray_double_copy_and_clear(&mesh->coords, &coords); - if(res != RES_OK) FATAL("Unexpected error.\n"); - res = darray_size_t_copy_and_clear(&mesh->indices, &indices); - if(res != RES_OK) FATAL("Unexpected error.\n"); + ERR(darray_double_copy_and_clear(&mesh->coords, &coords)); + ERR(darray_size_t_copy_and_clear(&mesh->indices, &indices)); exit: if(polygon) POLYGON(ref_put(polygon)); diff --git a/src/scpr_polygon.c b/src/scpr_polygon.c @@ -17,6 +17,7 @@ #include "scpr_c.h" #include <new> +#include <polygon.h> #include <rsys/mem_allocator.h> #include <rsys/rsys.h> @@ -229,24 +230,32 @@ error: } res_T -scpr_polygon_copy - (const struct scpr_polygon* polygon, - struct scpr_polygon* copy) +scpr_polygon_create_copy + (struct mem_allocator* allocator, + const struct scpr_polygon* src_polygon, + struct scpr_polygon** out_polygon) { + struct scpr_polygon* copy; + int copy_created = 0; res_T res = RES_OK; - if(!polygon || !copy) { + if(!src_polygon || !out_polygon) { res = RES_BAD_ARG; goto error; } + ERR(scpr_polygon_create(allocator, &copy)); + copy_created = 1; - copy->paths = polygon->paths; - d2_set(copy->lower, polygon->lower); - d2_set(copy->upper, polygon->upper); + copy->paths = src_polygon->paths; + d2_set(copy->lower, src_polygon->lower); + d2_set(copy->upper, src_polygon->upper); exit: + if(out_polygon) *out_polygon = copy; return res; error: + if(copy_created) CHK(RES_OK == scpr_polygon_ref_put(copy)); + copy = NULL; goto exit; } #undef TRY @@ -335,8 +344,7 @@ scpr_offset_polygon FOR_EACH(i, 0, nverts) { double pos[2]; - res = scpr_polygon_get_position(poly_desc, c, i, pos); - if(res != RES_OK) goto error; + ERR(scpr_polygon_get_position(poly_desc, c, i, pos)); d2_min(poly_desc->lower, poly_desc->lower, pos); d2_max(poly_desc->upper, poly_desc->upper, pos); } diff --git a/src/test_scpr_polygon.c b/src/test_scpr_polygon.c @@ -55,6 +55,7 @@ main(int argc, char** argv) CHK(scpr_polygon_create(&allocator, NULL) == RES_BAD_ARG); CHK(scpr_polygon_create(NULL, &polygon) == RES_OK); CHK(scpr_polygon_create(NULL, &copy) == RES_OK); + CHK(scpr_polygon_ref_put(copy) == RES_OK); CHK(scpr_polygon_ref_get(NULL) == RES_BAD_ARG); CHK(scpr_polygon_ref_get(polygon) == RES_OK); @@ -131,10 +132,10 @@ main(int argc, char** argv) } } - CHK(scpr_polygon_copy(NULL, NULL) == RES_BAD_ARG); - CHK(scpr_polygon_copy(NULL, copy) == RES_BAD_ARG); - CHK(scpr_polygon_copy(polygon, NULL) == RES_BAD_ARG); - CHK(scpr_polygon_copy(polygon, copy) == RES_OK); + CHK(scpr_polygon_create_copy(NULL, NULL, NULL) == RES_BAD_ARG); + CHK(scpr_polygon_create_copy(NULL, NULL, &copy) == RES_BAD_ARG); + CHK(scpr_polygon_create_copy(NULL, polygon, NULL) == RES_BAD_ARG); + CHK(scpr_polygon_create_copy(NULL, polygon, &copy) == RES_OK); CHK(scpr_polygon_eq(polygon, copy, &eq) == RES_OK); CHK(eq);