test_ssol_solver12.c (7454B)
1 /* Copyright (C) 2018-2026 |Meso|Star> (contact@meso-star.com) 2 * Copyright (C) 2016, 2018 CNRS 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17 #include "ssol.h" 18 #include "test_ssol_utils.h" 19 #define REFLECTIVITY 0 20 #include "test_ssol_materials.h" 21 22 #include <rsys/math.h> 23 24 #define X_SZ 10 25 #define Y_SZ 10 26 #define PLANE_NAME SQUARE 27 #define HALF_X (X_SZ / 2) 28 #define HALF_Y (Y_SZ / 2) 29 STATIC_ASSERT((HALF_X * 2 == X_SZ), ONLY_ENVEN_VALUES_FOR_SQUARE_X); 30 STATIC_ASSERT((HALF_Y * 2 == Y_SZ), ONLY_ENVEN_VALUES_FOR_SQUARE_Y); 31 #include "test_ssol_rect_geometry.h" 32 33 #define POLYGON_NAME POLY 34 #define HALF_X (X_SZ / 2) 35 #define HALF_Y (Y_SZ / 2) 36 STATIC_ASSERT((HALF_X * 2 == X_SZ), ONLY_ENVEN_VALUES_FOR_X_SZ); 37 STATIC_ASSERT((HALF_Y * 2 == Y_SZ), ONLY_ENVEN_VALUES_FOR_Y_SZ); 38 #include "test_ssol_rect2D_geometry.h" 39 40 #include <rsys/double33.h> 41 42 #include <star/s3d.h> 43 #include <star/ssp.h> 44 45 static void 46 get_wlen(const size_t i, double* wlen, double* data, void* ctx) 47 { 48 double wavelengths[3] = { 1, 2, 3 }; 49 double intensities[3] = { 1, 0.8, 1 }; 50 CHK(i < 3); 51 (void) ctx; 52 *wlen = wavelengths[i]; 53 *data = intensities[i]; 54 } 55 56 int 57 main(int argc, char** argv) 58 { 59 struct mem_allocator allocator; 60 struct ssol_device* dev; 61 struct ssp_rng* rng; 62 struct ssol_scene* scene; 63 struct ssol_shape* square; 64 struct ssol_shape* parabol; 65 struct ssol_vertex_data attribs[1] = { SSOL_VERTEX_DATA_NULL__ }; 66 struct ssol_material* m_mtl; 67 struct ssol_matte_shader shader = SSOL_MATTE_SHADER_NULL; 68 struct ssol_object* m_object; 69 struct ssol_object* q_object; 70 struct ssol_carving carving = SSOL_CARVING_NULL; 71 struct ssol_quadric quadric = SSOL_QUADRIC_DEFAULT; 72 struct ssol_punched_surface punched = SSOL_PUNCHED_SURFACE_NULL; 73 struct ssol_instance* geom1; 74 struct ssol_instance* geom2; 75 struct ssol_sun* sun; 76 struct ssol_spectrum* spectrum; 77 struct ssol_estimator* estimator; 78 struct ssol_mc_global mc_global1; 79 struct ssol_mc_global mc_global2; 80 struct ssol_mc_receiver mc_rcv1; 81 struct ssol_mc_receiver mc_rcv2; 82 double dir[3]; 83 double transform[12]; /* 3x4 column major matrix */ 84 size_t count; 85 86 (void) argc, (void) argv; 87 mem_init_proxy_allocator(&allocator, &mem_default_allocator); 88 89 d33_set_identity(transform); 90 91 CHK(ssol_device_create 92 (NULL, &allocator, SSOL_NTHREADS_DEFAULT, 0, &dev) == RES_OK); 93 94 #define DNI 1000 95 CHK(ssp_rng_create(&allocator, SSP_RNG_THREEFRY, &rng) == RES_OK); 96 CHK(ssol_spectrum_create(dev, &spectrum) == RES_OK); 97 CHK(ssol_spectrum_setup(spectrum, get_wlen, 3, NULL) == RES_OK); 98 CHK(ssol_sun_create_gaussian(dev, &sun) == RES_OK); 99 CHK(ssol_sun_gaussian_set_std_dev(sun, 0.01) == RES_OK); 100 CHK(ssol_sun_set_direction(sun, d3(dir, 0, 0, -1)) == RES_OK); 101 CHK(ssol_sun_set_spectrum(sun, spectrum) == RES_OK); 102 CHK(ssol_sun_set_dni(sun, DNI) == RES_OK); 103 CHK(ssol_scene_create(dev, &scene) == RES_OK); 104 CHK(ssol_scene_attach_sun(scene, sun) == RES_OK); 105 106 /* Create scene content */ 107 108 CHK(ssol_shape_create_mesh(dev, &square) == RES_OK); 109 attribs[0].usage = SSOL_POSITION; 110 attribs[0].get = get_position; 111 CHK(ssol_mesh_setup(square, SQUARE_NTRIS__, get_ids, 112 SQUARE_NVERTS__, attribs, 1, (void*) &SQUARE_DESC__) == RES_OK); 113 114 CHK(ssol_material_create_matte(dev, &m_mtl) == RES_OK); 115 shader.normal = get_shader_normal; 116 shader.reflectivity = get_shader_reflectivity_2; 117 CHK(ssol_matte_setup(m_mtl, &shader) == RES_OK); 118 119 CHK(ssol_object_create(dev, &m_object) == RES_OK); 120 CHK(ssol_object_add_shaded_shape(m_object, square, m_mtl, m_mtl) == RES_OK); 121 CHK(ssol_object_instantiate(m_object, &geom1) == RES_OK); 122 CHK(ssol_instance_set_receiver(geom1, SSOL_FRONT, 0) == RES_OK); 123 d3_splat(transform + 9, 0); 124 transform[9] = -10; 125 CHK(ssol_instance_set_transform(geom1, transform) == RES_OK); 126 CHK(ssol_scene_attach_instance(scene, geom1) == RES_OK); 127 128 #define N1__ 10000 129 #define GET_MC_RCV ssol_estimator_get_mc_receiver 130 CHK(ssol_solve(scene, rng, N1__, 0, NULL, &estimator) == RES_OK); 131 CHK(ssol_estimator_get_realisation_count(estimator, &count) == RES_OK); 132 CHK(count == N1__); 133 CHK(ssol_estimator_get_failed_count(estimator, &count) == RES_OK); 134 CHK(count == 0); 135 #define DNI_S (DNI * X_SZ * Y_SZ) 136 CHK(ssol_estimator_get_mc_global(estimator, &mc_global1) == RES_OK); 137 CHK(GET_MC_RCV(estimator, geom1, SSOL_FRONT, &mc_rcv1) == RES_OK); 138 139 print_global(&mc_global1); 140 print_rcv(&mc_rcv1); 141 CHK(mc_global1.cos_factor.E == 1); 142 CHK(mc_global1.cos_factor.SE == 0); 143 CHK(mc_global1.absorbed_by_receivers.E == DNI_S); 144 CHK(mc_global1.absorbed_by_receivers.SE == 0); 145 146 CHK(ssol_shape_create_punched_surface(dev, ¶bol) == RES_OK); 147 carving.get = get_polygon_vertices; 148 carving.operation = SSOL_AND; 149 carving.nb_vertices = POLY_NVERTS__; 150 carving.context = &POLY_EDGES__; 151 quadric.type = SSOL_QUADRIC_PARABOL; 152 quadric.data.parabol.focal = 10; 153 punched.nb_carvings = 1; 154 punched.quadric = &quadric; 155 punched.carvings = &carving; 156 CHK(ssol_punched_surface_setup(parabol, &punched) == RES_OK); 157 158 CHK(ssol_object_create(dev, &q_object) == RES_OK); 159 CHK(ssol_object_add_shaded_shape(q_object, parabol, m_mtl, m_mtl) == RES_OK); 160 CHK(ssol_object_instantiate(q_object, &geom2) == RES_OK); 161 CHK(ssol_instance_set_receiver(geom2, SSOL_FRONT, 0) == RES_OK); 162 d3_splat(transform + 9, 0); 163 transform[9] = +10; 164 CHK(ssol_instance_set_transform(geom2, transform) == RES_OK); 165 CHK(ssol_scene_attach_instance(scene, geom2) == RES_OK); 166 167 CHK(ssol_scene_detach_instance(scene, geom1) == RES_OK); 168 CHK(ssol_estimator_ref_put(estimator) == RES_OK); 169 170 #define N2__ 100000 171 CHK(ssol_solve(scene, rng, N2__, 0, NULL, &estimator) == RES_OK); 172 CHK(ssol_estimator_get_realisation_count(estimator, &count) == RES_OK); 173 CHK(count == N2__); 174 CHK(ssol_estimator_get_failed_count(estimator, &count) == RES_OK); 175 CHK(count == 0); 176 CHK(ssol_estimator_get_mc_global(estimator, &mc_global2) == RES_OK); 177 CHK(GET_MC_RCV(estimator, geom2, SSOL_FRONT, &mc_rcv2) == RES_OK); 178 179 print_global(&mc_global2); 180 print_rcv(&mc_rcv2); 181 CHK(eq_eps(mc_global2.absorbed_by_receivers.E, DNI_S, 3 * mc_global2.absorbed_by_receivers.SE) == 1); 182 183 /* Free data */ 184 CHK(ssol_instance_ref_put(geom1) == RES_OK); 185 CHK(ssol_instance_ref_put(geom2) == RES_OK); 186 CHK(ssol_object_ref_put(m_object) == RES_OK); 187 CHK(ssol_object_ref_put(q_object) == RES_OK); 188 CHK(ssol_shape_ref_put(square) == RES_OK); 189 CHK(ssol_shape_ref_put(parabol) == RES_OK); 190 CHK(ssol_material_ref_put(m_mtl) == RES_OK); 191 CHK(ssol_estimator_ref_put(estimator) == RES_OK); 192 CHK(ssol_device_ref_put(dev) == RES_OK); 193 CHK(ssol_scene_ref_put(scene) == RES_OK); 194 CHK(ssp_rng_ref_put(rng) == RES_OK); 195 CHK(ssol_spectrum_ref_put(spectrum) == RES_OK); 196 CHK(ssol_sun_ref_put(sun) == RES_OK); 197 198 check_memory_allocator(&allocator); 199 mem_shutdown_proxy_allocator(&allocator); 200 CHK(mem_allocated_size() == 0); 201 202 return 0; 203 }