commit 32067cb4e179d012983e6d0db49b81a44dfa43c7
parent f94df49a4928f28bc6ec4c765c720023d9149f24
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 4 Nov 2015 18:27:02 +0100
Add spherical mesh setup in polar coordinates
Diffstat:
2 files changed, 118 insertions(+), 75 deletions(-)
diff --git a/src/schiff_mesh.c b/src/schiff_mesh.c
@@ -27,6 +27,8 @@
* knowledge of the CeCILL license and that you accept its terms. */
#include "schiff_mesh.h"
+
+#include <rsys/float2.h>
#include <rsys/float3.h>
struct sin_cos { double sinus, cosine; };
@@ -36,6 +38,54 @@ struct sin_cos { double sinus, cosine; };
#include <rsys/dynamic_array.h>
/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+/* Assume that the vertices are arranged in "phi major" order and that the
+ * lower and upper polar vertices are the two last ones. */
+static void
+setup_sphere_indices
+ (struct darray_uint* indices,
+ const unsigned nthetas,
+ const unsigned nphis)
+{
+ unsigned i, itheta, iphi;
+ ASSERT(indices && nthetas && nphis);
+
+ /* Define the indices of the contour primitives */
+ i = 0;
+ FOR_EACH(itheta, 0, nthetas) {
+ const unsigned itheta0 = itheta * (nphis - 1);
+ const unsigned itheta1 = ((itheta + 1) % nthetas) * (nphis - 1);
+ FOR_EACH(iphi, 0, nphis-2) {
+ const unsigned iphi0 = iphi + 0;
+ const unsigned iphi1 = iphi + 1;
+
+ darray_uint_data_get(indices)[i++] = itheta0 + iphi0;
+ darray_uint_data_get(indices)[i++] = itheta0 + iphi1;
+ darray_uint_data_get(indices)[i++] = itheta1 + iphi0;
+
+ darray_uint_data_get(indices)[i++] = itheta1 + iphi0;
+ darray_uint_data_get(indices)[i++] = itheta0 + iphi1;
+ darray_uint_data_get(indices)[i++] = itheta1 + iphi1;
+ }
+ }
+
+ /* Define the indices of the polar primitives */
+ FOR_EACH(itheta, 0, nthetas) {
+ const unsigned itheta0 = itheta * (nphis - 1);
+ const unsigned itheta1 = ((itheta + 1) % nthetas) * (nphis - 1);
+
+ darray_uint_data_get(indices)[i++] = nthetas * (nphis - 1);
+ darray_uint_data_get(indices)[i++] = itheta0;
+ darray_uint_data_get(indices)[i++] = itheta1;
+
+ darray_uint_data_get(indices)[i++] = nthetas * (nphis - 1) + 1;
+ darray_uint_data_get(indices)[i++] = itheta1 + (nphis - 2);
+ darray_uint_data_get(indices)[i++] = itheta0 + (nphis - 2);
+ }
+}
+
+/*******************************************************************************
* Local functions
******************************************************************************/
res_T
@@ -57,6 +107,7 @@ schiff_mesh_init_sphere
res_T res = RES_OK;
ASSERT(allocator && sphere && nthetas);
+ sphere->coordinates = SCHIFF_CARTESIAN;
darray_float_init(allocator, &sphere->vertices);
darray_uint_init(allocator, &sphere->indices);
darray_sincos_init(allocator, &sincos_thetas);
@@ -101,42 +152,65 @@ schiff_mesh_init_sphere
f3(darray_float_data_get(&sphere->vertices) + i + 0, 0.f, 0.f,-1.f);
f3(darray_float_data_get(&sphere->vertices) + i + 3, 0.f, 0.f, 1.f);
- /* Define the indices of the contour primitives */
- i = 0;
- FOR_EACH(itheta, 0, nthetas) {
- const unsigned itheta0 = itheta * (nphis - 1);
- const unsigned itheta1 = ((itheta + 1) % nthetas) * (nphis - 1);
- FOR_EACH(iphi, 0, nphis-2) {
- const unsigned iphi0 = iphi + 0;
- const unsigned iphi1 = iphi + 1;
+ /* Define the indices of the sphere */
+ setup_sphere_indices(&sphere->indices, nthetas, nphis);
- darray_uint_data_get(&sphere->indices)[i++] = itheta0 + iphi0;
- darray_uint_data_get(&sphere->indices)[i++] = itheta0 + iphi1;
- darray_uint_data_get(&sphere->indices)[i++] = itheta1 + iphi0;
+exit:
+ darray_sincos_release(&sincos_thetas);
+ darray_sincos_release(&sincos_phis);
+ return res;
+error:
+ schiff_mesh_release(sphere);
+ goto exit;
+}
- darray_uint_data_get(&sphere->indices)[i++] = itheta1 + iphi0;
- darray_uint_data_get(&sphere->indices)[i++] = itheta0 + iphi1;
- darray_uint_data_get(&sphere->indices)[i++] = itheta1 + iphi1;
- }
- }
+res_T
+schiff_mesh_init_sphere_polar
+ (struct mem_allocator* allocator,
+ struct schiff_mesh* sphere,
+ const unsigned nthetas)
+{
+ /* Theta in [0, 2PI[ and phi in [0, PI[ */
+ const unsigned nphis = (unsigned)(((double)nthetas + 0.5) / 2.0);
+ const double step_theta = 2*PI / (double)nthetas;
+ const double step_phi = PI / (double)nphis;
+ size_t nverts;
+ size_t ntris;
+ size_t i;
+ unsigned itheta, iphi;
+ res_T res = RES_OK;
+ ASSERT(allocator && sphere && nthetas);
- /* Define the indices of the polar primitives */
- FOR_EACH(itheta, 0, nthetas) {
- const unsigned itheta0 = itheta * (nphis - 1);
- const unsigned itheta1 = ((itheta + 1) % nthetas) * (nphis - 1);
+ sphere->coordinates = SCHIFF_POLAR;
+ darray_float_init(allocator, &sphere->vertices);
+ darray_uint_init(allocator, &sphere->indices);
+
+ nverts = nthetas*(nphis-1)/* #contour verts */ + 2/* polar verts */;
+ ntris = 2*nthetas*(nphis-2)/* #contour tris */ + 2*nthetas/* #polar tris */;
- darray_uint_data_get(&sphere->indices)[i++] = nthetas * (nphis - 1);
- darray_uint_data_get(&sphere->indices)[i++] = itheta0;
- darray_uint_data_get(&sphere->indices)[i++] = itheta1;
+ res = darray_float_resize(&sphere->vertices, nverts * 2/* theta phi*/);
+ if(res != RES_OK) goto error;
+ res = darray_uint_resize(&sphere->indices, ntris * 3/*#indices per tri*/);
+ if(res != RES_OK) goto error;
- darray_uint_data_get(&sphere->indices)[i++] = nthetas * (nphis - 1) + 1;
- darray_uint_data_get(&sphere->indices)[i++] = itheta1 + (nphis - 2);
- darray_uint_data_get(&sphere->indices)[i++] = itheta0 + (nphis - 2);
+ /* Build the contour vertices */
+ i = 0;
+ FOR_EACH(itheta, 0, nthetas) {
+ const double theta = -PI + (double)itheta * step_theta;
+ FOR_EACH(iphi, 0, nphis-1) {
+ const double phi = -PI/2 + (double)(iphi + 1) * step_phi;
+ darray_float_data_get(&sphere->vertices)[i++] = (float)theta;
+ darray_float_data_get(&sphere->vertices)[i++] = (float)phi;
+ }
}
+ /* Setup polar vertices */
+ f2(darray_float_data_get(&sphere->vertices) + i+0,-(float)PI,-(float)PI/2.0);
+ f2(darray_float_data_get(&sphere->vertices) + i+2, (float)PI, (float)PI/2.0);
+
+ /* Define the indices of the sphere */
+ setup_sphere_indices(&sphere->indices, nthetas, nphis);
exit:
- darray_sincos_release(&sincos_thetas);
- darray_sincos_release(&sincos_phis);
return res;
error:
schiff_mesh_release(sphere);
@@ -156,6 +230,7 @@ schiff_mesh_init_cylinder
res_T res = RES_OK;
ASSERT(allocator && cylinder && nsteps);
+ cylinder->coordinates = SCHIFF_CARTESIAN;
darray_float_init(allocator, &cylinder->vertices);
darray_uint_init(allocator, &cylinder->indices);
@@ -226,42 +301,3 @@ schiff_mesh_release(struct schiff_mesh* mesh)
darray_uint_release(&mesh->indices);
}
-res_T
-schiff_mesh_dump(struct schiff_mesh* mesh, const char* filename)
-{
- FILE* fp = NULL;
- size_t nverts, ntris;
- size_t i;
- res_T res = RES_OK;
- ASSERT(mesh && filename);
- ASSERT(darray_float_size_get(&mesh->vertices) % 3 == 0); /* 3D */
- ASSERT(darray_uint_size_get(&mesh->indices) % 3 == 0); /* Triangles */
-
- fp = fopen(filename, "w");
- if(!fp) {
- res = RES_IO_ERR;
- goto error;
- }
-
- nverts = darray_float_size_get(&mesh->vertices) / 3;
- FOR_EACH(i, 0, nverts) {
- fprintf(fp, "v %f %f %f\n",
- SPLIT3(darray_float_data_get(&mesh->vertices) + i*3));
- }
-
- ntris = darray_uint_size_get(&mesh->indices) / 3;
- FOR_EACH(i, 0, ntris) {
- /* Obj indices start from 1 */
- fprintf(fp, "f %u %u %u\n",
- darray_uint_data_get(&mesh->indices)[i*3 + 0] + 1,
- darray_uint_data_get(&mesh->indices)[i*3 + 1] + 1,
- darray_uint_data_get(&mesh->indices)[i*3 + 2] + 1);
- }
-
-exit:
- if(fp) fclose(fp);
- return res;
-error:
- goto exit;
-}
-
diff --git a/src/schiff_mesh.h b/src/schiff_mesh.h
@@ -32,9 +32,15 @@
#include <rsys/dynamic_array_float.h>
#include <rsys/dynamic_array_uint.h>
+enum schiff_coordinates {
+ SCHIFF_POLAR,
+ SCHIFF_CARTESIAN
+};
+
struct schiff_mesh {
struct darray_float vertices;
struct darray_uint indices;
+ enum schiff_coordinates coordinates;
};
extern LOCAL_SYM res_T
@@ -44,6 +50,12 @@ schiff_mesh_init_sphere
const unsigned nthetas); /* # discret points along 2PI */
extern LOCAL_SYM res_T
+schiff_mesh_init_sphere_polar
+ (struct mem_allocator* allocator,
+ struct schiff_mesh* mesh,
+ const unsigned nthetas);
+
+extern LOCAL_SYM res_T
schiff_mesh_init_cylinder
(struct mem_allocator* allocator,
struct schiff_mesh* mesh,
@@ -53,11 +65,6 @@ extern LOCAL_SYM void
schiff_mesh_release
(struct schiff_mesh* mesh);
-extern LOCAL_SYM res_T
-schiff_mesh_dump
- (struct schiff_mesh* mesh,
- const char* filename);
-
static INLINE void
schiff_mesh_get_indices
(struct schiff_mesh* mesh,
@@ -74,13 +81,13 @@ schiff_mesh_get_indices
}
static INLINE void
-schiff_mesh_get_position
+schiff_mesh_get_cartesian_position
(struct schiff_mesh* mesh,
const unsigned ivert,
- float vertex[3])
+ float vertex[])
{
const size_t i = ivert * 3;
- ASSERT(mesh && vertex);
+ ASSERT(mesh && vertex && mesh->coordinates == SCHIFF_CARTESIAN);
ASSERT(darray_float_size_get(&mesh->vertices) % 3 == 0);
ASSERT(ivert < darray_float_size_get(&mesh->vertices) / 3);
vertex[0] = darray_float_data_get(&mesh->vertices)[i + 0];