schiff

Estimate the radiative properties of soft particless
git clone git://git.meso-star.com/schiff.git
Log | Files | Refs | README | LICENSE

commit 665a94251e0a4723d7a7cb47d6e984687f12ced0
parent b6c4287c456ac335389f91774702800dec1c81e4
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Sun,  1 Nov 2015 10:02:15 +0100

Refactor the management of the geometry and its associated distribution

Spheres and cylinders are managed through a generic
geometry/distribution. This is used to clean-up duplicated codes.

Diffstat:
Mcmake/CMakeLists.txt | 10++++------
Msrc/schiff.c | 28++++++----------------------
Msrc/schiff_args.c | 22+++++++++++-----------
Msrc/schiff_args.h | 43+++----------------------------------------
Dsrc/schiff_cylinder.c | 185-------------------------------------------------------------------------------
Dsrc/schiff_cylinder.h | 49-------------------------------------------------
Asrc/schiff_geometry.c | 276+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/schiff_geometry.h | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/schiff_sphere.c | 182-------------------------------------------------------------------------------
Dsrc/schiff_sphere.h | 49-------------------------------------------------
10 files changed, 388 insertions(+), 544 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -66,16 +66,14 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(SCHIFF_FILES_SRC schiff.c schiff_args.c - schiff_cylinder.c + schiff_geometry.c schiff_mesh.c - schiff_optical_properties.c - schiff_sphere.c) + schiff_optical_properties.c) set(SCHIFF_FILES_INC schiff_args.h - schiff_cylinder.h + schiff_geometry.h schiff_mesh.h - schiff_optical_properties.h - schiff_sphere.h) + schiff_optical_properties.h) set(SCHIFF_FILES_DOC COPYING.fr COPYING.en README.md) # Prepend each file in the `SCHIFF_FILES_<SRC|INC>' list by the absolute diff --git a/src/schiff.c b/src/schiff.c @@ -27,8 +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_geometry.h" #include "schiff_optical_properties.h" #include <rsys/stretchy_array.h> @@ -74,17 +73,8 @@ run(const struct schiff_args* args) goto error; } - 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; - } + res = schiff_geometry_distribution_init + (&distrib, &args->geom, args->properties); if(res != RES_OK) { fprintf(stderr, "Couldn't initialise the Star Schiff geometry distribution.\n"); @@ -96,15 +86,9 @@ run(const struct schiff_args* args) res = sschiff_integrate(sschiff, rng, &distrib, args->wavelengths, nwlens, 1, args->ngeoms, args->ndirs, &estimator); - 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; - } + /* Release before the check of the integration error code since if an error + * occurred the function will return without releasing the distribution. */ + schiff_geometry_distribution_release(&distrib); if(res != RES_OK) { fprintf(stderr, "Schiff integration error.\n"); diff --git a/src/schiff_args.c b/src/schiff_args.c @@ -96,7 +96,7 @@ parse_cylinder_distribution(const char* str, struct schiff_args* args) ASSERT(args && str); /* The distribution was already set to a non cylinder distribution. */ - if(args->geom_type!= SCHIFF_NONE && args->geom_type != SCHIFF_CYLINDER) { + if(args->geom.type!= SCHIFF_NONE && args->geom.type != SCHIFF_CYLINDER) { res = RES_BAD_ARG; goto error; @@ -121,11 +121,11 @@ parse_cylinder_distribution(const char* str, struct schiff_args* args) } /* Update the distribution */ - args->geom_type = SCHIFF_CYLINDER; - args->geom.cylinder.radius = list[0]; - args->geom.cylinder.sigma = list[1]; - args->geom.cylinder.aspect_ratio = list[2]; - args->geom.cylinder.nslices = nslices; + args->geom.type = SCHIFF_CYLINDER; + args->geom.data.cylinder.radius = list[0]; + args->geom.data.cylinder.sigma = list[1]; + args->geom.data.cylinder.aspect_ratio = list[2]; + args->geom.data.cylinder.nslices = nslices; exit: return res; @@ -143,7 +143,7 @@ parse_sphere_distribution(const char* str, struct schiff_args* args) ASSERT(args && str); /* The distribution was already set to a non sphere distribution. */ - if(args->geom_type != SCHIFF_NONE && args->geom_type != SCHIFF_SPHERE) { + if(args->geom.type != SCHIFF_NONE && args->geom.type != SCHIFF_SPHERE) { res = RES_BAD_ARG; goto error; @@ -167,10 +167,10 @@ parse_sphere_distribution(const char* str, struct schiff_args* args) } /* Update the distribution */ - args->geom_type = SCHIFF_SPHERE; - args->geom.sphere.radius = list[0]; - args->geom.sphere.sigma = list[1]; - args->geom.sphere.nslices = nslices; + args->geom.type = SCHIFF_SPHERE; + args->geom.data.sphere.radius = list[0]; + args->geom.data.sphere.sigma = list[1]; + args->geom.data.sphere.nslices = nslices; exit: return res; diff --git a/src/schiff_args.h b/src/schiff_args.h @@ -29,50 +29,14 @@ #ifndef SCHIFF_ARGS_H #define SCHIFF_ARGS_H +#include "schiff_geometry.h" #include <rsys/rsys.h> -/* List of supported geometry */ -enum schiff_type { - SCHIFF_CYLINDER, - SCHIFF_SPHERE, - SCHIFF_NONE -}; - -struct schiff_sphere { - double radius; - double sigma; - unsigned nslices; -}; - -#define SCHIFF_SPHERE_DEFAULT__ {1.0, 1.0, 64} -static const struct schiff_sphere SCHIFF_SPHERE_DEFAULT = - SCHIFF_SPHERE_DEFAULT__; - -struct schiff_cylinder { - double radius; - double sigma; - double aspect_ratio; - unsigned nslices; -}; - -#define SCHIFF_CYLINDER_DEFAULT__ {1.0, 1.0, 1.0, 64} -static const struct schiff_cylinder SCHIFF_CYLINDER_DEFAULT = - SCHIFF_CYLINDER_DEFAULT__; - -/* Generic distribution */ -union schiff_geometry { - struct schiff_sphere sphere; - struct schiff_cylinder cylinder; -}; - -#define SCHIFF_GEOMETRY_DEFAULT__ {SCHIFF_SPHERE_DEFAULT__} - struct schiff_args { const char* output_filename; struct schiff_optical_properties* properties; double* wavelengths; - enum schiff_type geom_type; - union schiff_geometry geom; + struct schiff_geometry geom; unsigned ngeoms; unsigned ndirs; }; @@ -81,8 +45,7 @@ static const struct schiff_args SCHIFF_ARGS_NULL = { NULL, /* Output filename */ NULL, /* List of optical properties */ NULL, /* List of wavelength to integrate */ - SCHIFF_NONE, - SCHIFF_GEOMETRY_DEFAULT__, + SCHIFF_GEOMETRY_NULL__, 1000, /* # Sampled geometries */ 100, /* # Sampled directions per gemetry */ }; diff --git a/src/schiff_cylinder.c b/src/schiff_cylinder.c @@ -1,185 +0,0 @@ -/* 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 @@ -1,49 +0,0 @@ -/* 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_geometry.c b/src/schiff_geometry.c @@ -0,0 +1,276 @@ +/* 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_geometry.h" +#include "schiff_mesh.h" +#include "schiff_optical_properties.h" + +#include <star/s3d.h> +#include <star/ssp.h> +#include <star/sschiff.h> + +/* 3D Context of the sphere geometry */ +struct sphere_context { + float radius; /* Sphere radius */ +}; + +/* 3D Context of the cylinder geometry */ +struct cylinder_context { + float radius; + float height; +}; + +/* Distribution context of a sphere geometry */ +struct sphere_distribution_context { + double log_mean_radius; /* Log of the mean radius */ + double log_sigma; /* Log of the sigma argument of the lognormal distribution*/ +}; + +/* Distribution context of a cylinder geometry */ +struct cylinder_distribution_context { + 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 */ +}; + +/* 3D context of a generic geometry */ +struct geometry_context { + struct schiff_mesh* mesh; /* Triangular mesh of the geometry */ + enum schiff_geometry_type type; + union { + struct cylinder_context cylinder; + struct sphere_context sphere; + } data; +}; + +/* Distribution context of a generic geometry */ +struct geometry_distribution_context { + struct schiff_mesh* mesh; /* Triangular mesh of the cylindrical mesh */ + struct schiff_optical_properties* properties; /* Per wavelength properties */ + enum schiff_geometry_type type; + union { + struct cylinder_distribution_context cylinder; + struct sphere_distribution_context sphere; + } data; +}; + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static void +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 void +geometry_get_indices(const unsigned itri, unsigned ids[3], void* ctx) +{ + struct geometry_context* geom = ctx; + ASSERT(geom); + schiff_mesh_get_indices(geom->mesh, itri, ids); +} + +static void +cylinder_get_position(const unsigned ivert, float vertex[3], void* ctx) +{ + struct geometry_context* geom = ctx; + ASSERT(geom && geom->type == SCHIFF_CYLINDER); + schiff_mesh_get_position(geom->mesh, ivert, vertex); + vertex[0] *= geom->data.cylinder.radius; + vertex[1] *= geom->data.cylinder.radius; + vertex[2] *= geom->data.cylinder.height; +} + +static void +sphere_get_position(const unsigned ivert, float vertex[3], void* ctx) +{ + struct geometry_context* geom = ctx; + ASSERT(geom && geom->type == SCHIFF_SPHERE); + schiff_mesh_get_position(geom->mesh, ivert, vertex); + vertex[0] *= geom->data.sphere.radius; + vertex[1] *= geom->data.sphere.radius; + vertex[2] *= geom->data.sphere.radius; +} + +static res_T +geometry_sample_sphere + (struct ssp_rng* rng, + struct sschiff_material* mtl, + struct s3d_shape* shape, + void* context) +{ + struct geometry_distribution_context* distrib = context; + struct geometry_context geom; + struct s3d_vertex_data attrib; + size_t nverts, nprims; + ASSERT(rng && mtl && shape && context); + ASSERT(distrib->type == SCHIFF_SPHERE); + + geom.mesh = distrib->mesh; + geom.type = SCHIFF_SPHERE; + geom.data.sphere.radius = (float)ssp_ran_lognormal + (rng, distrib->data.sphere.log_mean_radius, distrib->data.sphere.log_sigma); + + attrib.usage = S3D_POSITION; + attrib.type = S3D_FLOAT3; + attrib.get = sphere_get_position; + + mtl->get_property = get_material_property; + mtl->material = distrib->properties; + + nverts = darray_float_size_get(&distrib->mesh->vertices) / 3/*#coords*/; + nprims = darray_uint_size_get(&distrib->mesh->indices) / 3/*#indices*/; + + return s3d_mesh_setup_indexed_vertices(shape, (unsigned)nprims, + geometry_get_indices, (unsigned)nverts, &attrib, 1, &geom); +} + +static res_T +geometry_sample_cylinder + (struct ssp_rng* rng, + struct sschiff_material* mtl, + struct s3d_shape* shape, + void* context) +{ + struct geometry_distribution_context* distrib = context; + struct geometry_context geom; + struct s3d_vertex_data attrib; + size_t nverts, nprims; + double y; + ASSERT(rng && mtl && shape && context); + ASSERT(distrib->type == SCHIFF_CYLINDER); + + y = ssp_ran_lognormal + (rng, distrib->data.cylinder.log_mean_radius, distrib->data.cylinder.log_sigma); + geom.type = SCHIFF_CYLINDER; + geom.mesh = distrib->mesh; + geom.data.cylinder.radius = + (float)(y / pow(3.0 / (2.0*distrib->data.cylinder.aspect_ratio), 1.0/3.0)); + geom.data.cylinder.height = + (float)(2.f * geom.data.cylinder.radius / distrib->data.cylinder.aspect_ratio); + + attrib.usage = S3D_POSITION; + attrib.type = S3D_FLOAT3; + attrib.get = cylinder_get_position; + + mtl->get_property = get_material_property; + mtl->material = distrib->properties; + + nverts = darray_float_size_get(&distrib->mesh->vertices) / 3/*#coords*/; + nprims = darray_uint_size_get(&distrib->mesh->indices) / 3/*#indices per prim*/; + + return s3d_mesh_setup_indexed_vertices(shape, (unsigned)nprims, + geometry_get_indices, (unsigned)nverts, &attrib, 1, &geom); +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +schiff_geometry_distribution_init + (struct sschiff_geometry_distribution* distrib, + const struct schiff_geometry* geom, + struct schiff_optical_properties* properties) +{ + struct geometry_distribution_context* ctx = NULL; + res_T res = RES_OK; + ASSERT(distrib && geom && properties); + + ctx = mem_calloc(1, sizeof(struct geometry_distribution_context)); + if(!ctx) { + fprintf(stderr, +"Not enough memory: couldn't allocate the 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 mesh of the geometry.\n"); + res = RES_MEM_ERR; + goto error; + } + + /* Generate the mesh template and setup its distribution context */ + switch(geom->type) { + case SCHIFF_CYLINDER: + res = schiff_mesh_init_cylinder + (&mem_default_allocator, ctx->mesh, geom->data.cylinder.nslices); + ctx->data.cylinder.log_mean_radius = log(geom->data.cylinder.radius); + ctx->data.cylinder.log_sigma = log(geom->data.cylinder.sigma); + ctx->data.cylinder.aspect_ratio = geom->data.cylinder.aspect_ratio; + distrib->sample = geometry_sample_cylinder; + break; + case SCHIFF_SPHERE: + res = schiff_mesh_init_sphere + (&mem_default_allocator, ctx->mesh, geom->data.sphere.nslices); + ctx->data.sphere.log_mean_radius = log(geom->data.sphere.radius); + ctx->data.sphere.log_sigma = log(geom->data.sphere.sigma); + distrib->sample = geometry_sample_sphere; + break; + default: FATAL("Unreachable code.\n"); break; + } + if(res != RES_OK) { + fprintf(stderr, "Couldn't initialise the mesh template.\n"); + goto error; + } + ctx->properties = properties; + ctx->type = geom->type; + 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_release + (struct sschiff_geometry_distribution* distrib) +{ + struct 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_geometry.h b/src/schiff_geometry.h @@ -0,0 +1,88 @@ +/* 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_GEOMETRY_H +#define SCHIFF_GEOMETRY_H + +#include <rsys/rsys.h> + +enum schiff_geometry_type { + SCHIFF_CYLINDER, + SCHIFF_SPHERE, + SCHIFF_NONE +}; + +struct schiff_sphere { + double radius; + double sigma; + unsigned nslices; +}; + +#define SCHIFF_SPHERE_DEFAULT__ {1.0, 1.0, 64} +static const struct schiff_sphere SCHIFF_SPHERE_DEFAULT = + SCHIFF_SPHERE_DEFAULT__; + +struct schiff_cylinder { + double radius; + double sigma; + double aspect_ratio; + unsigned nslices; +}; + +#define SCHIFF_CYLINDER_DEFAULT__ {1.0, 1.0, 1.0, 64} +static const struct schiff_cylinder SCHIFF_CYLINDER_DEFAULT = + SCHIFF_CYLINDER_DEFAULT__; + +struct schiff_geometry { + enum schiff_geometry_type type; + union { + struct schiff_cylinder cylinder; + struct schiff_sphere sphere; + } data; +}; + +#define SCHIFF_GEOMETRY_NULL__ { SCHIFF_NONE, { SCHIFF_CYLINDER_DEFAULT__ } } +static const struct schiff_geometry SCHIFF_GEOMETRY_NULL = +SCHIFF_GEOMETRY_NULL__; + +/* Forward declarations */ +struct schiff_optical_properties; +struct sschiff_geometry_distribution; + +extern LOCAL_SYM res_T +schiff_geometry_distribution_init + (struct sschiff_geometry_distribution* distrib, + const struct schiff_geometry* geometry, + struct schiff_optical_properties* properties); + +extern LOCAL_SYM void +schiff_geometry_distribution_release + (struct sschiff_geometry_distribution* distrib); + +#endif /* SCHIFF_GEOMETRY_H */ + diff --git a/src/schiff_sphere.c b/src/schiff_sphere.c @@ -1,182 +0,0 @@ -/* 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_mesh.h" -#include "schiff_optical_properties.h" -#include "schiff_sphere.h" - -#include <star/s3d.h> -#include <star/ssp.h> -#include <star/sschiff.h> - -#include <rsys/float3.h> - -/* Sphere geometry */ -struct sphere { - struct schiff_mesh* mesh; /* Triangular mesh of an unit sphere */ - float radius; /* Sphere radius */ -}; - -/* Geometry distribution of a sphere */ -struct sphere_geometry_distribution_context { - struct schiff_mesh* mesh; /* Triangular mesh of the template 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*/ -}; - -/******************************************************************************* - * Helper functions - ******************************************************************************/ -static void -sphere_get_indices(const unsigned itri, unsigned ids[3], void* ctx) -{ - struct sphere* sphere = ctx; - schiff_mesh_get_indices(sphere->mesh, itri, ids); -} - -static void -sphere_get_position(const unsigned ivert, float vertex[3], void* ctx) -{ - struct sphere* sphere = ctx; - schiff_mesh_get_position(sphere->mesh, ivert, vertex); - f3_mulf(vertex, vertex, sphere->radius); -} - -static void -sphere_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 -sphere_sample_geometry - (struct ssp_rng* rng, - struct sschiff_material* mtl, - struct s3d_shape* shape, - void* context) -{ - struct sphere_geometry_distribution_context* ctx = context; - struct sphere sphere; - struct s3d_vertex_data attrib; - size_t nverts, nprims; - ASSERT(rng && mtl && shape && context); - - sphere.mesh = ctx->mesh; - sphere.radius = (float)ssp_ran_lognormal - (rng, ctx->log_mean_radius, ctx->log_sigma); - - attrib.usage = S3D_POSITION; - attrib.type = S3D_FLOAT3; - attrib.get = sphere_get_position; - - mtl->get_property = sphere_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, - sphere_get_indices, (unsigned)nverts, &attrib, 1, &sphere); -} - -/******************************************************************************* - * Local functions - ******************************************************************************/ -res_T -schiff_geometry_distribution_sphere_init - (struct sschiff_geometry_distribution* distrib, - const struct schiff_sphere* sphere, - struct schiff_optical_properties* properties) -{ - struct sphere_geometry_distribution_context* ctx = NULL; - res_T res = RES_OK; - ASSERT(sphere && distrib && properties); - - ctx = mem_calloc(1, sizeof(struct sphere_geometry_distribution_context)); - if(!ctx) { - fprintf(stderr, -"Not enough memory: couldn't allocate the sphere 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 sphere mesh template.\n"); - res = RES_MEM_ERR; - goto error; - } - - /* Generate the mesh template of the distribution */ - res = schiff_mesh_init_sphere - (&mem_default_allocator, ctx->mesh, sphere->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(sphere->radius); - ctx->log_sigma = log(sphere->sigma); - - distrib->sample = sphere_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_sphere_release - (struct sschiff_geometry_distribution* distrib) -{ - struct sphere_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_sphere.h b/src/schiff_sphere.h @@ -1,49 +0,0 @@ -/* 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_SPHERE_H -#define SCHIFF_SPHERE_H - -#include <rsys/rsys.h> - -struct schiff_sphere; -struct schiff_optical_properties; -struct sschiff_geometry_distribution; - -extern LOCAL_SYM res_T -schiff_geometry_distribution_sphere_init - (struct sschiff_geometry_distribution* distrib, - const struct schiff_sphere* sphere, - struct schiff_optical_properties* properties); - -extern LOCAL_SYM void -schiff_geometry_distribution_sphere_release - (struct sschiff_geometry_distribution* distrib); - -#endif /* SCHIFF_SPHERE_H */ -