sdis_realisation.c (3602B)
1 /* Copyright (C) 2016-2025 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include "sdis_medium_c.h" 17 #include "sdis_realisation.h" 18 19 /******************************************************************************* 20 * Helper functions 21 ******************************************************************************/ 22 static INLINE res_T 23 check_ray_realisation_args(const struct ray_realisation_args* args) 24 { 25 /* Check pointers */ 26 if(!args || !args->rng) return RES_BAD_ARG; 27 28 if(args->time < 0) return RES_BAD_ARG; 29 if(args->picard_order <= 0) return RES_BAD_ARG; 30 31 if((unsigned)args->diff_algo >= SDIS_DIFFUSION_ALGORITHMS_COUNT__) { 32 return RES_BAD_ARG; 33 } 34 35 /* Check the enclosure identifier. Only its validity is checked, not the fact 36 * that the enclosure is a fluid. Even though Stardis doesn't allow you to 37 * sample a radiative path in a solid, we don't query the medium of the 38 * enclosure since it may contain several: querying the medium will therefore 39 * return an error. The type of medium is checked later, when sampling the 40 * radiative path, when it reaches an interface whose medium must be a fluid*/ 41 if(args->enc_id == ENCLOSURE_ID_NULL) { 42 return RES_BAD_ARG; 43 } 44 45 return RES_OK; 46 } 47 48 /******************************************************************************* 49 * Local functions 50 ******************************************************************************/ 51 /* Generate the generic realisations */ 52 #define SDIS_XD_DIMENSION 2 53 #include "sdis_realisation_Xd.h" 54 #define SDIS_XD_DIMENSION 3 55 #include "sdis_realisation_Xd.h" 56 57 res_T 58 ray_realisation_3d 59 (struct sdis_scene* scn, 60 struct ray_realisation_args* args, 61 double* weight) 62 { 63 struct rwalk_context ctx = RWALK_CONTEXT_NULL; 64 struct rwalk rwalk = RWALK_NULL; 65 struct temperature T = TEMPERATURE_NULL; 66 float dir[3]; 67 res_T res = RES_OK; 68 ASSERT(scn && weight && check_ray_realisation_args(args) == RES_OK); 69 70 d3_set(rwalk.vtx.P, args->position); 71 rwalk.vtx.time = args->time; 72 rwalk.hit_3d = S3D_HIT_NULL; 73 rwalk.hit_side = SDIS_SIDE_NULL__; 74 rwalk.enc_id = args->enc_id; 75 76 ctx.heat_path = args->heat_path; 77 ctx.Tmin = scn->tmin; 78 ctx.Tmin2 = ctx.Tmin * ctx.Tmin; 79 ctx.Tmin3 = ctx.Tmin * ctx.Tmin2; 80 ctx.That = scn->tmax; 81 ctx.That2 = ctx.That * ctx.That; 82 ctx.That3 = ctx.That * ctx.That2; 83 ctx.max_branchings = args->picard_order - 1; 84 ctx.irealisation = args->irealisation; 85 ctx.diff_algo = args->diff_algo; 86 87 f3_set_d3(dir, args->direction); 88 89 /* Register the starting position against the heat path */ 90 res = register_heat_vertex 91 (args->heat_path, &rwalk.vtx, 0, SDIS_HEAT_VERTEX_RADIATIVE, 0); 92 if(res != RES_OK) goto error; 93 94 res = trace_radiative_path_3d(scn, dir, &ctx, &rwalk, args->rng, &T); 95 if(res != RES_OK) goto error; 96 97 if(!T.done) { 98 res = sample_coupled_path_3d(scn, &ctx, &rwalk, args->rng, &T); 99 if(res != RES_OK) goto error; 100 } 101 102 *weight = T.value; 103 104 exit: 105 return res; 106 error: 107 goto exit; 108 } 109