star-phor-input

File format for describing photoreactor configurations
git clone https://www.edstar.cnrs.fr/git/star-phor-input.git
Log | Files | Refs | README | LICENSE

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 }