commit d586516b973d19f472d97256d4605250fce34797
parent e26c0b1c7d435b81ebf582ec253626c46baacc3f
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Mon, 9 Jan 2023 12:11:08 +0100
Replace hard-coded catalog by yaml files parsing
Diffstat:
22 files changed, 1042 insertions(+), 455 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -54,6 +54,7 @@ set(CG2_VERSION ${CG2_VERSION_MAJOR}.${CG2_VERSION_MINOR}.${CG2_VERSION_PATCH})
set(CG2_FILES_SRC
cg_args.c
+ cg_catalog.c
cg_catalog_parsing.c
cg_city.c
cg_city_parsing.c
@@ -66,13 +67,16 @@ set(CG2_FILES_INC
cg.h
cg_args.h
cg_building.h
+ cg_catalog.h
cg_catalog_parsing.h
cg_city.h
cg_city_parsing.h
cg_city_parsing_schemas.h
cg_constructive_mode.h
cg_constructive_mode_0.h
+ cg_constructive_mode_0_parsing_schemas.h
cg_constructive_mode_1.h
+ cg_constructive_mode_1_parsing_schemas.h
cg_default.h.in
cg_ground.h
cg_version.h.in)
diff --git a/src/cg.h b/src/cg.h
@@ -20,7 +20,51 @@
#ifndef CG_H
#define CG_H
+#include <rsys/rsys.h>
+#include <cyaml/cyaml.h>
+
#define ERR(Expr) if((res = (Expr)) != RES_OK) goto error; else (void)0
+static INLINE void
+log_prt_fn(const char* msg, void* ctx)
+{
+ ASSERT(msg);
+ (void)ctx;
+
+ fprintf(stderr, "\x1b[32moutput:\x1b[0m %s", msg);
+}
+
+static INLINE void
+log_warn_fn(const char* msg, void* ctx)
+{
+ ASSERT(msg);
+ (void)ctx;
+
+ fprintf(stderr, "\x1b[33mwarning:\x1b[0m %s", msg);
+}
+
+static INLINE void
+log_err_fn(const char* msg, void* ctx)
+{
+ ASSERT(msg);
+ (void)ctx;
+
+ fprintf(stderr, "\x1b[31merror:\x1b[0m %s", msg);
+}
+
+static INLINE res_T
+cyaml_err_to_res_T(const cyaml_err_t err)
+{
+ res_T res = RES_OK;
+
+ switch(err) {
+ case CYAML_OK: res = RES_OK; break;
+ case CYAML_ERR_OOM: res = RES_MEM_ERR; break;
+ case CYAML_ERR_FILE_OPEN: res = RES_IO_ERR; break;
+ default: res = RES_UNKNOWN_ERR; break;
+ }
+ return res;
+}
+
#endif /*CG_H*/
diff --git a/src/cg_args.c b/src/cg_args.c
@@ -18,6 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "cg_args.h"
+#include "cg_catalog_parsing.h"
#include "cg_version.h"
#include "cg_default.h"
#include "cg.h"
@@ -41,17 +42,18 @@ short_help(void)
{
print_version();
printf("\nUsage:\n"
- "city_generator2 [-a] -b <FILENAME> -c <FILENAME> [-V verbosity]\n"
+ "city_generator2 -m <FILENAME> -c <FILENAME> [-V verbosity]\n"
"city_generator2 [-h]\n"
"city_generator2 [-v]\n"
);
printf(
"\nMandatory options\n"
"-----------------\n"
- "-b <construction_mode_filename>\n"
- " Read a yaml text file that describes the building.\n"
- "-c <city_filename>\n"
- " Read a yaml text file that describes the city.\n"
+ "-c <filename>\n"
+ " Read a yaml text file containing datasets for a given constructive mode.\n"
+ " Can be used more than once.\n"
+ "-m <city_map_filename>\n"
+ " Read a yaml text file that describes the city map.\n"
"\nOther options\n"
"-------------\n"
"-h\n"
@@ -80,19 +82,35 @@ short_help(void)
res_T
parse_args
- (struct logger* logger,
+ (struct mem_allocator* allocator,
+ struct logger* logger,
int argc,
char** argv,
- struct args* args)
+ struct args** out_args)
{
res_T res = RES_OK;
int opt;
- int info_provided = 0, b_provided = 0, c_provided = 0;
- struct args aaa = ARGS_NULL__;
- const char option_list[] = "b:c:f:hvV:";
+ int info_provided = 0, c_provided = 0, m_provided = 0;
+ struct args* args;
+ const char option_list[] = "c:m:f:hvV:";
+
+ ASSERT(allocator && logger && argv && out_args);
+
+ args = MEM_ALLOC(allocator, sizeof(*args));
+ if(!args) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ args->allocator = allocator;
+ args->logger = logger;
/* Set default values */
- *args = aaa;
+ args->city_filename = NULL;
+ darray_catalog_filenames_init(allocator, &args->catalog_filenames);
+ args->binary_export = CG2_BINARY_EXPORT_DEFAULT;
+ args->verbosity_level = CG2_DEFAULT_VERBOSE_LEVEL;
+ args->print_help = 0;
+ args->print_version = 0;
opterr = 0; /* No default error messages */
while((opt = getopt(argc, argv, option_list)) != -1) {
@@ -113,24 +131,19 @@ parse_args
goto error;
}
- case 'b':
- if(b_provided) {
- logger_print(logger, LOG_ERROR, "Option -%c provided twice.\n", opt);
- res = RES_BAD_ARG;
- goto error;
- }
- args->constructive_mode_filename = optarg;
- b_provided = 1;
+ case 'c':
+ c_provided = 1;
+ ERR(darray_catalog_filenames_push_back(&args->catalog_filenames, &optarg));
break;
- case 'c':
- if(c_provided) {
+ case 'm':
+ if(m_provided) {
logger_print(logger, LOG_ERROR, "Option -%c provided twice.\n", opt);
res = RES_BAD_ARG;
goto error;
}
args->city_filename = optarg;
- c_provided = 1;
+ m_provided = 1;
break;
case 'f':
@@ -183,14 +196,14 @@ parse_args
goto error;
}
- if(!b_provided && !info_provided) {
+ if(!c_provided && !info_provided) {
ERR(logger_print(logger, LOG_ERROR,
"Missing mandatory argument: -b <construction_mode_filename>\n"));
res = RES_BAD_ARG;
goto error;
}
- if(!c_provided && !info_provided) {
+ if(!m_provided && !info_provided) {
ERR(logger_print(logger, LOG_ERROR,
"Missing mandatory argument: -c <city_filename>\n"));
res = RES_BAD_ARG;
@@ -198,7 +211,20 @@ parse_args
}
exit:
+ *out_args = args;
return res;
error:
+ release_args(args);
+ args = NULL;
goto exit;
}
+
+void
+release_args
+ (struct args* args)
+{
+ if(!args) return;
+
+ darray_catalog_filenames_release(&args->catalog_filenames);
+ MEM_RM(args->allocator, args);
+}
diff --git a/src/cg_args.h b/src/cg_args.h
@@ -20,27 +20,37 @@
#ifndef PARSE_ARGS_H
#define PARSE_ARGS_H
-#include "cg_default.h"
-
#include <rsys/rsys.h>
+#include <rsys/dynamic_array.h>
struct logger;
-struct args;
+#define DARRAY_NAME catalog_filenames
+#define DARRAY_DATA char*
+#include <rsys/dynamic_array.h>
struct args {
+ struct mem_allocator* allocator;
+ struct logger* logger;
char* city_filename;
- char* constructive_mode_filename;
+ struct darray_catalog_filenames catalog_filenames;
int binary_export;
int verbosity_level;
int print_help;
int print_version;
};
-#define ARGS_NULL__ \
- { NULL, NULL, CG2_BINARY_EXPORT_DEFAULT, CG2_DEFAULT_VERBOSE_LEVEL, 0, 0 }
res_T
-parse_args(struct logger* logger, int argc, char** argv, struct args* args);
+parse_args
+ (struct mem_allocator* allocator,
+ struct logger* logger,
+ int argc,
+ char** argv,
+ struct args** out_args);
+
+void
+release_args
+ (struct args* args);
void
print_version(void);
diff --git a/src/cg_building.h b/src/cg_building.h
@@ -24,30 +24,34 @@
#include <rsys/str.h>
#include <rsys/hash_table.h>
-/* The specific constructive modes headers must be included here. */
#include "cg_constructive_mode_0.h"
#include "cg_constructive_mode_1.h"
struct scpr_polygon;
struct scad_geometry;
struct mem_allocator;
+struct logger;
+struct catalog;
/* A type to store the functors of a constructive mode */
struct constructive_mode_functors {
res_T (*init)
(struct building* building,
struct mem_allocator* allocator,
+ struct logger* logger,
struct parsed_city_building* parsed_data,
- struct htable_parameter_set* catalog);
+ struct catalog* catalog);
res_T (*build_cad)
- (struct building* building, struct mem_allocator* allocator, void** cad);
+ (struct building* building, struct mem_allocator* allocator,
+ struct logger* logger, void** cad);
res_T (*build_footprint)
(struct building* building, struct mem_allocator* allocator,
- struct scad_geometry** footprint);
+ struct logger* logger, struct scad_geometry** footprint);
res_T (*export_stl)
- (void* cad, const int binary);
+ (void* cad, struct mem_allocator* allocator, struct logger* logger,
+ const int binary);
res_T (*release_cad)
- (struct mem_allocator* allocator, void* cad);
+ (struct mem_allocator* allocator, struct logger* logger, void* cad);
};
/* A type to give an ID to constructive modes.
@@ -61,40 +65,6 @@ enum constructive_mode_type {
/* The name of the constructive modes, as expected in the city description. */
extern char const* constructive_mode_name[CONSTRUCTIVE_MODES_COUNT__];
-/* A type to store the parameter sets.
- * As each constructive mode has its own parameters, the actual struct is hidden
- * behind a void* data pointer. */
-struct parameter_set {
- enum constructive_mode_type constructive_mode;
- struct str name;
- void* data;
-};
-
-/* Utility function to define a hash table */
-static INLINE char
-eq_str(const struct str* a, const struct str* b)
-{
- return !strcmp(str_cget(a), str_cget(b));
-}
-
-static INLINE size_t
-hash_str(const struct str* a)
-{
- return hash_fnv32(str_cget(a), str_len(a));
-}
-
-/* A hash table to store building parameter-sets by name */
-#define HTABLE_NAME parameter_set
-#define HTABLE_DATA struct parameter_set
-#define HTABLE_KEY struct str
-#define HTABLE_KEY_FUNCTOR_INIT str_init
-#define HTABLE_KEY_FUNCTOR_RELEASE str_release
-#define HTABLE_KEY_FUNCTOR_COPY str_copy
-#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release
-#define HTABLE_KEY_FUNCTOR_EQ eq_str
-#define HTABLE_KEY_FUNCTOR_HASH hash_str
-#include <rsys/hash_table.h>
-
/* The type of buildings as described in the city description */
struct building {
/* constructive mode */
diff --git a/src/cg_catalog.c b/src/cg_catalog.c
@@ -0,0 +1,141 @@
+/* Copyright (C) 2022 Université de Pau et des Pays de l'Adour UPPA
+ * Copyright (C) 2022 CNRS
+ * Copyright (C) 2022 Sorbonne Université
+ * Copyright (C) 2022 Université Paul Sabatier
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "cg.h"
+#include "cg_catalog.h"
+#include "cg_catalog_parsing.h"
+#include "cg_constructive_mode_0.h"
+#include "cg_constructive_mode_1.h"
+#include "cg_constructive_mode_0_parsing_schemas.h"
+#include "cg_constructive_mode_1_parsing_schemas.h"
+
+#include <rsys/rsys.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/logger.h>
+#include <rsys/str.h>
+
+res_T
+create_catalog
+ (struct mem_allocator* allocator,
+ struct logger* logger,
+ struct parsed_catalog* parsed_catalog,
+ struct catalog** out_catalog)
+{
+ res_T res = RES_OK;
+ size_t i, j, count;
+ const struct parsed_catalog_items* items;
+ struct catalog* catalog;
+ struct str name;
+ int name_initialized = 0;
+
+ ASSERT(allocator && logger && parsed_catalog && out_catalog);
+
+ catalog = MEM_ALLOC(allocator, sizeof(*catalog));
+ if(!catalog) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+
+ str_init(allocator, &name);
+ name_initialized = 0;
+
+ catalog->allocator = allocator;
+ catalog->logger = logger;
+ htable_dataset_cmode_0_init(allocator, &catalog->catalog_0);
+ htable_dataset_cmode_1_init(allocator, &catalog->catalog_1);
+ count = darray_parsed_catalog_items_size_get(&parsed_catalog->catalog);
+ items = darray_parsed_catalog_items_cdata_get(&parsed_catalog->catalog);
+
+ for(i = 0; i < count; i++) {
+ switch(items[i].constructive_mode) {
+ case mode_0: {
+ const struct parsed_catalog_cmode_0* parsed_0 = items[i].parsed_items;
+ for(j = 0; j < parsed_0->datasets_count; j++) {
+ const struct parsed_dataset_cmode_0* parsed_item
+ = parsed_0->datasets + j;
+ struct dataset_cmode_0 item;
+ ERR(str_set(&name, parsed_item->name));
+ if(htable_dataset_cmode_0_find(&catalog->catalog_0, &name)) {
+ logger_print(logger, LOG_ERROR,
+ "Duplicate dataset name: '%s' (in file '%s').\n",
+ parsed_item->name, items[i].filename);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ item.wall_thickness = parsed_item->wall_thickness;
+ item.floor_thickness = parsed_item->floor_thickness;
+ ERR(htable_dataset_cmode_0_set(&catalog->catalog_0, &name, &item));
+ }
+ break;
+ }
+ case mode_1: {
+ const struct parsed_catalog_cmode_1* parsed_1 = items[i].parsed_items;
+ for(j = 0; j < parsed_1->datasets_count; j++) {
+ const struct parsed_dataset_cmode_1* parsed_item
+ = parsed_1->datasets + j;
+ struct dataset_cmode_1 item;
+ ERR(str_set(&name, parsed_item->name));
+ if(htable_dataset_cmode_1_find(&catalog->catalog_1, &name)) {
+ logger_print(logger, LOG_ERROR,
+ "Duplicate dataset name: '%s' (in file '%s').\n",
+ parsed_item->name, items[i].filename);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ item.inter_floor_count = parsed_item->inter_floor_count;
+ item.wall_thickness = parsed_item->wall_thickness;
+ item.floor_thickness = parsed_item->floor_thickness;
+ item.inter_floor_thickness = parsed_item->inter_floor_thickness;
+ item.roof_thickness = parsed_item->roof_thickness;
+ item.internal_insulation_thickness = parsed_item->internal_insulation_thickness;
+ item.external_insulation_thickness = parsed_item->external_insulation_thickness;
+ item.floor_insulation_thickness = parsed_item->floor_insulation_thickness;
+ item.roof_insulation_thickness = parsed_item->roof_insulation_thickness;
+ item.foundation_depth = parsed_item->foundation_depth;
+ item.crawl_height = parsed_item->crawl_height;
+ item.attic_height = parsed_item->attic_height;
+ item.glass_ratio = parsed_item->glass_ratio;
+ ERR(htable_dataset_cmode_1_set(&catalog->catalog_1, &name, &item));
+ }
+ break;
+ }
+ default: FATAL("Invalid enum value.");
+ }
+ }
+exit:
+ if(name_initialized) str_release(&name);
+ *out_catalog = catalog;
+ return res;
+error:
+ release_catalog(catalog);
+ catalog = NULL;
+ goto exit;
+}
+
+void
+release_catalog
+ (struct catalog* catalog)
+{
+ if(!catalog) return;
+
+ htable_dataset_cmode_0_release(&catalog->catalog_0);
+ htable_dataset_cmode_1_release(&catalog->catalog_1);
+ MEM_RM(catalog->allocator, catalog);
+}
+
diff --git a/src/cg_catalog.h b/src/cg_catalog.h
@@ -0,0 +1,51 @@
+/* Copyright (C) 2022 Université de Pau et des Pays de l'Adour UPPA
+ * Copyright (C) 2022 CNRS
+ * Copyright (C) 2022 Sorbonne Université
+ * Copyright (C) 2022 Université Paul Sabatier
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef FG_CATALOG__
+#define FG_CATALOG__
+
+#include "cg_constructive_mode_0.h"
+#include "cg_constructive_mode_1.h"
+#include "cg_constructive_mode_0_parsing_schemas.h"
+#include "cg_constructive_mode_1_parsing_schemas.h"
+
+struct mem_allocator;
+struct logger;
+struct parsed_catalog;
+struct catalog;
+
+struct catalog {
+ struct mem_allocator* allocator;
+ struct logger* logger;
+ struct htable_dataset_cmode_0 catalog_0;
+ struct htable_dataset_cmode_1 catalog_1;
+};
+
+res_T
+create_catalog
+ (struct mem_allocator* allocator,
+ struct logger* logger,
+ struct parsed_catalog* parsed_catalog,
+ struct catalog** out_catalog);
+
+void
+release_catalog
+ (struct catalog* catalog);
+
+#endif
diff --git a/src/cg_catalog_parsing.c b/src/cg_catalog_parsing.c
@@ -18,106 +18,124 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "cg.h"
+#include "cg_args.h"
#include "cg_catalog_parsing.h"
+#include "cg_constructive_modes_parsing_schemas.h"
#include "cg_building.h"
#include <rsys/logger.h>
#include <rsys/str.h>
-#include <rsys/stretchy_array.h>
+
+#include <cyaml/cyaml.h>
+
+static const struct cyaml_schema_value*
+get_schema_from_parsed_cmode
+ (const enum parsed_cmode_type parsed_cmode)
+{
+ switch(parsed_cmode) {
+ case PARSED_CMODE_0:
+ return &constructive_mode_0_schema;
+ case PARSED_CMODE_1:
+ return &constructive_mode_1_schema;
+ default: FATAL("Invalid enum value.\n");
+ }
+}
res_T
parse_catalog
- (struct logger* logger,
- struct htable_parameter_set* catalog)
+ (const struct darray_catalog_filenames* files_array,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ const struct cyaml_config* config,
+ struct parsed_catalog** out_parsed)
{
res_T res = RES_OK;
- struct data_set_cmode_0* data0;
- struct data_set_cmode_1* data1;
- struct parameter_set* params0;
+ cyaml_err_t err;
+ size_t i, files_count;
+ struct parsed_catalog_items* items;
+ struct parsed_catalog* parsed;
+ struct parsed_cmode* parsed_cmode = NULL;
+ char* filename = NULL;
(void)logger;
- htable_parameter_set_init(NULL, catalog);
+ ASSERT(files_array && allocator && logger && out_parsed);
- params0 = malloc(2*sizeof(struct parameter_set));
- if (!params0) {
+ parsed = MEM_ALLOC(allocator, sizeof(*parsed));
+ if(!parsed) {
res = RES_MEM_ERR;
goto error;
}
- data0 = malloc(sizeof(struct data_set_cmode_0));
- if (!data0) {
- res = RES_MEM_ERR;
- goto error;
+ parsed->allocator = allocator;
+ parsed->logger = logger;
+
+ files_count = darray_catalog_filenames_size_get(files_array);
+
+ darray_parsed_catalog_items_init(allocator, &parsed->catalog);
+ ERR(darray_parsed_catalog_items_resize(&parsed->catalog, files_count));
+ items = darray_parsed_catalog_items_data_get(&parsed->catalog);
+ for(i = 0; i < files_count; i++) {
+ const struct cyaml_schema_value* schema;
+
+ /* Parse constructive mode only */
+ filename = darray_catalog_filenames_cdata_get(files_array)[i];
+ err = cyaml_load_file(filename, config, &constructive_mode_schema,
+ (void**)&parsed_cmode, NULL);
+ ERR(cyaml_err_to_res_T(err));
+
+ /* Parse catalog items according to constructive mode */
+ schema = get_schema_from_parsed_cmode(parsed_cmode->cmode_type);
+ err = cyaml_load_file(filename, config, schema, &items[i].parsed_items, NULL);
+ ERR(cyaml_err_to_res_T(err));
+
+ /* Set other fields*/
+ items[i].filename = filename;
+ items[i].constructive_mode = parsed_cmode->cmode_type;
+
+ /* Free tmp struct */
+ err = cyaml_free(config, &constructive_mode_schema, parsed_cmode, 1);
+ CHK(RES_OK == cyaml_err_to_res_T(err));
+ parsed_cmode = NULL;
+ filename = NULL;
}
- params0[0].constructive_mode = mode_0;
- str_init(NULL, ¶ms0[0].name);
- ERR(str_set(¶ms0[0].name, "b0"));
- data0->wall = 0.2;
- data0->floor = 0.3;
- params0[0].data = malloc(sizeof(struct data_set_cmode_0));
- params0[0].data = (void*)data0;
- ERR(htable_parameter_set_set(catalog, ¶ms0[0].name, ¶ms0[0]));
-
- data1 = malloc(sizeof(struct data_set_cmode_1));
- if (!data1) {
- res = RES_MEM_ERR;
- goto error;
- }
- params0[1].constructive_mode = mode_1;
- str_init(NULL, ¶ms0[1].name);
- ERR(str_set(¶ms0[1].name, "b1"));
- data1->wall = 0.25;
- data1->floor = 0.35;
- data1->inter_floor = 0.2;
- data1->inter_floor_n = 0;
- data1->roof = 0.3;
- data1->int_insulation = 0.1;
- data1->ext_insulation = 0.2;
- data1->floor_insulation = 0;
- data1->roof_insulation = 0;
- data1->foundation = 2;
- data1->crawl = 0;
- data1->attic = 0;
- data1->glass_ratio = 0.5;
- params0[1].data = malloc(sizeof(struct data_set_cmode_1));
- params0[1].data = (void*)data1;
- ERR(htable_parameter_set_set(catalog, ¶ms0[1].name, ¶ms0[1]));
-
- /* check coherence */
- if (data1->roof_insulation <= 0) data1->attic = 0;
- if (data1->inter_floor <= 0) data1->inter_floor_n = 0;
- if (data1->inter_floor_n <= 0) data1->inter_floor = 0;
exit:
- free(params0);
+ if(parsed_cmode) {
+ err = cyaml_free(config, &city_schema, parsed_cmode, 1);
+ CHK(RES_OK == cyaml_err_to_res_T(err));
+ }
+ *out_parsed = parsed;
return res;
error:
- htable_parameter_set_release(catalog);
+ if(filename) {
+ logger_print(logger, LOG_ERROR,
+ "Error parsing catalog file '%s'.\n", filename);
+ }
+ release_parsed_catalog(config, parsed);
+ parsed = NULL;
goto exit;
}
-res_T
-release_params_building(struct parameter_set* params)
+void
+release_parsed_catalog
+ (const struct cyaml_config* config,
+ struct parsed_catalog* parsed)
{
- res_T res = RES_OK;
- size_t i;
+ struct parsed_catalog_items* items;
+ size_t i, count;
- if (!params) {
- res = RES_BAD_ARG;
- goto error;
- }
+ if(!parsed) return;
- printf("size params %lu \n", sa_size(params));
+ ASSERT(config);
- for (i=0; i<sa_size(params); ++i) {
- free(params[i].data);
+ count = darray_parsed_catalog_items_size_get(&parsed->catalog);
+ items = darray_parsed_catalog_items_data_get(&parsed->catalog);
+ for(i = 0; i < count; i++) {
+ const struct cyaml_schema_value* schema
+ = get_schema_from_parsed_cmode(items[i].constructive_mode);
+ cyaml_err_t err = cyaml_free(config, schema, items[i].parsed_items, 1);
+ CHK(RES_OK == cyaml_err_to_res_T(err));
}
-
- sa_release(params);
-
-exit:
- return res;
-error:
- goto exit;
+ darray_parsed_catalog_items_release(&parsed->catalog);
+ MEM_RM(parsed->allocator, parsed);
}
-
diff --git a/src/cg_catalog_parsing.h b/src/cg_catalog_parsing.h
@@ -20,22 +20,47 @@
#ifndef PARSING_H
#define PARSING_H
-#include <ctype.h>
+#include "cg_building.h"
+#include "cg_constructive_mode_0_parsing_schemas.h"
+#include "cg_constructive_mode_1_parsing_schemas.h"
+#include "cg_constructive_modes_parsing_schemas.h"
#include <rsys/rsys.h>
+#include <rsys/dynamic_array.h>
-struct txtrdr;
struct logger;
-struct htable_parameter_set;
+struct mem_allocator;
+struct cyaml_config;
+struct cyaml_schema_value;
+struct darray_catalog_filenames;
-struct parameter_set;
+struct parsed_catalog_items {
+ enum parsed_cmode_type constructive_mode;
+ const char* filename;
+ void* parsed_items;
+};
+
+#define DARRAY_NAME parsed_catalog_items
+#define DARRAY_DATA struct parsed_catalog_items
+#include <rsys/dynamic_array.h>
+
+struct parsed_catalog {
+ struct mem_allocator* allocator;
+ struct logger* logger;
+ struct darray_parsed_catalog_items catalog;
+};
res_T
parse_catalog
- (struct logger* logger,
- struct htable_parameter_set* catalog);
+ (const struct darray_catalog_filenames* files,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ const struct cyaml_config* config,
+ struct parsed_catalog** catalog);
-res_T
-release_params_building(struct parameter_set* params);
+void
+release_parsed_catalog
+ (const struct cyaml_config* config,
+ struct parsed_catalog* parsed);
#endif /*PARSING_H*/
diff --git a/src/cg_city.c b/src/cg_city.c
@@ -39,12 +39,12 @@
#include <string.h>
res_T
-city_create
+create_city
(struct mem_allocator* allocator,
struct logger* logger,
const struct args* args,
struct parsed_city* parsed_city,
- struct htable_parameter_set* catalog,
+ struct catalog* catalog,
struct city** out_city)
{
res_T res = RES_OK;
@@ -82,10 +82,10 @@ city_create
struct building* building = city->buildings + i;
switch(parsed_data->cmode_type) {
case PARSED_CMODE_0:
- ERR(init_model0(building, allocator, parsed_data, catalog));
+ ERR(init_cmode_0(building, allocator, logger, parsed_data, catalog));
break;
case PARSED_CMODE_1:
- ERR(init_model1(building, allocator, parsed_data, catalog));
+ ERR(init_cmode_1(building, allocator, logger, parsed_data, catalog));
break;
default:
res = RES_BAD_ARG;
@@ -97,35 +97,27 @@ exit:
*out_city = city;
return res;
error:
- if(city) city_release(city);
+ release_city(city);
out_city = NULL;
goto exit;
}
-res_T
-city_release(struct city* city)
+void
+release_city(struct city* city)
{
- res_T res = RES_OK;
size_t i;
+ if(!city) return;
+
/* iterate on building */
for (i=0; i<city->buildings_count; ++i) {
struct building* building = city->buildings + i;
-
- ERR(scpr_polygon_ref_put(building->pg));
-
- if(building->name_initialized) {
- str_release(&building->name);
- }
+ SCPR(polygon_ref_put(building->pg));
+ if(building->name_initialized) str_release(&building->name);
}
MEM_RM(city->allocator, city->buildings);
MEM_RM(city->allocator, city);
-
-exit:
- return res;
-error:
- goto exit;
}
res_T
@@ -147,10 +139,12 @@ city_cad_build(struct city* city)
struct building* building = city->buildings + i;
struct data_cad_cmode_0* cad = NULL;
/* create building */
- ERR(building->functors->build_cad(building, city->allocator, (void**)&cad));
+ ERR(building->functors->build_cad(building, city->allocator, city->logger,
+ (void**)&cad));
ERR(scad_scene_mesh());
- ERR(building->functors->export_stl(cad, city->binary_export));
- ERR(building->functors->release_cad(city->allocator, cad));
+ ERR(building->functors->export_stl(cad, city->allocator, city->logger,
+ city->binary_export));
+ ERR(building->functors->release_cad(city->allocator, city->logger, cad));
ERR(scad_scene_clear());
}
@@ -183,7 +177,8 @@ city_ground_build(struct city* city)
struct building* building = city->buildings + i;
struct scad_geometry** footprint = ground.footprints + i;
/* create building footprint */
- ERR(building->functors->build_footprint(building, city->allocator, footprint));
+ ERR(building->functors->build_footprint(building, city->allocator,
+ city->logger, footprint));
}
ERR(ground_build_cad(city, &ground));
diff --git a/src/cg_city.h b/src/cg_city.h
@@ -30,34 +30,7 @@ struct mem_allocator;
struct building;
struct args;
struct parsed_city;
-struct htable_parameter_set;
-
-static INLINE void
-log_prt_fn(const char* msg, void* ctx)
-{
- ASSERT(msg);
- (void)ctx;
-
- fprintf(stderr, "\x1b[32moutput:\x1b[0m %s", msg);
-}
-
-static INLINE void
-log_warn_fn(const char* msg, void* ctx)
-{
- ASSERT(msg);
- (void)ctx;
-
- fprintf(stderr, "\x1b[33mwarning:\x1b[0m %s", msg);
-}
-
-static INLINE void
-log_err_fn(const char* msg, void* ctx)
-{
- ASSERT(msg);
- (void)ctx;
-
- fprintf(stderr, "\x1b[31merror:\x1b[0m %s", msg);
-}
+struct catalog;
struct city {
double ground_extent[4]; /* [xmin, xmax, ymin, ymax */
@@ -72,12 +45,13 @@ struct city {
};
res_T
-city_create
+create_city
(struct mem_allocator* allocator,
struct logger* logger,
const struct args* args,
struct parsed_city* parsed_city,
- struct htable_parameter_set* catalog, struct city** out_city);
+ struct catalog* catalog,
+ struct city** out_city);
res_T
city_cad_build
@@ -87,7 +61,7 @@ res_T
city_ground_build
(struct city* city);
-res_T
-city_release(struct city* city);
+void
+release_city(struct city* city);
#endif /*CITY_H*/
diff --git a/src/cg_city_parsing.c b/src/cg_city_parsing.c
@@ -42,56 +42,35 @@ parse_city
struct parsed_city *parsed = NULL;
cyaml_err_t err;
- (void)allocator; (void)logger;
-
- if(!name || !config || !out_parsed) {
- res = RES_BAD_ARG;
- goto error;
- }
+ ASSERT(allocator && logger && name && config && out_parsed);
err = cyaml_load_file(name, config, &city_schema, (void**)&parsed, NULL);
+ ERR(cyaml_err_to_res_T(err));
- switch(err) {
- case CYAML_OK: break;
- case CYAML_ERR_OOM: res = RES_MEM_ERR; goto error;
- case CYAML_ERR_FILE_OPEN: res = RES_IO_ERR; goto error;
- default: res = RES_UNKNOWN_ERR; goto error;
- }
-
- *out_parsed = parsed;
+ parsed->allocator = allocator;
+ parsed->logger = logger;
exit:
+ *out_parsed = parsed;
return res;
error:
- cyaml_free(config, &city_schema, parsed, 1);
+ logger_print(logger, LOG_ERROR, "Error parsing city map file '%s'.\n", name);
+ release_parsed_city(config, parsed);
parsed = NULL;
goto exit;
}
-res_T
+void
release_parsed_city
(const struct cyaml_config* config,
struct parsed_city* parsed)
{
- res_T res = RES_OK;
cyaml_err_t err;
- if(!parsed || !config) {
- res = RES_BAD_ARG;
- goto error;
- }
+ if(!parsed) return;
- err = cyaml_free(config, &city_schema, parsed, 1);
+ ASSERT(config);
- switch(err) {
- case CYAML_OK: break;
- case CYAML_ERR_OOM: res = RES_MEM_ERR; goto error;
- case CYAML_ERR_FILE_OPEN: res = RES_IO_ERR; goto error;
- default: res = RES_UNKNOWN_ERR; goto error;
- }
-
-exit:
- return res;
-error:
- goto exit;
+ err = cyaml_free(config, &city_schema, parsed, 1);
+ CHK(RES_OK == cyaml_err_to_res_T(err));
}
diff --git a/src/cg_city_parsing.h b/src/cg_city_parsing.h
@@ -35,7 +35,7 @@ parse_city
const struct cyaml_config* config,
struct parsed_city** out_parsed);
-res_T
+void
release_parsed_city
(const struct cyaml_config* config,
struct parsed_city* parsed);
diff --git a/src/cg_city_parsing_schemas.h b/src/cg_city_parsing_schemas.h
@@ -20,26 +20,14 @@
#ifndef FG_CITY_PARSING_SCHEMAS__
#define FG_CITY_PARSING_SCHEMAS__
+#include "cg_constructive_modes_parsing_schemas.h"
+
#include <cyaml/cyaml.h>
/********************************************************/
/* Types used for parsing and to define parsing schemas */
/********************************************************/
-/* constructive mode type */
-enum parsed_cmode_type {
- PARSED_CMODE_0,
- PARSED_CMODE_1,
- PARSED_CMODE_TYPE_UNDEFINED
-};
-
-/* Mapping from "constructive mode type" strings to enum parsed_model_type values for
- * schema. */
-static const cyaml_strval_t city_building_types_strings[] = {
- { "Model0", PARSED_CMODE_0 },
- { "Model1", PARSED_CMODE_1 }
-};
-
struct parsed_city_building {
char* name;
enum parsed_cmode_type cmode_type;
@@ -56,6 +44,8 @@ struct parsed_ground {
};
struct parsed_city {
+ struct mem_allocator* allocator;
+ struct logger* logger;
struct parsed_city_building* city_building_list;
struct parsed_ground ground;
diff --git a/src/cg_constructive_mode_0.c b/src/cg_constructive_mode_0.c
@@ -19,12 +19,15 @@
#include "cg.h"
#include "cg_building.h"
+#include "cg_catalog.h"
+#include "cg_city.h"
#include "cg_city_parsing_schemas.h"
#include "cg_constructive_mode_0.h"
#include "cg_constructive_mode.h"
#include <rsys/rsys.h>
#include <rsys/str.h>
+#include <rsys/logger.h>
#include <star/scad.h>
static res_T
@@ -54,7 +57,7 @@ build_floor
{
res_T res = RES_OK;
double e;
- struct data_set_cmode_0* data;
+ struct dataset_cmode_0* data;
struct scad_geometry* footprint = NULL;
double d[3] = {0, 0, 0};
char* floorname = NULL;
@@ -63,8 +66,8 @@ build_floor
ASSERT(pg && b && floor);
- data = (struct data_set_cmode_0*)b->data;
- e = data->floor;
+ data = (struct dataset_cmode_0*)b->data;
+ e = data->floor_thickness;
str_init(NULL, &name);
is_init = 1;
@@ -98,7 +101,7 @@ build_roof
double height;
double e;
double d[3] = {0, 0, 0};
- struct data_set_cmode_0* data;
+ struct dataset_cmode_0* data;
char* roofname = NULL;
struct str name;
int is_init = 0;
@@ -114,8 +117,8 @@ build_roof
}
height = b->height;
- data = (struct data_set_cmode_0*)b->data;
- e = data->floor;
+ data = (struct dataset_cmode_0*)b->data;
+ e = data->floor_thickness;
ERR(scad_geometry_copy(floor, roofname, roof));
d[2] = height - e ;
@@ -207,7 +210,7 @@ build_cavity
{
res_T res = RES_OK;
double e, height;
- struct data_set_cmode_0* data;
+ struct dataset_cmode_0* data;
double d[3] = {0, 0, 0};
struct scad_geometry* polygon = NULL;
char* cavityname = NULL;
@@ -218,8 +221,8 @@ build_cavity
ASSERT(pg && b && cavity);
height = b->height;
- data = (struct data_set_cmode_0*)b->data;
- e = data->floor;
+ data = (struct dataset_cmode_0*)b->data;
+ e = data->floor_thickness;
str_init(NULL, &name);
is_init = 1;
@@ -396,23 +399,24 @@ error:
/*----------------------------------------------------------------------------*/
res_T
-init_model0
+init_cmode_0
(struct building* building,
struct mem_allocator* allocator,
+ struct logger* logger,
struct parsed_city_building* parsed_data,
- struct htable_parameter_set* catalog)
+ struct catalog* catalog)
{
res_T res = RES_OK;
- struct parameter_set* params;
+ struct dataset_cmode_0* dataset;
struct str dataset_name;
int name_initialized = 0;
static struct constructive_mode_functors functors_0
= {
- &init_model0,
- &build_cad_model0,
- &build_footprint_model0,
- &export_stl_model0,
- &release_cad_model0
+ &init_cmode_0,
+ &build_cad_cmode_0,
+ &build_footprint_cmode_0,
+ &export_stl_cmode_0,
+ &release_cad_cmode_0
};
(void)parsed_data;
@@ -434,20 +438,16 @@ init_model0
ERR(scpr_polygon_create(allocator, &building->pg));
ERR(scpr_polygon_setup_indexed_vertices(building->pg, 1, get_nverts, get_pos,
parsed_data));
- params = htable_parameter_set_find(catalog, &dataset_name);
- if (params == NULL) {
+ dataset = htable_dataset_cmode_0_find(&catalog->catalog_0, &dataset_name);
+ if (dataset == NULL) {
+ ERR(logger_print(logger, LOG_ERROR,
+ "Unknown dataset name: '%s' used by building '%s'.\n",
+ str_cget(&dataset_name), str_cget(&building->name)));
res = RES_BAD_ARG;
goto error;
}
- if (params->constructive_mode != mode_0
- || parsed_data->cmode_type != PARSED_CMODE_0)
- {
- res = RES_BAD_ARG;
- goto error;
- }
-
- building->data = params->data;
+ building->data = dataset;
exit:
if(name_initialized) str_release(&dataset_name);
@@ -457,16 +457,17 @@ error:
}
res_T
-build_cad_model0
+build_cad_cmode_0
(struct building* building,
struct mem_allocator* allocator,
+ struct logger* logger,
void** cad)
{
res_T res = RES_OK;
double height;
struct scpr_polygon* pg = NULL;
struct scpr_polygon* pg_int = NULL;
- struct data_set_cmode_0* data = NULL;
+ struct dataset_cmode_0* data = NULL;
struct data_cad_cmode_0* data_cad = NULL;
double e_wall;
const char* name;
@@ -478,9 +479,9 @@ build_cad_model0
height = building->height;
pg = building->pg;
- data = (struct data_set_cmode_0 *)building->data;
+ data = (struct dataset_cmode_0 *)building->data;
- if (height <= 0 || data->wall <= 0 || data->floor <= 0) {
+ if (height <= 0 || data->wall_thickness <= 0 || data->floor_thickness <= 0) {
res = RES_BAD_ARG;
goto error;
}
@@ -491,7 +492,7 @@ build_cad_model0
goto error;
}
- e_wall = data->wall;
+ e_wall = data->wall_thickness;
ERR(scpr_polygon_create_copy(NULL, pg, &pg_int));
ERR(scpr_offset_polygon(pg_int, -e_wall, SCPR_JOIN_MITER));
@@ -524,29 +525,30 @@ exit:
*(struct data_cad_cmode_0**)cad = data_cad;
return res;
error:
- if(data_cad) CHK(RES_OK == release_cad_model0(allocator, data_cad));
+ if(data_cad) CHK(RES_OK == release_cad_cmode_0(allocator, logger, data_cad));
data_cad = NULL;
goto exit;
}
res_T
-build_footprint_model0
+build_footprint_cmode_0
(struct building* building,
struct mem_allocator* allocator,
+ struct logger* logger,
struct scad_geometry** footprint)
{
res_T res = RES_OK;
struct scpr_polygon* pg = building->pg;
- struct data_set_cmode_0* data = (struct data_set_cmode_0 *)building->data;
+ struct dataset_cmode_0* data = (struct dataset_cmode_0 *)building->data;
double e_wall;
- (void)allocator;
+ (void)allocator; (void)logger;
if(!building || ! footprint) {
res = RES_BAD_ARG;
goto error;
}
- e_wall = data->wall;
+ e_wall = data->wall_thickness;
ERR(building_ground_connection(NULL, pg, e_wall, footprint));
@@ -557,12 +559,16 @@ error:
}
res_T
-export_stl_model0
- (void* cad, const int binary)
+export_stl_cmode_0
+ (void* cad,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ const int binary)
{
res_T res = RES_OK;
struct data_cad_cmode_0* data_cad = (struct data_cad_cmode_0*)cad;
size_t i;
+ (void)allocator; (void)logger;
if(!cad) {
res = RES_BAD_ARG;
@@ -599,13 +605,15 @@ error:
}
res_T
-release_cad_model0
+release_cad_cmode_0
(struct mem_allocator* allocator,
+ struct logger* logger,
void* cad)
{
res_T res = RES_OK;
struct data_cad_cmode_0* data_cad = (struct data_cad_cmode_0 *)cad;
size_t i;
+ (void)logger;
if(!allocator || ! cad) {
res = RES_BAD_ARG;
diff --git a/src/cg_constructive_mode_0.h b/src/cg_constructive_mode_0.h
@@ -21,21 +21,35 @@
#define CONSTRUCTIVE_MODE_0_H
#include <rsys/rsys.h>
+#include <rsys/str.h>
+#include <rsys/hash_table.h>
struct scad_geometry;
struct building;
-struct htable_parameter_set;
-struct parameter_set;
struct mem_allocator;
+struct logger;
struct parsed_city_building;
+struct catalog;
-/* specific data for model 0 */
-struct data_set_cmode_0 {
- double wall; /* wall thickness */
- double floor; /* floor thickness */
+/* specific data for constructive mode 0 */
+struct dataset_cmode_0 {
+ double wall_thickness;
+ double floor_thickness;
};
+#define HTABLE_NAME dataset_cmode_0
+#define HTABLE_DATA struct dataset_cmode_0
+#define HTABLE_KEY struct str
+#define HTABLE_KEY_FUNCTOR_INIT str_init
+#define HTABLE_KEY_FUNCTOR_RELEASE str_release
+#define HTABLE_KEY_FUNCTOR_COPY str_copy
+#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release
+#define HTABLE_KEY_FUNCTOR_COPY_AND_CLEAR str_copy_and_clear
+#define HTABLE_KEY_FUNCTOR_EQ str_eq
+#define HTABLE_KEY_FUNCTOR_HASH str_hash
+#include <rsys/hash_table.h>
+
struct data_cad_cmode_0 {
struct scad_geometry* wall;
struct scad_geometry* roof;
@@ -48,32 +62,38 @@ struct data_cad_cmode_0 {
};
res_T
-init_model0
+init_cmode_0
(struct building* building,
struct mem_allocator* allocator,
+ struct logger* logger,
struct parsed_city_building* parsed_data,
- struct htable_parameter_set* catalog);
+ struct catalog* catalog);
res_T
-build_cad_model0
+build_cad_cmode_0
(struct building* building,
struct mem_allocator* allocator,
+ struct logger* logger,
void** cad);
res_T
-build_footprint_model0
+build_footprint_cmode_0
(struct building* building,
struct mem_allocator* allocator,
+ struct logger* logger,
struct scad_geometry** footprint);
res_T
-export_stl_model0
+export_stl_cmode_0
(void* cad,
+ struct mem_allocator* allocator,
+ struct logger* logger,
const int binary);
res_T
-release_cad_model0
+release_cad_cmode_0
(struct mem_allocator* allocator,
+ struct logger* logger,
void* cad);
#endif /* CONSTRUCTIVE_MODE_0_H */
diff --git a/src/cg_constructive_mode_0_parsing_schemas.h b/src/cg_constructive_mode_0_parsing_schemas.h
@@ -0,0 +1,97 @@
+/* Copyright (C) 2022 Université de Pau et des Pays de l'Adour UPPA
+ * Copyright (C) 2022 CNRS
+ * Copyright (C) 2022 Sorbonne Université
+ * Copyright (C) 2022 Université Paul Sabatier
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef FG_MODE0_PARSING_SCHEMAS__
+#define FG_MODE0_PARSING_SCHEMAS__
+
+#include "cg_building.h"
+#include "cg_city_parsing_schemas.h"
+
+#include <cyaml/cyaml.h>
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+struct scpr_polygon;
+struct scad_geometry;
+struct mem_allocator;
+
+struct parsed_dataset_cmode_0 {
+ char* name;
+ double wall_thickness; /* must be > 0 */
+ double floor_thickness; /* must be > 0 */
+};
+
+/********************************************************/
+/* Types used for parsing and to define parsing schemas */
+/********************************************************/
+
+struct parsed_catalog_cmode_0 {
+ struct parsed_dataset_cmode_0* datasets;
+ size_t datasets_count;
+};
+
+static const cyaml_schema_field_t dataset_cmode_0_fields_schema[] = {
+ CYAML_FIELD_STRING_PTR("name", CYAML_FLAG_POINTER,
+ struct parsed_dataset_cmode_0, name, 0, CYAML_UNLIMITED),
+ CYAML_FIELD_FLOAT("wall_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_0, wall_thickness),
+ CYAML_FIELD_FLOAT("floor_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_0, floor_thickness),
+ CYAML_FIELD_END
+};
+
+static const struct cyaml_schema_value p_dataset_cmode_0_schema = {
+ CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_dataset_cmode_0,
+ dataset_cmode_0_fields_schema),
+};
+
+static const struct cyaml_schema_value dataset_cmode_0_schema = {
+ CYAML_VALUE_MAPPING(CYAML_FLAG_DEFAULT, struct parsed_dataset_cmode_0,
+ dataset_cmode_0_fields_schema),
+};
+
+static const cyaml_schema_field_t cmode_0_fields_schemas[] = {
+ CYAML_FIELD_IGNORE("contructive_mode_type", CYAML_FLAG_DEFAULT),
+ {
+ .key = "sets",
+ .value = {
+ .type = CYAML_SEQUENCE,
+ .flags = CYAML_FLAG_POINTER,
+ .data_size = sizeof(struct parsed_dataset_cmode_0),
+ .sequence = {
+ .entry = &dataset_cmode_0_schema,
+ .min = 1,
+ .max = CYAML_UNLIMITED,
+ }
+ },
+ .data_offset = offsetof(struct parsed_catalog_cmode_0, datasets),
+ .count_size = sizeof(((struct parsed_catalog_cmode_0*)0)->datasets_count),
+ .count_offset = offsetof(struct parsed_catalog_cmode_0, datasets_count),
+ },
+ CYAML_FIELD_END
+};
+
+/* Top-level schema. The top level value for the constructive mode is a mapping */
+static const cyaml_schema_value_t constructive_mode_0_schema = {
+ CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_catalog_cmode_0,
+ cmode_0_fields_schemas),
+};
+
+#endif
diff --git a/src/cg_constructive_mode_1.c b/src/cg_constructive_mode_1.c
@@ -19,11 +19,13 @@
#include "cg.h"
#include "cg_building.h"
+#include "cg_catalog.h"
#include "cg_city_parsing_schemas.h"
#include "cg_constructive_mode.h"
#include "cg_constructive_mode_1.h"
#include <rsys/str.h>
+#include <rsys/logger.h>
#include <rsys/stretchy_array.h>
#include <star/scad.h>
#include <star/scpr.h>
@@ -33,13 +35,13 @@ build_floor
(const char* prefix,
struct mem_allocator* allocator,
const struct scpr_polygon* pg,
- const struct data_set_cmode_1* data,
+ const struct dataset_cmode_1* data,
struct scad_geometry** floor)
{
res_T res = RES_OK;
- double e_wall = data->wall;
- double e_insulation = data->ext_insulation;
- double e_floor = data->floor;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
+ double e_floor = data->floor_thickness;
double offset = 0;
struct scpr_polygon* pg_int = NULL;
size_t nverts = 0;
@@ -86,12 +88,12 @@ build_wall
struct mem_allocator* allocator,
const struct scpr_polygon* pg,
const double height,
- const struct data_set_cmode_1* data,
+ const struct dataset_cmode_1* data,
struct scad_geometry** wall)
{
res_T res = RES_OK;
- double e_wall = data->wall;
- double e_insulation = data->ext_insulation;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
double offset = 0;
struct scpr_polygon* pg_int = NULL;
struct scpr_polygon* pg_ext = NULL;
@@ -158,17 +160,17 @@ build_int_insulation
struct mem_allocator* allocator,
const struct scpr_polygon* pg,
const double height,
- const struct data_set_cmode_1* data,
+ const struct dataset_cmode_1* data,
struct scad_geometry* inter_floor,
struct scad_geometry** insulation)
{
res_T res = RES_OK;
- double e_wall = data->wall;
- double e_roof = data->roof;
- double e_roof_insulation = data->roof_insulation;
- double attic = data->attic;
- double e_ext_insulation = data->ext_insulation;
- double e_int_insulation = data->int_insulation;
+ double e_wall = data->wall_thickness;
+ double e_roof = data->roof_thickness;
+ double e_roof_insulation = data->roof_insulation_thickness;
+ double attic = data->attic_height;
+ double e_ext_insulation = data->external_insulation_thickness;
+ double e_int_insulation = data->internal_insulation_thickness;
double offset = 0;
struct scpr_polygon* pg_int = NULL;
struct scpr_polygon* pg_ext = NULL;
@@ -238,13 +240,13 @@ build_roof
struct mem_allocator* allocator,
const struct scpr_polygon* pg,
const double height,
- const struct data_set_cmode_1* data,
+ const struct dataset_cmode_1* data,
struct scad_geometry** roof)
{
res_T res = RES_OK;
- double e_wall = data->wall;
- double e_insulation = data->ext_insulation;
- double e_roof = data->roof;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
+ double e_roof = data->roof_thickness;
double offset = 0;
double z_roof = 0;
struct scpr_polygon* pg_int = NULL;
@@ -292,15 +294,15 @@ build_roof_insulation
struct mem_allocator* allocator,
const struct scpr_polygon* pg,
const double height,
- const struct data_set_cmode_1* data,
+ const struct dataset_cmode_1* data,
struct scad_geometry** insulation)
{
res_T res = RES_OK;
- double e_wall = data->wall;
- double e_insulation = data->ext_insulation;
- double e_roof = data->roof;
- double attic = data->attic;
- double e_roof_insulation = data->roof_insulation;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
+ double e_roof = data->roof_thickness;
+ double attic = data->attic_height;
+ double e_roof_insulation = data->roof_insulation_thickness;
double offset = 0;
double z_insulation = 0;
struct scpr_polygon* pg_int = NULL;
@@ -348,14 +350,14 @@ build_floor_insulation
(const char* prefix,
struct mem_allocator* allocator,
const struct scpr_polygon* pg,
- const struct data_set_cmode_1* data,
+ const struct dataset_cmode_1* data,
struct scad_geometry** insulation)
{
res_T res = RES_OK;
- double e_wall = data->wall;
- double e_insulation = data->ext_insulation;
- double e_floor = data->floor;
- double e_floor_insulation = data->floor_insulation;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
+ double e_floor = data->floor_thickness;
+ double e_floor_insulation = data->floor_insulation_thickness;
double offset = 0;
double z_insulation = 0;
struct scpr_polygon* pg_int = NULL;
@@ -404,18 +406,18 @@ build_inter_floor
struct mem_allocator* allocator,
const struct scpr_polygon* pg,
const double height,
- const struct data_set_cmode_1* data,
+ const struct dataset_cmode_1* data,
struct scad_geometry** inter_floor)
{
res_T res = RES_OK;
size_t i = 0;
- size_t floor_n = data->inter_floor_n;
- double e_roof = data->roof;
- double e_roof_ins = data->roof_insulation;
- double attic = data->attic;
- double e_floor = data->inter_floor;
- double e_wall = data->wall;
- double e_insulation = data->ext_insulation;
+ size_t floor_n = data->inter_floor_count;
+ double e_roof = data->roof_thickness;
+ double e_roof_ins = data->roof_insulation_thickness;
+ double attic = data->attic_height;
+ double e_floor = data->inter_floor_thickness;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
double offset = 0;
double z_floor = 0;
double h_cavity = 0;
@@ -483,11 +485,11 @@ build_ext_insulation
struct mem_allocator* allocator,
const struct scpr_polygon* pg,
const double height,
- const struct data_set_cmode_1* data,
+ const struct dataset_cmode_1* data,
struct scad_geometry** insulation)
{
res_T res = RES_OK;
- double e_insulation = data->ext_insulation;
+ double e_insulation = data->external_insulation_thickness;
double offset = 0;
struct scpr_polygon* pg_int = NULL;
struct scpr_polygon* pg_ext = NULL;
@@ -547,15 +549,15 @@ build_crawlspace
(const char* prefix,
struct mem_allocator* allocator,
const struct scpr_polygon* pg,
- const struct data_set_cmode_1* data,
+ const struct dataset_cmode_1* data,
struct scad_geometry** crawlspace)
{
res_T res = RES_OK;
- double e_wall = data->wall;
- double e_insulation = data->ext_insulation;
- double e_crawl = data->crawl;
- double e_floor = data->floor;
- double e_floor_insulation = data->floor_insulation;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
+ double e_crawl = data->crawl_height;
+ double e_floor = data->floor_thickness;
+ double e_floor_insulation = data->floor_insulation_thickness;
double offset = 0;
double z_crawl= 0;
struct scpr_polygon* pg_int = NULL;
@@ -604,17 +606,17 @@ build_habitable
struct mem_allocator* allocator,
const struct scpr_polygon* pg,
const double height,
- const struct data_set_cmode_1* data,
+ const struct dataset_cmode_1* data,
struct scad_geometry* floor,
struct scad_geometry** cavity)
{
res_T res = RES_OK;
- double e_wall = data->wall;
- double e_ext_insulation = data->ext_insulation;
- double e_int_insulation = data->int_insulation;
- double e_roof = data->roof;
- double e_roof_insulation = data->roof_insulation;
- double e_attic = data->attic;
+ double e_wall = data->wall_thickness;
+ double e_ext_insulation = data->external_insulation_thickness;
+ double e_int_insulation = data->internal_insulation_thickness;
+ double e_roof = data->roof_thickness;
+ double e_roof_insulation = data->roof_insulation_thickness;
+ double e_attic = data->attic_height;
double offset = 0;
struct scpr_polygon* pg_int = NULL;
size_t nverts = 0;
@@ -669,14 +671,14 @@ build_attic
struct mem_allocator* allocator,
const struct scpr_polygon* pg,
const double height,
- const struct data_set_cmode_1* data,
+ const struct dataset_cmode_1* data,
struct scad_geometry** attic)
{
res_T res = RES_OK;
- double e_wall = data->wall;
- double e_insulation = data->ext_insulation;
- double e_roof = data->roof;
- double e_attic = data->attic;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
+ double e_roof = data->roof_thickness;
+ double e_attic = data->attic_height;
double offset = 0;
double z_attic = 0;
struct scpr_polygon* pg_int = NULL;
@@ -723,7 +725,7 @@ static res_T
build_windows
(const char* prefix,
struct mem_allocator* allocator,
- const struct data_set_cmode_1* data,
+ const struct dataset_cmode_1* data,
struct data_cad_cmode_1* data_cad)
{
res_T res = RES_OK;
@@ -769,9 +771,12 @@ build_windows
ERR(scad_geometry_dilate(surface, center, scale));
- dir[0] = 1.1*N[0] * (data->wall + data->int_insulation + data->ext_insulation);
- dir[1] = 1.1*N[1] * (data->wall + data->int_insulation + data->ext_insulation);
- dir[2] = 1.1*N[2] * (data->wall + data->int_insulation + data->ext_insulation);
+ dir[0] = 1.1*N[0] * (data->wall_thickness
+ + data->internal_insulation_thickness + data->external_insulation_thickness);
+ dir[1] = 1.1*N[1] * (data->wall_thickness
+ + data->internal_insulation_thickness + data->external_insulation_thickness);
+ dir[2] = 1.1*N[2] * (data->wall_thickness
+ + data->internal_insulation_thickness + data->external_insulation_thickness);
ERR(scad_geometry_extrude(surface, NULL, dir, &hole));
sa_push(hole_list, hole);
@@ -1146,23 +1151,24 @@ error:
/*----------------------------------------------------------------------------*/
res_T
-init_model1
+init_cmode_1
(struct building* building,
struct mem_allocator* allocator,
+ struct logger* logger,
struct parsed_city_building* parsed_data,
- struct htable_parameter_set* catalog)
+ struct catalog* catalog)
{
res_T res = RES_OK;
- struct parameter_set* params;
+ struct dataset_cmode_1* dataset;
struct str dataset_name;
int name_initialized = 0;
static struct constructive_mode_functors functors_1
= {
- &init_model1,
- &build_cad_model1,
- &build_footprint_model1,
- &export_stl_model1,
- &release_cad_model1
+ &init_cmode_1,
+ &build_cad_cmode_1,
+ &build_footprint_cmode_1,
+ &export_stl_cmode_1,
+ &release_cad_cmode_1
};
(void) parsed_data;
@@ -1184,20 +1190,16 @@ init_model1
ERR(scpr_polygon_create(allocator, &building->pg));
ERR(scpr_polygon_setup_indexed_vertices(building->pg, 1, get_nverts, get_pos,
parsed_data));
- params = htable_parameter_set_find(catalog, &dataset_name);
- if (params == NULL) {
+ dataset = htable_dataset_cmode_1_find(&catalog->catalog_1, &dataset_name);
+ if (dataset == NULL) {
+ ERR(logger_print(logger, LOG_ERROR,
+ "Unknown dataset name: '%s' used by building '%s'.\n",
+ str_cget(&dataset_name), str_cget(&building->name)));
res = RES_BAD_ARG;
goto error;
}
- if (params->constructive_mode != mode_1
- || parsed_data->cmode_type != PARSED_CMODE_1)
- {
- res = RES_BAD_ARG;
- goto error;
- }
-
- building->data = params->data;
+ building->data = dataset;
exit:
if(name_initialized) str_release(&dataset_name);
@@ -1207,15 +1209,16 @@ error:
}
res_T
-build_cad_model1
+build_cad_cmode_1
(struct building* building,
struct mem_allocator* allocator,
+ struct logger* logger,
void** cad)
{
res_T res = RES_OK;
double height = building->height;
struct scpr_polygon* pg = building->pg;
- struct data_set_cmode_1* data = (struct data_set_cmode_1 *)building->data;
+ struct dataset_cmode_1* data = (struct dataset_cmode_1 *)building->data;
struct data_cad_cmode_1* data_cad = NULL;
const char* name;
@@ -1252,33 +1255,33 @@ build_cad_model1
- floor insulation
*/
- if (data->foundation > 0) {
- double depth = -data->foundation;
+ if (data->foundation_depth > 0) {
+ double depth = -data->foundation_depth;
ERR(build_wall(name, "foundation", allocator, pg, depth, data,
&data_cad->foundation));
}
- if (data->inter_floor_n > 0) {
+ if (data->inter_floor_count > 0) {
ERR(build_inter_floor(name, allocator, pg, height, data,
&data_cad->intermediate_floor));
}
- if (data->ext_insulation > 0) {
+ if (data->external_insulation_thickness> 0) {
ERR(build_ext_insulation(name, allocator, pg, height, data,
&data_cad->external_insulation));
}
- if (data->int_insulation > 0) {
+ if (data->internal_insulation_thickness> 0) {
ERR(build_int_insulation(name, allocator, pg, height, data,
data_cad->intermediate_floor, &data_cad->internal_insulation));
}
- if (data->roof_insulation > 0) {
+ if (data->roof_insulation_thickness > 0) {
ERR(build_roof_insulation(name, allocator, pg, height, data,
&data_cad->roof_insulation));
}
- if (data->floor_insulation > 0) {
+ if (data->floor_insulation_thickness > 0) {
ERR(build_floor_insulation(name, allocator, pg, data,
&data_cad->floor_insulation));
}
@@ -1289,14 +1292,14 @@ build_cad_model1
- crawlspace
*/
- if (data->attic > 0) {
+ if (data->attic_height > 0) {
ERR(build_attic(name, allocator, pg, height, data, &data_cad->attic_cavity));
}
ERR(build_habitable(name, allocator, pg, height, data,
data_cad->intermediate_floor, &data_cad->habitable_cavity));
- if (data->crawl > 0) {
+ if (data->crawl_height > 0) {
ERR(build_crawlspace(name, allocator, pg, data, &data_cad->crawlspace_cavity));
}
@@ -1306,7 +1309,7 @@ build_cad_model1
}
/* fake ground */
- ERR(build_fake_ground(data_cad, pg, data->foundation, &data_cad->fake_ground));
+ ERR(build_fake_ground(data_cad, pg, data->foundation_depth, &data_cad->fake_ground));
ERR(scad_scene_partition());
@@ -1324,20 +1327,21 @@ exit:
*(struct data_cad_cmode_1**)cad = data_cad;
return res;
error:
- if(data_cad) CHK(RES_OK == release_cad_model1(allocator, data_cad));
+ if(data_cad) CHK(RES_OK == release_cad_cmode_1(allocator, logger, data_cad));
data_cad = NULL;
goto exit;
}
res_T
-build_footprint_model1
+build_footprint_cmode_1
(struct building* building,
struct mem_allocator* allocator,
+ struct logger* logger,
struct scad_geometry** footprint)
{
res_T res = RES_OK;
struct scpr_polygon* pg = building->pg;
- (void)allocator;
+ (void)allocator; (void)logger;
if (!building || !footprint) {
res = RES_BAD_ARG;
@@ -1353,12 +1357,16 @@ error:
}
res_T
-export_stl_model1
- (void* cad, const int binary)
+export_stl_cmode_1
+ (void* cad,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ const int binary)
{
res_T res = RES_OK;
struct data_cad_cmode_1* data_cad = (struct data_cad_cmode_1 *)cad;
size_t i = 0;
+ (void)allocator; (void)logger;
if (!cad) {
res = RES_BAD_ARG;
@@ -1442,13 +1450,15 @@ error:
}
res_T
-release_cad_model1
+release_cad_cmode_1
(struct mem_allocator* allocator,
+ struct logger* logger,
void* cad)
{
res_T res = RES_OK;
struct data_cad_cmode_1* data_cad = (struct data_cad_cmode_1 *)cad;
size_t i;
+ (void)logger;
if (!allocator || !cad) {
res = RES_BAD_ARG;
diff --git a/src/cg_constructive_mode_1.h b/src/cg_constructive_mode_1.h
@@ -21,32 +21,46 @@
#define CONSTRUCTIVE_MODE_1_H
#include <rsys/rsys.h>
+#include <rsys/str.h>
+#include <rsys/hash_table.h>
struct scad_geometry;
struct building;
-struct htable_parameter_set;
-struct parameter_set;
struct mem_allocator;
+struct logger;
struct parsed_city_building;
+struct catalog;
/* specific data for constructive mode 1 */
-struct data_set_cmode_1 {
- size_t inter_floor_n; /* number of intermediate floor >= 0 */
- double wall; /* wall thickness > 0 */
- double floor; /* floor thickness > 0*/
- double inter_floor; /* intermediate floor thickness > 0 */
- double roof; /* roof thickness > 0*/
- double int_insulation; /* internal insulation thickness >= 0 */
- double ext_insulation; /* external insulation thickness >= 0 */
- double floor_insulation; /* floor insulation thickness >= 0 */
- double roof_insulation; /* roof insulation thickness >= 0*/
- double foundation; /* foundation depth >= 0 */
- double crawl; /* crawl space height >= 0 */
- double attic; /* attic height >= 0 (and only if roof insulation > 0)*/
+struct dataset_cmode_1 {
+ size_t inter_floor_count; /* can be 0 */
+ double wall_thickness; /* must be > 0 */
+ double floor_thickness; /* must be > 0 */
+ double inter_floor_thickness; /* must be > 0 */
+ double roof_thickness; /* must be > 0 */
+ double internal_insulation_thickness; /* can be 0 */
+ double external_insulation_thickness; /* can be 0 */
+ double floor_insulation_thickness; /* can be 0 */
+ double roof_insulation_thickness; /* can be 0 */
+ double foundation_depth; /* can be 0 */
+ double crawl_height; /* can be 0 */
+ double attic_height; /* can be 0 */
double glass_ratio; /* in [0, 1] */
};
+#define HTABLE_NAME dataset_cmode_1
+#define HTABLE_DATA struct dataset_cmode_1
+#define HTABLE_KEY struct str
+#define HTABLE_KEY_FUNCTOR_INIT str_init
+#define HTABLE_KEY_FUNCTOR_RELEASE str_release
+#define HTABLE_KEY_FUNCTOR_COPY str_copy
+#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release
+#define HTABLE_KEY_FUNCTOR_COPY_AND_CLEAR str_copy_and_clear
+#define HTABLE_KEY_FUNCTOR_EQ str_eq
+#define HTABLE_KEY_FUNCTOR_HASH str_hash
+#include <rsys/hash_table.h>
+
struct data_cad_cmode_1 {
struct scad_geometry* wall;
struct scad_geometry* roof;
@@ -69,32 +83,38 @@ struct data_cad_cmode_1 {
};
res_T
-init_model1
+init_cmode_1
(struct building* building,
struct mem_allocator* allocator,
+ struct logger* logger,
struct parsed_city_building* parsed_data,
- struct htable_parameter_set* catalog);
+ struct catalog* catalog);
res_T
-build_cad_model1
+build_cad_cmode_1
(struct building* building,
struct mem_allocator* allocator,
+ struct logger* logger,
void** cad);
res_T
-build_footprint_model1
+build_footprint_cmode_1
(struct building* building,
struct mem_allocator* allocator,
+ struct logger* logger,
struct scad_geometry** footprint);
res_T
-export_stl_model1
+export_stl_cmode_1
(void* cad,
+ struct mem_allocator* allocator,
+ struct logger* logger,
const int binary);
res_T
-release_cad_model1
+release_cad_cmode_1
(struct mem_allocator* allocator,
+ struct logger* logger,
void* cad);
#endif /* CONSTRUCTIVE_MODE_1_H */
diff --git a/src/cg_constructive_mode_1_parsing_schemas.h b/src/cg_constructive_mode_1_parsing_schemas.h
@@ -0,0 +1,132 @@
+/* Copyright (C) 2022 Université de Pau et des Pays de l'Adour UPPA
+ * Copyright (C) 2022 CNRS
+ * Copyright (C) 2022 Sorbonne Université
+ * Copyright (C) 2022 Université Paul Sabatier
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef FG_MODE1_PARSING_SCHEMAS__
+#define FG_MODE1_PARSING_SCHEMAS__
+
+#include "cg_building.h"
+#include "cg_city_parsing_schemas.h"
+
+#include <cyaml/cyaml.h>
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+
+struct scpr_polygon;
+struct scad_geometry;
+struct mem_allocator;
+
+struct parsed_dataset_cmode_1 {
+ char* name;
+ size_t inter_floor_count; /* can be 0 */
+ double wall_thickness; /* must be > 0 */
+ double floor_thickness; /* must be > 0 */
+ double inter_floor_thickness; /* must be > 0 */
+ double roof_thickness; /* must be > 0 */
+ double internal_insulation_thickness; /* can be 0 */
+ double external_insulation_thickness; /* can be 0 */
+ double floor_insulation_thickness; /* can be 0 */
+ double roof_insulation_thickness; /* can be 0 */
+ double foundation_depth; /* can be 0 */
+ double crawl_height; /* can be 0 */
+ double attic_height; /* can be 0 */
+ double glass_ratio; /* in [0, 1] */
+};
+
+/********************************************************/
+/* Types used for parsing and to define parsing schemas */
+/********************************************************/
+
+struct parsed_catalog_cmode_1 {
+ struct parsed_dataset_cmode_1* datasets;
+ size_t datasets_count;
+};
+
+static const cyaml_schema_field_t dataset_cmode_1_fields_schema[] = {
+ CYAML_FIELD_STRING_PTR("name", CYAML_FLAG_POINTER,
+ struct parsed_dataset_cmode_1, name, 0, CYAML_UNLIMITED),
+ CYAML_FIELD_INT("inter_floor_count", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, inter_floor_count),
+ CYAML_FIELD_FLOAT("wall_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, wall_thickness),
+ CYAML_FIELD_FLOAT("floor_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, floor_thickness),
+ CYAML_FIELD_FLOAT("inter_floor_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, inter_floor_thickness),
+ CYAML_FIELD_FLOAT("roof_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, roof_thickness),
+ CYAML_FIELD_FLOAT("internal_insulation_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, internal_insulation_thickness),
+ CYAML_FIELD_FLOAT("external_insulation_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, external_insulation_thickness),
+ CYAML_FIELD_FLOAT("floor_insulation_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, floor_insulation_thickness),
+ CYAML_FIELD_FLOAT("roof_insulation_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, roof_insulation_thickness),
+ CYAML_FIELD_FLOAT("foundation_depth", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, foundation_depth),
+ CYAML_FIELD_FLOAT("crawl_height", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, crawl_height),
+ CYAML_FIELD_FLOAT("attic_height", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, attic_height),
+ CYAML_FIELD_FLOAT("glass_ratio", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, glass_ratio),
+ CYAML_FIELD_END
+};
+
+static const struct cyaml_schema_value p_dataset_cmode_1_schema = {
+ CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_dataset_cmode_1,
+ dataset_cmode_1_fields_schema),
+};
+
+static const struct cyaml_schema_value dataset_cmode_1_schema = {
+ CYAML_VALUE_MAPPING(CYAML_FLAG_DEFAULT, struct parsed_dataset_cmode_1,
+ dataset_cmode_1_fields_schema),
+};
+
+static const cyaml_schema_field_t cmode_1_fields_schemas[] = {
+ CYAML_FIELD_IGNORE("contructive_mode_type", CYAML_FLAG_DEFAULT),
+ {
+ .key = "sets",
+ .value = {
+ .type = CYAML_SEQUENCE,
+ .flags = CYAML_FLAG_POINTER,
+ .data_size = sizeof(struct parsed_dataset_cmode_1),
+ .sequence = {
+ .entry = &dataset_cmode_1_schema,
+ .min = 1,
+ .max = CYAML_UNLIMITED,
+ }
+ },
+ .data_offset = offsetof(struct parsed_catalog_cmode_1, datasets),
+ .count_size = sizeof(((struct parsed_catalog_cmode_1*)0)->datasets_count),
+ .count_offset = offsetof(struct parsed_catalog_cmode_1, datasets_count),
+ },
+ CYAML_FIELD_END
+};
+
+/* Top-level schema. The top level value for the constructive mode is a mapping.
+ * Its fields are defined in cmode_1_fields_schemas.
+ */
+static const cyaml_schema_value_t constructive_mode_1_schema = {
+ CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_catalog_cmode_1,
+ cmode_1_fields_schemas),
+};
+
+#endif
diff --git a/src/cg_constructive_modes_parsing_schemas.h b/src/cg_constructive_modes_parsing_schemas.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 2022 Université de Pau et des Pays de l'Adour UPPA
+ * Copyright (C) 2022 CNRS
+ * Copyright (C) 2022 Sorbonne Université
+ * Copyright (C) 2022 Université Paul Sabatier
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef FG_CMODES_PARSING_SCHEMAS__
+#define FG_CMODES_PARSING_SCHEMAS__
+
+#include <cyaml/cyaml.h>
+
+/********************************************************/
+/* Types used for parsing and to define parsing schemas */
+/********************************************************/
+
+/* constructive mode type */
+enum parsed_cmode_type {
+ PARSED_CMODE_0,
+ PARSED_CMODE_1,
+ PARSED_CMODE_TYPE_UNDEFINED
+};
+
+/* Mapping from "constructive mode type" strings to enum parsed_cmode_type values for
+ * schema. */
+static const cyaml_strval_t city_building_types_strings[] = {
+ { "Constructive_Mode_0", PARSED_CMODE_0 },
+ { "Constructive_Mode_1", PARSED_CMODE_1 }
+};
+
+struct parsed_cmode {
+ enum parsed_cmode_type cmode_type;
+};
+
+static const cyaml_schema_field_t constructive_mode_fields_schemas[] = {
+ CYAML_FIELD_ENUM("contructive_mode_type",
+ CYAML_FLAG_CASE_INSENSITIVE, struct parsed_cmode, cmode_type,
+ city_building_types_strings, CYAML_ARRAY_LEN(city_building_types_strings)),
+ CYAML_FIELD_IGNORE("sets", CYAML_FLAG_DEFAULT),
+ CYAML_FIELD_END
+};
+
+/* Top-level schema. The top level value for the constructive mode is a mapping */
+static const cyaml_schema_value_t constructive_mode_schema = {
+ CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_cmode,
+ constructive_mode_fields_schemas),
+};
+
+#endif
diff --git a/src/cg_main.c b/src/cg_main.c
@@ -22,7 +22,10 @@
#include "cg_building.h"
#include "cg_city.h"
#include "cg_city_parsing.h"
+#include "cg_catalog.h"
#include "cg_catalog_parsing.h"
+#include "cg_constructive_mode_0_parsing_schemas.h"
+#include "cg_constructive_mode_1_parsing_schemas.h"
#include <cyaml/cyaml.h>
@@ -31,19 +34,16 @@
#include <rsys/mem_allocator.h>
#include <star/scad.h>
-char const* constructive_mode_name[CONSTRUCTIVE_MODES_COUNT__] = {
- "model0",
- "model1"
-};
-
-static void
+static int
check_memory_allocator(struct mem_allocator* allocator) {
if(MEM_ALLOCATED_SIZE(allocator)) {
char dump[4096];
MEM_DUMP(allocator, dump, sizeof(dump)/sizeof(char));
fprintf(stderr, "%s\n", dump);
- FATAL("Memory leaks.\n");
+ fprintf(stderr, "Memory leaks.\n");
+ return 1;
}
+ return 0;
}
static void cg_log
@@ -86,14 +86,14 @@ int main
{
int err = EXIT_SUCCESS;
res_T res = RES_OK;
- struct args args;
+ struct args* args = NULL;
struct city* city = NULL;
struct logger logger;
struct mem_allocator allocator;
- struct parsed_city* parsed_city;
- struct htable_parameter_set catalog;
+ struct parsed_city* parsed_city = NULL;
+ struct parsed_catalog* parsed_catalog = NULL;
+ struct catalog* catalog = NULL;
int logger_initialized = 0, allocator_initialized = 0;
- int parsed_city_initialized = 0, cg_initialized = 0;
const struct cyaml_config config = {
.log_fn = cg_log,
.log_ctx = &logger,
@@ -115,55 +115,67 @@ int main
logger_set_stream(&logger, LOG_ERROR, log_err_fn, NULL);
/* parse command line */
- ERR(parse_args(&logger, argc, argv, &args));
- if(args.print_help) {
+ ERR(parse_args(&allocator, &logger, argc, argv, &args));
+ if(args->print_help) {
short_help();
goto exit;
}
- else if(args.print_version) {
+ else if(args->print_version) {
print_version();
goto exit;
}
/* Deactivate some loggin according to the -V arg */
- if(args.verbosity_level < 1)
+ if(args->verbosity_level < 1)
logger_set_stream(&logger, LOG_ERROR, NULL, NULL);
- if(args.verbosity_level < 2)
+ if(args->verbosity_level < 2)
logger_set_stream(&logger, LOG_WARNING, NULL, NULL);
- if(args.verbosity_level < 3)
+ if(args->verbosity_level < 3)
logger_set_stream(&logger, LOG_OUTPUT, NULL, NULL);
- /* Parse city description.
+ /* Parse catalog.
* No semantic validation is done at this stage */
- ERR(parse_city(args.city_filename, &allocator, &logger, &config, &parsed_city));
- parsed_city_initialized = 1;
+ ERR(parse_catalog(&args->catalog_filenames, &allocator, &logger, &config,
+ &parsed_catalog));
- /* Parse catalog. */
- ERR(parse_catalog(&logger, &catalog));
+ /* Create catalog from parsed data.
+ * Semantic validation is done along the process as well as the emission of
+ * informative logs */
+ ERR(create_catalog(&allocator, &logger, parsed_catalog, &catalog));
+ release_parsed_catalog(&config, parsed_catalog);
+ parsed_catalog = NULL;
+
+ /* Parse city description.
+ * No semantic validation is done at this stage */
+ ERR(parse_city(args->city_filename, &allocator, &logger, &config, &parsed_city));
- /* Feed city with parsed data
+ /* Create city with parsed data.
* Semantic validation is done along the process as well as the emission of
* informative logs */
- ERR(city_create(&allocator, &logger, &args, parsed_city, &catalog, &city));
- cg_initialized = 1;
- ERR(release_parsed_city(&config, parsed_city));
- parsed_city_initialized = 0;
+ ERR(create_city(&allocator, &logger, args, parsed_city, catalog, &city));
+ release_parsed_city(&config, parsed_city);
+ parsed_city = NULL;
+ release_args(args);
+ args = NULL;
ERR(city_ground_build(city));
ERR(city_cad_build(city));
exit:
- if(cg_initialized) city_release(city);
+ release_args(args);
+ release_city(city);
+ release_catalog(catalog);
+ release_parsed_catalog(&config, parsed_catalog);
+ release_parsed_city(&config, parsed_city);
if(logger_initialized) logger_release(&logger);
- if(parsed_city_initialized) release_parsed_city(&config, parsed_city);
if(allocator_initialized) {
- check_memory_allocator(&allocator);
+ if(check_memory_allocator(&allocator)) err = EXIT_FAILURE;
mem_shutdown_proxy_allocator(&allocator);
CHK(mem_allocated_size() == 0);
}
return err;
error:
err = EXIT_FAILURE;
- printf("ERROR\n");
+ printf("City generator failed.\n");
goto exit;
}