htrdr_atmosphere_args.c (8099B)
1 /* Copyright (C) 2018-2019, 2022-2025 Centre National de la Recherche Scientifique 2 * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux 3 * Copyright (C) 2022-2025 Institut Pierre-Simon Laplace 4 * Copyright (C) 2022-2025 Institut de Physique du Globe de Paris 5 * Copyright (C) 2018-2025 |Méso|Star> (contact@meso-star.com) 6 * Copyright (C) 2022-2025 Observatoire de Paris 7 * Copyright (C) 2022-2025 Université de Reims Champagne-Ardenne 8 * Copyright (C) 2022-2025 Université de Versaille Saint-Quentin 9 * Copyright (C) 2018-2019, 2022-2025 Université Paul Sabatier 10 * 11 * This program is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation, either version 3 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 23 24 #include "atmosphere/htrdr_atmosphere_args.h" 25 26 #include <rsys/cstr.h> 27 28 #include <getopt.h> 29 30 /******************************************************************************* 31 * Helper functions 32 ******************************************************************************/ 33 static void 34 usage(void) 35 { 36 printf("usage: htrdr-atmosphere [-dfhRrv] [-c clouds]\n"); 37 printf(" [-C persp_camera_opt[:persp_camera_opt ...]]\n"); 38 printf(" [-D sun_azimuth,sun_elevation] [-g ground]\n"); 39 printf(" [-i image_opt[:image_opt ...]] [-M materials] [-m mie]\n"); 40 printf(" [-n sky_mtl] [-O cache] [-o output]\n"); 41 printf(" [-P ortho_camera_opt[:ortho_camera_opt ...]]\n"); 42 printf(" [-p flux_sensor_opt[:flux_sensor_opt ...]]\n"); 43 printf(" [-s spectral_opt[:spectral_opt ...]]\n"); 44 printf(" [-T optical_thickness] [-t threads_count] [-V x,y,z]\n"); 45 printf(" -a atmosphere\n"); 46 } 47 48 static res_T 49 parse_grid_definition(struct htrdr_atmosphere_args* args, const char* str) 50 { 51 unsigned def[3]; 52 size_t len; 53 res_T res = RES_OK; 54 ASSERT(args && str); 55 56 res = cstr_to_list_uint(str, ',', def, &len, 3); 57 if(res == RES_OK && len != 3) res = RES_BAD_ARG; 58 if(res != RES_OK) { 59 fprintf(stderr, "Invalid grid definition `%s'.\n", str); 60 goto error; 61 } 62 63 if(!def[0] || !def[1] || !def[2]) { 64 fprintf(stderr, 65 "Invalid null grid definition {%u, %u, %u}.\n", SPLIT3(def)); 66 res = RES_BAD_ARG; 67 goto error; 68 } 69 70 args->grid_max_definition[0] = def[0]; 71 args->grid_max_definition[1] = def[1]; 72 args->grid_max_definition[2] = def[2]; 73 74 exit: 75 return res; 76 error: 77 goto exit; 78 } 79 80 static res_T 81 parse_sun_dir(struct htrdr_atmosphere_args* args, const char* str) 82 { 83 double angles[2]; 84 size_t len; 85 res_T res = RES_OK; 86 ASSERT(args && str); 87 88 res = cstr_to_list_double(str, ',', angles, &len, 2); 89 if(res == RES_OK && len != 2) res = RES_BAD_ARG; 90 if(res != RES_OK) { 91 fprintf(stderr, "Invalid direction `%s'.\n", str); 92 goto error; 93 } 94 95 if(angles[0] < 0 || angles[0] >= 360) { 96 fprintf(stderr, 97 "Invalid azimuth angle `%g'. Azimuth must be in [0, 360[ degrees.\n", 98 angles[0]); 99 res = RES_BAD_ARG; 100 goto error; 101 } 102 103 if(angles[1] < 0 || angles[1] > 90) { 104 fprintf(stderr, 105 "Invalid elevation angle `%g'. Elevation must be in [0, 90] degrees.\n", 106 angles[1]); 107 res = RES_BAD_ARG; 108 goto error; 109 } 110 111 args->sun_azimuth = angles[0]; 112 args->sun_elevation = angles[1]; 113 114 exit: 115 return res; 116 error: 117 goto exit; 118 } 119 120 /******************************************************************************* 121 * Local functions 122 ******************************************************************************/ 123 res_T 124 htrdr_atmosphere_args_init 125 (struct htrdr_atmosphere_args* args, 126 int argc, 127 char** argv) 128 { 129 int opt; 130 res_T res = RES_OK; 131 ASSERT(args && argc && argv); 132 133 *args = HTRDR_ATMOSPHERE_ARGS_DEFAULT; 134 135 while((opt = getopt(argc, argv, "a:C:c:D:dfg:hi:M:m:n:O:o:P:p:Rrs:T:t:V:v")) != -1) { 136 switch(opt) { 137 case 'a': args->filename_gas = optarg; break; 138 case 'C': 139 args->output_type = HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE; 140 args->cam_type = HTRDR_ARGS_CAMERA_PERSPECTIVE; 141 res = htrdr_args_camera_perspective_parse(&args->cam_persp, optarg); 142 break; 143 case 'c': args->filename_les = optarg; break; 144 case 'D': res = parse_sun_dir(args, optarg); break; 145 case 'd': 146 args->output_type = HTRDR_ATMOSPHERE_ARGS_OUTPUT_OCTREES; 147 break; 148 case 'f': args->force_overwriting = 1; break; 149 case 'g': args->filename_obj = optarg; break; 150 case 'h': 151 usage(); 152 htrdr_atmosphere_args_release(args); 153 args->quit = 1; 154 goto exit; 155 case 'i': 156 res = htrdr_args_image_parse(&args->image, optarg); 157 break; 158 case 'M': args->filename_mtl = optarg; break; 159 case 'm': args->filename_mie = optarg; break; 160 case 'n': args->sky_mtl_name = optarg; break; 161 case 'O': args->filename_cache = optarg; break; 162 case 'o': args->filename_output = optarg; break; 163 case 'p': 164 args->output_type = HTRDR_ATMOSPHERE_ARGS_OUTPUT_FLUX_MAP;; 165 res = htrdr_args_rectangle_parse(&args->flux_map, optarg); 166 break; 167 case 'P': 168 args->output_type = HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE; 169 args->cam_type = HTRDR_ARGS_CAMERA_ORTHOGRAPHIC; 170 res = htrdr_args_camera_orthographic_parse(&args->cam_ortho, optarg); 171 break; 172 case 'r': args->repeat_clouds = 1; break; 173 case 'R': args->repeat_ground = 1; break; 174 case 's': 175 res = htrdr_args_spectral_parse(&args->spectral, optarg); 176 break; 177 case 'T': 178 res = cstr_to_double(optarg, &args->optical_thickness); 179 if(res == RES_OK && args->optical_thickness < 0) res = RES_BAD_ARG; 180 break; 181 case 't': /* Submit an hint on the number of threads to use */ 182 res = cstr_to_uint(optarg, &args->nthreads); 183 if(res == RES_OK && !args->nthreads) res = RES_BAD_ARG; 184 break; 185 case 'V': res = parse_grid_definition(args, optarg); break; 186 case 'v': args->verbose = 1; break; 187 default: res = RES_BAD_ARG; break; 188 } 189 if(res != RES_OK) { 190 if(optarg) { 191 fprintf(stderr, "%s: invalid option argument '%s' -- '%c'\n", 192 argv[0], optarg, opt); 193 } 194 goto error; 195 } 196 } 197 if(!args->filename_gas) { 198 fprintf(stderr, 199 "missing the path of the gas optical properties file -- option '-a'\n"); 200 res = RES_BAD_ARG; 201 goto error; 202 } 203 if(args->filename_obj && !args->filename_mtl) { 204 fprintf(stderr, 205 "missing the path of the file listing the ground materials -- option '-M'\n"); 206 res = RES_BAD_ARG; 207 goto error; 208 } 209 if(args->filename_les && !args->filename_mie) { 210 fprintf(stderr, 211 "missing the path toward the file of the Mie's data -- option '-m'\n"); 212 res = RES_BAD_ARG; 213 goto error; 214 } 215 216 /* Setup default ref temperature if necessary */ 217 if(args->spectral.ref_temperature <= 0) { 218 switch(args->spectral.spectral_type) { 219 case HTRDR_SPECTRAL_LW: 220 args->spectral.ref_temperature = HTRDR_DEFAULT_LW_REF_TEMPERATURE; 221 break; 222 case HTRDR_SPECTRAL_SW: 223 args->spectral.ref_temperature = HTRDR_SUN_TEMPERATURE; 224 break; 225 case HTRDR_SPECTRAL_SW_CIE_XYZ: 226 args->spectral.ref_temperature = -1; /* Unused */ 227 break; 228 default: FATAL("Unreachable code.\n"); break; 229 } 230 } 231 232 exit: 233 return res; 234 error: 235 usage(); 236 htrdr_atmosphere_args_release(args); 237 goto exit; 238 } 239 240 void 241 htrdr_atmosphere_args_release(struct htrdr_atmosphere_args* args) 242 { 243 ASSERT(args); 244 *args = HTRDR_ATMOSPHERE_ARGS_DEFAULT; 245 }