city_generator2

Generated conformal 3D meshes representing a city
git clone git://git.meso-star.fr/city_generator2.git
Log | Files | Refs | README | LICENSE

cg_catalog_parsing.c (5659B)


      1 /* Copyright (C) 2022 Université de Pau et des Pays de l'Adour UPPA
      2  * Copyright (C) 2022 CNRS
      3  * Copyright (C) 2022 Sorbonne Université
      4  * Copyright (C) 2022 Université Paul Sabatier
      5  * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
      6  *
      7  * This program is free software: you can redistribute it and/or modify
      8  * it under the terms of the GNU General Public License as published by
      9  * the Free Software Foundation, either version 3 of the License, or
     10  * (at your option) any later version.
     11  *
     12  * This program is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     15  * GNU General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU General Public License
     18  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     19 
     20 #include "cg.h"
     21 #include "cg_args.h"
     22 #include "cg_catalog_parsing.h"
     23 #include "cg_construction_mode_0_parsing_schemas.h"
     24 #include "cg_construction_mode_1_parsing_schemas.h"
     25 #include "cg_construction_mode_2_parsing_schemas.h"
     26 #include "cg_city_parsing_schemas.h"
     27 #include "cg_cyaml.h"
     28 
     29 #include <rsys/logger.h>
     30 #include <rsys/str.h>
     31 #include <rsys/clock_time.h>
     32 
     33 static const struct cyaml_schema_value*
     34 get_schema_from_parsed_cmode
     35   (const enum parsed_cmode_type parsed_cmode)
     36 {
     37     switch(parsed_cmode) {
     38       case PARSED_CMODE_0:
     39         return &construction_mode_0_schema;
     40       case PARSED_CMODE_1:
     41         return &construction_mode_1_schema;
     42       case PARSED_CMODE_2:
     43         return &construction_mode_2_schema;
     44       default: FATAL("Invalid enum value.\n");
     45     }
     46 }
     47 
     48 res_T
     49 parse_catalog
     50   (const struct darray_names* files_array,
     51    struct mem_allocator* allocator,
     52    struct logger* logger,
     53    const struct cyaml_config* config,
     54    struct parsed_catalog** out_parsed)
     55 {
     56   res_T res = RES_OK;
     57   cyaml_err_t err;
     58   size_t i, files_count;
     59   struct parsed_catalog_items* items;
     60   struct parsed_catalog* parsed;
     61   struct parsed_cmode* parsed_cmode = NULL;
     62   const char* filename = NULL;
     63   FILE* f;
     64   struct time t0, dt;
     65   char buf[128];
     66   (void)logger;
     67 
     68   ASSERT(files_array && allocator && logger && out_parsed);
     69 
     70   parsed = MEM_ALLOC(allocator, sizeof(*parsed));
     71   if(!parsed) {
     72     res = RES_MEM_ERR;
     73     goto error;
     74   }
     75 
     76   parsed->allocator = allocator;
     77   parsed->logger = logger;
     78 
     79   files_count = darray_names_size_get(files_array);
     80 
     81   darray_parsed_catalog_items_init(allocator, &parsed->catalog);
     82   ERR(darray_parsed_catalog_items_resize(&parsed->catalog, files_count));
     83   items = darray_parsed_catalog_items_data_get(&parsed->catalog);
     84   for(i = 0; i < files_count; i++) {
     85     const struct cyaml_schema_value* schema;
     86     size_t set_count;
     87 
     88     time_current(&t0);
     89     /* Parse construction mode only */
     90     filename = darray_names_cdata_get(files_array)[i];
     91     err = cyaml_load_file(filename, config, &construction_mode_schema,
     92         (void**)&parsed_cmode, NULL);
     93     ERR(cyaml_err_to_res_T(err));
     94 
     95     /* Parse catalog items according to construction mode */
     96     schema = get_schema_from_parsed_cmode(parsed_cmode->cmode_type);
     97     err = cyaml_load_file(filename, config, schema, &items[i].parsed_data, NULL);
     98     ERR(cyaml_err_to_res_T(err));
     99 
    100     /* Set other fields*/
    101     items[i].filename = filename;
    102     items[i].construction_mode = parsed_cmode->cmode_type;
    103 
    104     /* Log outcome */
    105     switch(items[i].construction_mode) {
    106       case PARSED_CMODE_0:
    107         set_count =
    108           ((struct parsed_catalog_cmode_0*)items[i].parsed_data)->datasets_count;
    109         break;
    110       case PARSED_CMODE_1:
    111         set_count =
    112           ((struct parsed_catalog_cmode_1*)items[i].parsed_data)->datasets_count;
    113         break;
    114       case PARSED_CMODE_2:
    115         set_count =
    116           ((struct parsed_catalog_cmode_2*)items[i].parsed_data)->datasets_count;
    117         break;
    118       default: FATAL("Invalid enum value.\n");
    119     }
    120     time_sub(&dt, time_current(&dt), &t0);
    121     time_dump(&dt, TIME_SEC | TIME_MSEC, NULL, buf, sizeof(buf));
    122     logger_print(logger, LOG_OUTPUT,
    123         "Catalog file '%s' parsed: mode '%s', %zu dataset(s) read. in %s\n",
    124         filename,
    125         city_building_types_strings[items[i].construction_mode].str,
    126         set_count,
    127         buf);
    128 
    129     /* Free tmp struct */
    130     err = cyaml_free(config, &construction_mode_schema, parsed_cmode, 1);
    131     CHK(RES_OK == cyaml_err_to_res_T(err));
    132     parsed_cmode = NULL;
    133     filename = NULL;
    134   }
    135 
    136 exit:
    137   if(parsed_cmode) {
    138     err = cyaml_free(config, &city_schema, parsed_cmode, 1);
    139     CHK(RES_OK == cyaml_err_to_res_T(err));
    140   }
    141   *out_parsed = parsed;
    142   return res;
    143 error:
    144   if(filename) {
    145     logger_print(logger, LOG_ERROR,
    146         "Error parsing catalog file '%s'.\n", filename);
    147   }
    148   f = fopen(filename, "r");
    149   if(f) {
    150     fclose(f);
    151   } else {
    152     logger_print(logger, LOG_ERROR, "Could not open file.\n");
    153   }
    154   release_parsed_catalog(config, parsed);
    155   parsed = NULL;
    156   goto exit;
    157 }
    158 
    159 void
    160 release_parsed_catalog
    161   (const struct cyaml_config* config,
    162    struct parsed_catalog* parsed)
    163 {
    164   struct parsed_catalog_items* items;
    165   size_t i, count;
    166 
    167   if(!parsed) return;
    168 
    169   ASSERT(config);
    170 
    171   count = darray_parsed_catalog_items_size_get(&parsed->catalog);
    172   items = darray_parsed_catalog_items_data_get(&parsed->catalog);
    173   for(i = 0; i < count; i++) {
    174     const struct cyaml_schema_value* schema
    175       = get_schema_from_parsed_cmode(items[i].construction_mode);
    176     cyaml_err_t err = cyaml_free(config, schema, items[i].parsed_data, 1);
    177     CHK(RES_OK == cyaml_err_to_res_T(err));
    178   }
    179   darray_parsed_catalog_items_release(&parsed->catalog);
    180   MEM_RM(parsed->allocator, parsed);
    181 }