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:
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);