commit b6c4287c456ac335389f91774702800dec1c81e4
parent 40b3d9d737008dc8497b135421b0f48894061112
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 29 Oct 2015 16:25:28 +0100
Add the cylinder geometry distribution
Diffstat:
6 files changed, 265 insertions(+), 6 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -66,11 +66,13 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SCHIFF_FILES_SRC
schiff.c
schiff_args.c
+ schiff_cylinder.c
schiff_mesh.c
schiff_optical_properties.c
schiff_sphere.c)
set(SCHIFF_FILES_INC
schiff_args.h
+ schiff_cylinder.h
schiff_mesh.h
schiff_optical_properties.h
schiff_sphere.h)
diff --git a/src/schiff.c b/src/schiff.c
@@ -27,6 +27,7 @@
* knowledge of the CeCILL license and that you accept its terms. */
#include "schiff_args.h"
+#include "schiff_cylinder.h"
#include "schiff_sphere.h"
#include "schiff_optical_properties.h"
@@ -73,8 +74,17 @@ run(const struct schiff_args* args)
goto error;
}
- res = schiff_geometry_distribution_sphere_init
- (&distrib, &args->geom.sphere, args->properties);
+ switch(args->geom_type) {
+ case SCHIFF_SPHERE:
+ res = schiff_geometry_distribution_sphere_init
+ (&distrib, &args->geom.sphere, args->properties);
+ break;
+ case SCHIFF_CYLINDER:
+ res = schiff_geometry_distribution_cylinder_init
+ (&distrib, &args->geom.cylinder, args->properties);
+ break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
if(res != RES_OK) {
fprintf(stderr,
"Couldn't initialise the Star Schiff geometry distribution.\n");
@@ -85,7 +95,16 @@ run(const struct schiff_args* args)
nwlens = sa_size(args->wavelengths);
res = sschiff_integrate(sschiff, rng, &distrib, args->wavelengths, nwlens, 1,
args->ngeoms, args->ndirs, &estimator);
- schiff_geometry_distribution_sphere_release(&distrib);
+
+ switch(args->geom_type) {
+ case SCHIFF_SPHERE:
+ schiff_geometry_distribution_sphere_release(&distrib);
+ break;
+ case SCHIFF_CYLINDER:
+ schiff_geometry_distribution_cylinder_release(&distrib);
+ break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
if(res != RES_OK) {
fprintf(stderr, "Schiff integration error.\n");
diff --git a/src/schiff_cylinder.c b/src/schiff_cylinder.c
@@ -0,0 +1,185 @@
+/* Copyright (C) |Meso|Star> 2015 (contact@meso-star.com)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms. */
+
+#include "schiff_args.h"
+#include "schiff_cylinder.h"
+#include "schiff_mesh.h"
+#include "schiff_optical_properties.h"
+
+#include <star/s3d.h>
+#include <star/ssp.h>
+#include <star/sschiff.h>
+
+struct cylinder {
+ struct schiff_mesh* mesh; /* Trinagular mesh of a "unit" cylinder */
+ float radius;
+ float height;
+};
+
+struct cylinder_geometry_distribution_context {
+ struct schiff_mesh* mesh; /* Triangular mesh of the cylindrical mesh */
+ struct schiff_optical_properties* properties; /* Per wavelength properties */
+ double log_mean_radius; /* Log of the mean radius */
+ double log_sigma; /* Log of the sigma argument of the lognormal distribution*/
+ double aspect_ratio; /* aspect ratio of the cylinder distribution */
+};
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+cylinder_get_indices(const unsigned itri, unsigned ids[3], void* ctx)
+{
+ struct cylinder* cylinder = ctx;
+ schiff_mesh_get_indices(cylinder->mesh, itri, ids);
+}
+
+static void
+cylinder_get_position(const unsigned ivert, float vertex[3], void* ctx)
+{
+ struct cylinder* cylinder = ctx;
+ schiff_mesh_get_position(cylinder->mesh, ivert, vertex);
+ vertex[0] *= cylinder->radius;
+ vertex[1] *= cylinder->radius;
+ vertex[2] *= cylinder->height;
+}
+
+static void
+cylinder_get_material_property
+ (void* mtl,
+ const double wavelength,
+ struct sschiff_material_properties* props)
+{
+ struct schiff_optical_properties* properties = mtl;
+ schiff_optical_properties_fetch(properties, wavelength, props);
+}
+
+static res_T
+cylinder_sample_geometry
+ (struct ssp_rng* rng,
+ struct sschiff_material* mtl,
+ struct s3d_shape* shape,
+ void* context)
+{
+ struct cylinder_geometry_distribution_context* ctx = context;
+ struct cylinder cylinder;
+ struct s3d_vertex_data attrib;
+ size_t nverts, nprims;
+ double y;
+
+ y = ssp_ran_lognormal(rng, ctx->log_mean_radius, ctx->log_sigma);
+ cylinder.mesh = ctx->mesh;
+ cylinder.radius = (float)(y / pow(3.0 / (2.0*ctx->aspect_ratio), 1.0/3.0));
+ cylinder.height = (float)(2.f * cylinder.radius / ctx->aspect_ratio);
+
+ attrib.usage = S3D_POSITION;
+ attrib.type = S3D_FLOAT3;
+ attrib.get = cylinder_get_position;
+
+ mtl->get_property = cylinder_get_material_property;
+ mtl->material = ctx->properties;
+
+ nverts = darray_float_size_get(&ctx->mesh->vertices) / 3/*#coords*/;
+ nprims = darray_uint_size_get(&ctx->mesh->indices) / 3/*#indices per prim*/;
+
+ return s3d_mesh_setup_indexed_vertices(shape, (unsigned)nprims,
+ cylinder_get_indices, (unsigned)nverts, &attrib, 1, &cylinder);
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+res_T
+schiff_geometry_distribution_cylinder_init
+ (struct sschiff_geometry_distribution* distrib,
+ const struct schiff_cylinder* cylinder,
+ struct schiff_optical_properties* properties)
+{
+ struct cylinder_geometry_distribution_context* ctx = NULL;
+ res_T res = RES_OK;
+ ASSERT(distrib && cylinder && properties);
+
+ ctx = mem_calloc(1, sizeof(struct cylinder_geometry_distribution_context));
+ if(!ctx) {
+ fprintf(stderr,
+"Not enough memory: couldn't allocate the cylinder geometry distribution context\n");
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ctx->mesh = mem_calloc(1, sizeof(struct schiff_mesh));
+ if(!ctx->mesh) {
+ fprintf(stderr,
+"Not enough memory: couldn't allocate the cylinder mesh template.\n");
+ res = RES_MEM_ERR;
+ goto error;
+ }
+
+ /* Generate the mesh template of the distribution */
+ res = schiff_mesh_init_cylinder
+ (&mem_default_allocator, ctx->mesh, cylinder->nslices);
+ if(res != RES_OK) {
+ fprintf(stderr, "Couldn't initialise the sphere mesh template.\n");
+ goto error;
+ }
+
+ /* Setup the geometry distribution context */
+ ctx->properties = properties;
+ ctx->log_mean_radius = log(cylinder->radius);
+ ctx->log_sigma = log(cylinder->sigma);
+ ctx->aspect_ratio = cylinder->aspect_ratio;
+
+ distrib->sample = cylinder_sample_geometry;
+ distrib->context = ctx;
+
+exit:
+ return res;
+error:
+ if(ctx) {
+ if(ctx->mesh) {
+ schiff_mesh_release(ctx->mesh);
+ mem_rm(ctx->mesh);
+ }
+ mem_rm(ctx);
+ ctx = NULL;
+ }
+ goto exit;
+}
+
+
+void
+schiff_geometry_distribution_cylinder_release
+ (struct sschiff_geometry_distribution* distrib)
+{
+ struct cylinder_geometry_distribution_context* ctx;
+ ASSERT(distrib);
+ ctx = distrib->context;
+ schiff_mesh_release(ctx->mesh);
+ mem_rm(ctx->mesh);
+ mem_rm(ctx);
+}
+
diff --git a/src/schiff_cylinder.h b/src/schiff_cylinder.h
@@ -0,0 +1,49 @@
+/* Copyright (C) |Meso|Star> 2015 (contact@meso-star.com)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms. */
+
+#ifndef SCHIFF_CYLINDER_H
+#define SCHIFF_CYLINDER_H
+
+#include <rsys/rsys.h>
+
+struct schiff_cylinder;
+struct schiff_optical_properties;
+struct sschiff_geometry_distribution;
+
+extern LOCAL_SYM res_T
+schiff_geometry_distribution_cylinder_init
+ (struct sschiff_geometry_distribution* distrib,
+ const struct schiff_cylinder* cylinder,
+ struct schiff_optical_properties* properties);
+
+extern LOCAL_SYM void
+schiff_geometry_distribution_cylinder_release
+ (struct sschiff_geometry_distribution* distrib);
+
+#endif /* SCHIFF_SPHERE_H */
+
diff --git a/src/schiff_sphere.c b/src/schiff_sphere.c
@@ -121,7 +121,7 @@ schiff_geometry_distribution_sphere_init
{
struct sphere_geometry_distribution_context* ctx = NULL;
res_T res = RES_OK;
- ASSERT(sphere);
+ ASSERT(sphere && distrib && properties);
ctx = mem_calloc(1, sizeof(struct sphere_geometry_distribution_context));
if(!ctx) {
@@ -158,7 +158,10 @@ exit:
return res;
error:
if(ctx) {
- if(ctx->mesh) mem_rm(ctx->mesh);
+ if(ctx->mesh) {
+ schiff_mesh_release(ctx->mesh);
+ mem_rm(ctx->mesh);
+ }
mem_rm(ctx);
ctx = NULL;
}
diff --git a/src/schiff_sphere.h b/src/schiff_sphere.h
@@ -31,7 +31,7 @@
#include <rsys/rsys.h>
-struct schiff_distribution_sphere;
+struct schiff_sphere;
struct schiff_optical_properties;
struct sschiff_geometry_distribution;
@@ -46,3 +46,4 @@ schiff_geometry_distribution_sphere_release
(struct sschiff_geometry_distribution* distrib);
#endif /* SCHIFF_SPHERE_H */
+