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.c (9586B)


      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_building.h"
     22 #include "cg_catalog.h"
     23 #include "cg_catalog_parsing.h"
     24 #include "cg_construction_mode_0.h"
     25 #include "cg_construction_mode_1.h"
     26 #include "cg_construction_mode_2.h"
     27 #include "cg_construction_mode_0_parsing_schemas.h"
     28 #include "cg_construction_mode_1_parsing_schemas.h"
     29 #include "cg_construction_mode_2_parsing_schemas.h"
     30 
     31 #include <rsys/rsys.h>
     32 #include <rsys/mem_allocator.h>
     33 #include <rsys/logger.h>
     34 #include <rsys/str.h>
     35 
     36 static const char*
     37 find_first_filename
     38   (const char* dataset_name,
     39    const enum parsed_cmode_type dataset_cmode,
     40    const struct parsed_catalog_items* items,
     41    size_t count)
     42 {
     43   size_t i, j;
     44 
     45   ASSERT(dataset_name && items && count > 0);
     46 
     47   for(i = 0; i < count; i++) {
     48     if(items[i].construction_mode != dataset_cmode) continue;
     49     switch(items[i].construction_mode) {
     50       case mode_0: {
     51         const struct parsed_catalog_cmode_0* prsd_0 = items[i].parsed_data;
     52         for(j = 0; j < prsd_0->datasets_count; j++) {
     53           const struct parsed_dataset_cmode_0* prsd_item = prsd_0->datasets + j;
     54           if(0 == strcmp(prsd_item->name, dataset_name)) {
     55               return items[i].filename;
     56             }
     57         }
     58         break;
     59       }
     60       case mode_1: {
     61         const struct parsed_catalog_cmode_1* prsd_1 = items[i].parsed_data;
     62         for(j = 0; j < prsd_1->datasets_count; j++) {
     63           const struct parsed_dataset_cmode_1* prsd_item = prsd_1->datasets + j;
     64           if(0 == strcmp(prsd_item->name, dataset_name)) {
     65               return items[i].filename;
     66             }
     67         }
     68         break;
     69       }
     70       case mode_2: {
     71         const struct parsed_catalog_cmode_2* prsd_2 = items[i].parsed_data;
     72         for(j = 0; j < prsd_2->datasets_count; j++) {
     73           const struct parsed_dataset_cmode_2* prsd_item = prsd_2->datasets + j;
     74           if(0 == strcmp(prsd_item->name, dataset_name)) {
     75               return items[i].filename;
     76             }
     77         }
     78         break;
     79       }
     80       default: FATAL("Invalid enum value.");
     81     }
     82   }
     83   CHK(0); /* Should not be there */
     84 }
     85 
     86 res_T
     87 create_catalog
     88   (struct mem_allocator* allocator,
     89    struct logger* logger,
     90    struct parsed_catalog* parsed_catalog,
     91    struct catalog** out_catalog)
     92 {
     93   res_T res = RES_OK;
     94   size_t i, j, count;
     95   const struct parsed_catalog_items* items;
     96   struct catalog* catalog;
     97   struct str name;
     98   int name_initialized = 0;
     99 
    100   ASSERT(allocator && logger && parsed_catalog && out_catalog);
    101 
    102   catalog = MEM_ALLOC(allocator, sizeof(*catalog));
    103   if(!catalog) {
    104     res = RES_MEM_ERR;
    105     goto error;
    106   }
    107 
    108   str_init(allocator, &name);
    109   name_initialized = 0;
    110 
    111   catalog->allocator = allocator;
    112   catalog->logger = logger;
    113   htable_dataset_cmode_0_init(allocator, &catalog->catalog_0);
    114   htable_dataset_cmode_1_init(allocator, &catalog->catalog_1);
    115   htable_dataset_cmode_2_init(allocator, &catalog->catalog_2);
    116   count = darray_parsed_catalog_items_size_get(&parsed_catalog->catalog);
    117   items = darray_parsed_catalog_items_cdata_get(&parsed_catalog->catalog);
    118 
    119   for(i = 0; i < count; i++) {
    120     switch(items[i].construction_mode) {
    121       case mode_0: {
    122         const struct parsed_catalog_cmode_0* parsed_0 = items[i].parsed_data;
    123         for(j = 0; j < parsed_0->datasets_count; j++) {
    124           const struct parsed_dataset_cmode_0* parsed_item
    125             = parsed_0->datasets + j;
    126           struct dataset_cmode_0 item;
    127           ERR(str_set(&name, parsed_item->name));
    128           /* test name unicity */
    129           if(htable_dataset_cmode_0_find(&catalog->catalog_0, &name)) {
    130             const char* first_filename
    131             = find_first_filename(parsed_item->name, PARSED_CMODE_0, items, count);
    132             logger_print(logger, LOG_ERROR,
    133                 "Duplicate dataset name: '%s' (in files '%s' and '%s').\n",
    134                 parsed_item->name, first_filename, items[i].filename);
    135             res = RES_BAD_ARG;
    136             goto error;
    137           }
    138           /* Setup item */
    139           item.wall_thickness = parsed_item->wall_thickness;
    140           item.floor_thickness = parsed_item->floor_thickness;
    141           ERR(htable_dataset_cmode_0_set(&catalog->catalog_0, &name, &item));
    142         }
    143         break;
    144       }
    145       case mode_1: {
    146         const struct parsed_catalog_cmode_1* parsed_1 = items[i].parsed_data;
    147         for(j = 0; j < parsed_1->datasets_count; j++) {
    148           const struct parsed_dataset_cmode_1* parsed_item
    149             = parsed_1->datasets + j;
    150           struct dataset_cmode_1 item;
    151           ERR(str_set(&name, parsed_item->name));
    152           /* test name unicity */
    153           if(htable_dataset_cmode_1_find(&catalog->catalog_1, &name)) {
    154             const char* first_filename
    155             = find_first_filename(parsed_item->name, PARSED_CMODE_1, items, count);
    156             logger_print(logger, LOG_ERROR,
    157                 "Duplicate dataset name: '%s' (in files '%s' and '%s').\n",
    158                 parsed_item->name, first_filename, items[i].filename);
    159             res = RES_BAD_ARG;
    160             goto error;
    161           }
    162           /* Setup item */
    163           item.inter_floor_count = parsed_item->inter_floor_count;
    164           item.wall_thickness = parsed_item->wall_thickness;
    165           item.floor_thickness = parsed_item->floor_thickness;
    166           item.inter_floor_thickness = parsed_item->inter_floor_thickness;
    167           item.roof_thickness = parsed_item->roof_thickness;
    168           item.internal_insulation_thickness
    169             = parsed_item->internal_insulation_thickness;
    170           item.external_insulation_thickness
    171             = parsed_item->external_insulation_thickness;
    172           item.floor_insulation_thickness = parsed_item->floor_insulation_thickness;
    173           item.roof_insulation_thickness = parsed_item->roof_insulation_thickness;
    174           item.foundation_depth = parsed_item->foundation_depth;
    175           item.crawl_height = parsed_item->crawl_height;
    176           item.attic_height = parsed_item->attic_height;
    177           item.glass_ratio = parsed_item->glass_ratio;
    178           ERR(htable_dataset_cmode_1_set(&catalog->catalog_1, &name, &item));
    179         }
    180         break;
    181       }
    182       case mode_2: {
    183         const struct parsed_catalog_cmode_2* parsed_2 = items[i].parsed_data;
    184         for(j = 0; j < parsed_2->datasets_count; j++) {
    185           const struct parsed_dataset_cmode_2* parsed_item
    186             = parsed_2->datasets + j;
    187           struct dataset_cmode_2 item;
    188           ERR(str_set(&name, parsed_item->name));
    189           /* test name unicity */
    190           if(htable_dataset_cmode_2_find(&catalog->catalog_2, &name)) {
    191             const char* first_filename
    192             = find_first_filename(parsed_item->name, PARSED_CMODE_2, items, count);
    193             logger_print(logger, LOG_ERROR,
    194                 "Duplicate dataset name: '%s' (in files '%s' and '%s').\n",
    195                 parsed_item->name, first_filename, items[i].filename);
    196             res = RES_BAD_ARG;
    197             goto error;
    198           }
    199           /* Setup item */
    200           item.wall_thickness = parsed_item->wall_thickness;
    201           item.floor_thickness = parsed_item->floor_thickness;
    202           item.inter_floor_thickness = parsed_item->inter_floor_thickness;
    203           item.roof_thickness = parsed_item->roof_thickness;
    204           item.internal_insulation_thickness
    205             = parsed_item->internal_insulation_thickness;
    206           item.external_insulation_thickness
    207             = parsed_item->external_insulation_thickness;
    208           item.floor_insulation_thickness = parsed_item->floor_insulation_thickness;
    209           item.roof_insulation_thickness = parsed_item->roof_insulation_thickness;
    210           item.foundation_depth = parsed_item->foundation_depth;
    211           item.crawl_height = parsed_item->crawl_height;
    212           item.has_attic = parsed_item->has_attic;
    213           item.glass_ratio = parsed_item->glass_ratio;
    214           item.windows_min_width = parsed_item->windows_min_width;
    215           item.windows_max_width = parsed_item->windows_max_width;
    216           item.windows_min_spacing = parsed_item->windows_min_spacing;
    217           item.windows_height_ratio = parsed_item->windows_height_ratio;
    218           ERR(htable_dataset_cmode_2_set(&catalog->catalog_2, &name, &item));
    219         }
    220         break;
    221       }
    222       default: FATAL("Invalid enum value.");
    223     }
    224   }
    225 exit:
    226   if(name_initialized) str_release(&name);
    227   *out_catalog = catalog;
    228   return res;
    229 error:
    230   release_catalog(catalog);
    231   catalog = NULL;
    232   goto exit;
    233 }
    234 
    235 void
    236 release_catalog
    237   (struct catalog* catalog)
    238 {
    239   if(!catalog) return;
    240 
    241   htable_dataset_cmode_0_release(&catalog->catalog_0);
    242   htable_dataset_cmode_1_release(&catalog->catalog_1);
    243   htable_dataset_cmode_2_release(&catalog->catalog_2);
    244   MEM_RM(catalog->allocator, catalog);
    245 }
    246