commit 1b508a1927856bc55a8aa51411881b58c30ee52f
parent d52298d1d16f4214dbaafcddae6a9ab0389630d0
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 8 Oct 2015 09:52:48 +0200
Rename the project from Star-Algae to Star-Schiff
Update the API prefix, the file and library names with respect to the
new project name.
Diffstat:
15 files changed, 1080 insertions(+), 1082 deletions(-)
diff --git a/README.md b/README.md
@@ -1,4 +1,4 @@
-# Star Algae
+# Star Schiff
The purpose of this library is to numericaly solve the radiative properties of
micro organism with respect to an "Approximation Method for Short Wavelength or
@@ -6,22 +6,21 @@ High-Energy Scattering" (L. Schiff, 1956).
## How to build
-The *Star-Algae* library relies on the [CMake](http://www.cmake.org) and the
+The *Star-Schiff* library relies on the [CMake](http://www.cmake.org) and the
[RCMake](https://gitlab.com/vaplv/rcmake/) package to build. It also depends on the
[RSys](https://gitlab.com/vaplv/rsys/),
-[Star-3D](https://gitlab.com/meso-star/star-3d/),
-[Star-MC](https://gitlab.com/meso-star/star-mc/) and
+[Star-3D](https://gitlab.com/meso-star/star-3d/) and
[Star-SP](https://gitlab.com/meso-star/star-sp/) libraries.
First ensure that CMake is installed on your system. Then install the RCMake
-package as well as all the *Star-Algae* prerequisites. Then generate the
+package as well as all the *Star-Schiff* prerequisites. Then generate the
project from the `cmake/CMakeLists.txt` file by appending to the
`CMAKE_PREFIX_PATH` variable the install directories of its dependencies and
the RCMake package.
## Licenses
-*Star-Algae* is Copyright (C) |Meso|Star> 2015 (<contact@meso-star.com>). It is a
+*Star-Schiff* is Copyright (C) |Meso|Star> 2015 (<contact@meso-star.com>). It is a
free software released under the [OSI](http://opensource.org)-approved CeCILL
license. You are welcome to redistribute it under certain conditions; refer to
the COPYING files for details.
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -27,10 +27,10 @@
# knowledge of the CeCILL license and that you accept its terms.
cmake_minimum_required(VERSION 2.8)
-project(star-algae C)
+project(star-schiff C)
enable_testing()
-set(SALGAE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
+set(SSCHIFF_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
option(NO_TEST "Disable the test" OFF)
################################################################################
@@ -59,50 +59,50 @@ set(VERSION_MINOR 3)
set(VERSION_PATCH 0)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
-set(SALGAE_FILES_SRC salgae_device.c salgae_estimator.c)
-set(SALGAE_FILES_INC_API salgae.h)
-set(SALGAE_FILES_INC salgae_device.h)
-set(SALGAE_FILES_DOC COPYING.en COPYING.fr README.md)
+set(SSCHIFF_FILES_SRC sschiff_device.c sschiff_estimator.c)
+set(SSCHIFF_FILES_INC_API sschiff.h)
+set(SSCHIFF_FILES_INC sschiff_device.h)
+set(SSCHIFF_FILES_DOC COPYING.en COPYING.fr README.md)
-# Prepend each file in the `SALGAE_FILES_<SRC|INC>' list by `SALGAE_SOURCE_DIR'
-rcmake_prepend_path(SALGAE_FILES_SRC ${SALGAE_SOURCE_DIR})
-rcmake_prepend_path(SALGAE_FILES_INC_API ${SALGAE_SOURCE_DIR})
-rcmake_prepend_path(SALGAE_FILES_INC ${SALGAE_SOURCE_DIR})
-rcmake_prepend_path(SALGAE_FILES_DOC ${PROJECT_SOURCE_DIR}/../)
+# Prepend each file in the `SSCHIFF_FILES_<SRC|INC>' list by `SSCHIFF_SOURCE_DIR'
+rcmake_prepend_path(SSCHIFF_FILES_SRC ${SSCHIFF_SOURCE_DIR})
+rcmake_prepend_path(SSCHIFF_FILES_INC_API ${SSCHIFF_SOURCE_DIR})
+rcmake_prepend_path(SSCHIFF_FILES_INC ${SSCHIFF_SOURCE_DIR})
+rcmake_prepend_path(SSCHIFF_FILES_DOC ${PROJECT_SOURCE_DIR}/../)
-add_library(salgae SHARED ${SALGAE_FILES_SRC} ${SALGAE_FILES_INC_API} ${SALGAE_FILES_INC})
-set_target_properties(salgae PROPERTIES
- DEFINE_SYMBOL SALGAE_SHARED_BUILD
+add_library(sschiff SHARED ${SSCHIFF_FILES_SRC} ${SSCHIFF_FILES_INC_API} ${SSCHIFF_FILES_INC})
+set_target_properties(sschiff PROPERTIES
+ DEFINE_SYMBOL SSCHIFF_SHARED_BUILD
VERSION ${VERSION}
SOVERSION ${VERSION_MAJOR})
-target_link_libraries(salgae RSys Star3D StarSP)
+target_link_libraries(sschiff RSys Star3D StarSP)
if(CMAKE_COMPILER_IS_GNUCC)
- target_link_libraries(salgae m)
+ target_link_libraries(sschiff m)
endif()
-rcmake_setup_devel(salgae StarAlgae ${VERSION} star/salgae_version.h)
+rcmake_setup_devel(sschiff StarAlgae ${VERSION} star/sschiff_version.h)
################################################################################
# Add tests
################################################################################
if(NOT NO_TEST)
function(new_test _name)
- add_executable(${_name} ${SALGAE_SOURCE_DIR}/${_name}.c)
- target_link_libraries(${_name} salgae RSys)
+ add_executable(${_name} ${SSCHIFF_SOURCE_DIR}/${_name}.c)
+ target_link_libraries(${_name} sschiff RSys)
add_test(${_name} ${_name})
endfunction(new_test)
- new_test(test_salgae_device)
- new_test(test_salgae_estimator)
+ new_test(test_sschiff_device)
+ new_test(test_sschiff_estimator)
endif()
################################################################################
# Define output & install directories
################################################################################
-install(TARGETS salgae
+install(TARGETS sschiff
ARCHIVE DESTINATION bin
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
-install(FILES ${SALGAE_FILES_INC_API} DESTINATION include/star)
-install(FILES ${SALGAE_FILES_DOC} DESTINATION doc/star-algae)
+install(FILES ${SSCHIFF_FILES_INC_API} DESTINATION include/star)
+install(FILES ${SSCHIFF_FILES_DOC} DESTINATION doc/star-schiff)
diff --git a/src/salgae.h b/src/salgae.h
@@ -1,156 +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 SALGAE_H
-#define SALGAE_H
-
-#include <rsys/rsys.h>
-
-/* Library symbol management */
-#if defined(SALGAE_SHARED_BUILD) /* Build shared library */
- #define SALGAE_API extern EXPORT_SYM
-#elif defined(SALGAE_STATIC) /* Use/build static library */
- #define SALGAE_API extern LOCAL_SYM
-#else /* Use shared library */
- #define SALGAE_API extern IMPORT_SYM
-#endif
-
-/* Helper macro that asserts if the invocation of the sgf function `Func'
- * returns an error. One should use this macro on salgae function calls for
- * which no explicit error checking is performed */
-#ifndef NDEBUG
- #define SALGAE(Func) ASSERT(salgae_ ## Func == RES_OK)
-#else
- #define SALGAE(Func) salgae_ ## Func
-#endif
-
-/* Forward declaration of external types */
-struct mem_allocator;
-struct logger;
-struct s3d_device;
-struct s3d_shape;
-struct ssp_rng;
-
-struct salgae_refractive_index { double real, imag; };
-
-/* Material of an Algae */
-struct salgae_material {
- /* Retrieve the refractive complex index of the material */
- void (*get_refractive_index)
- (void* material,
- const double wavelength,
- struct salgae_refractive_index* value);
- void* material; /* Opaque user defined representation of the material */
-};
-
-static const struct salgae_material SALGAE_NULL_MATERIAL = { NULL, NULL };
-
-struct salgae_integrator_desc {
- res_T (*sample_geometry) /* Sample a geometry i.e. a shape and its material */
- (struct ssp_rng* rng,
- struct salgae_material* mtl, /* Sampled material */
- struct s3d_shape* shape, /* Sampled shape */
- void* sampler_context);
- void* sampler_context;
- size_t scattering_angles_count; /* # of scattering angles to handle */
-};
-
-static const struct salgae_integrator_desc SALGAE_NULL_INTEGRATOR_DESC = {
- NULL, NULL, 0
-};
-
-/* Result of the Monte Carlo estimation */
-struct salgae_estimator_status {
- double E; /* Expected value */
- double V; /* Variance */
- double SE; /* Standard error */
- size_t nsteps;
-};
-
-/* Opaque types */
-struct salgae_device;
-struct salgae_estimator;
-
-/*******************************************************************************
- * Star Algae API
- ******************************************************************************/
-BEGIN_DECLS
-
-SALGAE_API res_T
-salgae_device_create
- (struct logger* logger, /* May be NULL <=> use default logger */
- struct mem_allocator* allocator, /* May be NULL <=> use default allocator */
- const int verbose,
- struct s3d_device* s3d, /* May be NULL <=> internally create a S3D device */
- struct salgae_device** dev);
-
-SALGAE_API res_T
-salgae_device_ref_get
- (struct salgae_device* dev);
-
-SALGAE_API res_T
-salgae_device_ref_put
- (struct salgae_device* dev);
-
-SALGAE_API res_T
-salgae_integrate
- (struct salgae_device* dev,
- struct ssp_rng* rng,
- struct salgae_integrator_desc* desc,
- const double wavelength, /* Wavelength to integrate */
- const size_t steps_count, /* #realisations */
- struct salgae_estimator** estimator);
-
-SALGAE_API res_T
-salgae_estimator_ref_get
- (struct salgae_estimator* estimator);
-
-SALGAE_API res_T
-salgae_estimator_ref_put
- (struct salgae_estimator* estimator);
-
-SALGAE_API res_T
-salgae_estimator_get_extinction_cross_section
- (struct salgae_estimator* estimator,
- struct salgae_estimator_status* status);
-
-SALGAE_API res_T
-salgae_estimator_get_absorption_cross_section
- (struct salgae_estimator* estimator,
- struct salgae_estimator_status* status);
-
-SALGAE_API res_T
-salgae_estimator_get_phase_function
- (struct salgae_estimator* estimator,
- const size_t iscattering_angle,
- struct salgae_estimator_status* status);
-
-END_DECLS
-
-#endif /* SALGAE_H */
-
diff --git a/src/salgae_device.c b/src/salgae_device.c
@@ -1,143 +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 "salgae.h"
-#include "salgae_device.h"
-
-#include <rsys/logger.h>
-#include <rsys/mem_allocator.h>
-
-#include <star/s3d.h>
-
-#include <stdarg.h>
-
-/*******************************************************************************
- * Helper function
- ******************************************************************************/
-static void
-device_release(ref_T* ref)
-{
- struct salgae_device* dev;
- ASSERT(ref);
- dev = CONTAINER_OF(ref, struct salgae_device, ref);
- if(dev) S3D(device_ref_put(dev->s3d));
- MEM_RM(dev->allocator, dev);
-}
-
-/*******************************************************************************
- * Local functions
- ******************************************************************************/
-void
-log_error(struct salgae_device* dev, const char* msg, ...)
-{
- va_list vargs_list;
- ASSERT(dev && msg);
- if(dev->verbose) {
- res_T res; (void)res;
- va_start(vargs_list, msg);
- res = logger_vprint(dev->logger, LOG_ERROR, msg, vargs_list);
- ASSERT(res == RES_OK);
- va_end(vargs_list);
- }
-}
-
-
-/*******************************************************************************
- * API functions
- ******************************************************************************/
-res_T
-salgae_device_create
- (struct logger* log,
- struct mem_allocator* allocator,
- const int verbose,
- struct s3d_device* s3d,
- struct salgae_device** out_dev)
-{
- struct mem_allocator* mem_allocator;
- struct salgae_device* dev = NULL;
- struct logger* logger = NULL;
- res_T res = RES_OK;
-
- if(!out_dev) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- mem_allocator = allocator ? allocator : &mem_default_allocator;
- logger = log ? log : LOGGER_DEFAULT;
-
- dev = MEM_CALLOC(mem_allocator, 1, sizeof(struct salgae_device));
- if(!dev) {
- log_error(dev, "Couldn't allocate the Star-Algae device.\n");
- res = RES_MEM_ERR;
- goto error;
- }
- ref_init(&dev->ref);
- dev->allocator = mem_allocator;
- dev->logger = logger;
- dev->verbose = verbose;
-
- if(s3d) {
- S3D(device_ref_get(s3d));
- dev->s3d = s3d;
- } else {
- res = s3d_device_create(dev->logger, dev->allocator, verbose, &dev->s3d);
- if(res != RES_OK) {
- log_error
- (dev, "Couldn't create the internal Star-3D device of Star-Algea.\n");
- goto error;
- }
- }
-
-exit:
- if(out_dev) *out_dev = dev;
- return res;
-error:
- if(dev) {
- SALGAE(device_ref_put(dev));
- dev = NULL;
- }
- goto exit;
-}
-
-res_T
-salgae_device_ref_get(struct salgae_device* dev)
-{
- if(!dev) return RES_BAD_ARG;
- ref_get(&dev->ref);
- return RES_OK;
-}
-
-res_T
-salgae_device_ref_put(struct salgae_device* dev)
-{
- if(!dev) return RES_BAD_ARG;
- ref_put(&dev->ref, device_release);
- return RES_OK;
-}
-
diff --git a/src/salgae_device.h b/src/salgae_device.h
@@ -1,57 +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 SALGAE_DEVICE_H
-#define SALGAE_DEVICE_H
-
-#include <rsys/ref_count.h>
-
-struct logger;
-struct mem_allocator;
-struct s3d_device;
-
-struct salgae_device {
- int verbose;
- struct logger* logger;
- struct s3d_device* s3d;
-
- struct mem_allocator* allocator;
- ref_T ref;
-};
-
-extern LOCAL_SYM void
-log_error
- (struct salgae_device* dev,
- const char* msg,
- ...)
-#ifdef COMPILER_GCC
- __attribute((format(printf, 2, 3)))
-#endif
-;
-#endif /* SALGAE_DEVICE_H */
-
diff --git a/src/salgae_estimator.c b/src/salgae_estimator.c
@@ -1,395 +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 "salgae.h"
-#include "salgae_device.h"
-
-#include <rsys/float2.h>
-#include <rsys/float3.h>
-#include <rsys/image.h>
-#include <rsys/logger.h>
-#include <rsys/mem_allocator.h>
-#include <rsys/stretchy_array.h>
-
-#include <star/s3d.h>
-#include <star/ssp.h>
-
-#define NDIRS 1 /* # Sampled directions */
-
-struct salgae_estimator {
- size_t nsteps;
- double wavelength;
-
- struct salgae_device* dev;
- ref_T ref;
-};
-
-/*******************************************************************************
- * Helper functions
- ******************************************************************************/
-static FINLINE uint16_t
-morton2D_decode(const uint32_t u32)
-{
- uint32_t x = u32 & 0x55555555;
- x = (x | (x >> 1)) & 0x33333333;
- x = (x | (x >> 2)) & 0x0F0F0F0F;
- x = (x | (x >> 4)) & 0x00FF00FF;
- x = (x | (x >> 8)) & 0x0000FFFF;
- return (uint16_t)x;
-}
-
-/* Compute an orthonormal basis where `dir' is the Z axis */
-static void
-build_basis(const float dir[3], float basis[9])
-{
- float dir_abs[3];
- float axis_min[3];
- int i;
- ASSERT(dir && basis && f3_is_normalized(dir));
-
- /* Define which axis direction is minimal and use its unit vector to compute
- * a vector ortogonal to `dir'. This ensures that the unit vector and `dir'
- * are not colinear and thus that their cross product is not a zero vector */
- FOR_EACH(i, 0, 3) dir_abs[i] = absf(dir[i]);
- if(dir_abs[0] < dir_abs[1]) {
- if(dir_abs[0] < dir_abs[2]) f3(axis_min, 1.f, 0.f, 0.f);
- else f3(axis_min, 0.f, 0.f, 1.f);
- } else {
- if(dir_abs[1] < dir_abs[2]) f3(axis_min, 0.f, 1.f, 0.f);
- else f3(axis_min, 0.f, 0.f, 1.f);
- }
-
- f3_normalize(basis + 0, f3_cross(basis + 0, dir, axis_min));
- f3_cross(basis + 3, dir, basis + 0);
- f3_set(basis + 6, dir);
-}
-
-/* Compute a 3x4 affine transformation from a orthonormal basis and the
- * position of the origin */
-static FINLINE void
-build_transform
- (const float pos[3], /* Position of the origin */
- const float basis[9], /* Column major */
- float transform[12]) /* Column major */
-{
- ASSERT(pos && basis && transform);
-
- /* The linear part of the transformamatrix is the inverse of the
- * orthonormal basis (i.e. its transpose) */
- f3(transform + 0, basis[0], basis[3], basis[6]);
- f3(transform + 3, basis[1], basis[4], basis[7]);
- f3(transform + 6, basis[2], basis[5], basis[8]);
-
- /* Affine part of the transform matrix */
- transform[9 ] = -f3_dot(basis+0, pos);
- transform[10] = -f3_dot(basis+3, pos);
- transform[11] = -f3_dot(basis+6, pos);
-}
-
-/* Cast rays into the RT volume */
-static void
-draw_thumbnail
- (struct s3d_scene* scn,
- const float basis[9], /* World space basis of the RT volume */
- const float pos[3], /* World space centroid of the RT volume */
- const float lower[3], /* Lower boundary of the RT volume */
- const float upper[3], /* Upper boundary of the RT volume */
- const char* name) /* Filename of the thumbnail */
-{
-#define DEFINITION 128
- STATIC_ASSERT(IS_POW2(DEFINITION), Invalid_thumbnail_definition);
- const float range[2] = { 0, FLT_MAX };
- const float pixel_size = 1.f/(float)DEFINITION;
- float axis_x[3], axis_y[3], axis_z[3];
- float plane_size[2];
- float ray_org[3];
- float org[3];
- uint32_t npixels = (uint32_t)(DEFINITION * DEFINITION);
- uint32_t mcode;
- unsigned char* img = NULL;
- ASSERT(basis && pos && lower && upper);
-
- /* Allocate the thumbnail buffer */
- img = sa_add(img, DEFINITION*DEFINITION);
- ASSERT(img != NULL);
-
- /* Define the projection axis */
- f2_sub(plane_size, upper, lower);
- f3_mulf(axis_x, basis + 0, plane_size[0] * 0.5f);
- f3_mulf(axis_y, basis + 3, plane_size[1] * 0.5f);
- f3_set(axis_z, basis + 6);
-
- /* Compute the origin of the projection plane */
- f3_add(org, pos, f3_mulf(org, axis_z, lower[2]));
-
- FOR_EACH(mcode, 0, npixels) {
- struct s3d_hit hit;
- size_t ipixel;
- float sample[2], x[3], y[3];
- uint16_t ipixel_x, ipixel_y;
-
- /* Compute the sample position in [0, 1)^2 onto the projection plane */
- ipixel_x = morton2D_decode(mcode);
- ipixel_y = morton2D_decode(mcode>>1);
- sample[0] = ((float)ipixel_x + 0.5f) * pixel_size;
- sample[1] = ((float)ipixel_y + 0.5f) * pixel_size;
-
- /* Compute the ray origin */
- f3_mulf(x, axis_x, sample[0]*2.f - 1.f);
- f3_mulf(y, axis_y, sample[1]*2.f - 1.f);
- f3_add(ray_org, f3_add(ray_org, x, y), org);
-
- S3D(scene_trace_ray(scn, ray_org, axis_z, range, &hit));
-
- /* Simple shading */
- ipixel = (size_t)(ipixel_y * DEFINITION + ipixel_x);
- if(S3D_HIT_NONE(&hit)) {
- img[ipixel] = 0;
- } else {
- float N[3] = {0.f,0.f,0.f};
- float cosine;
- f3_normalize(N, hit.normal);
- if(0 > (cosine = f3_dot(N, axis_z))) {
- cosine = f3_dot(f3_minus(N, N), axis_z);
- }
- img[ipixel] = (unsigned char)(cosine*255.f + 0.5f/*Round*/);
- }
- }
- image_ppm_write(name, DEFINITION, DEFINITION, 1, img);
- sa_release(img);
-#undef DEFINITION
-}
-
-static res_T
-radiative_path_length
- (struct salgae_device* dev,
- struct ssp_rng* rng,
- struct salgae_integrator_desc* desc,
- const int istep)
-{
- struct s3d_shape* shape = NULL;
- struct s3d_scene* scene = NULL;
- struct salgae_material material = SALGAE_NULL_MATERIAL;
- int idir;
- res_T res = RES_OK;
- ASSERT(dev && rng && desc);
-
- res = s3d_shape_create_mesh(dev->s3d, &shape);
- if(res != RES_OK) {
- log_error(dev, "Couldn't create the Star-3D Algae shape.\n");
- goto error;
- }
- res = s3d_scene_create(dev->s3d, &scene);
- if(res != RES_OK) {
- log_error(dev, "Couldn't create the Star-3D Algae scene.\n");
- goto error;
- }
- res = s3d_scene_attach_shape(scene, shape);
- if(res != RES_OK) {
- log_error(dev,
- "Couldn't attach the Star-3D Algae shape to the Star-3D Algae scene.\n");
- goto error;
- }
-
- res = desc->sample_geometry(rng, &material, shape, desc->sampler_context);
- if(res != RES_OK) {
- log_error(dev, "Error in sampling an Algea geometry.\n");
- goto error;
- }
-
- S3D(scene_begin_session(scene, S3D_TRACE));
- FOR_EACH(idir, 0, NDIRS) {
- char thumb_name[64];
- float dir[4];
- float centroid[3];
- float basis[9];
- float lower[3], upper[3];
- float transform[12];
- float pt[8][3];
- int i;
-
- ssp_ran_sphere_uniform(rng, dir);
- S3D(scene_get_aabb(scene, lower, upper));
-
- /* AABB vertex layout
- * 6-------7
- * /' /|
- * 2-------3 |
- * | 4.....|.5
- * |, |/
- * 0-------1 */
- f3(pt[0], lower[0], lower[1], lower[2]);
- f3(pt[1], upper[0], lower[1], lower[2]);
- f3(pt[2], lower[0], upper[1], lower[2]);
- f3(pt[3], upper[0], upper[1], lower[2]);
- f3(pt[4], lower[0], lower[1], upper[2]);
- f3(pt[5], upper[0], lower[1], upper[2]);
- f3(pt[6], lower[0], upper[1], upper[2]);
- f3(pt[7], upper[0], upper[1], upper[2]);
-
- /* Build the transformation matrix from world to footprint space. Use the
- * AABB centroid as the origin of the footprint space. */
- f3_mulf(centroid, f3_add(centroid, lower, upper), 0.5f);
- build_basis(dir, basis);
- build_transform(centroid, basis, transform);
-
- /* Transform the AABB from world to footprint space */
- FOR_EACH(i, 0, 8) {
- f3_add(pt[i], f33_mulf3(pt[i], transform, pt[i]), transform + 9);
- }
-
- /* Compute the AABB of the footprint */
- f3_splat(lower, FLT_MAX); f3_splat(upper,-FLT_MAX);
- FOR_EACH(i, 0, 8) {
- f3_min(lower, lower, pt[i]);
- f3_max(upper, upper, pt[i]);
- }
-
- /* Compute an image of the shape transformed in the footprint space */
- sprintf(thumb_name, "%d_%d.ppm", istep, idir);
- draw_thumbnail(scene, basis, centroid, lower, upper, thumb_name);
- }
- S3D(scene_end_session(scene));
-
-exit:
- if(scene) S3D(scene_ref_put(scene));
- if(shape) S3D(shape_ref_put(shape));
- return res;
-error:
- goto exit;
-}
-
-static char
-check_desc(struct salgae_integrator_desc* desc)
-{
- ASSERT(desc);
- return desc->sample_geometry
- && desc->scattering_angles_count;
-}
-
-static void
-estimator_release(ref_T* ref)
-{
- struct salgae_estimator* estimator;
- struct salgae_device* dev;
- ASSERT(ref);
- estimator = CONTAINER_OF(ref, struct salgae_estimator, ref);
- dev = estimator->dev;
- MEM_RM(dev->allocator, estimator);
- SALGAE(device_ref_put(dev));
-}
-
-static res_T
-estimator_create
- (struct salgae_device* dev, struct salgae_estimator** out_estimator)
-{
- struct salgae_estimator* estimator = NULL;
- res_T res = RES_OK;
- ASSERT(dev && out_estimator);
-
- estimator = MEM_CALLOC(dev->allocator, 1, sizeof(struct salgae_estimator));
- if(!estimator) {
- log_error
- (dev, "Not enough memory: couldn't allocate the Star-Algea estimator.\n");
- res = RES_MEM_ERR;
- goto error;
- }
- ref_init(&estimator->ref);
- SALGAE(device_ref_get(dev));
- estimator->dev = dev;
-
-exit:
- *out_estimator = estimator;
- return res;
-error:
- if(estimator) {
- SALGAE(estimator_ref_put(estimator));
- estimator = NULL;
- }
- goto exit;
-}
-
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-salgae_integrate
- (struct salgae_device* dev,
- struct ssp_rng* rng,
- struct salgae_integrator_desc* desc,
- const double wavelength, /* Wavelength to integrate */
- const size_t steps_count, /* #realisations */
- struct salgae_estimator** out_estimator)
-{
- struct salgae_estimator* estimator = NULL;
- int i;
- res_T res = RES_OK;
-
- if(!dev || !rng || !desc || !check_desc(desc) || wavelength < 0.0
- || !steps_count || !out_estimator) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- res = estimator_create(dev, &estimator);
- if(res != RES_OK) goto error;
- estimator->nsteps = steps_count;
- estimator->wavelength = wavelength;
-
- FOR_EACH(i, 0, (int)steps_count) {
- res = radiative_path_length(dev, rng, desc, i);
- if(res != RES_OK) goto error;
- }
-
-exit:
- if(out_estimator) *out_estimator = estimator;
- return res;
-error:
- if(estimator) {
- SALGAE(estimator_ref_put(estimator));
- estimator = NULL;
- }
- goto exit;
-}
-
-res_T
-salgae_estimator_ref_get(struct salgae_estimator* estimator)
-{
- if(!estimator) return RES_BAD_ARG;
- ref_get(&estimator->ref);
- return RES_OK;
-}
-
-res_T
-salgae_estimator_ref_put(struct salgae_estimator* estimator)
-{
- if(!estimator) return RES_BAD_ARG;
- ref_put(&estimator->ref, estimator_release);
- return RES_OK;
-}
-
diff --git a/src/sschiff.h b/src/sschiff.h
@@ -0,0 +1,155 @@
+/* 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 SSCHIFF_H
+#define SSCHIFF_H
+
+#include <rsys/rsys.h>
+
+/* Library symbol management */
+#if defined(SSCHIFF_SHARED_BUILD) /* Build shared library */
+ #define SSCHIFF_API extern EXPORT_SYM
+#elif defined(SSCHIFF_STATIC) /* Use/build static library */
+ #define SSCHIFF_API extern LOCAL_SYM
+#else /* Use shared library */
+ #define SSCHIFF_API extern IMPORT_SYM
+#endif
+
+/* Helper macro that asserts if the invocation of the sgf function `Func'
+ * returns an error. One should use this macro on sschiff function calls for
+ * which no explicit error checking is performed */
+#ifndef NDEBUG
+ #define SSCHIFF(Func) ASSERT(sschiff_ ## Func == RES_OK)
+#else
+ #define SSCHIFF(Func) sschiff_ ## Func
+#endif
+
+/* Forward declaration of external types */
+struct mem_allocator;
+struct logger;
+struct s3d_device;
+struct s3d_shape;
+struct ssp_rng;
+
+struct sschiff_refractive_index { double real, imag; };
+
+struct sschiff_material {
+ /* Retrieve the refractive complex index of the material */
+ void (*get_refractive_index)
+ (void* material,
+ const double wavelength,
+ struct sschiff_refractive_index* value);
+ void* material; /* Opaque user defined representation of the material */
+};
+
+static const struct sschiff_material SSCHIFF_NULL_MATERIAL = { NULL, NULL };
+
+struct sschiff_integrator_desc {
+ res_T (*sample_geometry) /* Sample a geometry i.e. a shape and its material */
+ (struct ssp_rng* rng,
+ struct sschiff_material* mtl, /* Sampled material */
+ struct s3d_shape* shape, /* Sampled shape */
+ void* sampler_context);
+ void* sampler_context;
+ size_t scattering_angles_count; /* # of scattering angles to handle */
+};
+
+static const struct sschiff_integrator_desc SSCHIFF_NULL_INTEGRATOR_DESC = {
+ NULL, NULL, 0
+};
+
+/* Result of the Monte Carlo estimation */
+struct sschiff_estimator_status {
+ double E; /* Expected value */
+ double V; /* Variance */
+ double SE; /* Standard error */
+ size_t nsteps;
+};
+
+/* Opaque types */
+struct sschiff_device;
+struct sschiff_estimator;
+
+/*******************************************************************************
+ * Star Schiff API
+ ******************************************************************************/
+BEGIN_DECLS
+
+SSCHIFF_API res_T
+sschiff_device_create
+ (struct logger* logger, /* May be NULL <=> use default logger */
+ struct mem_allocator* allocator, /* May be NULL <=> use default allocator */
+ const int verbose,
+ struct s3d_device* s3d, /* May be NULL <=> internally create a S3D device */
+ struct sschiff_device** dev);
+
+SSCHIFF_API res_T
+sschiff_device_ref_get
+ (struct sschiff_device* dev);
+
+SSCHIFF_API res_T
+sschiff_device_ref_put
+ (struct sschiff_device* dev);
+
+SSCHIFF_API res_T
+sschiff_integrate
+ (struct sschiff_device* dev,
+ struct ssp_rng* rng,
+ struct sschiff_integrator_desc* desc,
+ const double wavelength, /* Wavelength to integrate */
+ const size_t steps_count, /* #realisations */
+ struct sschiff_estimator** estimator);
+
+SSCHIFF_API res_T
+sschiff_estimator_ref_get
+ (struct sschiff_estimator* estimator);
+
+SSCHIFF_API res_T
+sschiff_estimator_ref_put
+ (struct sschiff_estimator* estimator);
+
+SSCHIFF_API res_T
+sschiff_estimator_get_extinction_cross_section
+ (struct sschiff_estimator* estimator,
+ struct sschiff_estimator_status* status);
+
+SSCHIFF_API res_T
+sschiff_estimator_get_absorption_cross_section
+ (struct sschiff_estimator* estimator,
+ struct sschiff_estimator_status* status);
+
+SSCHIFF_API res_T
+sschiff_estimator_get_phase_function
+ (struct sschiff_estimator* estimator,
+ const size_t iscattering_angle,
+ struct sschiff_estimator_status* status);
+
+END_DECLS
+
+#endif /* SSCHIFF_H */
+
diff --git a/src/sschiff_device.c b/src/sschiff_device.c
@@ -0,0 +1,143 @@
+/* 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 "sschiff.h"
+#include "sschiff_device.h"
+
+#include <rsys/logger.h>
+#include <rsys/mem_allocator.h>
+
+#include <star/s3d.h>
+
+#include <stdarg.h>
+
+/*******************************************************************************
+ * Helper function
+ ******************************************************************************/
+static void
+device_release(ref_T* ref)
+{
+ struct sschiff_device* dev;
+ ASSERT(ref);
+ dev = CONTAINER_OF(ref, struct sschiff_device, ref);
+ if(dev) S3D(device_ref_put(dev->s3d));
+ MEM_RM(dev->allocator, dev);
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+void
+log_error(struct sschiff_device* dev, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(dev && msg);
+ if(dev->verbose) {
+ res_T res; (void)res;
+ va_start(vargs_list, msg);
+ res = logger_vprint(dev->logger, LOG_ERROR, msg, vargs_list);
+ ASSERT(res == RES_OK);
+ va_end(vargs_list);
+ }
+}
+
+
+/*******************************************************************************
+ * API functions
+ ******************************************************************************/
+res_T
+sschiff_device_create
+ (struct logger* log,
+ struct mem_allocator* allocator,
+ const int verbose,
+ struct s3d_device* s3d,
+ struct sschiff_device** out_dev)
+{
+ struct mem_allocator* mem_allocator;
+ struct sschiff_device* dev = NULL;
+ struct logger* logger = NULL;
+ res_T res = RES_OK;
+
+ if(!out_dev) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ mem_allocator = allocator ? allocator : &mem_default_allocator;
+ logger = log ? log : LOGGER_DEFAULT;
+
+ dev = MEM_CALLOC(mem_allocator, 1, sizeof(struct sschiff_device));
+ if(!dev) {
+ log_error(dev, "Couldn't allocate the Star-Schiff device.\n");
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&dev->ref);
+ dev->allocator = mem_allocator;
+ dev->logger = logger;
+ dev->verbose = verbose;
+
+ if(s3d) {
+ S3D(device_ref_get(s3d));
+ dev->s3d = s3d;
+ } else {
+ res = s3d_device_create(dev->logger, dev->allocator, verbose, &dev->s3d);
+ if(res != RES_OK) {
+ log_error
+ (dev, "Couldn't create the internal Star-3D device of Star-Schiff.\n");
+ goto error;
+ }
+ }
+
+exit:
+ if(out_dev) *out_dev = dev;
+ return res;
+error:
+ if(dev) {
+ SSCHIFF(device_ref_put(dev));
+ dev = NULL;
+ }
+ goto exit;
+}
+
+res_T
+sschiff_device_ref_get(struct sschiff_device* dev)
+{
+ if(!dev) return RES_BAD_ARG;
+ ref_get(&dev->ref);
+ return RES_OK;
+}
+
+res_T
+sschiff_device_ref_put(struct sschiff_device* dev)
+{
+ if(!dev) return RES_BAD_ARG;
+ ref_put(&dev->ref, device_release);
+ return RES_OK;
+}
+
diff --git a/src/sschiff_device.h b/src/sschiff_device.h
@@ -0,0 +1,57 @@
+/* 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 SSCHIFF_DEVICE_H
+#define SSCHIFF_DEVICE_H
+
+#include <rsys/ref_count.h>
+
+struct logger;
+struct mem_allocator;
+struct s3d_device;
+
+struct sschiff_device {
+ int verbose;
+ struct logger* logger;
+ struct s3d_device* s3d;
+
+ struct mem_allocator* allocator;
+ ref_T ref;
+};
+
+extern LOCAL_SYM void
+log_error
+ (struct sschiff_device* dev,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+#endif /* SSCHIFF_DEVICE_H */
+
diff --git a/src/sschiff_estimator.c b/src/sschiff_estimator.c
@@ -0,0 +1,395 @@
+/* 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 "sschiff.h"
+#include "sschiff_device.h"
+
+#include <rsys/float2.h>
+#include <rsys/float3.h>
+#include <rsys/image.h>
+#include <rsys/logger.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/stretchy_array.h>
+
+#include <star/s3d.h>
+#include <star/ssp.h>
+
+#define NDIRS 1 /* # Sampled directions */
+
+struct sschiff_estimator {
+ size_t nsteps;
+ double wavelength;
+
+ struct sschiff_device* dev;
+ ref_T ref;
+};
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static FINLINE uint16_t
+morton2D_decode(const uint32_t u32)
+{
+ uint32_t x = u32 & 0x55555555;
+ x = (x | (x >> 1)) & 0x33333333;
+ x = (x | (x >> 2)) & 0x0F0F0F0F;
+ x = (x | (x >> 4)) & 0x00FF00FF;
+ x = (x | (x >> 8)) & 0x0000FFFF;
+ return (uint16_t)x;
+}
+
+/* Compute an orthonormal basis where `dir' is the Z axis */
+static void
+build_basis(const float dir[3], float basis[9])
+{
+ float dir_abs[3];
+ float axis_min[3];
+ int i;
+ ASSERT(dir && basis && f3_is_normalized(dir));
+
+ /* Define which axis direction is minimal and use its unit vector to compute
+ * a vector ortogonal to `dir'. This ensures that the unit vector and `dir'
+ * are not colinear and thus that their cross product is not a zero vector */
+ FOR_EACH(i, 0, 3) dir_abs[i] = absf(dir[i]);
+ if(dir_abs[0] < dir_abs[1]) {
+ if(dir_abs[0] < dir_abs[2]) f3(axis_min, 1.f, 0.f, 0.f);
+ else f3(axis_min, 0.f, 0.f, 1.f);
+ } else {
+ if(dir_abs[1] < dir_abs[2]) f3(axis_min, 0.f, 1.f, 0.f);
+ else f3(axis_min, 0.f, 0.f, 1.f);
+ }
+
+ f3_normalize(basis + 0, f3_cross(basis + 0, dir, axis_min));
+ f3_cross(basis + 3, dir, basis + 0);
+ f3_set(basis + 6, dir);
+}
+
+/* Compute a 3x4 affine transformation from a orthonormal basis and the
+ * position of the origin */
+static FINLINE void
+build_transform
+ (const float pos[3], /* Position of the origin */
+ const float basis[9], /* Column major */
+ float transform[12]) /* Column major */
+{
+ ASSERT(pos && basis && transform);
+
+ /* The linear part of the transformamatrix is the inverse of the
+ * orthonormal basis (i.e. its transpose) */
+ f3(transform + 0, basis[0], basis[3], basis[6]);
+ f3(transform + 3, basis[1], basis[4], basis[7]);
+ f3(transform + 6, basis[2], basis[5], basis[8]);
+
+ /* Affine part of the transform matrix */
+ transform[9 ] = -f3_dot(basis+0, pos);
+ transform[10] = -f3_dot(basis+3, pos);
+ transform[11] = -f3_dot(basis+6, pos);
+}
+
+/* Cast rays into the RT volume */
+static void
+draw_thumbnail
+ (struct s3d_scene* scn,
+ const float basis[9], /* World space basis of the RT volume */
+ const float pos[3], /* World space centroid of the RT volume */
+ const float lower[3], /* Lower boundary of the RT volume */
+ const float upper[3], /* Upper boundary of the RT volume */
+ const char* name) /* Filename of the thumbnail */
+{
+#define DEFINITION 128
+ STATIC_ASSERT(IS_POW2(DEFINITION), Invalid_thumbnail_definition);
+ const float range[2] = { 0, FLT_MAX };
+ const float pixel_size = 1.f/(float)DEFINITION;
+ float axis_x[3], axis_y[3], axis_z[3];
+ float plane_size[2];
+ float ray_org[3];
+ float org[3];
+ uint32_t npixels = (uint32_t)(DEFINITION * DEFINITION);
+ uint32_t mcode;
+ unsigned char* img = NULL;
+ ASSERT(basis && pos && lower && upper);
+
+ /* Allocate the thumbnail buffer */
+ img = sa_add(img, DEFINITION*DEFINITION);
+ ASSERT(img != NULL);
+
+ /* Define the projection axis */
+ f2_sub(plane_size, upper, lower);
+ f3_mulf(axis_x, basis + 0, plane_size[0] * 0.5f);
+ f3_mulf(axis_y, basis + 3, plane_size[1] * 0.5f);
+ f3_set(axis_z, basis + 6);
+
+ /* Compute the origin of the projection plane */
+ f3_add(org, pos, f3_mulf(org, axis_z, lower[2]));
+
+ FOR_EACH(mcode, 0, npixels) {
+ struct s3d_hit hit;
+ size_t ipixel;
+ float sample[2], x[3], y[3];
+ uint16_t ipixel_x, ipixel_y;
+
+ /* Compute the sample position in [0, 1)^2 onto the projection plane */
+ ipixel_x = morton2D_decode(mcode);
+ ipixel_y = morton2D_decode(mcode>>1);
+ sample[0] = ((float)ipixel_x + 0.5f) * pixel_size;
+ sample[1] = ((float)ipixel_y + 0.5f) * pixel_size;
+
+ /* Compute the ray origin */
+ f3_mulf(x, axis_x, sample[0]*2.f - 1.f);
+ f3_mulf(y, axis_y, sample[1]*2.f - 1.f);
+ f3_add(ray_org, f3_add(ray_org, x, y), org);
+
+ S3D(scene_trace_ray(scn, ray_org, axis_z, range, &hit));
+
+ /* Simple shading */
+ ipixel = (size_t)(ipixel_y * DEFINITION + ipixel_x);
+ if(S3D_HIT_NONE(&hit)) {
+ img[ipixel] = 0;
+ } else {
+ float N[3] = {0.f,0.f,0.f};
+ float cosine;
+ f3_normalize(N, hit.normal);
+ if(0 > (cosine = f3_dot(N, axis_z))) {
+ cosine = f3_dot(f3_minus(N, N), axis_z);
+ }
+ img[ipixel] = (unsigned char)(cosine*255.f + 0.5f/*Round*/);
+ }
+ }
+ image_ppm_write(name, DEFINITION, DEFINITION, 1, img);
+ sa_release(img);
+#undef DEFINITION
+}
+
+static res_T
+radiative_path_length
+ (struct sschiff_device* dev,
+ struct ssp_rng* rng,
+ struct sschiff_integrator_desc* desc,
+ const int istep)
+{
+ struct s3d_shape* shape = NULL;
+ struct s3d_scene* scene = NULL;
+ struct sschiff_material material = SSCHIFF_NULL_MATERIAL;
+ int idir;
+ res_T res = RES_OK;
+ ASSERT(dev && rng && desc);
+
+ res = s3d_shape_create_mesh(dev->s3d, &shape);
+ if(res != RES_OK) {
+ log_error(dev, "Couldn't create the Star-3D Schiff shape.\n");
+ goto error;
+ }
+ res = s3d_scene_create(dev->s3d, &scene);
+ if(res != RES_OK) {
+ log_error(dev, "Couldn't create the Star-3D Schiff scene.\n");
+ goto error;
+ }
+ res = s3d_scene_attach_shape(scene, shape);
+ if(res != RES_OK) {
+ log_error(dev,
+ "Couldn't attach the Star-3D Schiff shape to the Star-3D Schiff scene.\n");
+ goto error;
+ }
+
+ res = desc->sample_geometry(rng, &material, shape, desc->sampler_context);
+ if(res != RES_OK) {
+ log_error(dev, "Error in sampling a Schiff geometry.\n");
+ goto error;
+ }
+
+ S3D(scene_begin_session(scene, S3D_TRACE));
+ FOR_EACH(idir, 0, NDIRS) {
+ char thumb_name[64];
+ float dir[4];
+ float centroid[3];
+ float basis[9];
+ float lower[3], upper[3];
+ float transform[12];
+ float pt[8][3];
+ int i;
+
+ ssp_ran_sphere_uniform(rng, dir);
+ S3D(scene_get_aabb(scene, lower, upper));
+
+ /* AABB vertex layout
+ * 6-------7
+ * /' /|
+ * 2-------3 |
+ * | 4.....|.5
+ * |, |/
+ * 0-------1 */
+ f3(pt[0], lower[0], lower[1], lower[2]);
+ f3(pt[1], upper[0], lower[1], lower[2]);
+ f3(pt[2], lower[0], upper[1], lower[2]);
+ f3(pt[3], upper[0], upper[1], lower[2]);
+ f3(pt[4], lower[0], lower[1], upper[2]);
+ f3(pt[5], upper[0], lower[1], upper[2]);
+ f3(pt[6], lower[0], upper[1], upper[2]);
+ f3(pt[7], upper[0], upper[1], upper[2]);
+
+ /* Build the transformation matrix from world to footprint space. Use the
+ * AABB centroid as the origin of the footprint space. */
+ f3_mulf(centroid, f3_add(centroid, lower, upper), 0.5f);
+ build_basis(dir, basis);
+ build_transform(centroid, basis, transform);
+
+ /* Transform the AABB from world to footprint space */
+ FOR_EACH(i, 0, 8) {
+ f3_add(pt[i], f33_mulf3(pt[i], transform, pt[i]), transform + 9);
+ }
+
+ /* Compute the AABB of the footprint */
+ f3_splat(lower, FLT_MAX); f3_splat(upper,-FLT_MAX);
+ FOR_EACH(i, 0, 8) {
+ f3_min(lower, lower, pt[i]);
+ f3_max(upper, upper, pt[i]);
+ }
+
+ /* Compute an image of the shape transformed in the footprint space */
+ sprintf(thumb_name, "%d_%d.ppm", istep, idir);
+ draw_thumbnail(scene, basis, centroid, lower, upper, thumb_name);
+ }
+ S3D(scene_end_session(scene));
+
+exit:
+ if(scene) S3D(scene_ref_put(scene));
+ if(shape) S3D(shape_ref_put(shape));
+ return res;
+error:
+ goto exit;
+}
+
+static char
+check_desc(struct sschiff_integrator_desc* desc)
+{
+ ASSERT(desc);
+ return desc->sample_geometry
+ && desc->scattering_angles_count;
+}
+
+static void
+estimator_release(ref_T* ref)
+{
+ struct sschiff_estimator* estimator;
+ struct sschiff_device* dev;
+ ASSERT(ref);
+ estimator = CONTAINER_OF(ref, struct sschiff_estimator, ref);
+ dev = estimator->dev;
+ MEM_RM(dev->allocator, estimator);
+ SSCHIFF(device_ref_put(dev));
+}
+
+static res_T
+estimator_create
+ (struct sschiff_device* dev, struct sschiff_estimator** out_estimator)
+{
+ struct sschiff_estimator* estimator = NULL;
+ res_T res = RES_OK;
+ ASSERT(dev && out_estimator);
+
+ estimator = MEM_CALLOC(dev->allocator, 1, sizeof(struct sschiff_estimator));
+ if(!estimator) {
+ log_error
+ (dev, "Not enough memory: couldn't allocate the Star-Schiff estimator.\n");
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&estimator->ref);
+ SSCHIFF(device_ref_get(dev));
+ estimator->dev = dev;
+
+exit:
+ *out_estimator = estimator;
+ return res;
+error:
+ if(estimator) {
+ SSCHIFF(estimator_ref_put(estimator));
+ estimator = NULL;
+ }
+ goto exit;
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+sschiff_integrate
+ (struct sschiff_device* dev,
+ struct ssp_rng* rng,
+ struct sschiff_integrator_desc* desc,
+ const double wavelength, /* Wavelength to integrate */
+ const size_t steps_count, /* #realisations */
+ struct sschiff_estimator** out_estimator)
+{
+ struct sschiff_estimator* estimator = NULL;
+ int i;
+ res_T res = RES_OK;
+
+ if(!dev || !rng || !desc || !check_desc(desc) || wavelength < 0.0
+ || !steps_count || !out_estimator) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = estimator_create(dev, &estimator);
+ if(res != RES_OK) goto error;
+ estimator->nsteps = steps_count;
+ estimator->wavelength = wavelength;
+
+ FOR_EACH(i, 0, (int)steps_count) {
+ res = radiative_path_length(dev, rng, desc, i);
+ if(res != RES_OK) goto error;
+ }
+
+exit:
+ if(out_estimator) *out_estimator = estimator;
+ return res;
+error:
+ if(estimator) {
+ SSCHIFF(estimator_ref_put(estimator));
+ estimator = NULL;
+ }
+ goto exit;
+}
+
+res_T
+sschiff_estimator_ref_get(struct sschiff_estimator* estimator)
+{
+ if(!estimator) return RES_BAD_ARG;
+ ref_get(&estimator->ref);
+ return RES_OK;
+}
+
+res_T
+sschiff_estimator_ref_put(struct sschiff_estimator* estimator)
+{
+ if(!estimator) return RES_BAD_ARG;
+ ref_put(&estimator->ref, estimator_release);
+ return RES_OK;
+}
+
diff --git a/src/test_salgae_device.c b/src/test_salgae_device.c
@@ -1,98 +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 "salgae.h"
-#include "test_salgae_utils.h"
-
-#include <rsys/logger.h>
-#include <rsys/mem_allocator.h>
-#include <rsys/rsys.h>
-
-#include <star/s3d.h>
-
-static void
-log_stream(const char* msg, void* ctx)
-{
- ASSERT(msg);
- (void)msg, (void)ctx;
- printf("%s\n", msg);
-}
-
-int
-main(int argc, char** argv)
-{
- struct logger logger;
- struct mem_allocator allocator;
- struct salgae_device* dev;
- struct s3d_device* s3d;
- (void)argc, (void)argv;
-
- CHECK(salgae_device_create(NULL, NULL, 0, NULL, NULL), RES_BAD_ARG);
- CHECK(salgae_device_create(NULL, NULL, 0, NULL, &dev), RES_OK);
-
- CHECK(salgae_device_ref_get(NULL), RES_BAD_ARG);
- CHECK(salgae_device_ref_get(dev), RES_OK);
- CHECK(salgae_device_ref_put(NULL), RES_BAD_ARG);
- CHECK(salgae_device_ref_put(dev), RES_OK);
- CHECK(salgae_device_ref_put(dev), RES_OK);
-
- mem_init_proxy_allocator(&allocator, &mem_default_allocator);
-
- CHECK(MEM_ALLOCATED_SIZE(&allocator), 0);
- CHECK(salgae_device_create(NULL, &allocator, 1, NULL, NULL), RES_BAD_ARG);
- CHECK(salgae_device_create(NULL, &allocator, 1, NULL, &dev), RES_OK);
- CHECK(salgae_device_ref_put(dev), RES_OK);
- CHECK(MEM_ALLOCATED_SIZE(&allocator), 0);
-
- CHECK(logger_init(&allocator, &logger), RES_OK);
- logger_set_stream(&logger, LOG_OUTPUT, log_stream, NULL);
- logger_set_stream(&logger, LOG_ERROR, log_stream, NULL);
- logger_set_stream(&logger, LOG_WARNING, log_stream, NULL);
-
- CHECK(salgae_device_create(&logger, NULL, 0, NULL, NULL), RES_BAD_ARG);
- CHECK(salgae_device_create(&logger, NULL, 0, NULL, &dev), RES_OK);
- CHECK(salgae_device_ref_put(dev), RES_OK);
-
- CHECK(salgae_device_create(&logger, &allocator, 1, NULL, NULL), RES_BAD_ARG);
- CHECK(salgae_device_create(&logger, &allocator, 1, NULL, &dev), RES_OK);
- CHECK(salgae_device_ref_put(dev), RES_OK);
-
- CHECK(s3d_device_create(NULL, NULL, 0, &s3d), RES_OK);
- CHECK(salgae_device_create(NULL, NULL, 0, s3d, NULL), RES_BAD_ARG);
- CHECK(salgae_device_create(NULL, NULL, 0, s3d, &dev), RES_OK);
-
- CHECK(s3d_device_ref_put(s3d), RES_OK);
- CHECK(salgae_device_ref_put(dev), RES_OK);
-
- logger_release(&logger);
- check_memory_allocator(&allocator);
- mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
- return 0;
-}
-
diff --git a/src/test_salgae_estimator.c b/src/test_salgae_estimator.c
@@ -1,203 +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 "salgae.h"
-#include "test_salgae_utils.h"
-
-#include <rsys/float3.h>
-
-#include <star/s3d.h>
-#include <star/ssp.h>
-
-#define STEP 0.05f
-
-enum { A, B, M, N0, N1, N2 };
-
-struct super_shape {
- float super_formulas[2][6];
- size_t ntheta, nphi;
-};
-
-static void
-super_shape_get_indices(const unsigned itri, unsigned ids[3], void* ctx)
-{
- struct super_shape* sshape = ctx;
- const size_t iquad = itri / 2;
- const size_t iquad_tri = itri % 2;
- const size_t i = iquad / (sshape->nphi - 1);
- const size_t j = iquad % (sshape->nphi - 1);
- size_t A, B;
-
- B = i * sshape->nphi + j + 1;
- A = ((i + 1) % sshape->ntheta) * sshape->nphi + j;
- if(iquad_tri == 0) {
- ids[0] = (unsigned)B - 1;
- ids[1] = (unsigned)A;
- ids[2] = (unsigned)B;
- } else { ASSERT(iquad_tri == 1);
- ids[0] = (unsigned)B;
- ids[1] = (unsigned)A;
- ids[2] = (unsigned)A + 1;
- }
-}
-
-static void
-super_shape_get_vertex_position(const unsigned ivert, float vertex[3], void* ctx)
-{
- struct super_shape* sshape = ctx;
- const size_t itheta = ivert / sshape->nphi;
- const size_t iphi = ivert % sshape->nphi;
- double angle[2];
- double sin_angle[2];
- double cos_angle[2];
- double uv[2];
- int iform;
- ASSERT(itheta < sshape->ntheta);
-
- if(iphi == sshape->nphi - 1) { /* Polar vertices: Force polar coordinates */
- angle[0] = PI;
- angle[1] = PI/2;
- } else {
- angle[0] = -PI + (double)itheta * STEP;
- angle[1] = -PI/2 + (double)iphi * STEP;
- }
-
- FOR_EACH(iform, 0, 2) {
- double m, k, g;
- float* form = sshape->super_formulas[iform];
- m = cos(form[M] * angle[iform] / 4.0);
- m = fabs(m) / form[A];
- k = sin(form[M] * angle[iform] / 4.0);
- k = fabs(k) / form[B];
- g = pow(m, form[N1]) + pow(k, form[N2]);
- uv[iform] = pow(g, (-1.0/form[N0]));
-
- cos_angle[iform] = cos(angle[iform]);
- sin_angle[iform] = sin(angle[iform]);
- }
-
- vertex[0] = (float)(uv[0] * cos_angle[0] * uv[1] * cos_angle[1]);
- vertex[1] = (float)(uv[0] * sin_angle[0] * uv[1] * cos_angle[1]);
- vertex[2] = (float)(uv[1] * sin_angle[1]);
-}
-
-static res_T
-sample_geometry
- (struct ssp_rng* rng,
- struct salgae_material* mtl,
- struct s3d_shape* shape,
- void* sampler_context)
-{
- struct s3d_vertex_data attrib;
- struct super_shape sshape;
- const size_t ntheta = (int)((2*PI)/STEP) + 1;
- const size_t nphi = (int)((PI)/STEP) + 1;
- const size_t nverts = ntheta * nphi;
- const size_t nprims = ntheta * (nphi - 1)/*#quads*/ * 2/*#triangles*/;
-
- (void)sampler_context;
-
- NCHECK(rng, NULL);
- NCHECK(mtl, NULL);
- NCHECK(shape, NULL);
-
- attrib.usage = S3D_POSITION;
- attrib.type = S3D_FLOAT3;
- attrib.get = super_shape_get_vertex_position;
-
- sshape.super_formulas[0][A] = 1;
- sshape.super_formulas[0][B] = 1;
- sshape.super_formulas[0][M] = (float)ssp_rng_uniform_double(rng, 0.1, 6);
- sshape.super_formulas[0][N0] = 1;
- sshape.super_formulas[0][N1] = 1;
- sshape.super_formulas[0][N2] = (float)ssp_rng_uniform_double(rng, 0.1, 6);
-
- sshape.super_formulas[1][A] = 1;
- sshape.super_formulas[1][B] = 1;
- sshape.super_formulas[1][M] = (float)ssp_rng_uniform_double(rng, 0.1, 6);
- sshape.super_formulas[1][N0] = 1;
- sshape.super_formulas[1][N1] = 1;
- sshape.super_formulas[1][N2] = (float)ssp_rng_uniform_double(rng, 0.1, 6);
-
- sshape.ntheta = ntheta;
- sshape.nphi = nphi;
-
- *mtl = SALGAE_NULL_MATERIAL;
- return s3d_mesh_setup_indexed_vertices(shape, (unsigned)nprims,
- super_shape_get_indices, (unsigned)nverts, &attrib, 1, &sshape);
-}
-
-int
-main(int argc, char** argv)
-{
- struct mem_allocator allocator;
- struct salgae_device* dev;
- struct salgae_estimator* estimator;
- struct salgae_integrator_desc desc = SALGAE_NULL_INTEGRATOR_DESC;
- struct ssp_rng* rng;
- (void)argc, (void)argv;
-
- mem_init_proxy_allocator(&allocator, &mem_default_allocator);
-
- CHECK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng), RES_OK);
- CHECK(salgae_device_create(NULL, &allocator, 0, NULL, &dev), RES_OK);
-
- desc.sample_geometry = sample_geometry;
- desc.scattering_angles_count = 1;
- CHECK(salgae_integrate(NULL, NULL, NULL, 0, 0, NULL), RES_BAD_ARG);
- CHECK(salgae_integrate(dev, NULL, NULL, 0, 0, NULL), RES_BAD_ARG);
- CHECK(salgae_integrate(NULL, rng, NULL, 0, 0, NULL), RES_BAD_ARG);
- CHECK(salgae_integrate(dev, rng, NULL, 0, 0, NULL), RES_BAD_ARG);
- CHECK(salgae_integrate(NULL, NULL, &desc, 0, 0, NULL), RES_BAD_ARG);
- CHECK(salgae_integrate(dev, NULL, &desc, 0, 0, NULL), RES_BAD_ARG);
- CHECK(salgae_integrate(NULL, rng, &desc, 0, 0, NULL), RES_BAD_ARG);
- CHECK(salgae_integrate(dev, rng, &desc, 0, 0, NULL), RES_BAD_ARG);
- CHECK(salgae_integrate(NULL, NULL, NULL, 0, 1, &estimator), RES_BAD_ARG);
- CHECK(salgae_integrate(dev, NULL, NULL, 0, 1, &estimator), RES_BAD_ARG);
- CHECK(salgae_integrate(NULL, rng, NULL, 0, 1, &estimator), RES_BAD_ARG);
- CHECK(salgae_integrate(dev, rng, NULL, 0, 1, &estimator), RES_BAD_ARG);
- CHECK(salgae_integrate(NULL, NULL, &desc, 0, 1, &estimator), RES_BAD_ARG);
- CHECK(salgae_integrate(dev, NULL, &desc, 0, 1, &estimator), RES_BAD_ARG);
- CHECK(salgae_integrate(NULL, rng, &desc, 0, 1, &estimator), RES_BAD_ARG);
- CHECK(salgae_integrate(dev, rng, &desc, 0, 100, &estimator), RES_OK);
-
- CHECK(salgae_estimator_ref_get(NULL), RES_BAD_ARG);
- CHECK(salgae_estimator_ref_get(estimator), RES_OK);
- CHECK(salgae_estimator_ref_put(NULL), RES_BAD_ARG);
- CHECK(salgae_estimator_ref_put(estimator), RES_OK);
- CHECK(salgae_estimator_ref_put(estimator), RES_OK);
-
- CHECK(salgae_device_ref_put(dev), RES_OK);
- CHECK(ssp_rng_ref_put(rng), RES_OK);
-
- check_memory_allocator(&allocator);
- mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
- return 0;
-}
-
diff --git a/src/test_sschiff_device.c b/src/test_sschiff_device.c
@@ -0,0 +1,98 @@
+/* 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 "sschiff.h"
+#include "test_sschiff_utils.h"
+
+#include <rsys/logger.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/rsys.h>
+
+#include <star/s3d.h>
+
+static void
+log_stream(const char* msg, void* ctx)
+{
+ ASSERT(msg);
+ (void)msg, (void)ctx;
+ printf("%s\n", msg);
+}
+
+int
+main(int argc, char** argv)
+{
+ struct logger logger;
+ struct mem_allocator allocator;
+ struct sschiff_device* dev;
+ struct s3d_device* s3d;
+ (void)argc, (void)argv;
+
+ CHECK(sschiff_device_create(NULL, NULL, 0, NULL, NULL), RES_BAD_ARG);
+ CHECK(sschiff_device_create(NULL, NULL, 0, NULL, &dev), RES_OK);
+
+ CHECK(sschiff_device_ref_get(NULL), RES_BAD_ARG);
+ CHECK(sschiff_device_ref_get(dev), RES_OK);
+ CHECK(sschiff_device_ref_put(NULL), RES_BAD_ARG);
+ CHECK(sschiff_device_ref_put(dev), RES_OK);
+ CHECK(sschiff_device_ref_put(dev), RES_OK);
+
+ mem_init_proxy_allocator(&allocator, &mem_default_allocator);
+
+ CHECK(MEM_ALLOCATED_SIZE(&allocator), 0);
+ CHECK(sschiff_device_create(NULL, &allocator, 1, NULL, NULL), RES_BAD_ARG);
+ CHECK(sschiff_device_create(NULL, &allocator, 1, NULL, &dev), RES_OK);
+ CHECK(sschiff_device_ref_put(dev), RES_OK);
+ CHECK(MEM_ALLOCATED_SIZE(&allocator), 0);
+
+ CHECK(logger_init(&allocator, &logger), RES_OK);
+ logger_set_stream(&logger, LOG_OUTPUT, log_stream, NULL);
+ logger_set_stream(&logger, LOG_ERROR, log_stream, NULL);
+ logger_set_stream(&logger, LOG_WARNING, log_stream, NULL);
+
+ CHECK(sschiff_device_create(&logger, NULL, 0, NULL, NULL), RES_BAD_ARG);
+ CHECK(sschiff_device_create(&logger, NULL, 0, NULL, &dev), RES_OK);
+ CHECK(sschiff_device_ref_put(dev), RES_OK);
+
+ CHECK(sschiff_device_create(&logger, &allocator, 1, NULL, NULL), RES_BAD_ARG);
+ CHECK(sschiff_device_create(&logger, &allocator, 1, NULL, &dev), RES_OK);
+ CHECK(sschiff_device_ref_put(dev), RES_OK);
+
+ CHECK(s3d_device_create(NULL, NULL, 0, &s3d), RES_OK);
+ CHECK(sschiff_device_create(NULL, NULL, 0, s3d, NULL), RES_BAD_ARG);
+ CHECK(sschiff_device_create(NULL, NULL, 0, s3d, &dev), RES_OK);
+
+ CHECK(s3d_device_ref_put(s3d), RES_OK);
+ CHECK(sschiff_device_ref_put(dev), RES_OK);
+
+ logger_release(&logger);
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHECK(mem_allocated_size(), 0);
+ return 0;
+}
+
diff --git a/src/test_sschiff_estimator.c b/src/test_sschiff_estimator.c
@@ -0,0 +1,203 @@
+/* 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 "sschiff.h"
+#include "test_sschiff_utils.h"
+
+#include <rsys/float3.h>
+
+#include <star/s3d.h>
+#include <star/ssp.h>
+
+#define STEP 0.05f
+
+enum { A, B, M, N0, N1, N2 };
+
+struct super_shape {
+ float super_formulas[2][6];
+ size_t ntheta, nphi;
+};
+
+static void
+super_shape_get_indices(const unsigned itri, unsigned ids[3], void* ctx)
+{
+ struct super_shape* sshape = ctx;
+ const size_t iquad = itri / 2;
+ const size_t iquad_tri = itri % 2;
+ const size_t i = iquad / (sshape->nphi - 1);
+ const size_t j = iquad % (sshape->nphi - 1);
+ size_t A, B;
+
+ B = i * sshape->nphi + j + 1;
+ A = ((i + 1) % sshape->ntheta) * sshape->nphi + j;
+ if(iquad_tri == 0) {
+ ids[0] = (unsigned)B - 1;
+ ids[1] = (unsigned)A;
+ ids[2] = (unsigned)B;
+ } else { ASSERT(iquad_tri == 1);
+ ids[0] = (unsigned)B;
+ ids[1] = (unsigned)A;
+ ids[2] = (unsigned)A + 1;
+ }
+}
+
+static void
+super_shape_get_vertex_position(const unsigned ivert, float vertex[3], void* ctx)
+{
+ struct super_shape* sshape = ctx;
+ const size_t itheta = ivert / sshape->nphi;
+ const size_t iphi = ivert % sshape->nphi;
+ double angle[2];
+ double sin_angle[2];
+ double cos_angle[2];
+ double uv[2];
+ int iform;
+ ASSERT(itheta < sshape->ntheta);
+
+ if(iphi == sshape->nphi - 1) { /* Polar vertices: Force polar coordinates */
+ angle[0] = PI;
+ angle[1] = PI/2;
+ } else {
+ angle[0] = -PI + (double)itheta * STEP;
+ angle[1] = -PI/2 + (double)iphi * STEP;
+ }
+
+ FOR_EACH(iform, 0, 2) {
+ double m, k, g;
+ float* form = sshape->super_formulas[iform];
+ m = cos(form[M] * angle[iform] / 4.0);
+ m = fabs(m) / form[A];
+ k = sin(form[M] * angle[iform] / 4.0);
+ k = fabs(k) / form[B];
+ g = pow(m, form[N1]) + pow(k, form[N2]);
+ uv[iform] = pow(g, (-1.0/form[N0]));
+
+ cos_angle[iform] = cos(angle[iform]);
+ sin_angle[iform] = sin(angle[iform]);
+ }
+
+ vertex[0] = (float)(uv[0] * cos_angle[0] * uv[1] * cos_angle[1]);
+ vertex[1] = (float)(uv[0] * sin_angle[0] * uv[1] * cos_angle[1]);
+ vertex[2] = (float)(uv[1] * sin_angle[1]);
+}
+
+static res_T
+sample_geometry
+ (struct ssp_rng* rng,
+ struct sschiff_material* mtl,
+ struct s3d_shape* shape,
+ void* sampler_context)
+{
+ struct s3d_vertex_data attrib;
+ struct super_shape sshape;
+ const size_t ntheta = (int)((2*PI)/STEP) + 1;
+ const size_t nphi = (int)((PI)/STEP) + 1;
+ const size_t nverts = ntheta * nphi;
+ const size_t nprims = ntheta * (nphi - 1)/*#quads*/ * 2/*#triangles*/;
+
+ (void)sampler_context;
+
+ NCHECK(rng, NULL);
+ NCHECK(mtl, NULL);
+ NCHECK(shape, NULL);
+
+ attrib.usage = S3D_POSITION;
+ attrib.type = S3D_FLOAT3;
+ attrib.get = super_shape_get_vertex_position;
+
+ sshape.super_formulas[0][A] = 1;
+ sshape.super_formulas[0][B] = 1;
+ sshape.super_formulas[0][M] = (float)ssp_rng_uniform_double(rng, 0.1, 6);
+ sshape.super_formulas[0][N0] = 1;
+ sshape.super_formulas[0][N1] = 1;
+ sshape.super_formulas[0][N2] = (float)ssp_rng_uniform_double(rng, 0.1, 6);
+
+ sshape.super_formulas[1][A] = 1;
+ sshape.super_formulas[1][B] = 1;
+ sshape.super_formulas[1][M] = (float)ssp_rng_uniform_double(rng, 0.1, 6);
+ sshape.super_formulas[1][N0] = 1;
+ sshape.super_formulas[1][N1] = 1;
+ sshape.super_formulas[1][N2] = (float)ssp_rng_uniform_double(rng, 0.1, 6);
+
+ sshape.ntheta = ntheta;
+ sshape.nphi = nphi;
+
+ *mtl = SSCHIFF_NULL_MATERIAL;
+ return s3d_mesh_setup_indexed_vertices(shape, (unsigned)nprims,
+ super_shape_get_indices, (unsigned)nverts, &attrib, 1, &sshape);
+}
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct sschiff_device* dev;
+ struct sschiff_estimator* estimator;
+ struct sschiff_integrator_desc desc = SSCHIFF_NULL_INTEGRATOR_DESC;
+ struct ssp_rng* rng;
+ (void)argc, (void)argv;
+
+ mem_init_proxy_allocator(&allocator, &mem_default_allocator);
+
+ CHECK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng), RES_OK);
+ CHECK(sschiff_device_create(NULL, &allocator, 0, NULL, &dev), RES_OK);
+
+ desc.sample_geometry = sample_geometry;
+ desc.scattering_angles_count = 1;
+ CHECK(sschiff_integrate(NULL, NULL, NULL, 0, 0, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, NULL, 0, 0, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, NULL, 0, 0, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, NULL, 0, 0, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, &desc, 0, 0, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, &desc, 0, 0, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, &desc, 0, 0, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, &desc, 0, 0, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, NULL, 0, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, NULL, 0, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, NULL, 0, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, NULL, 0, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, &desc, 0, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, &desc, 0, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, &desc, 0, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, &desc, 0, 100, &estimator), RES_OK);
+
+ CHECK(sschiff_estimator_ref_get(NULL), RES_BAD_ARG);
+ CHECK(sschiff_estimator_ref_get(estimator), RES_OK);
+ CHECK(sschiff_estimator_ref_put(NULL), RES_BAD_ARG);
+ CHECK(sschiff_estimator_ref_put(estimator), RES_OK);
+ CHECK(sschiff_estimator_ref_put(estimator), RES_OK);
+
+ CHECK(sschiff_device_ref_put(dev), RES_OK);
+ CHECK(ssp_rng_ref_put(rng), RES_OK);
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHECK(mem_allocated_size(), 0);
+ return 0;
+}
+
diff --git a/src/test_salgae_utils.h b/src/test_sschiff_utils.h