sphin_brdf.c (6740B)
1 /* Copyright (C) 2024-2026 Centre National de la Recherche Scientifique 2 * Copyright (C) 2024-2026 Clermont Auvergne INP 3 * Copyright (C) 2024-2026 INSA Lyon 4 * Copyright (C) 2024-2026 Institut Mines Télécom Albi-Carmaux 5 * Copyright (C) 2024-2026 Institut National Polytechnique de Toulouse 6 * Copyright (C) 2024-2026 |Méso|Star> (contact@meso-star.com) 7 * Copyright (C) 2024-2026 PhotonLyX (info@photonlyx.com) 8 * Copyright (C) 2024-2026 Université de Lorraine 9 * Copyright (C) 2024-2026 Université Paul Sabatier 10 * Copyright (C) 2024-2026 Université Toulouse - Jean Jaurès 11 * 12 * This program is free software: you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation, either version 3 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 24 25 #define _POSIX_C_SOURCE 200112L /* for strtok_r support */ 26 27 #include "sphin.h" 28 #include "sphin_c.h" 29 #include "sphin_brdf.h" 30 #include "sphin_config.h" 31 #include "sphin_spectral_property.h" 32 33 #include <rsys/cstr.h> 34 #include <rsys/mem_allocator.h> 35 #include <rsys/ref_count.h> 36 #include <rsys/rsys.h> 37 #include <rsys/text_reader.h> 38 39 struct sphin_brdf { 40 enum sphin_brdf_direction_distribution direction_distribution; 41 enum sphin_brdf_reflectivity_type reflectivity_type; /* Constant, Frensel */ 42 struct sphin_spectral_property* reflectivity; /* Only used if reflectivity is 43 * a constant */ 44 struct sphin* sphin; 45 ref_T ref; 46 }; 47 48 /******************************************************************************* 49 * Helper functions 50 ******************************************************************************/ 51 static res_T 52 brdf_create 53 (struct sphin* sphin, 54 struct sphin_brdf** out_brdf) 55 { 56 struct sphin_brdf* brdf = NULL; 57 res_T res = RES_OK; 58 59 ASSERT(NULL != sphin); 60 ASSERT(NULL != out_brdf); 61 62 brdf = MEM_CALLOC(sphin->allocator, 1, sizeof(struct sphin_brdf)); 63 if (NULL == brdf) { res = RES_MEM_ERR; goto error; } 64 ref_init(&brdf->ref); 65 SPHIN(ref_get(sphin)); 66 brdf->sphin = sphin; 67 brdf->reflectivity_type = SPHIN_BRDF_REFLECTIVITY_NONE__; 68 brdf->direction_distribution = SPHIN_BRDF_DIRECTION_NONE__; 69 brdf->reflectivity = NULL; 70 71 exit: 72 *out_brdf = brdf; 73 return res; 74 error: 75 if (NULL != brdf) { 76 SPHIN(brdf_ref_put(brdf)); 77 brdf = NULL; 78 } 79 goto exit; 80 } 81 82 static void 83 release_brdf 84 (ref_T* address) 85 { 86 struct sphin_brdf* brdf = NULL; 87 struct sphin* sphin = NULL; 88 89 ASSERT(NULL != address); 90 91 brdf = CONTAINER_OF(address, struct sphin_brdf, ref); 92 sphin = brdf->sphin; 93 if (NULL != brdf->reflectivity) { 94 SPHIN(spectral_property_ref_put(brdf->reflectivity)); 95 } 96 MEM_RM(sphin->allocator, brdf); 97 SPHIN(ref_put(sphin)); 98 } 99 100 /******************************************************************************* 101 * Local functions 102 ******************************************************************************/ 103 res_T 104 parse_brdf 105 (struct sphin* sphin, 106 struct txtrdr* txtrdr, 107 char* value, 108 struct sphin_brdf** out_brdf) 109 { 110 char* brdf_type = NULL; 111 char* str_reflectivity = NULL; 112 char* token_ptr = NULL; 113 char* filename = NULL; 114 struct sphin_brdf* brdf = NULL; 115 res_T res = RES_OK; 116 117 ASSERT(NULL != sphin); 118 ASSERT(NULL != txtrdr); 119 ASSERT(NULL != out_brdf); 120 121 if (NULL == value) { res = RES_BAD_ARG; goto error; } 122 123 res = brdf_create(sphin, &brdf); 124 if (RES_OK != res) { goto error; } 125 /* Parse brdf type */ 126 brdf_type = strtok_r(value, " \t", &token_ptr); 127 if (NULL == brdf_type){ res = RES_BAD_ARG; goto error; } 128 if (0 == strcmp(brdf_type, "LAMBERT")) { 129 brdf->direction_distribution = SPHIN_BRDF_DIRECTION_LAMBERT; 130 } 131 else if (0 == strcmp(brdf_type, "SPECULAR")) { 132 brdf->direction_distribution = SPHIN_BRDF_DIRECTION_SPECULAR; 133 } 134 else { res = RES_BAD_ARG; goto error; } 135 136 /* Parse reflectivity value */ 137 str_reflectivity = strtok_r(NULL, " \t", &token_ptr); 138 if (NULL == str_reflectivity){ res = RES_BAD_ARG; goto error; } 139 140 if (0 == strcmp(str_reflectivity, "FRESNEL_DIELECTRIC")) { 141 brdf->reflectivity_type = SPHIN_BRDF_REFLECTIVITY_FRESNEL_DIELECTRIC; 142 } 143 else if (0 == strcmp(str_reflectivity, "FRESNEL_DIELECTRIC_CONDUCTOR")) { 144 brdf->reflectivity_type 145 = SPHIN_BRDF_REFLECTIVITY_FRESNEL_DIELECTRIC_CONDUCTOR; 146 } 147 else { 148 filename = trim_keyword(str_reflectivity); 149 if (NULL == filename) { res = RES_BAD_ARG; goto error; } 150 151 res = parse_spectral_property(sphin, filename, &brdf->reflectivity); 152 if (RES_OK != res) { goto error; } 153 154 brdf->reflectivity_type = SPHIN_BRDF_REFLECTIVITY_TABULATED; 155 } 156 157 res = txtrdr_read_line(txtrdr); 158 if (RES_OK != res) { goto error; } 159 160 exit: 161 *out_brdf = brdf; 162 return res; 163 error: 164 if (brdf != NULL){ 165 SPHIN(brdf_ref_put(brdf)); 166 brdf = NULL; 167 } 168 goto exit; 169 } 170 171 /******************************************************************************* 172 * Exported functions 173 ******************************************************************************/ 174 res_T 175 sphin_brdf_ref_get 176 (struct sphin_brdf* brdf) 177 { 178 if (NULL == brdf) { 179 return RES_BAD_ARG; 180 } 181 ref_get(&brdf->ref); 182 return RES_OK; 183 } 184 185 res_T 186 sphin_brdf_ref_put 187 (struct sphin_brdf* brdf) 188 { 189 if (NULL == brdf) { 190 return RES_BAD_ARG; 191 } 192 ref_put(&brdf->ref, release_brdf); 193 return RES_OK; 194 } 195 196 res_T 197 sphin_brdf_get_direction_distribution 198 (struct sphin_brdf* brdf, 199 enum sphin_brdf_direction_distribution* direction_distribution) 200 { 201 res_T res = RES_OK; 202 203 if (NULL == brdf || NULL == direction_distribution) { 204 return RES_BAD_ARG; 205 } 206 207 *direction_distribution = brdf->direction_distribution; 208 return res; 209 } 210 211 res_T 212 sphin_brdf_get_reflectivity_type 213 (struct sphin_brdf* brdf, 214 enum sphin_brdf_reflectivity_type* reflectivity_type) 215 { 216 res_T res = RES_OK; 217 218 if (NULL == brdf || NULL == reflectivity_type) { 219 return RES_BAD_ARG; 220 } 221 222 *reflectivity_type= brdf->reflectivity_type; 223 return res; 224 } 225 226 res_T 227 sphin_brdf_get_reflectivity_value 228 (struct sphin_brdf* brdf, 229 struct sphin_spectral_property** reflectivity) 230 { 231 res_T res = RES_OK; 232 233 if (NULL == brdf || NULL == reflectivity) { 234 return RES_BAD_ARG; 235 } 236 237 /* Not defined for Fresnel reflectivities types */ 238 if (SPHIN_BRDF_REFLECTIVITY_TABULATED != brdf->reflectivity_type) { 239 return RES_BAD_ARG; 240 } 241 242 *reflectivity = brdf->reflectivity; 243 244 return res; 245 }