star-3dut

Generate meshes of simple geometric shapes
git clone git://git.meso-star.fr/star-3dut.git
Log | Files | Refs | README | LICENSE

commit 896ed1f6c4f437c753922cc3f40cdfa7325152c1
parent 8fe72bbfa9fa55c83177df4212c4e87f074494ca
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Thu,  5 Oct 2017 11:35:52 +0200

Change the s3dut_create_cylinder function signature.

Add a new param to specify if bottom and/or top end has to be closed.

Diffstat:
Msrc/s3dut.h | 16+++++++++++-----
Msrc/s3dut_cylinder.c | 64+++++++++++++++++++++++++++++++++++++++++-----------------------
Msrc/test_s3dut_cylinder.c | 79++++++++++++++++++++++++++++++++++++++++---------------------------------------
3 files changed, 92 insertions(+), 67 deletions(-)

diff --git a/src/s3dut.h b/src/s3dut.h @@ -45,6 +45,11 @@ struct s3dut_mesh_data { size_t nprimitives; /* # primitives */ }; +enum s3dut_ends { + S3DUT_END_BOTTOM = 1, + S3DUT_END_TOP = 2 +}; + /******************************************************************************* * Stard-3DUT API ******************************************************************************/ @@ -74,11 +79,11 @@ s3dut_create_sphere struct s3dut_mesh** sphere); /* Create a triangulated cylinder centered in 0 discretized in `nslices' around - * the Z axis and `nstacks' along the Z axis. The top and the bottom of the - * cylinder is closed with a triangle fan whose center is on the Z axis. Face - * vertices are CCW ordered with respect to the cylinder center, i.e. they are - * CW ordered from the outside - * point of view. */ + * the Z axis and `nstacks' along the Z axis. The top and the bottom ends of + * the cylinder can be closed with a triangle fan whose center is on the Z axis + * or not, according to the `close_ends' argument bit mask. Facevertices are + * CCW ordered with respect to the cylinder center, i.e. they are CW ordered + * from the outside point of view. */ S3DUT_API res_T s3dut_create_cylinder (struct mem_allocator* allocator, /* May be NULL <=> use default allocator */ @@ -86,6 +91,7 @@ s3dut_create_cylinder const double height, /* In ]0, INF) */ const unsigned nslices, /* # subdivisions around Z axis in [3, INF) */ const unsigned nstacks, /* # subdivision along Z axis in [1, INF) */ + const unsigned close_ends, /* Close ends of the cylinder? */ struct s3dut_mesh** cylinder); /* Create a triangulated cuboid centered in 0. Face vertices are CCW ordered diff --git a/src/s3dut_cylinder.c b/src/s3dut_cylinder.c @@ -25,7 +25,9 @@ setup_cylinder_coords const double radius, const double height, const unsigned nslices, - const unsigned nstacks) + const unsigned nstacks, + const int close_bottom, + const int close_top) { double step_theta; double step_z; @@ -51,21 +53,27 @@ setup_cylinder_coords } /* Bottom polar vertex */ - coords[i++] = 0; - coords[i++] = 0; - coords[i++] = -height * 0.5; + if(close_bottom) { + coords[i++] = 0; + coords[i++] = 0; + coords[i++] = -height * 0.5; + } /* Top polar vertex */ - coords[i++] = 0; - coords[i++] = 0; - coords[i++] = height * 0.5; + if(close_top) { + coords[i++] = 0; + coords[i++] = 0; + coords[i++] = height * 0.5; + } } static void setup_cylinder_indices (size_t* ids, const unsigned nslices, - const unsigned nstacks) + const unsigned nstacks, + const int close_bottom, + const int close_top) { size_t islice; size_t istack; @@ -91,18 +99,22 @@ setup_cylinder_indices } } - ibottom = nslices * (nstacks+1); - FOR_EACH(islice, 0, nslices) { - ids[i++] = ibottom; - ids[i++] = islice * (nstacks+1); - ids[i++] = ((islice+1)%nslices) * (nstacks+1); + if(close_bottom) { + ibottom = nslices * (nstacks+1); + FOR_EACH(islice, 0, nslices) { + ids[i++] = ibottom; + ids[i++] = islice * (nstacks+1); + ids[i++] = ((islice+1)%nslices) * (nstacks+1); + } } - itop = ibottom + 1; - FOR_EACH(islice, 0, nslices) { - ids[i++] = itop; - ids[i++] = ((islice+1)%nslices) * (nstacks+1) + nstacks; - ids[i++] = islice * (nstacks+1) + nstacks; + if(close_top) { + itop = (close_bottom) ? nslices * (nstacks+1) + 1 : nslices * (nstacks+1); + FOR_EACH(islice, 0, nslices) { + ids[i++] = itop; + ids[i++] = ((islice+1)%nslices) * (nstacks+1) + nstacks; + ids[i++] = islice * (nstacks+1) + nstacks; + } } } @@ -116,6 +128,7 @@ s3dut_create_cylinder const double height, const unsigned nslices, const unsigned nstacks, + const unsigned close_ends, struct s3dut_mesh** mesh) { struct s3dut_mesh* cylinder = NULL; @@ -123,6 +136,9 @@ s3dut_create_cylinder size_t* ids = NULL; size_t nverts; size_t ntris; + const int close_bottom = close_ends & S3DUT_END_BOTTOM; + const int close_top = close_ends & S3DUT_END_TOP; + const int nb_closed_ends = (close_bottom ? 1 : 0) + (close_top ? 1 : 0); res_T res = RES_OK; if(radius <= 0 || height <= 0 || nslices < 3 || nstacks < 1 || !mesh) { @@ -130,16 +146,19 @@ s3dut_create_cylinder goto error; } - nverts = nslices * (nstacks+1) /*#contour vers*/ + 2/*#polar verts*/; - ntris = 2*nslices*nstacks /*#contour tris*/ + 2*nslices/* #cao tris*/; + nverts = nslices * (nstacks+1) /*#contour verts*/ + + nb_closed_ends; /*#polar verts*/ + ntris = 2*nslices*nstacks /*#contour tris*/ + + nb_closed_ends * nslices; /*#trg fans tris*/ res = mesh_create(allocator, S3DUT_MESH_CYLINDER, nverts, ntris, &cylinder); if(res != RES_OK) goto error; coords = darray_double_data_get(&cylinder->coords); ids = darray_size_t_data_get(&cylinder->ids); - setup_cylinder_coords(coords, radius, height, nslices, nstacks); - setup_cylinder_indices(ids, nslices, nstacks); + setup_cylinder_coords + (coords, radius, height, nslices, nstacks, close_bottom, close_top); + setup_cylinder_indices(ids, nslices, nstacks, close_bottom, close_top); exit: if(mesh) *mesh = cylinder; @@ -151,4 +170,3 @@ error: } goto exit; } - diff --git a/src/test_s3dut_cylinder.c b/src/test_s3dut_cylinder.c @@ -25,50 +25,51 @@ main(int argc, char** argv) (void)argc, (void)argv; CHECK(mem_init_proxy_allocator(&allocator, &mem_default_allocator), RES_OK); - - CHECK(s3dut_create_cylinder(NULL, 0, 0, 0, 0, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 0, 0, 0, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 1, 0, 0, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 1, 0, 0, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 0, 3, 0, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 0, 3, 0, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 1, 3, 0, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 1, 3, 0, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 0, 0, 1, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 0, 0, 1, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 1, 0, 1, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 1, 0, 1, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 0, 3, 1, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 0, 3, 1, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 1, 3, 1, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 1, 3, 1, NULL), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 0, 0, 0, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 0, 0, 0, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 1, 0, 0, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 1, 0, 0, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 0, 3, 0, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 0, 3, 0, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 1, 3, 0, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 1, 3, 0, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 0, 0, 1, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 0, 0, 1, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 1, 0, 1, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 1, 0, 1, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 0, 3, 1, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 0, 3, 1, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 0, 1, 3, 1, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(NULL, 1, 1, 3, 1, &msh), RES_OK); + #define CR_CYL s3dut_create_cylinder + CHECK(CR_CYL(NULL, 0, 0, 0, 0, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 0, 0, 0, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 1, 0, 0, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 1, 0, 0, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 0, 3, 0, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 0, 3, 0, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 1, 3, 0, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 1, 3, 0, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 0, 0, 1, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 0, 0, 1, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 1, 0, 1, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 1, 0, 1, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 0, 3, 1, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 0, 3, 1, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 1, 3, 1, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 1, 3, 1, 0, NULL), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 0, 0, 0, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 0, 0, 0, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 1, 0, 0, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 1, 0, 0, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 0, 3, 0, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 0, 3, 0, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 1, 3, 0, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 1, 3, 0, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 0, 0, 1, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 0, 0, 1, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 1, 0, 1, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 1, 0, 1, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 0, 3, 1, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 0, 3, 1, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 0, 1, 3, 1, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(NULL, 1, 1, 3, 1, 0, &msh), RES_OK); CHECK(s3dut_mesh_ref_put(msh), RES_OK); - CHECK(s3dut_create_cylinder(&allocator, 1, 1, 3, 1, &msh), RES_OK); + CHECK(CR_CYL(&allocator, 1, 1, 3, 1, 0, &msh), RES_OK); CHECK(s3dut_mesh_ref_put(msh), RES_OK); - CHECK(s3dut_create_cylinder(&allocator,-1, 1, 3, 1, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(&allocator, 1,-1, 3, 1, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(&allocator, 1, 1, 2, 1, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(&allocator, 1, 1, 3, 0, &msh), RES_BAD_ARG); - CHECK(s3dut_create_cylinder(&allocator, 1, 2, 16, 4, &msh), RES_OK); + CHECK(CR_CYL(&allocator,-1, 1, 3, 1, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(&allocator, 1,-1, 3, 1, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(&allocator, 1, 1, 2, 1, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(&allocator, 1, 1, 3, 0, 0, &msh), RES_BAD_ARG); + CHECK(CR_CYL(&allocator, 1, 2, 16, 4, S3DUT_END_BOTTOM, &msh), RES_OK); + #undef CR_CYL CHECK(s3dut_mesh_get_data(msh, &data), RES_OK); dump_mesh_data(stdout, &data);