commit 8fe72bbfa9fa55c83177df4212c4e87f074494ca
parent 37f1b96e71f0f94efafa3e23ef6f7a05234c0826
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 29 May 2017 15:38:15 +0200
Merge branch 'release-0.2'
Diffstat:
14 files changed, 308 insertions(+), 21 deletions(-)
diff --git a/README.md b/README.md
@@ -1,6 +1,6 @@
# Star-3DUtilityToolkit
-This library provides functionnalities to create 3D shapes.
+This library provides functionalities to create 3D shapes.
## How to build
@@ -13,9 +13,16 @@ package as well as all the RSys library. Then generate the project from the
`cmake/CMakeLists.txt` file by appending to the `CMAKE_PREFIX_PATH` variable
the install directories of its dependencies.
+## Release notes
+
+### Version 0.2
+
+- Add the `s3dut_create_hemisphere` function that creates a triangulated UV
+ hemisphere oriented along the positive Z axis.
+
## License
-Star-3DUtilityToolkit is Copyright (C) |Meso|Star> 2016
+Star-3DUtilityToolkit is Copyright (C) |Meso|Star> 2016-2017
(<contact@meso-star.com>). It is a free software released under the
[OSI](http://opensource.org)-approved GPL v3+ license. You are welcome to
redistribute it under certain conditions; refer to the COPYING file for
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2016 |Meso|Star> (contact@meso-star.com)
+# Copyright (C) 2016-2017 |Meso|Star> (contact@meso-star.com)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -37,13 +37,14 @@ include(rcmake_runtime)
# Define targets
################################################################################
set(VERSION_MAJOR 0)
-set(VERSION_MINOR 1)
+set(VERSION_MINOR 2)
set(VERSION_PATCH 0)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(S3DUT_FILES_SRC
s3dut_cuboid.c
s3dut_cylinder.c
+ s3dut_hemisphere.c
s3dut_mesh.c
s3dut_sphere.c)
set(S3DUT_FILES_INC s3dut_mesh.h)
@@ -82,6 +83,7 @@ if(NOT NO_TEST)
new_test(test_s3dut_cuboid)
new_test(test_s3dut_cylinder)
+ new_test(test_s3dut_hemisphere)
new_test(test_s3dut_sphere)
rcmake_copy_runtime_libraries(test_s3dut_cuboid)
diff --git a/src/s3dut.h b/src/s3dut.h
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2016-2017 (contact@meso-star.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -61,10 +61,10 @@ s3dut_mesh_get_data
(const struct s3dut_mesh* mesh,
struct s3dut_mesh_data* data);
-/* Create a triangulated UV sphere discretized in `nslices' around the Z axis
- * and `nstacks' along the Z axis. Face vertices are CCW ordered with respect
- * to the sphere center, i.e. they are CW ordered from the outside point of
- * view. */
+/* Create a triangulated UV sphere centered in 0 discretized in `nslices'
+ * around the Z axis and `nstacks' along the Z axis. Face vertices are CCW
+ * ordered with respect to the sphere center, i.e. they are CW ordered from the
+ * outside point of view. */
S3DUT_API res_T
s3dut_create_sphere
(struct mem_allocator* allocator, /* May be NULL <=> use default allocator */
@@ -74,9 +74,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. 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 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. */
S3DUT_API res_T
s3dut_create_cylinder
(struct mem_allocator* allocator, /* May be NULL <=> use default allocator */
@@ -97,5 +99,19 @@ s3dut_create_cuboid
const double depth,
struct s3dut_mesh** cuboid);
+/* Create a triangulated UV hemisphere oriented wrt Z axis. It discretized in
+ * `nslices' around the Z axis and `nstacks' along the Z axis. The back of the
+ * hemisphere is not triangulated. Face vertices are CCW ordered with respect
+ * to the hemisphere center, i.e. they are CW ordered from the outside point of
+ * view. */
+S3DUT_API res_T
+s3dut_create_hemisphere
+ (struct mem_allocator* allocator,
+ const double radius,
+ const unsigned nslices, /* # subdivisions around Z axis in [2, INF) */
+ const unsigned nstacks, /* # subdivisions along Z axis int [2, INF) */
+ struct s3dut_mesh** hemisphere);
+
+
#endif /* S3DUT_H */
diff --git a/src/s3dut_cuboid.c b/src/s3dut_cuboid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2016-2017 (contact@meso-star.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/s3dut_cylinder.c b/src/s3dut_cylinder.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2016-2017 (contact@meso-star.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/s3dut_hemisphere.c b/src/s3dut_hemisphere.c
@@ -0,0 +1,172 @@
+/* Copyright (C) |Meso|Star> 2016-2017 (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "s3dut.h"
+#include "s3dut_mesh.h"
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static res_T
+setup_hemisphere_coords
+ (struct mem_allocator* allocator,
+ double* coords,
+ const double radius,
+ const unsigned nslices, /* # subdivisions around the Z axis */
+ const unsigned nstacks) /* # subdivisions along the Z axis */
+{
+ enum { SIN, COS };
+ struct darray_double sincos_theta;
+ struct darray_double sincos_phi;
+ double step_theta;
+ double step_phi;
+ size_t itheta;
+ size_t iphi;
+ size_t i;
+ res_T res = RES_OK;
+ ASSERT(coords && radius > 0 && nslices >= 2 && nstacks >= 2);
+
+ darray_double_init(allocator, &sincos_theta);
+ darray_double_init(allocator, &sincos_phi);
+
+ res = darray_double_resize(&sincos_theta, nslices*2/*sin & cos*/);
+ if(res != RES_OK) goto error;
+ res = darray_double_resize(&sincos_phi, (nstacks-1)*2/*sin & cos*/);
+ if(res != RES_OK) goto error;
+
+ /* Precompute the sinus/cosine of the theta/phi angles */
+ step_theta = 2*PI / (double)nslices;
+ FOR_EACH(itheta, 0, nslices) {
+ const double theta = -PI + (double)itheta * step_theta;
+ darray_double_data_get(&sincos_theta)[itheta*2 + SIN] = sin(theta);
+ darray_double_data_get(&sincos_theta)[itheta*2 + COS] = cos(theta);
+ }
+ step_phi = PI/((double)nstacks * 2.0);
+ FOR_EACH(iphi, 0, nstacks-1) {
+ const double phi = (double)(iphi) * step_phi;
+ darray_double_data_get(&sincos_phi)[iphi*2 + SIN] = sin(phi);
+ darray_double_data_get(&sincos_phi)[iphi*2 + COS] = cos(phi);
+ }
+
+ /* Setup the contour vertices */
+ i = 0;
+ FOR_EACH(itheta, 0, nslices) {
+ const double* theta = darray_double_cdata_get(&sincos_theta) + itheta*2;
+ FOR_EACH(iphi, 0, nstacks-1) {
+ const double* phi = darray_double_cdata_get(&sincos_phi) + iphi*2;
+ coords[i++] = radius * COS[theta] * COS[phi];
+ coords[i++] = radius * SIN[theta] * COS[phi];
+ coords[i++] = radius * SIN[phi];
+ }
+ }
+
+ /* Setup the top polar vertex */
+ coords[i++] = 0;
+ coords[i++] = 0;
+ coords[i++] = radius;
+
+exit:
+ darray_double_release(&sincos_theta);
+ darray_double_release(&sincos_phi);
+ return res;
+error:
+ goto exit;
+}
+
+static void
+setup_hemisphere_indices
+ (size_t* ids,
+ const unsigned nslices, /* # subdivisions around the Z axis */
+ const unsigned nstacks) /* # subdivisions along the Z axis */
+{
+ size_t i, itheta, iphi;
+ ASSERT(ids && nslices && nstacks);
+
+ /* Define the indices of the contour primitives */
+ i = 0;
+ FOR_EACH(itheta, 0, nslices) {
+ const size_t itheta0 = itheta * (nstacks - 1);
+ const size_t itheta1 = ((itheta + 1) % nslices) * (nstacks - 1);
+ FOR_EACH(iphi, 0, nstacks-2) {
+ const size_t iphi0 = iphi + 0;
+ const size_t iphi1 = iphi + 1;
+
+ ids[i++] = itheta0 + iphi0;
+ ids[i++] = itheta0 + iphi1;
+ ids[i++] = itheta1 + iphi0;
+
+ ids[i++] = itheta1 + iphi0;
+ ids[i++] = itheta0 + iphi1;
+ ids[i++] = itheta1 + iphi1;
+ }
+ }
+
+ /* Define the indices of the polar primitives */
+ FOR_EACH(itheta, 0, nslices) {
+ const size_t itheta0 = itheta * (nstacks - 1);
+ const size_t itheta1 = ((itheta + 1) % nslices) * (nstacks - 1);
+
+ ids[i++] = nslices * (nstacks - 1);
+ ids[i++] = itheta1 + (nstacks - 2);
+ ids[i++] = itheta0 + (nstacks - 2);
+ }
+}
+
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+s3dut_create_hemisphere
+ (struct mem_allocator* allocator,
+ const double radius,
+ const unsigned nslices, /* # subdivisions around the Z axis */
+ const unsigned nstacks, /* # subdivisions along the Z axis */
+ struct s3dut_mesh** mesh)
+{
+ struct s3dut_mesh* hemisphere = NULL;
+ size_t nverts;
+ size_t ntris;
+ res_T res = RES_OK;
+
+ if(radius <= 0 || nslices < 2 || nstacks < 2 || !mesh) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ nverts = nslices*(nstacks-1)/* #contour verts*/ + 1/*polar vertex*/;
+ ntris = 2*nslices*(nstacks-2)/* #contour tris*/ + nslices/* #polar tris*/;
+
+ res = mesh_create(allocator, S3DUT_MESH_HEMISPHERE, nverts, ntris, &hemisphere);
+ if(res != RES_OK) goto error;
+
+ res = setup_hemisphere_coords(allocator,
+ darray_double_data_get(&hemisphere->coords), radius, nslices, nstacks);
+ if(res != RES_OK) goto error;
+
+ setup_hemisphere_indices
+ (darray_size_t_data_get(&hemisphere->ids), nslices, nstacks);
+
+exit:
+ if(mesh) *mesh = hemisphere;
+ return res;
+error:
+ if(hemisphere) {
+ S3DUT(mesh_ref_put(hemisphere));
+ hemisphere = NULL;
+ }
+ goto exit;
+}
+
diff --git a/src/s3dut_mesh.c b/src/s3dut_mesh.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2016-2017 (contact@meso-star.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/s3dut_mesh.h b/src/s3dut_mesh.h
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2016-2017 (contact@meso-star.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,6 +23,7 @@
enum s3dut_mesh_type {
S3DUT_MESH_CUBOID,
S3DUT_MESH_CYLINDER,
+ S3DUT_MESH_HEMISPHERE,
S3DUT_MESH_SPHERE
};
diff --git a/src/s3dut_sphere.c b/src/s3dut_sphere.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2016-2017 (contact@meso-star.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/test_s3dut_cuboid.c b/src/test_s3dut_cuboid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2016-2017 (contact@meso-star.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/test_s3dut_cylinder.c b/src/test_s3dut_cylinder.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2016-2017 (contact@meso-star.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/test_s3dut_hemisphere.c b/src/test_s3dut_hemisphere.c
@@ -0,0 +1,89 @@
+/* Copyright (C) |Meso|Star> 2016-2017 (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "s3dut.h"
+#include "test_s3dut_utils.h"
+
+#include <rsys/double3.h>
+#include <rsys/math.h>
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct s3dut_mesh* msh;
+ struct s3dut_mesh_data data;
+ size_t i;
+ (void)argc, (void)argv;
+
+ CHECK(mem_init_proxy_allocator(&allocator, &mem_default_allocator), RES_OK);
+
+ CHECK(s3dut_create_hemisphere(NULL, 0, 0, 0, NULL), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 1, 0, 0, NULL), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 0, 2, 0, NULL), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 1, 2, 0, NULL), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 0, 0, 2, NULL), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 1, 0, 2, NULL), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 0, 2, 2, NULL), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 1, 2, 2, NULL), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 0, 0, 0, &msh), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 1, 0, 0, &msh), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 0, 2, 0, &msh), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 1, 2, 0, &msh), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 0, 0, 2, &msh), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 1, 0, 2, &msh), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 0, 2, 2, &msh), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(NULL, 1, 2, 2, &msh), RES_OK);
+
+ CHECK(s3dut_mesh_ref_get(NULL), RES_BAD_ARG);
+ CHECK(s3dut_mesh_ref_get(msh), RES_OK);
+ CHECK(s3dut_mesh_ref_put(NULL), RES_BAD_ARG);
+ CHECK(s3dut_mesh_ref_put(msh), RES_OK);
+ CHECK(s3dut_mesh_ref_put(msh), RES_OK);
+
+ CHECK(s3dut_create_hemisphere(&allocator, 1, 2, 2, &msh), RES_OK);
+ CHECK(s3dut_mesh_ref_put(msh), RES_OK);
+
+ CHECK(s3dut_create_hemisphere(&allocator, 1, 1, 2, &msh), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(&allocator, 1, 2, 1, &msh), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(&allocator,-1, 2, 2, &msh), RES_BAD_ARG);
+ CHECK(s3dut_create_hemisphere(&allocator, 1, 32, 16, &msh), RES_OK);
+
+ CHECK(s3dut_mesh_get_data(NULL, NULL), RES_BAD_ARG);
+ CHECK(s3dut_mesh_get_data(msh, NULL), RES_BAD_ARG);
+ CHECK(s3dut_mesh_get_data(NULL, &data), RES_BAD_ARG);
+ CHECK(s3dut_mesh_get_data(msh, &data), RES_OK);
+ NCHECK(data.positions, NULL);
+ NCHECK(data.indices, NULL);
+ CHECK(data.nvertices >= (32*(16-1)+1), 1);
+ CHECK(data.nprimitives, (32*(16-2)*2) + 32);
+
+ FOR_EACH(i, 0, data.nvertices) {
+ double v[3];
+ d3_set(v, data.positions + i*3);
+ v[2] = sqrt(MMAX(0, 1 - v[0]*v[0] - v[1]*v[1]));
+ CHECK(d3_eq_eps(v, data.positions + i*3, 1.e-6), 1);
+ }
+
+ dump_mesh_data(stdout, &data);
+
+ CHECK(s3dut_mesh_ref_put(msh), RES_OK);
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHECK(mem_allocated_size(), 0);
+ return 0;
+}
+
diff --git a/src/test_s3dut_sphere.c b/src/test_s3dut_sphere.c
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2016-2017 (contact@meso-star.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/src/test_s3dut_utils.h b/src/test_s3dut_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com)
+/* Copyright (C) |Meso|Star> 2016-2017 (contact@meso-star.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by