commit 3c2633534b79f672152e985ce013cd0a2599d2ba
parent 34c1f431e3ef0c4ff983a68fba1600f9c39b5eaa
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Wed, 29 Jun 2016 17:59:06 +0200
First try at suns.
Diffstat:
4 files changed, 382 insertions(+), 2 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -54,7 +54,8 @@ set(SSOL_FILES_SRC
ssol_object_instance.c
ssol_scene.c
ssol_shape.c
- ssol_spectrum.c)
+ ssol_spectrum.c
+ ssol_sun.c)
set(SSOL_FILES_INC_API
ssol.h)
@@ -67,7 +68,8 @@ set(SSOL_FILES_INC
ssol_object_instance_c.h
ssol_scene_c.h
ssol_shape_c.h
- ssol_spectrum_c.h)
+ ssol_spectrum_c.h
+ ssol_sun_c.h)
set(SSOL_FILES_DOC COPYING README.md)
@@ -124,6 +126,7 @@ if(NOT NO_TEST)
new_test(test_ssol_scene)
new_test(test_ssol_shape)
new_test(test_ssol_spectrum)
+ new_test(test_ssol_sun)
endif(NOT NO_TEST)
################################################################################
diff --git a/src/ssol_sun.c b/src/ssol_sun.c
@@ -0,0 +1,180 @@
+/* Copyright (C) CNRS 2016
+*
+* 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 "ssol_sun_c.h"
+#include "ssol_device_c.h"
+
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/ref_count.h>
+#include <rsys/math.h>
+
+/*******************************************************************************
+* Helper functions
+******************************************************************************/
+
+static void
+sun_release(ref_T* ref)
+{
+ struct ssol_sun* sun;
+ struct ssol_device* dev;
+ ASSERT(ref);
+ sun = CONTAINER_OF(ref, struct ssol_sun, ref);
+ dev = sun->dev;
+ if (sun->spectrum)
+ SSOL(spectrum_ref_put(sun->spectrum));
+ ASSERT(dev && dev->allocator);
+ MEM_RM(dev->allocator, sun);
+ SSOL(device_ref_put(dev));
+}
+
+/*******************************************************************************
+* Local functions
+******************************************************************************/
+
+res_T
+ssol_sun_create
+ (struct ssol_device* dev,
+ struct ssol_sun** out_sun,
+ enum sun_type type)
+{
+ struct ssol_sun* sun = NULL;
+ res_T res = RES_OK;
+ if (!dev || !out_sun) {
+ return RES_BAD_ARG;
+ }
+
+ sun = (struct ssol_sun*)MEM_CALLOC
+ (dev->allocator, 1, sizeof(struct ssol_sun));
+ if (!sun) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+
+ SSOL(device_ref_get(dev));
+ sun->dev = dev;
+ sun->type = type;
+ ref_init(&sun->ref);
+
+exit:
+ if (out_sun) *out_sun = sun;
+ return res;
+error:
+ if (sun) {
+ SSOL(sun_ref_put(sun));
+ sun = NULL;
+ }
+ goto exit;
+}
+
+/*******************************************************************************
+* Exported ssol_image functions
+******************************************************************************/
+
+res_T
+ssol_sun_create_directional
+ (struct ssol_device* dev,
+ struct ssol_sun** out_sun)
+{
+ return ssol_sun_create(dev, out_sun, SUN_DIRECTIONAL);
+}
+
+res_T
+ssol_sun_create_pillbox
+ (struct ssol_device* dev,
+ struct ssol_sun** out_sun)
+{
+ return ssol_sun_create(dev, out_sun, SUN_PILLBOX);
+}
+
+res_T
+ssol_sun_create_circumsolar_ratio
+ (struct ssol_device* dev,
+ struct ssol_sun** out_sun)
+{
+ return ssol_sun_create(dev, out_sun, SUN_CSR);
+}
+
+res_T
+ssol_sun_ref_get
+(struct ssol_sun* sun)
+{
+ if (!sun)
+ return RES_BAD_ARG;
+ ref_get(&sun->ref);
+ return RES_OK;
+}
+
+res_T
+ssol_sun_ref_put
+(struct ssol_sun* sun)
+{
+ if (!sun)
+ return RES_BAD_ARG;
+ ref_put(&sun->ref, sun_release);
+ return RES_OK;
+}
+
+res_T
+ssol_sun_set_direction
+ (struct ssol_sun* sun,
+ const double direction[3])
+{
+ if (!sun || !direction)
+ return RES_BAD_ARG;
+ memcpy(sun->direction, direction, 3 * sizeof(double));
+ return RES_OK;
+}
+
+res_T
+ssol_sun_set_spectrum
+ (struct ssol_sun* sun,
+ struct ssol_spectrum* spectrum)
+{
+ if (!sun || !spectrum)
+ return RES_BAD_ARG;
+ SSOL(spectrum_ref_get(spectrum));
+ sun->spectrum = spectrum;
+ return RES_OK;
+}
+
+res_T
+ssol_sun_set_pillbox_aperture
+ (struct ssol_sun* sun,
+ const double angle)
+{
+ if (!sun
+ || angle <= 0
+ || angle > PI * 0.5
+ || sun->type != SUN_PILLBOX)
+ return RES_BAD_ARG;
+ sun->data.pillbox.aperture = angle;
+ return RES_OK;
+}
+
+res_T
+ssol_sun_set_circumsolar_ratio
+ (struct ssol_sun* sun,
+ const double ratio)
+{
+ if (!sun
+ || ratio <= 0
+ || ratio >= 1
+ || sun->type != SUN_CSR)
+ return RES_BAD_ARG;
+ sun->data.csr.ratio = ratio;
+ return RES_OK;
+}
+\ No newline at end of file
diff --git a/src/ssol_sun_c.h b/src/ssol_sun_c.h
@@ -0,0 +1,49 @@
+/* Copyright (C) CNRS 2016
+*
+* 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_SUN_C_H
+#define SSOL_SUN_C_H
+
+#include <rsys/ref_count.h>
+#include <rsys/list.h>
+
+enum sun_type {
+ SUN_DIRECTIONAL,
+ SUN_PILLBOX,
+ SUN_CSR
+};
+
+struct pillbox {
+ double aperture;
+};
+
+struct csr {
+ double ratio;
+};
+
+struct ssol_sun {
+ double direction[3];
+ struct ssol_spectrum* spectrum;
+ enum sun_type type;
+ union {
+ struct pillbox pillbox;
+ struct csr csr;
+ } data;
+
+ struct ssol_device* dev;
+ ref_T ref;
+};
+
+#endif /* SSOL_SUN_C_H */
diff --git a/src/test_ssol_sun.c b/src/test_ssol_sun.c
@@ -0,0 +1,146 @@
+/* Copyright (C) CNRS 2016
+*
+* 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/logger.h>
+
+/*******************************************************************************
+* test main program
+******************************************************************************/
+int
+main(int argc, char** argv)
+{
+ struct logger logger;
+ struct mem_allocator allocator;
+ struct ssol_device* dev;
+ struct ssol_spectrum* spectrum;
+ struct ssol_sun* sun;
+ double dir[3] = { 1, 0, 0 };
+ (void) argc, (void) argv;
+
+ mem_init_proxy_allocator(&allocator, &mem_default_allocator);
+
+ 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(ssol_device_create(&logger, &allocator, SSOL_NTHREADS_DEFAULT, 0, &dev), RES_OK);
+
+ CHECK(ssol_spectrum_create(dev, &spectrum), RES_OK);
+
+ CHECK(ssol_sun_create_directional(NULL, &sun), RES_BAD_ARG);
+ CHECK(ssol_sun_create_directional(dev, NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_create_directional(dev, &sun), RES_OK);
+
+ CHECK(ssol_sun_ref_get(NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_ref_get(sun), RES_OK);
+
+ CHECK(ssol_sun_ref_put(NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_ref_put(sun), RES_OK);
+
+ CHECK(ssol_sun_set_spectrum(NULL, spectrum), RES_BAD_ARG);
+ CHECK(ssol_sun_set_spectrum(sun, NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_set_spectrum(sun, spectrum), RES_OK);
+
+ CHECK(ssol_sun_set_direction(NULL, dir), RES_BAD_ARG);
+ CHECK(ssol_sun_set_direction(sun, NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_set_direction(sun, dir), RES_OK);
+
+ CHECK(ssol_sun_set_pillbox_aperture(NULL, 0.1), RES_BAD_ARG);
+ CHECK(ssol_sun_set_pillbox_aperture(sun, -0.1), RES_BAD_ARG);
+ CHECK(ssol_sun_set_pillbox_aperture(sun, 999), RES_BAD_ARG);
+ CHECK(ssol_sun_set_pillbox_aperture(sun, 0.1), RES_BAD_ARG);
+
+ CHECK(ssol_sun_set_circumsolar_ratio(NULL, 0.1), RES_BAD_ARG);
+ CHECK(ssol_sun_set_circumsolar_ratio(sun, -0.1), RES_BAD_ARG);
+ CHECK(ssol_sun_set_circumsolar_ratio(sun, 999), RES_BAD_ARG);
+ CHECK(ssol_sun_set_circumsolar_ratio(sun, 0.1), RES_BAD_ARG);
+
+ CHECK(ssol_sun_ref_put(sun), RES_OK);
+
+ CHECK(ssol_sun_create_pillbox(NULL, &sun), RES_BAD_ARG);
+ CHECK(ssol_sun_create_pillbox(dev, NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_create_pillbox(dev, &sun), RES_OK);
+
+ CHECK(ssol_sun_ref_get(NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_ref_get(sun), RES_OK);
+
+ CHECK(ssol_sun_ref_put(NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_ref_put(sun), RES_OK);
+
+ CHECK(ssol_sun_set_spectrum(NULL, spectrum), RES_BAD_ARG);
+ CHECK(ssol_sun_set_spectrum(sun, NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_set_spectrum(sun, spectrum), RES_OK);
+
+ CHECK(ssol_sun_set_direction(NULL, dir), RES_BAD_ARG);
+ CHECK(ssol_sun_set_direction(sun, NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_set_direction(sun, dir), RES_OK);
+
+ CHECK(ssol_sun_set_pillbox_aperture(NULL, 0.1), RES_BAD_ARG);
+ CHECK(ssol_sun_set_pillbox_aperture(sun, -0.1), RES_BAD_ARG);
+ CHECK(ssol_sun_set_pillbox_aperture(sun, 999), RES_BAD_ARG);
+ CHECK(ssol_sun_set_pillbox_aperture(sun, 0.1), RES_OK);
+
+ CHECK(ssol_sun_set_circumsolar_ratio(NULL, 0.1), RES_BAD_ARG);
+ CHECK(ssol_sun_set_circumsolar_ratio(sun, -0.1), RES_BAD_ARG);
+ CHECK(ssol_sun_set_circumsolar_ratio(sun, 999), RES_BAD_ARG);
+ CHECK(ssol_sun_set_circumsolar_ratio(sun, 0.1), RES_BAD_ARG);
+
+ CHECK(ssol_sun_ref_put(sun), RES_OK);
+
+ CHECK(ssol_sun_create_circumsolar_ratio(NULL, &sun), RES_BAD_ARG);
+ CHECK(ssol_sun_create_circumsolar_ratio(dev, NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_create_circumsolar_ratio(dev, &sun), RES_OK);
+
+ CHECK(ssol_sun_ref_get(NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_ref_get(sun), RES_OK);
+
+ CHECK(ssol_sun_ref_put(NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_ref_put(sun), RES_OK);
+
+ CHECK(ssol_sun_set_spectrum(NULL, spectrum), RES_BAD_ARG);
+ CHECK(ssol_sun_set_spectrum(sun, NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_set_spectrum(sun, spectrum), RES_OK);
+
+ CHECK(ssol_sun_set_direction(NULL, dir), RES_BAD_ARG);
+ CHECK(ssol_sun_set_direction(sun, NULL), RES_BAD_ARG);
+ CHECK(ssol_sun_set_direction(sun, dir), RES_OK);
+
+ CHECK(ssol_sun_set_pillbox_aperture(NULL, 0.1), RES_BAD_ARG);
+ CHECK(ssol_sun_set_pillbox_aperture(sun, -0.1), RES_BAD_ARG);
+ CHECK(ssol_sun_set_pillbox_aperture(sun, 999), RES_BAD_ARG);
+ CHECK(ssol_sun_set_pillbox_aperture(sun, 0.1), RES_BAD_ARG);
+
+ CHECK(ssol_sun_set_circumsolar_ratio(NULL, 0.1), RES_BAD_ARG);
+ CHECK(ssol_sun_set_circumsolar_ratio(sun, -0.1), RES_BAD_ARG);
+ CHECK(ssol_sun_set_circumsolar_ratio(sun, 999), RES_BAD_ARG);
+ CHECK(ssol_sun_set_circumsolar_ratio(sun, 0.1), RES_OK);
+
+ CHECK(ssol_sun_ref_put(sun), RES_OK);
+
+ CHECK(ssol_spectrum_ref_put(spectrum), RES_OK);
+ CHECK(ssol_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;
+}
+\ No newline at end of file