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 }