commit 5b1b7e0d8b475e5d19612915e158d180c68b266e
parent 25fab4432369fe6f393fa024544afa4f28fb9d74
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 25 Apr 2017 15:42:43 +0200
Merge branch 'feature_spectral' into develop
Diffstat:
14 files changed, 399 insertions(+), 69 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -57,6 +57,7 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SSOL_FILES_SRC
ssol_atmosphere.c
ssol_camera.c
+ ssol_data.c
ssol_device.c
ssol_draw.c
ssol_draw_pt.c
@@ -154,6 +155,7 @@ if(NOT NO_TEST)
new_test(test_ssol_atmosphere)
new_test(test_ssol_by_receiver_integration)
new_test(test_ssol_camera)
+ new_test(test_ssol_data)
new_test(test_ssol_device)
new_test(test_ssol_image)
new_test(test_ssol_material)
diff --git a/src/ssol.h b/src/ssol.h
@@ -119,6 +119,11 @@ enum ssol_attrib_usage {
SSOL_ATTRIBS_COUNT__
};
+enum ssol_data_type {
+ SSOL_DATA_REAL,
+ SSOL_DATA_SPECTRUM
+};
+
/* Describe a vertex data */
struct ssol_vertex_data {
enum ssol_attrib_usage usage; /* Semantic of the data */
@@ -242,11 +247,21 @@ struct ssol_punched_surface {
static const struct ssol_punched_surface SSOL_PUNCHED_SURFACE_NULL =
SSOL_PUNCHED_SURFACE_NULL__;
+struct ssol_data {
+ enum ssol_data_type type;
+ union {
+ double real;
+ struct ssol_spectrum* spectrum;
+ } value;
+};
+#define SSOL_DATA_NULL__ {SSOL_DATA_REAL, {0.0}}
+static const struct ssol_data SSOL_DATA_NULL = SSOL_DATA_NULL__;
+
struct ssol_medium {
- double absorptivity;
- double refractive_index;
+ struct ssol_data absorptivity;
+ struct ssol_data refractive_index;
};
-#define SSOL_MEDIUM_VACUUM__ { 0, 1 }
+#define SSOL_MEDIUM_VACUUM__ {{SSOL_DATA_REAL, {0}}, {SSOL_DATA_REAL, {1}}}
static const struct ssol_medium SSOL_MEDIUM_VACUUM = SSOL_MEDIUM_VACUUM__;
struct ssol_surface_fragment {
@@ -1182,6 +1197,61 @@ ssol_draw_pt
ssol_write_pixels_T writer,
void* writer_data);
+/*******************************************************************************
+ * Data API
+ ******************************************************************************/
+SSOL_API struct ssol_data*
+ssol_data_set_real
+ (struct ssol_data* data,
+ const double real);
+
+/* Get a reference onto the submitted spectrum */
+SSOL_API struct ssol_data*
+ssol_data_set_spectrum
+ (struct ssol_data* data,
+ struct ssol_spectrum* spectrum);
+
+/* Release the reference on its associated spectrum, if defined */
+SSOL_API struct ssol_data*
+ssol_data_clear
+ (struct ssol_data* data);
+
+SSOL_API struct ssol_data*
+ssol_data_copy
+ (struct ssol_data* dst,
+ const struct ssol_data* src);
+
+SSOL_API int
+ssol_data_eq
+ (const struct ssol_data* op0,
+ const struct ssol_data* op1);
+
+SSOL_API double
+ssol_data_get_value
+ (const struct ssol_data* data,
+ const double wavelength);
+
+/*******************************************************************************
+ * Medium API
+ ******************************************************************************/
+static FINLINE struct ssol_medium*
+ssol_medium_clear(struct ssol_medium* medium)
+{
+ ASSERT(medium);
+ ssol_data_clear(&medium->absorptivity);
+ ssol_data_clear(&medium->refractive_index);
+ return medium;
+}
+
+static FINLINE struct ssol_medium*
+ssol_medium_copy(struct ssol_medium* dst, const struct ssol_medium* src)
+{
+ ASSERT(dst && src);
+ ssol_data_copy(&dst->absorptivity, &src->absorptivity);
+ ssol_data_copy(&dst->refractive_index, &src->refractive_index);
+ return dst;
+}
+
END_DECLS
#endif /* SSOL_H */
diff --git a/src/ssol_data.c b/src/ssol_data.c
@@ -0,0 +1,112 @@
+/* Copyright (C) CNRS 2016-2017
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SSOL_DATA_C_H
+#define SSOL_DATA_C_H
+
+#include "ssol.h"
+#include "ssol_spectrum_c.h"
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+struct ssol_data*
+ssol_data_set_real(struct ssol_data* data, const double real)
+{
+ const double r = real;
+ ASSERT(data);
+ ssol_data_clear(data);
+ data->type = SSOL_DATA_REAL;
+ data->value.real = r;
+ return data;
+}
+
+struct ssol_data*
+ssol_data_set_spectrum(struct ssol_data* data, struct ssol_spectrum* spectrum)
+{
+ ASSERT(data && spectrum);
+ if(data->type == SSOL_DATA_SPECTRUM && data->value.spectrum == spectrum)
+ return data;
+ ssol_data_clear(data);
+ data->type = SSOL_DATA_SPECTRUM;
+ data->value.spectrum = spectrum;
+ SSOL(spectrum_ref_get(spectrum));
+ return data;
+}
+
+struct ssol_data*
+ssol_data_clear(struct ssol_data* data)
+{
+ ASSERT(data);
+ if(data->type != SSOL_DATA_SPECTRUM) return data;
+ ASSERT(data->value.spectrum);
+ SSOL(spectrum_ref_put(data->value.spectrum));
+ *data = SSOL_DATA_NULL;
+ return data;
+}
+
+struct ssol_data*
+ssol_data_copy(struct ssol_data* dst, const struct ssol_data* src)
+{
+ ASSERT(dst && src);
+ if(dst == src) return dst;
+ dst->type = src->type;
+ switch(dst->type) {
+ case SSOL_DATA_REAL:
+ dst->value.real = src->value.real;
+ break;
+ case SSOL_DATA_SPECTRUM:
+ dst->value.spectrum = src->value.spectrum;
+ SSOL(spectrum_ref_get(dst->value.spectrum));
+ break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+ return dst;
+}
+
+int
+ssol_data_eq(const struct ssol_data* a, const struct ssol_data* b)
+{
+ ASSERT(a && b);
+ if(a->type != b->type) return 0;
+ switch(a->type) {
+ case SSOL_DATA_REAL: return a->value.real == b->value.real;
+ case SSOL_DATA_SPECTRUM: return a->value.spectrum == b->value.spectrum;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+ return 0;
+}
+
+double
+ssol_data_get_value(const struct ssol_data* data, const double wavelength)
+{
+ double val;
+ ASSERT(data);
+
+ switch(data->type) {
+ case SSOL_DATA_REAL:
+ val = data->value.real;
+ break;
+ case SSOL_DATA_SPECTRUM:
+ ASSERT(wavelength >= 0);
+ val = spectrum_interpolate(data->value.spectrum, wavelength);
+ break;
+ default: FATAL("Unreachable code\n"); break;
+ }
+ return val;
+}
+
+#endif /* SSOL_DATA_C_H */
+
diff --git a/src/ssol_draw_pt.c b/src/ssol_draw_pt.c
@@ -128,7 +128,7 @@ Li(struct ssol_scene* scn,
const float dir[3],
double val[3])
{
- struct ssol_medium medium;
+ struct ssol_medium medium = SSOL_MEDIUM_VACUUM;
struct s3d_hit hit;
struct ray_data ray_data = RAY_DATA_NULL;
struct ssol_instance* inst;
@@ -159,15 +159,14 @@ Li(struct ssol_scene* scn,
f3_set(ray_org, org);
f3_set(ray_dir, dir);
- /* Assume that the path starts from vacuum */
- medium = SSOL_MEDIUM_VACUUM;
-
for(;;) {
+ double absorptivity;
S3D(scene_view_trace_ray
(view, ray_org, ray_dir, ray_range, &ray_data, &hit));
- if(medium.absorptivity > 0) {
- throughput *= exp(-medium.absorptivity * hit.distance);
+ absorptivity = ssol_data_get_value(&medium.absorptivity, 1/*Wavelength*/);
+ if(absorptivity > 0) {
+ throughput *= exp(-absorptivity * hit.distance);
}
if(S3D_HIT_NONE(&hit)) { /* Background lighting */
@@ -265,6 +264,7 @@ Li(struct ssol_scene* scn,
d3_splat(val, L);
exit:
+ ssol_medium_clear(&medium);
return res;
error:
d3(val, 1, 1, 0);
diff --git a/src/ssol_material.c b/src/ssol_material.c
@@ -15,8 +15,9 @@
#include "ssol.h"
#include "ssol_c.h"
-#include "ssol_material_c.h"
#include "ssol_device_c.h"
+#include "ssol_material_c.h"
+#include "ssol_spectrum_c.h"
#include <rsys/double2.h>
#include <rsys/double3.h>
@@ -71,8 +72,8 @@ setup_dielectric_bsdf
goto error;
}
- eta_i = mtl->out_medium.refractive_index;
- eta_t = mtl->in_medium.refractive_index;
+ eta_i = ssol_data_get_value(&mtl->out_medium.refractive_index, wavelength);
+ eta_t = ssol_data_get_value(&mtl->in_medium.refractive_index, wavelength);
#define CALL(Func) { res = Func; if(res != RES_OK) goto error; } (void)0
/* Setup the reflective part */
@@ -219,9 +220,11 @@ setup_thin_dielectric_bsdf
ASSERT(bsdf);
(void)wavelength, (void)fragment;
- eta_i = mtl->out_medium.refractive_index;
- eta_t = mtl->data.thin_dielectric.slab_medium.refractive_index;
- absorptivity = mtl->data.thin_dielectric.slab_medium.absorptivity;
+ eta_i = ssol_data_get_value(&mtl->out_medium.refractive_index, wavelength);
+ eta_t = ssol_data_get_value
+ (&mtl->data.thin_dielectric.slab_medium.refractive_index, wavelength);
+ absorptivity = ssol_data_get_value
+ (&mtl->data.thin_dielectric.slab_medium.absorptivity, wavelength);
thickness = mtl->data.thin_dielectric.thickness;
/* Setup the BxDF */
@@ -275,9 +278,38 @@ check_shader_thin_differential(const struct ssol_thin_dielectric_shader* shader)
static INLINE int
check_medium(const struct ssol_medium* medium)
{
- return medium
- && medium->refractive_index > 0
- && medium->absorptivity >= 0;
+ if(!medium) return 0;
+
+ /* Check absorptivity in [0, INF) */
+ switch(medium->absorptivity.type) {
+ case SSOL_DATA_REAL:
+ if(medium->absorptivity.value.real < 0)
+ return 0;
+ break;
+ case SSOL_DATA_SPECTRUM:
+ if(!medium->absorptivity.value.spectrum
+ || !spectrum_check_data(medium->absorptivity.value.spectrum, 0, DBL_MAX))
+ return 0;
+ break;
+ default: FATAL("Unreachable code\n"); break;
+ }
+
+ /* Check absorptivity in ]0, INF) */
+ switch(medium->refractive_index.type) {
+ case SSOL_DATA_REAL:
+ if(medium->refractive_index.value.real <= 0)
+ return 0;
+ break;
+ case SSOL_DATA_SPECTRUM:
+ if(!medium->refractive_index.value.spectrum
+ || !spectrum_check_data
+ (medium->refractive_index.value.spectrum, DBL_EPSILON, DBL_MAX))
+ return 0;
+ break;
+ default: FATAL("Unreachable code\n"); break;
+ }
+
+ return 1;
}
static void
@@ -420,8 +452,8 @@ ssol_dielectric_setup
|| !check_medium(inside_medium))
return RES_BAD_ARG;
material->data.dielectric.dummy = 1;
- material->out_medium = *outside_medium;
- material->in_medium = *inside_medium;
+ ssol_medium_copy(&material->out_medium, outside_medium);
+ ssol_medium_copy(&material->in_medium, inside_medium);
material->normal = shader->normal;
return RES_OK;
}
@@ -470,8 +502,8 @@ ssol_thin_dielectric_setup
return RES_BAD_ARG;
material->data.thin_dielectric.slab_medium = *slab_medium;
material->data.thin_dielectric.thickness = thickness;
- material->out_medium = *outside_medium;
- material->in_medium = *outside_medium;
+ ssol_medium_copy(&material->out_medium, outside_medium);
+ ssol_medium_copy(&material->in_medium, outside_medium);
material->normal = shader->normal;
return RES_OK;
}
@@ -647,16 +679,16 @@ material_get_next_medium
/* The material is an interface between 2 media */
case SSOL_MATERIAL_DIELECTRIC:
if(MEDIA_EQ(&mtl->out_medium, medium)) {
- *next_medium = mtl->in_medium;
+ ssol_medium_copy(next_medium, &mtl->in_medium);
} else {
- *next_medium = mtl->out_medium;
+ ssol_medium_copy(next_medium, &mtl->out_medium);
}
break;
/* The material is not an interface between 2 media */
case SSOL_MATERIAL_MATTE:
case SSOL_MATERIAL_MIRROR:
case SSOL_MATERIAL_THIN_DIELECTRIC:
- *next_medium = *medium;
+ ssol_medium_copy(next_medium, medium);
break;
default: FATAL("Unreachable code\n"); break;
}
diff --git a/src/ssol_material_c.h b/src/ssol_material_c.h
@@ -24,8 +24,8 @@ struct ssf_bsdf;
struct ssol_device;
#define MEDIA_EQ(A, B) \
- ( ((A)->refractive_index == (B)->refractive_index) \
- && ((A)->absorptivity == (B)->absorptivity))
+ ( ssol_data_eq(&((A)->refractive_index), &((B)->refractive_index)) \
+ && ssol_data_eq(&((A)->absorptivity), &((B)->absorptivity)))
struct dielectric {
int dummy;
diff --git a/src/ssol_ranst_sun_wl.c b/src/ssol_ranst_sun_wl.c
@@ -158,22 +158,24 @@ ranst_sun_wl_setup
const size_t sz)
{
res_T res = RES_OK;
- if (sz && (!ran || !wavelengths || !intensities))
+ if(!ran || !wavelengths || !intensities || !sz)
return RES_BAD_ARG;
- if (sz > 1) {
+
+ if(sz <= 1) {
+ ran->type = WL_DIRAC;
+ ran->get = &ran_dirac_get;
+ ran->state.dirac.wavelength = sz ? wavelengths[0] : -1;
+ } else {
ran->type = WL_PIECEWISE;
ran->get = &ran_piecewise_get;
res = ssp_ranst_piecewise_linear_create
(ran->allocator, &ran->state.piecewise.spectrum);
- if (res != RES_OK) goto error;
+ if(res != RES_OK) goto error;
res = ssp_ranst_piecewise_linear_setup
(ran->state.piecewise.spectrum, wavelengths, intensities, sz);
- if (res != RES_OK) goto error;
- } else {
- ran->type = WL_DIRAC;
- ran->get = &ran_dirac_get;
- ran->state.dirac.wavelength = sz ? wavelengths[0] : -1;
+ if(res != RES_OK) goto error;
}
+
exit:
return res;
error:
diff --git a/src/ssol_solver.c b/src/ssol_solver.c
@@ -495,6 +495,11 @@ check_scene(const struct ssol_scene* scene, const char* caller)
return RES_BAD_ARG;
}
+ if(!scene->sun->spectrum) {
+ log_error(scene->dev, "%s: sun's spectrum undefined.\n", caller);
+ return RES_BAD_ARG;
+ }
+
if(scene->sun->dni <= 0) {
log_error(scene->dev, "%s: sun's DNI undefined.\n", caller);
return RES_BAD_ARG;
@@ -774,8 +779,8 @@ trace_radiative_path
if(scn->atmosphere) {
/* Assume that the path starts from an uniform atmosphere */
- medium.absorptivity = atmosphere_uniform_get_absorption
- (scn->atmosphere, pt.wl);
+ ssol_data_set_real(&medium.absorptivity,
+ atmosphere_uniform_get_absorption(scn->atmosphere, pt.wl));
}
if(tracker) {
@@ -815,6 +820,7 @@ trace_radiative_path
for(;;) { /* Here we go for the radiative random walk */
struct ray_data ray_data = RAY_DATA_NULL;
struct ssol_material* mtl;
+ double absorptivity;
/* Compute interaction with material */
mtl = point_get_material(&pt);
@@ -874,8 +880,9 @@ trace_radiative_path
depth += mtl->type != SSOL_MATERIAL_VIRTUAL;
/* Take into account the medium attenuation */
- if(medium.absorptivity > 0 && hit.distance > 0) {
- const double transmissivity = exp(-medium.absorptivity * hit.distance);
+ absorptivity = ssol_data_get_value(&medium.absorptivity, pt.wl);
+ if(absorptivity > 0 && hit.distance > 0) {
+ const double transmissivity = exp(-absorptivity * hit.distance);
ASSERT(0 < transmissivity && transmissivity <= 1);
pt.absorptivity_loss += (1 - transmissivity) * pt.weight;
pt.weight *= transmissivity;
@@ -905,6 +912,7 @@ trace_radiative_path
}
exit:
if(tracker) path_release(&path);
+ ssol_medium_clear(&medium);
return res;
error:
goto exit;
diff --git a/src/ssol_spectrum.c b/src/ssol_spectrum.c
@@ -92,15 +92,21 @@ spectrum_interpolate
double slope;
double intensity;
size_t id_next, sz;
- ASSERT(spectrum && spectrum_includes_point(spectrum, wavelength));
+ ASSERT(spectrum);
sz = darray_double_size_get(&spectrum->wavelengths);
wls = darray_double_cdata_get(&spectrum->wavelengths);
ints = darray_double_cdata_get(&spectrum->intensities);
next = search_lower_bound(&wavelength, wls, sz, sizeof(double), &eq_dbl);
- ASSERT(next); /* because spectrum_includes_point */
+ if(!next) { /* Clamp to upper bound */
+ return ints[sz-1];
+ }
id_next = (size_t)(next - wls);
+ if(!id_next) { /* Clamp to lower bound */
+ return ints[0];
+ }
+
ASSERT(id_next); /* because spectrum_includes_point */
ASSERT(ints[id_next] >= ints[id_next - 1]);
ASSERT(wls[id_next] >= wls[id_next - 1]);
@@ -111,6 +117,19 @@ spectrum_interpolate
return intensity;
}
+int
+spectrum_check_data
+ (const struct ssol_spectrum* spectrum, const double lower, const double upper)
+{
+ size_t i;
+ ASSERT(spectrum && lower <= upper);
+ FOR_EACH(i, 0, darray_double_size_get(&spectrum->intensities)) {
+ const double data = darray_double_cdata_get(&spectrum->intensities)[i];
+ if(data < lower || data > upper) return 0;
+ }
+ return 1;
+}
+
/*******************************************************************************
* Exported ssol_spectrum functions
******************************************************************************/
diff --git a/src/ssol_spectrum_c.h b/src/ssol_spectrum_c.h
@@ -40,4 +40,10 @@ spectrum_interpolate
(const struct ssol_spectrum* spectrum,
const double wavelength);
+extern LOCAL_SYM int
+spectrum_check_data
+ (const struct ssol_spectrum* spectrum,
+ const double lower, /* Inclusive lower bound */
+ const double upper); /* Inclusive upper bound */
+
#endif /* SSOL_SPECTRUM_C_H */
diff --git a/src/ssol_sun.c b/src/ssol_sun.c
@@ -212,15 +212,11 @@ sun_create_distributions
/* Create and setup the spectrum distribution */
res = ranst_sun_wl_create(sun->dev->allocator, &ran_wl);
if(res != RES_OK) goto error;
- if(!sun->spectrum) {
- res = ranst_sun_wl_setup(ran_wl, NULL, NULL, 0);
- }
- else {
- res = ranst_sun_wl_setup(ran_wl,
- darray_double_cdata_get(&sun->spectrum->wavelengths),
- darray_double_cdata_get(&sun->spectrum->intensities),
- darray_double_size_get(&sun->spectrum->wavelengths));
- }
+
+ res = ranst_sun_wl_setup(ran_wl,
+ darray_double_cdata_get(&sun->spectrum->wavelengths),
+ darray_double_cdata_get(&sun->spectrum->intensities),
+ darray_double_size_get(&sun->spectrum->wavelengths));
if(res != RES_OK) goto error;
/* Create and setup the the direction distribution */
diff --git a/src/test_ssol_data.c b/src/test_ssol_data.c
@@ -0,0 +1,85 @@
+/* Copyright (C) CNRS 2016-2017
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "ssol.h"
+#include "test_ssol_utils.h"
+
+#include <rsys/math.h>
+
+static void
+get_wlen(const size_t i, double* wlen, double* data, void* ctx)
+{
+ NCHECK(wlen, NULL);
+ NCHECK(data, NULL);
+ *wlen = (double)(i+1);
+ *data = (double)(i+2);
+ (void)ctx;
+}
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct ssol_device* dev;
+ struct ssol_spectrum* spectrum;
+ struct ssol_data data = SSOL_DATA_NULL;
+ size_t i;
+ (void)argc, (void)argv;
+
+ CHECK(mem_init_proxy_allocator(&allocator, &mem_default_allocator), RES_OK);
+
+ CHECK(ssol_device_create
+ (NULL, &allocator, SSOL_NTHREADS_DEFAULT, 0, &dev), RES_OK);
+ CHECK(ssol_spectrum_create(dev, &spectrum), RES_OK);
+ CHECK(ssol_spectrum_setup(spectrum, get_wlen, 10, NULL), RES_OK);
+
+ CHECK(ssol_data_get_value(&data, 1), ssol_data_get_value(&SSOL_DATA_NULL, 1));
+ CHECK(ssol_data_get_value(&data, 4), ssol_data_get_value(&SSOL_DATA_NULL, 4));
+ CHECK(ssol_data_get_value(&data, 2), ssol_data_get_value(&SSOL_DATA_NULL, 2));
+ CHECK(ssol_data_get_value(&data, 7), ssol_data_get_value(&SSOL_DATA_NULL, 7));
+
+ CHECK(ssol_data_set_real(&data, 1.25), &data);
+ CHECK(ssol_data_get_value(&data, 1), 1.25);
+ CHECK(ssol_data_get_value(&data, 1.234), 1.25);
+ CHECK(data.type, SSOL_DATA_REAL);
+ CHECK(data.value.real, 1.25);
+
+ CHECK(ssol_data_set_spectrum(&data, spectrum), &data);
+ CHECK(ssol_data_set_spectrum(&data, spectrum), &data);
+
+ CHECK(data.type, SSOL_DATA_SPECTRUM);
+ CHECK(data.value.spectrum, spectrum);
+ CHECK(ssol_spectrum_ref_put(spectrum), RES_OK);
+
+ FOR_EACH(i, 0, 10) {
+ CHECK(ssol_data_get_value(&data, (double)(i+1)), (double)(i+2));
+ }
+
+ CHECK(eq_eps(ssol_data_get_value(&data, 1.5), 2.5, 1.e-6), 1);
+ CHECK(eq_eps(ssol_data_get_value(&data, 1.25), 2.25, 1.e-6), 1);
+ CHECK(ssol_data_get_value(&data, 0.5), 2);
+ CHECK(ssol_data_get_value(&data, 0.1), 2);
+ CHECK(ssol_data_get_value(&data, 10), 11);
+ CHECK(ssol_data_get_value(&data, 10.1), 11);
+
+ CHECK(ssol_device_ref_put(dev), RES_OK);
+ ssol_data_clear(&data);
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHECK(mem_allocated_size(), 0);
+ return 0;
+}
+
diff --git a/src/test_ssol_material.c b/src/test_ssol_material.c
@@ -162,21 +162,21 @@ test_thin_dielectric(struct ssol_device* dev)
CHECK(ssol_thin_dielectric_setup(mtl, &shader, &mdm0, &mdm1, 1), RES_BAD_ARG);
shader.normal = get_shader_normal;
- mdm0.absorptivity = -1;
+ ssol_data_set_real(&mdm0.absorptivity, -1);
CHECK(ssol_thin_dielectric_setup(mtl, &shader, &mdm0, &mdm1, 1), RES_BAD_ARG);
- mdm0.absorptivity = SSOL_MEDIUM_VACUUM.absorptivity;
+ ssol_data_copy(&mdm0.absorptivity, &SSOL_MEDIUM_VACUUM.absorptivity);
- mdm0.refractive_index = 0;
+ ssol_data_set_real(&mdm0.refractive_index, 0);
CHECK(ssol_thin_dielectric_setup(mtl, &shader, &mdm0, &mdm1, 1), RES_BAD_ARG);
- mdm0.refractive_index = SSOL_MEDIUM_VACUUM.refractive_index;
+ ssol_data_copy(&mdm0.refractive_index, &SSOL_MEDIUM_VACUUM.refractive_index);
- mdm1.absorptivity = -1;
+ ssol_data_set_real(&mdm1.absorptivity, -1);
CHECK(ssol_thin_dielectric_setup(mtl, &shader, &mdm0, &mdm1, 1), RES_BAD_ARG);
- mdm1.absorptivity = SSOL_MEDIUM_VACUUM.absorptivity;
+ ssol_data_copy(&mdm1.absorptivity, &SSOL_MEDIUM_VACUUM.absorptivity);
- mdm1.refractive_index = 0;
+ ssol_data_set_real(&mdm1.refractive_index, 0);
CHECK(ssol_thin_dielectric_setup(mtl, &shader, &mdm0, &mdm1, 1), RES_BAD_ARG);
- mdm1.refractive_index = SSOL_MEDIUM_VACUUM.refractive_index;
+ ssol_data_copy(&mdm1.refractive_index, &SSOL_MEDIUM_VACUUM.refractive_index);
CHECK(ssol_material_ref_put(mtl), RES_OK);
}
@@ -221,21 +221,21 @@ test_dielectric(struct ssol_device* dev)
CHECK(ssol_dielectric_setup(NULL, &dielectric, &mdm0, &mdm1), RES_BAD_ARG);
dielectric.normal = get_shader_normal;
- mdm0.refractive_index = 0;
+ ssol_data_set_real(&mdm0.refractive_index, 0);
CHECK(ssol_dielectric_setup(NULL, &dielectric, &mdm0, &mdm1), RES_BAD_ARG);
- mdm0.refractive_index = SSOL_MEDIUM_VACUUM.refractive_index;
+ ssol_data_copy(&mdm0.refractive_index, &SSOL_MEDIUM_VACUUM.refractive_index);
- mdm1.refractive_index = 0;
+ ssol_data_set_real(&mdm1.refractive_index, 0);
CHECK(ssol_dielectric_setup(NULL, &dielectric, &mdm0, &mdm1), RES_BAD_ARG);
- mdm1.refractive_index = SSOL_MEDIUM_VACUUM.refractive_index;
+ ssol_data_copy(&mdm1.refractive_index, &SSOL_MEDIUM_VACUUM.refractive_index);
- mdm0.absorptivity = -1;
+ ssol_data_set_real(&mdm0.absorptivity, -1);
CHECK(ssol_dielectric_setup(NULL, &dielectric, &mdm0, &mdm1), RES_BAD_ARG);
- mdm0.absorptivity = SSOL_MEDIUM_VACUUM.refractive_index;
+ ssol_data_copy(&mdm0.absorptivity, &SSOL_MEDIUM_VACUUM.refractive_index);
- mdm1.absorptivity = -1;
+ ssol_data_set_real(&mdm1.absorptivity, -1);
CHECK(ssol_dielectric_setup(NULL, &dielectric, &mdm0, &mdm1), RES_BAD_ARG);
- mdm1.refractive_index = SSOL_MEDIUM_VACUUM.refractive_index;
+ ssol_data_copy(&mdm1.refractive_index, &SSOL_MEDIUM_VACUUM.refractive_index);
CHECK(ssol_material_ref_put(material), RES_OK);
}
diff --git a/src/test_ssol_solver1.c b/src/test_ssol_solver1.c
@@ -91,7 +91,6 @@ main(int argc, char** argv)
double a_m, a_std;
uint32_t r_id;
unsigned ntris;
-
(void) argc, (void) argv;
d33_splat(transform1, 0);
@@ -260,10 +259,9 @@ main(int argc, char** argv)
CHECK(ssol_sun_set_direction(sun, d3(dir, 1, 0, -1)), RES_OK);
CHECK(ssol_sun_set_dni(sun, 1000), RES_OK);
CHECK(ssol_scene_attach_sun(scene, sun), RES_OK);
- CHECK(ssol_solve(scene, rng, 10, 0, NULL, &estimator), RES_OK);
+ CHECK(ssol_solve(scene, rng, 10, 0, NULL, &estimator), RES_BAD_ARG);
CHECK(ssol_scene_detach_sun(scene, sun), RES_OK);
CHECK(ssol_sun_ref_put(sun), RES_OK);
- CHECK(ssol_estimator_ref_put(estimator), RES_OK);
/* Sun with undefined DNI */
CHECK(ssol_sun_create_directional(dev, &sun), RES_OK);