rngrd

Describe a surface and its physical properties
git clone git://git.meso-star.fr/rngrd.git
Log | Files | Refs | README | LICENSE

rngrd.c (6924B)


      1 /* Copyright (C) 2022, 2023, 2025 Centre National de la Recherche Scientifique
      2  * Copyright (C) 2022, 2023, 2025 Institut Pierre-Simon Laplace
      3  * Copyright (C) 2022, 2023, 2025 Institut de Physique du Globe de Paris
      4  * Copyright (C) 2022, 2023, 2025 |Méso|Star> (contact@meso-star.com)
      5  * Copyright (C) 2022, 2023, 2025 Observatoire de Paris
      6  * Copyright (C) 2022, 2023, 2025 Université de Reims Champagne-Ardenne
      7  * Copyright (C) 2022, 2023, 2025 Université de Versaille Saint-Quentin
      8  * Copyright (C) 2022, 2023, 2025 Université Paul Sabatier
      9  *
     10  * This program is free software: you can redistribute it and/or modify
     11  * it under the terms of the GNU General Public License as published by
     12  * the Free Software Foundation, either version 3 of the License, or
     13  * (at your option) any later version.
     14  *
     15  * This program is distributed in the hope that it will be useful,
     16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     18  * GNU General Public License for more details.
     19  *
     20  * You should have received a copy of the GNU General Public License
     21  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     22 
     23 #include "rngrd.h"
     24 #include "rngrd_c.h"
     25 #include "rngrd_log.h"
     26 
     27 #include <mrumtl.h>
     28 
     29 #include <star/s3d.h>
     30 #include <star/sbuf.h>
     31 #include <star/ssf.h>
     32 
     33 #include <rsys/cstr.h>
     34 #include <rsys/mem_allocator.h>
     35 #include <rsys/str.h>
     36 
     37 /*******************************************************************************
     38  * Helper functions
     39  ******************************************************************************/
     40 static res_T
     41 check_rngrd_create_args(const struct rngrd_create_args* args)
     42 {
     43   /* Invalid args */
     44   if(!args) {
     45     return RES_BAD_ARG;
     46   }
     47   /* Filenames cannot be NULL */
     48   if(!args->smsh_filename
     49   || !args->props_filename
     50   || !args->mtllst_filename) {
     51     return RES_BAD_ARG;
     52   }
     53   /* The name cannot be NULL */
     54   if(!args->name) {
     55     return RES_BAD_ARG;
     56   }
     57 
     58   return RES_OK;
     59 }
     60 
     61 static res_T
     62 create_rngrd
     63   (const struct rngrd_create_args* args,
     64    struct rngrd** out_ground)
     65 {
     66   struct rngrd* ground = NULL;
     67   struct mem_allocator* allocator = NULL;
     68   res_T res = RES_OK;
     69 
     70   if(!out_ground) { res = RES_BAD_ARG; goto error;}
     71   res = check_rngrd_create_args(args);
     72   if(res != RES_OK) goto error;
     73 
     74   allocator = args->allocator ? args->allocator : &mem_default_allocator;
     75   ground = MEM_CALLOC(allocator, 1, sizeof(*ground));
     76   if(!ground) {
     77     if(args->verbose) {
     78       #define ERR_STR "Could not allocate the device of the Rad-Net GRounD library"
     79       if(args->logger) {
     80         logger_print(args->logger, LOG_ERROR, ERR_STR);
     81       } else {
     82         fprintf(stderr, MSG_ERROR_PREFIX ERR_STR);
     83       }
     84       #undef ERR_STR
     85     }
     86     res = RES_MEM_ERR;
     87     goto error;
     88   }
     89   ref_init(&ground->ref);
     90   ground->allocator = allocator;
     91   ground->verbose = args->verbose;
     92   darray_mtl_init(ground->allocator, &ground->mtls);
     93   str_init(ground->allocator, &ground->name);
     94   if(args->logger) {
     95     ground->logger = args->logger;
     96   } else {
     97     res = setup_log_default(ground);
     98     if(res != RES_OK) {
     99       if(args->verbose) {
    100         fprintf(stderr, MSG_ERROR_PREFIX
    101           "Could not setup the default logger of the Rad-Net GRounD library.\n");
    102       }
    103       goto error;
    104     }
    105   }
    106 
    107   res = str_set(&ground->name, args->name);
    108   if(res != RES_OK) {
    109     log_err(ground, "Could not setup the ground name to `%s' -- %s\n",
    110       args->name, res_to_cstr(res));
    111     goto error;
    112   }
    113 
    114 exit:
    115   if(out_ground) *out_ground = ground;
    116   return res;
    117 error:
    118   if(ground) { RNGRD(ref_put(ground)); ground = NULL; }
    119   goto exit;
    120 }
    121 
    122 static void
    123 release_rngrd(ref_T* ref)
    124 {
    125   struct rngrd* ground = CONTAINER_OF(ref, struct rngrd, ref);
    126   ASSERT(ref);
    127 
    128   if(ground->logger == &ground->logger__) logger_release(&ground->logger__);
    129   if(ground->s3d) S3D(device_ref_put(ground->s3d));
    130   if(ground->s3d_view) S3D(scene_view_ref_put(ground->s3d_view));
    131   if(ground->props) SBUF(ref_put(ground->props));
    132   darray_mtl_release(&ground->mtls);
    133   str_release(&ground->name);
    134   MEM_RM(ground->allocator, ground);
    135 }
    136 
    137 /*******************************************************************************
    138  * Exported symbols
    139  ******************************************************************************/
    140 res_T
    141 rngrd_create
    142   (const struct rngrd_create_args* args,
    143    struct rngrd** out_ground)
    144 {
    145   struct rngrd* ground = NULL;
    146   res_T res = RES_OK;
    147 
    148   res = create_rngrd(args, &ground);
    149   if(res != RES_OK) goto error;
    150 
    151   res = setup_mesh(ground, args);
    152   if(res != RES_OK) goto error;
    153   res = setup_properties(ground, args);
    154   if(res != RES_OK) goto error;
    155 
    156 exit:
    157   if(out_ground) *out_ground = ground;
    158   return res;
    159 error:
    160   if(ground) { RNGRD(ref_put(ground)); ground = NULL; }
    161   goto exit;
    162 }
    163 
    164 res_T
    165 rngrd_ref_get(struct rngrd* ground)
    166 {
    167   if(!ground) return RES_BAD_ARG;
    168   ref_get(&ground->ref);
    169   return RES_OK;
    170 }
    171 
    172 res_T
    173 rngrd_ref_put(struct rngrd* ground)
    174 {
    175   if(!ground) return RES_BAD_ARG;
    176   ref_put(&ground->ref, release_rngrd);
    177   return RES_OK;
    178 }
    179 
    180 res_T
    181 rngrd_validate(const struct rngrd* ground)
    182 {
    183   res_T res = RES_OK;
    184 
    185   if(!ground) { res = RES_BAD_ARG; goto error; }
    186 
    187   res = check_properties(ground);
    188   if(res != RES_OK) goto error;
    189 
    190 exit:
    191   return res;
    192 error:
    193   goto exit;
    194 }
    195 
    196 /*******************************************************************************
    197  * Local functions
    198  ******************************************************************************/
    199 res_T
    200 bsdf_init(struct mem_allocator* allocator, struct ssf_bsdf** bsdf)
    201 {
    202   ASSERT(bsdf);
    203   (void)allocator;
    204   *bsdf = NULL;
    205   return RES_OK;
    206 }
    207 
    208 void
    209 bsdf_release(struct ssf_bsdf** bsdf)
    210 {
    211   ASSERT(bsdf);
    212   if(*bsdf) SSF(bsdf_ref_put(*bsdf));
    213 }
    214 
    215 res_T
    216 bsdf_copy(struct ssf_bsdf** dst, struct ssf_bsdf* const* src)
    217 {
    218   ASSERT(dst && src);
    219   if(*dst) SSF(bsdf_ref_put(*dst));
    220   *dst = *src;
    221   if(*dst) SSF(bsdf_ref_get(*dst));
    222   return RES_OK;
    223 }
    224 
    225 res_T
    226 bsdf_copy_and_release(struct ssf_bsdf** dst, struct ssf_bsdf** src)
    227 {
    228   ASSERT(dst && src);
    229   if(*dst) SSF(bsdf_ref_put(*dst));
    230   *dst = *src;
    231   *src = NULL;
    232   return RES_OK;
    233 }
    234 
    235 
    236 res_T
    237 mtl_init(struct mem_allocator* allocator, struct mtl* mtl)
    238 {
    239   ASSERT(mtl);
    240   mtl->mrumtl = NULL;
    241   darray_bsdf_init(allocator, &mtl->bsdf_lst);
    242   return RES_OK;
    243 }
    244 
    245 void
    246 mtl_release(struct mtl* mtl)
    247 {
    248   ASSERT(mtl);
    249   if(mtl->mrumtl) MRUMTL(ref_put(mtl->mrumtl));
    250   darray_bsdf_release(&mtl->bsdf_lst);
    251 }
    252 
    253 res_T
    254 mtl_copy(struct mtl* dst, const struct mtl* src)
    255 {
    256   ASSERT(dst && src);
    257   if(dst->mrumtl) MRUMTL(ref_put(dst->mrumtl));
    258   dst->mrumtl = src->mrumtl;
    259   if(dst->mrumtl) MRUMTL(ref_get(dst->mrumtl));
    260   return darray_bsdf_copy(&dst->bsdf_lst, &src->bsdf_lst);;
    261 }
    262 
    263 res_T
    264 mtl_copy_and_release(struct mtl* dst, struct mtl* src)
    265 {
    266   ASSERT(dst && src);
    267   if(dst->mrumtl) MRUMTL(ref_put(dst->mrumtl));
    268   dst->mrumtl = src->mrumtl;
    269   src->mrumtl = NULL;
    270   return darray_bsdf_copy_and_release(&dst->bsdf_lst, &src->bsdf_lst);
    271 }