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:
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 */
-