city_generator2

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

commit a06b1a701f2d3e11094d068a1bfd57f444e565e6
parent 4fc629972614452a6263f10a1eb0d444122fbc03
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Wed,  7 Dec 2022 16:37:01 +0100

Rename stuff; mainly fixing 'building' VS 'constructive mode' ambiguity

Diffstat:
Mcmake/CMakeLists.txt | 8++++----
Msrc/cg_args.c | 32++++++++++++++++----------------
Msrc/cg_args.h | 4++--
Msrc/cg_building.h | 49++++++++++++++++++++++++++++---------------------
Dsrc/cg_building_model0.c | 572-------------------------------------------------------------------------------
Dsrc/cg_building_model0.h | 68--------------------------------------------------------------------
Dsrc/cg_building_model1.c | 1523-------------------------------------------------------------------------------
Dsrc/cg_building_model1.h | 89-------------------------------------------------------------------------------
Msrc/cg_city.c | 16++++++++--------
Asrc/cg_constructive_mode_0.c | 572+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cg_constructive_mode_0.h | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cg_constructive_mode_1.c | 1523+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/cg_constructive_mode_1.h | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/cg_main.c | 3++-
Msrc/cg_parsing.c | 57++++++++++++++++++++++++++++-----------------------------
Msrc/cg_parsing.h | 10+++++-----
16 files changed, 2345 insertions(+), 2338 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -53,8 +53,8 @@ set(CG2_VERSION ${CG2_VERSION_MAJOR}.${CG2_VERSION_MINOR}.${CG2_VERSION_PATCH}) set(CG2_FILES_SRC cg_main.c cg_city.c - cg_building_model0.c - cg_building_model1.c + cg_constructive_mode_0.c + cg_constructive_mode_1.c cg_ground.c cg_args.c cg_parsing.c) @@ -63,8 +63,8 @@ set(CG2_FILES_INC cg.h cg_args.h cg_building.h - cg_building_model0.h - cg_building_model1.h + cg_constructive_mode_0.h + cg_constructive_mode_1.h cg_city.h cg_default.h.in cg_ground.h diff --git a/src/cg_args.c b/src/cg_args.c @@ -41,16 +41,16 @@ short_help(void) { print_version(); printf("\nUsage:\n" - "city_generator2 [-a] -b <FILE> -c <FILE> [-V verbosity]\n" + "city_generator2 [-a] -b <FILENAME> -c <FILENAME> [-V verbosity]\n" "city_generator2 [-h]\n" "city_generator2 [-v]\n" ); printf( "\nMandatory options\n" "-----------------\n" - "-b <building_model_file>\n" + "-b <construction_mode_filename>\n" " Read a yaml text file that describes the building.\n" - "-c <city_model_file>\n" + "-c <city_filename>\n" " Read a yaml text file that describes the city.\n" "\nOther options\n" "-------------\n" @@ -119,10 +119,20 @@ parse_args res = RES_BAD_ARG; goto error; } - args->building_model_file = optarg; + args->constructive_mode_filename = optarg; b_provided = 1; break; + case 'c': + if(c_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; + break; + case 'f': if(0 == strcmp(optarg, "A") || 0 == strcmp(optarg, "a")) args->binary_export = 0; @@ -142,16 +152,6 @@ parse_args args->print_help = 1; break; - case 'c': - if(c_provided) { - logger_print(logger, LOG_ERROR, "Option -%c provided twice.\n", opt); - res = RES_BAD_ARG; - goto error; - } - args->city_model_file = optarg; - c_provided = 1; - break; - case 'v': info_provided = 1; args->print_version = 1; @@ -185,14 +185,14 @@ parse_args if(!b_provided && !info_provided) { ERR(logger_print(logger, LOG_ERROR, - "Missing mandatory argument: -b <building_model_file>\n")); + "Missing mandatory argument: -b <construction_mode_filename>\n")); res = RES_BAD_ARG; goto error; } if(!c_provided && !info_provided) { ERR(logger_print(logger, LOG_ERROR, - "Missing mandatory argument: -c <city_model_file>\n")); + "Missing mandatory argument: -c <city_filename>\n")); res = RES_BAD_ARG; goto error; } diff --git a/src/cg_args.h b/src/cg_args.h @@ -29,8 +29,8 @@ struct logger; struct args; struct args { - char* city_model_file; - char* building_model_file; + char* city_filename; + char* constructive_mode_filename; int binary_export; int verbose; int print_help; diff --git a/src/cg_building.h b/src/cg_building.h @@ -24,24 +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; -enum model_type { - model0, - model1, - MODEL_COUNT_ +/* A type to give an ID to constructive modes. + * Add a new entry for each new constructive mode. */ +enum constructive_mode_type { + mode_0, + mode_1, + CONSTRUCTIVE_MODES_COUNT__ }; -extern char const* model_str[1]; +/* The name of the constructive modes, as expected in the city description. */ +extern char const* constructive_mode_name[CONSTRUCTIVE_MODES_COUNT__]; -struct building_params { - enum model_type model; +/* 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) { @@ -54,8 +64,9 @@ hash_str(const struct str* a) return hash_fnv32(str_cget(a), str_len(a)); } -#define HTABLE_NAME building_params -#define HTABLE_DATA struct building_params +/* 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 @@ -65,26 +76,22 @@ hash_str(const struct str* a) #define HTABLE_KEY_FUNCTOR_HASH hash_str #include <rsys/hash_table.h> - -/* the specific building model functors headers must be included here */ -#include "cg_building_model0.h" -#include "cg_building_model1.h" - +/* The type of buildings as described in the city description */ struct building { - /* generic building data */ + /* generic constructive mode data */ size_t id; - enum model_type model; - struct str* data_name; + enum constructive_mode_type constructive_mode; + struct str* constructive_mode_name; double height; struct scpr_polygon* pg; - /* specific data depending model */ + /* specific data depending to the constructive mode */ void* data; void* data_cad; - /* functors depending model */ + /* functors depending to the constructive mode */ res_T (*init) - (struct building* building, struct htable_building_params* htparams); + (struct building* building, struct htable_parameter_set* catalog); res_T (*build_cad)(struct building* building); res_T (*build_footprint) (struct building* building, diff --git a/src/cg_building_model0.c b/src/cg_building_model0.c @@ -1,572 +0,0 @@ -/* 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_building.h" - -#include <rsys/str.h> -#include <star/scad.h> -#include <star/scpr.h> - -static void get_position_pg - (const size_t ivert, double pos[2], void* ctx) -{ - struct scpr_polygon* pg = ctx; - ASSERT(pos && pg); - CHK(scpr_polygon_get_position(pg, 0, ivert, pos) == RES_OK); -} - -static res_T -build_floor_footprint - (struct scpr_polygon* pg, - struct scad_geometry** footprint) -{ - res_T res = RES_OK; - size_t nverts; - ERR(scpr_polygon_get_vertices_count(pg, 0, &nverts)); - ERR(scad_add_polygon(NULL, get_position_pg, pg, 0, nverts, footprint)); - -exit: - return res; -error: - goto exit; -} - -static res_T -build_floor - (const char* prefix, - struct scpr_polygon* pg, - struct building* b, - struct scad_geometry** floor) -{ - res_T res = RES_OK; - double e; - struct data_model0* data; - struct scad_geometry* footprint = NULL; - double d[3] = {0, 0, 0}; - char* floorname = NULL; - struct str name; - int is_init = 0; - - data = (struct data_model0*)b->data; - e = data->floor; - - str_init(NULL, &name); - is_init = 1; - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_floor")); - floorname = str_get(&name); - } - - ERR(build_floor_footprint(pg, &footprint)); - - d[2] = e; - ERR(scad_geometry_extrude(footprint, floorname, d, floor)); - -exit: - scad_geometry_delete(footprint); - if (is_init) str_release(&name); - return res; -error: - goto exit; -} - -static res_T -build_roof - (const char* prefix, - const struct building* b, - const struct scad_geometry* floor, - struct scad_geometry** roof) -{ - res_T res = RES_OK; - double height; - double e; - double d[3] = {0, 0, 0}; - struct data_model0* data; - /*struct data_cad_model0* data_cad;*/ - char* roofname = NULL; - struct str name; - int is_init = 0; - - str_init(NULL, &name); - is_init = 1; - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_roof")); - roofname = str_get(&name); - } - - height = b->height; - data = (struct data_model0*)b->data; - /*data_cad = (struct data_cad_model0*)b->data_cad;*/ - e = data->floor; - - ERR(scad_geometry_copy(floor, roofname, roof)); - d[2] = height - e ; - ERR(scad_geometry_translate(*roof, d)); - -exit: - if (is_init) str_release(&name); - return res; -error: - goto exit; -} - -static res_T -build_wall_footprint - (struct scpr_polygon* pg, - struct scpr_polygon* pg_int, - struct scad_geometry** footprint) -{ - res_T res = RES_OK; - /*struct data_cad_model0* data_cad;*/ - struct scad_geometry* polygon = NULL; - struct scad_geometry* polygon_int = NULL; - size_t nverts, nverts_int; - - ERR(scpr_polygon_get_vertices_count(pg, 0, &nverts)); - ERR(scad_add_polygon(NULL, get_position_pg, pg, 0, nverts, &polygon)); - - ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts_int)); - ERR(scad_add_polygon(NULL, get_position_pg, pg_int, 0, nverts_int, &polygon_int)); - - ERR(scad_cut_geometries(NULL, &polygon, 1, &polygon_int, 1, footprint)); - -exit: - if(polygon) scad_geometry_delete(polygon); - if(polygon_int) scad_geometry_delete(polygon_int); - return res; -error: - goto exit; -} - -static res_T -build_wall - (const char* prefix, - struct scpr_polygon* pg, - struct scpr_polygon* pg_int, - struct building* b, - struct scad_geometry** wall) -{ - res_T res = RES_OK; - double height; - struct scad_geometry* footprint = NULL; - double d[3] = {0, 0, 0}; - char* wallname = NULL; - struct str name; - int is_init = 0; - - height = b->height; - - str_init(NULL, &name); - is_init = 1; - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_wall")); - wallname = str_get(&name); - } - - ERR(build_wall_footprint(pg, pg_int, &footprint)); - - d[2] = height; - ERR(scad_geometry_extrude(footprint, wallname, d, wall)); - -exit: - if(footprint) scad_geometry_delete(footprint); - if (is_init) str_release(&name); - return res; -error: - goto exit; -} - -static res_T -build_cavity - (const char* prefix, - struct scpr_polygon* pg, - const struct building* b, - struct scad_geometry** cavity) -{ - res_T res = RES_OK; - double e, height; - struct data_model0* data; - double d[3] = {0, 0, 0}; - struct scad_geometry* polygon = NULL; - char* cavityname = NULL; - struct str name; - int is_init = 0; - size_t nverts; - - height = b->height; - data = (struct data_model0*)b->data; - e = data->floor; - - str_init(NULL, &name); - is_init = 1; - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_cavity")); - cavityname = str_get(&name); - } - - ERR(scpr_polygon_get_vertices_count(pg, 0, &nverts)); - ERR(scad_add_polygon(NULL, get_position_pg, pg, e, nverts, &polygon)); - - d[2] = height - e; - ERR(scad_geometry_extrude(polygon, cavityname, d, cavity)); - -exit: - if(polygon) scad_geometry_delete(polygon); - if (is_init) str_release(&name); - return res; -error: - goto exit; -} - -static res_T -build_connection - (const char* prefix, - struct data_cad_model0* cad) -{ - res_T res = RES_OK; - char* cname = NULL; - struct str name; - int is_init = 0; - - cad->connection = malloc(3 * sizeof(struct scad_geometry*)); - cad->n_connection = 3; - - /* cavity/floor connection */ - str_init(NULL, &name); - is_init = 1; - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_C_cavity_floor")); - cname = str_get(&name); - } - - ERR(scad_geometries_common_boundaries - (cname, - &cad->cavity, 1, - &cad->floor, 1, - &cad->connection[0])); - - /* cavity/wall connection */ - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_C_cavity_wall")); - cname = str_get(&name); - } - - ERR(scad_geometries_common_boundaries - (cname, - &cad->cavity, 1, - &cad->wall, 1, - &cad->connection[1])); - - /* cavity/roof connection */ - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_C_cavity_roof")); - cname = str_get(&name); - } - - ERR(scad_geometries_common_boundaries - (cname, - &cad->cavity, 1, - &cad->roof, 1, - &cad->connection[2])); - -exit: - if (is_init) str_release(&name); - return res; -error: - goto exit; -} - -static res_T -build_boundary - (const char* prefix, - struct data_cad_model0* cad) -{ - res_T res = RES_OK; - struct scad_geometry** list = NULL; - struct scad_geometry* boundary = NULL; - /*struct scad_geometry* footprint = NULL;*/ - char* cname = NULL; - struct str name; - int is_init = 0; - - list = malloc(4 * sizeof(struct scad_geometry*)); - list[0] = cad->floor; - list[1] = cad->wall; - list[2] = cad->roof; - list[3] = cad->cavity; - - str_init(NULL, &name); - is_init = 1; - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_boundary")); - cname = str_get(&name); - } - - ERR(scad_geometry_boundary(NULL, list, 4, &boundary)); - - ERR(scad_cut_geometries(cname, &boundary, 1, &cad->ground_connection, 1, - &cad->boundary)); - -exit: - if(boundary) scad_geometry_delete(boundary); - /*if(footprint) scad_geometry_delete(footprint);*/ - if (list) free(list); - if (is_init) str_release(&name); - return res; -error: - goto exit; -} - -static res_T -building_ground_connection - (const char* prefix, - struct scpr_polygon* pg, - const double e, - struct scad_geometry** connection) -{ - res_T res = RES_OK; - struct scpr_polygon* pg_int = NULL; - struct scad_geometry* geom[2]; - char* cname = NULL; - struct str name; - int is_init = 0; - - if (prefix) { - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_C_building_ground")); - cname = str_get(&name); - } - - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -e, SCPR_JOIN_MITER)); - - ERR(build_wall_footprint(pg, pg_int, &geom[0])); - ERR(build_floor_footprint(pg, &geom[1])); - - ERR(scad_fragment_geometries(cname, &geom[0], 1, &geom[1], 1, connection)); - -exit: - if(is_init) str_release(&name); - if(geom[0]) scad_geometry_delete(geom[0]); - if(geom[1]) scad_geometry_delete(geom[1]); - if(pg_int) scpr_polygon_ref_put(pg_int); - return res; -error: - goto exit; -} - -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ - -res_T -init_model0 - (struct building* building, struct htable_building_params* htparams) -{ - res_T res = RES_OK; - struct data_model0 data; - struct building_params* params; - - params = htable_building_params_find(htparams, building->data_name); - if (params == NULL) { - res = RES_BAD_ARG; - goto error; - } - - if (params->model != building->model) { - res = RES_BAD_ARG; - goto error; - } - - data = *(struct data_model0*)params->data; - building->data = malloc(sizeof(struct data_model0)); - if (!building->data) { - res = RES_MEM_ERR; - goto error; - } - *(struct data_model0*)(building->data) = data; - building->build_cad = &build_cad_model0; - building->export_stl = &export_stl_model0; - building->release = &release_model0; - building->build_footprint = &build_footprint_model0; - -exit: - return res; -error: - goto exit; -} - -res_T -build_cad_model0(struct building* building) -{ - res_T res = RES_OK; - size_t id = building->id; - enum model_type model = building->model; - double height = building->height; - struct scpr_polygon* pg = building->pg; - struct scpr_polygon* pg_int = NULL; - struct data_model0* data = (struct data_model0 *)building->data; - struct data_cad_model0* data_cad; - double e_wall; - struct str prefix; - int is_init = 0; - - if (!building) { - res = RES_BAD_ARG; - goto error; - } - - if (height <= 0 || data->wall <= 0 || data->floor <= 0) { - res = RES_BAD_ARG; - goto error; - } - - str_init(NULL, &prefix); - is_init = 1; - ERR(str_set(&prefix, "building_")); - ERR(str_append_printf(&prefix, "%lu_", (unsigned long)id)); - ERR(str_append(&prefix, model_str[model])); - - data_cad = malloc(sizeof(struct data_cad_model0)); - building->data_cad = (struct data_cad_model0*)data_cad; - - e_wall = data->wall; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -e_wall, SCPR_JOIN_MITER)); - - /* build floor with pg_int */ - ERR(build_floor(str_cget(&prefix), pg_int, building, &data_cad->floor)); - - /* roof is a translated copy of floor */ - ERR(build_roof(str_cget(&prefix), building, data_cad->floor, &data_cad->roof)); - - /* build wall with pg and pg_int */ - ERR(build_wall(str_cget(&prefix), pg, pg_int, building, &data_cad->wall)); - - /* build cavity */ - ERR(build_cavity(str_cget(&prefix), pg_int, building, &data_cad->cavity)); - - ERR(scad_scene_partition()); - - /* build ground/building connection */ - ERR(building_ground_connection(str_cget(&prefix), pg, e_wall, - &data_cad->ground_connection)); - - /* build boundary */ - ERR(build_boundary(str_cget(&prefix), building->data_cad)); - - /* build cavity/floor connectiona*/ - ERR(build_connection(str_cget(&prefix), building->data_cad)); - - -exit: - if(is_init) str_release(&prefix); - if(pg_int) scpr_polygon_ref_put(pg_int); - return res; -error: - goto exit; -} - -res_T -build_footprint_model0 - (struct building* building, - struct scad_geometry** footprint) -{ - res_T res = RES_OK; - struct scpr_polygon* pg = building->pg; - struct data_model0* data = (struct data_model0 *)building->data; - double e_wall; - - e_wall = data->wall; - - ERR(building_ground_connection(NULL, pg, e_wall, footprint)); - -exit: - return res; -error: - goto exit; -} - -res_T -export_stl_model0 - (const struct building* building, const int binary) -{ - res_T res = RES_OK; - struct data_cad_model0* data_cad = (struct data_cad_model0 *)building->data_cad; - size_t i; - - /* floor export */ - ERR(scad_stl_export(data_cad->floor, NULL, binary)); - - /* roof export */ - ERR(scad_stl_export(data_cad->roof, NULL, binary)); - - /* wall export */ - ERR(scad_stl_export(data_cad->wall, NULL, binary)); - - /* cavity export */ - ERR(scad_stl_export(data_cad->cavity, NULL, binary)); - - /* connection export */ - for (i=0; i<data_cad->n_connection; ++i) { - ERR(scad_stl_export(data_cad->connection[i], NULL, binary)); - } - - /* boundary export */ - ERR(scad_stl_export(data_cad->boundary, NULL, binary)); - - /* footprint export */ - ERR(scad_stl_export(data_cad->ground_connection, NULL, binary)); - -exit: - return res; -error: - goto exit; -} - -res_T -release_model0 - (struct building* building) -{ - res_T res = RES_OK; - - struct data_model0* data = (struct data_model0 *)building->data; - struct data_cad_model0* data_cad = (struct data_cad_model0 *)building->data_cad; - - scpr_polygon_ref_put(building->pg); - - str_release(building->data_name); - - if (data_cad->connection) free(data_cad->connection); - if (data) free(data); - if (data_cad) free(data_cad); - - return res; -} diff --git a/src/cg_building_model0.h b/src/cg_building_model0.h @@ -1,68 +0,0 @@ -/* 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 BUILDING_MODEL0_H -#define BUILDING_MODEL0_H - -#include <rsys/rsys.h> - -struct scad_geometry; - -struct building; -struct htable_building_params; -struct building_params; - -/* specific data for model 0 */ -struct data_model0 { - double wall; /* wall thickness */ - double floor; /* floor thickness */ -}; - -struct data_cad_model0 { - struct scad_geometry* wall; - struct scad_geometry* roof; - struct scad_geometry* floor; - struct scad_geometry* cavity; - struct scad_geometry* boundary; - struct scad_geometry** connection; - struct scad_geometry* ground_connection; - size_t n_connection; -}; - -res_T -init_model0 - (struct building* building, struct htable_building_params* htparams); - -res_T -build_cad_model0(struct building* building); - -res_T -build_footprint_model0 - (struct building* building, - struct scad_geometry** footprint); - -res_T -export_stl_model0 - (const struct building* building, const int binary); - -res_T -release_model0 - (struct building* building); - -#endif /* BUILDING_MODEL0_H */ diff --git a/src/cg_building_model1.c b/src/cg_building_model1.c @@ -1,1523 +0,0 @@ -/* 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_building.h" - -#include <rsys/str.h> -#include <rsys/stretchy_array.h> -#include <star/scad.h> -#include <star/scpr.h> - -static void get_position_pg - (const size_t ivert, double pos[2], void* ctx) -{ - struct scpr_polygon* pg = ctx; - ASSERT(pos && pg); - CHK(scpr_polygon_get_position(pg, 0, ivert, pos) == RES_OK); -} - -static res_T -build_floor - (const char* prefix, - const struct scpr_polygon* pg, - const struct data_model1* 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 offset = 0; - struct scpr_polygon* pg_int = NULL; - size_t nverts = 0; - struct scad_geometry* footprint = NULL; - double d[3] = {0, 0, 0}; - char* floorname = NULL; - struct str name; - int is_init = 0; - - if (!pg || !data || !floor) { - res = RES_BAD_ARG; - goto error; - } - - if (prefix) { - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_floor")); - floorname = str_get(&name); - } - - offset = e_wall + e_insulation; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - - /*footprint*/ - ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); - ERR(scad_add_polygon(NULL, get_position_pg, pg_int, 0, nverts, &footprint)); - - d[2] = -e_floor; - ERR(scad_geometry_extrude(footprint, floorname, d, floor)); - -exit: - scad_geometry_delete(footprint); - if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); - return res; -error: - goto exit; -} - -static res_T -build_wall - (const char* prefix, - const char* suffix, - const struct scpr_polygon* pg, - const double height, - const struct data_model1* data, - struct scad_geometry** wall) -{ - res_T res = RES_OK; - double e_wall = data->wall; - double e_insulation = data->ext_insulation; - double offset = 0; - struct scpr_polygon* pg_int = NULL; - struct scpr_polygon* pg_ext = NULL; - size_t nverts = 0; - struct scad_geometry* footprint = NULL; - struct scad_geometry* footprint_int = NULL; - struct scad_geometry* footprint_ext = NULL; - double d[3] = {0, 0, 0}; - char* wallname = NULL; - struct str name; - int is_init = 0; - - if (!pg || !data || !wall) { - res = RES_BAD_ARG; - goto error; - } - - if (prefix) { - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, prefix)); - if (suffix) { - ERR(str_append(&name, "_")); - ERR(str_append(&name, suffix)); - } - wallname = str_get(&name); - } - - offset = e_insulation; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_ext)); - ERR(scpr_offset_polygon(pg_ext, -offset, SCPR_JOIN_MITER)); - - offset = e_wall + e_insulation; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - - /*wall footprint*/ - ERR(scpr_polygon_get_vertices_count(pg_ext, 0, &nverts)); - ERR(scad_add_polygon( - NULL, get_position_pg, pg_ext, 0, nverts, &footprint_ext)); - - ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); - ERR(scad_add_polygon( - NULL, get_position_pg, pg_int, 0, nverts, &footprint_int)); - - ERR(scad_cut_geometries( - NULL, &footprint_ext, 1, &footprint_int, 1, &footprint)); - - d[2] = height; - ERR(scad_geometry_extrude(footprint, wallname, d, wall)); - -exit: - scad_geometry_delete(footprint); - scad_geometry_delete(footprint_int); - scad_geometry_delete(footprint_ext); - if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); - if (pg_ext) scpr_polygon_ref_put(pg_ext); - return res; -error: - goto exit; -} - -static res_T -build_int_insulation - (const char* prefix, - const struct scpr_polygon* pg, - const double height, - const struct data_model1* 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 offset = 0; - struct scpr_polygon* pg_int = NULL; - struct scpr_polygon* pg_ext = NULL; - size_t nverts = 0; - struct scad_geometry* footprint = NULL; - struct scad_geometry* footprint_int = NULL; - struct scad_geometry* footprint_ext = NULL; - struct scad_geometry* geom = NULL; - double d[3] = {0, 0, 0}; - char* insulationname = NULL; - struct str name; - int is_init = 0; - - if (!pg || !data || !insulation) { - res = RES_BAD_ARG; - goto error; - } - - if (prefix) { - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_int_insulation")); - insulationname = str_get(&name); - } - - offset = e_ext_insulation + e_wall; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_ext)); - ERR(scpr_offset_polygon(pg_ext, -offset, SCPR_JOIN_MITER)); - - offset = e_ext_insulation + e_wall + e_int_insulation; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - - /* insulation footprint */ - ERR(scpr_polygon_get_vertices_count(pg_ext, 0, &nverts)); - ERR(scad_add_polygon( - NULL, get_position_pg, pg_ext, 0, nverts, &footprint_ext)); - - ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); - ERR(scad_add_polygon( - NULL, get_position_pg, pg_int, 0, nverts, &footprint_int)); - - ERR(scad_cut_geometries( - NULL, &footprint_ext, 1, &footprint_int, 1, &footprint)); - - d[2] = height - e_roof - attic - e_roof_insulation; - ERR(scad_geometry_extrude(footprint, NULL, d, &geom)); - - if (inter_floor) { - ERR(scad_cut_geometries( - insulationname, &geom, 1, &inter_floor, 1, insulation)); - } else { - ERR(scad_geometry_copy(geom, insulationname, insulation)); - } - - -exit: - scad_geometry_delete(footprint); - scad_geometry_delete(footprint_int); - scad_geometry_delete(footprint_ext); - scad_geometry_delete(geom); - if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); - if (pg_ext) scpr_polygon_ref_put(pg_ext); - return res; -error: - goto exit; -} - -static res_T -build_roof - (const char* prefix, - const struct scpr_polygon* pg, - const double height, - const struct data_model1* 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 offset = 0; - double z_roof = 0; - struct scpr_polygon* pg_int = NULL; - size_t nverts = 0; - struct scad_geometry* footprint = NULL; - double d[3] = {0, 0, 0}; - char* roofname = NULL; - struct str name; - int is_init = 0; - - if (!pg || !data || !roof) { - res = RES_BAD_ARG; - goto error; - } - - if (prefix) { - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_roof")); - roofname = str_get(&name); - } - - offset = e_wall + e_insulation; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - - /*footprint*/ - ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); - z_roof = height - e_roof; - ERR(scad_add_polygon(NULL, get_position_pg, pg_int, z_roof, nverts, &footprint)); - - d[2] = e_roof; - ERR(scad_geometry_extrude(footprint, roofname, d, roof)); - -exit: - scad_geometry_delete(footprint); - if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); - return res; -error: - goto exit; -} - -static res_T -build_roof_insulation - (const char* prefix, - const struct scpr_polygon* pg, - const double height, - const struct data_model1* 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 offset = 0; - double z_insulation = 0; - struct scpr_polygon* pg_int = NULL; - size_t nverts = 0; - struct scad_geometry* footprint = NULL; - double d[3] = {0, 0, 0}; - char* insulationname = NULL; - struct str name; - int is_init = 0; - - if (!pg || !data || !insulation) { - res = RES_BAD_ARG; - goto error; - } - - if (prefix) { - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_roof_insulation")); - insulationname = str_get(&name); - } - - offset = e_wall + e_insulation; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - - /*footprint*/ - ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); - z_insulation = height - e_roof - attic - e_roof_insulation; - ERR(scad_add_polygon( - NULL, get_position_pg, pg_int, z_insulation, nverts, &footprint)); - - d[2] = e_roof_insulation; - ERR(scad_geometry_extrude(footprint, insulationname, d, insulation)); - -exit: - scad_geometry_delete(footprint); - if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); - return res; -error: - goto exit; -} - -static res_T -build_floor_insulation - (const char* prefix, - const struct scpr_polygon* pg, - const struct data_model1* 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 offset = 0; - double z_insulation = 0; - struct scpr_polygon* pg_int = NULL; - size_t nverts = 0; - struct scad_geometry* footprint = NULL; - double d[3] = {0, 0, 0}; - char* insulationname = NULL; - struct str name; - int is_init = 0; - - if (!pg || !data || !insulation) { - res = RES_BAD_ARG; - goto error; - } - - if (prefix) { - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_floor_insulation")); - insulationname = str_get(&name); - } - - offset = e_wall + e_insulation; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - - /*footprint*/ - ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); - z_insulation = - e_floor - e_floor_insulation; - ERR(scad_add_polygon( - NULL, get_position_pg, pg_int, z_insulation, nverts, &footprint)); - - d[2] = e_floor_insulation; - ERR(scad_geometry_extrude(footprint, insulationname, d, insulation)); - -exit: - scad_geometry_delete(footprint); - if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); - return res; -error: - goto exit; -} -static res_T -build_inter_floor - (const char* prefix, - const struct scpr_polygon* pg, - const double height, - const struct data_model1* 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; - double offset = 0; - double z_floor = 0; - double h_cavity = 0; - struct scpr_polygon* pg_int = NULL; - size_t nverts = 0; - struct scad_geometry** floor_list = NULL; - double d[3] = {0, 0, 0}; - char* floorname = NULL; - struct str name; - int is_init = 0; - - if (!pg || !data || !inter_floor) { - res = RES_BAD_ARG; - goto error; - } - - if (prefix) { - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_inter_floor")); - floorname = str_get(&name); - } - - offset = e_wall + e_insulation; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); - - h_cavity = height - e_roof - attic - e_roof_ins - (double)floor_n*e_floor; - z_floor = h_cavity/(double)(1 + floor_n); - d[2] = e_floor; - for (i=0; i< floor_n; ++i) { - struct scad_geometry* floor = NULL; - struct scad_geometry* footprint = NULL; - - ERR(scad_add_polygon( - NULL, get_position_pg, pg_int, z_floor, nverts, &footprint)); - ERR(scad_geometry_extrude(footprint, NULL, d, &floor)); - sa_push(floor_list, floor); - ERR(scad_geometry_delete(footprint)); - z_floor += h_cavity/(double)(1 + floor_n) + e_floor; - } - - ERR(scad_fuse_geometries( - floorname, - floor_list, sa_size(floor_list), - floor_list, sa_size(floor_list), - inter_floor)); - -exit: - if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); - if (floor_list) { - for (i=0; i< floor_n; ++i) { - scad_geometry_delete(floor_list[i]); - } - sa_release(floor_list); - } - return res; -error: - goto exit; -} -static res_T -build_ext_insulation - (const char* prefix, - const struct scpr_polygon* pg, - const double height, - const struct data_model1* data, - struct scad_geometry** insulation) -{ - res_T res = RES_OK; - double e_insulation = data->ext_insulation; - double offset = 0; - struct scpr_polygon* pg_int = NULL; - struct scpr_polygon* pg_ext = NULL; - size_t nverts = 0; - struct scad_geometry* footprint = NULL; - struct scad_geometry* footprint_int = NULL; - struct scad_geometry* footprint_ext = NULL; - double d[3] = {0, 0, 0}; - char* insulationname = NULL; - struct str name; - int is_init = 0; - - if (!pg || !data || !insulation) { - res = RES_BAD_ARG; - goto error; - } - - if (prefix) { - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_ext_insulation")); - insulationname = str_get(&name); - } - - offset = e_insulation; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_polygon_create_copy(NULL, pg, &pg_ext)); - ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - - /*insulation footprint*/ - ERR(scpr_polygon_get_vertices_count(pg_ext, 0, &nverts)); - ERR(scad_add_polygon( - NULL, get_position_pg, pg_ext, 0, nverts, &footprint_ext)); - - ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); - ERR(scad_add_polygon( - NULL, get_position_pg, pg_int, 0, nverts, &footprint_int)); - - ERR(scad_cut_geometries( - NULL, &footprint_ext, 1, &footprint_int, 1, &footprint)); - - d[2] = height; - ERR(scad_geometry_extrude(footprint, insulationname, d, insulation)); - -exit: - scad_geometry_delete(footprint); - scad_geometry_delete(footprint_int); - scad_geometry_delete(footprint_ext); - if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); - if (pg_ext) scpr_polygon_ref_put(pg_ext); - return res; -error: - goto exit; -} - -static res_T -build_crawlspace - (const char* prefix, - const struct scpr_polygon* pg, - const struct data_model1* 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 offset = 0; - double z_crawl= 0; - struct scpr_polygon* pg_int = NULL; - size_t nverts = 0; - struct scad_geometry* footprint = NULL; - double d[3] = {0, 0, 0}; - char* crawlname = NULL; - struct str name; - int is_init = 0; - - if (!pg || !data || !crawlspace) { - res = RES_BAD_ARG; - goto error; - } - - if (prefix) { - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_crawlspace")); - crawlname = str_get(&name); - } - - offset = e_wall + e_insulation; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - - /*footprint*/ - ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); - z_crawl = - e_floor - e_floor_insulation - e_crawl; - ERR(scad_add_polygon( - NULL, get_position_pg, pg_int, z_crawl, nverts, &footprint)); - - d[2] = e_crawl; - ERR(scad_geometry_extrude(footprint, crawlname, d, crawlspace)); - -exit: - scad_geometry_delete(footprint); - if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); - return res; -error: - goto exit; -} - -static res_T -build_habitable - (const char* prefix, - const struct scpr_polygon* pg, - const double height, - const struct data_model1* 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 offset = 0; - struct scpr_polygon* pg_int = NULL; - size_t nverts = 0; - struct scad_geometry* footprint = NULL; - struct scad_geometry* geom = NULL; - double d[3] = {0, 0, 0}; - char* cavityname = NULL; - struct str name; - int is_init = 0; - - if (!pg || !data || !cavity) { - res = RES_BAD_ARG; - goto error; - } - - if (prefix) { - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_cavity")); - cavityname = str_get(&name); - } - - offset = e_wall + e_ext_insulation + e_int_insulation; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - - /*footprint*/ - ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); - ERR(scad_add_polygon( - NULL, get_position_pg, pg_int, 0, nverts, &footprint)); - - d[2] = height - e_roof - e_attic - e_roof_insulation; - ERR(scad_geometry_extrude(footprint, NULL, d, &geom)); - if (floor) { - ERR(scad_cut_geometries( - cavityname, &geom, 1, &floor, 1, cavity)); - } else { - ERR(scad_geometry_copy(geom, cavityname, cavity)); - } - -exit: - scad_geometry_delete(footprint); - scad_geometry_delete(geom); - if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); - return res; -error: - goto exit; -} - -static res_T -build_attic - (const char* prefix, - const struct scpr_polygon* pg, - const double height, - const struct data_model1* 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 offset = 0; - double z_attic = 0; - struct scpr_polygon* pg_int = NULL; - size_t nverts = 0; - struct scad_geometry* footprint = NULL; - double d[3] = {0, 0, 0}; - char* atticname = NULL; - struct str name; - int is_init = 0; - - if (!pg || !data || !attic) { - res = RES_BAD_ARG; - goto error; - } - - if (prefix) { - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_attic")); - atticname = str_get(&name); - } - - offset = e_wall + e_insulation; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - - /*footprint*/ - ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); - z_attic = height - e_roof - e_attic; - ERR(scad_add_polygon( - NULL, get_position_pg, pg_int, z_attic, nverts, &footprint)); - - d[2] = e_attic; - ERR(scad_geometry_extrude(footprint, atticname, d, attic)); - -exit: - scad_geometry_delete(footprint); - if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); - return res; -error: - goto exit; -} - -static res_T -build_windows - (const char* prefix, - const struct data_model1* data, - struct data_cad_model1* data_cad) -{ - res_T res = RES_OK; - size_t i = 0; - double N[3]; - double dir[3]; - double scale[3]; - struct scad_geometry* surface = NULL; - struct scad_geometry* hole = NULL; - struct scad_geometry** hole_list = NULL; - struct scad_geometry* geom = NULL; - struct scad_geometry* bcavity = NULL; - struct scad_geometry** list = NULL; - struct scad_geometry* glass = NULL; - struct scad_geometry** glass_list = NULL; - size_t list_n = 0; - char* name = NULL; - struct str gname; - int is_init = 0; - - if (!data || !data_cad) { - res = RES_BAD_ARG; - goto error; - } - - scale[0] = sqrt(data->glass_ratio); - scale[1] = scale[0]; - scale[2] = scale[0]; - - /* windows are build from the vertical faces of habitable cavities */ - ERR(scad_geometry_boundary(NULL, &data_cad->habitable_cavity, 1, &bcavity)); - ERR(scad_geometry_explode(bcavity, NULL, &list, &list_n)); - - for (i=0; i<list_n; ++i){ - double* center = NULL; - size_t center_n = 0; - - ERR(scad_geometry_get_centerofmass(list[i], &center, &center_n)); - - ERR(scad_geometry_normal(list[i], center, N, NULL, &surface)); - - if (N[2] != 0) { - ERR(scad_geometry_delete(surface)); - surface = NULL; - continue; /* keep only vertical face */ - } - - 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); - ERR(scad_geometry_extrude(surface, NULL, dir, &hole)); - sa_push(hole_list, hole); - - dir[0] = N[0] * 0.024; - dir[1] = N[1] * 0.024; - dir[2] = N[2] * 0.024; - ERR(scad_geometry_extrude(surface, NULL, dir, &glass)); - sa_push(glass_list, glass); - - ERR(scad_geometry_delete(surface)); - surface = NULL; - } - - /* wall perforation */ - ERR(scad_geometry_get_name(data_cad->wall, &name)); - ERR(scad_cut_geometries( - NULL, &data_cad->wall, 1, hole_list, sa_size(hole_list), &geom)); - ERR(scad_geometry_delete(data_cad->wall)); - /*data_cad->wall = geom;*/ - ERR(scad_geometry_copy(geom, name, &data_cad->wall)); - ERR(scad_geometry_delete(geom)); - geom = NULL; - - /* internal insulation perforation */ - if (data_cad->internal_insulation) { - ERR(scad_geometry_get_name(data_cad->internal_insulation, &name)); - ERR(scad_cut_geometries( - NULL, &data_cad->internal_insulation, 1, - hole_list, sa_size(hole_list), &geom)); - ERR(scad_geometry_delete(data_cad->internal_insulation)); - ERR(scad_geometry_copy(geom, name, &data_cad->internal_insulation)); - ERR(scad_geometry_delete(geom)); - geom = NULL; - } - - /* external insulation perforation */ - if (data_cad->external_insulation) { - ERR(scad_geometry_get_name(data_cad->external_insulation, &name)); - ERR(scad_cut_geometries( - NULL, &data_cad->external_insulation, 1, - hole_list, sa_size(hole_list), &geom)); - ERR(scad_geometry_delete(data_cad->external_insulation)); - ERR(scad_geometry_copy(geom, name, &data_cad->external_insulation)); - ERR(scad_geometry_delete(geom)); - geom = NULL; - } - - /* build glass */ - if (prefix) { - str_init(NULL, &gname); - is_init = 1; - ERR(str_set(&gname, prefix)); - ERR(str_append(&gname, "_glass")); - } - - ERR(scad_fuse_geometries(str_cget(&gname), glass_list, 1, - glass_list+1, sa_size(glass_list) - 1, &data_cad->glass)); - -exit: - for (i=0 ; i<list_n; ++i) { - scad_geometry_delete(list[i]); - } - for (i=0 ; i<sa_size(hole_list); ++i) { - scad_geometry_delete(hole_list[i]); - } - for (i=0 ; i<sa_size(glass_list); ++i) { - scad_geometry_delete(glass_list[i]); - } - if (hole_list) sa_release(hole_list); - if (glass_list) sa_release(glass_list); - if (surface) scad_geometry_delete(surface); - if (geom) scad_geometry_delete(geom); - if (bcavity) scad_geometry_delete(bcavity); - /*scad_synchronize();*/ - if (name) free(name); - if (list) free(list); - if (is_init) str_release(&gname); - return res; -error: - goto exit; -} - -static res_T -build_boundary - (const char* prefix, - struct data_cad_model1* data_cad, - struct scad_geometry*** boundary) -{ - res_T res = RES_OK; - struct scad_geometry** list = NULL; - struct scad_geometry* bound = NULL; - char* boundaryname = NULL; - struct str name; - int is_init = 0; - - if (!prefix || !data_cad || !boundary) { - res = RES_BAD_ARG; - goto error; - } - - str_init(NULL, &name); - is_init = 1; - - sa_push(list, data_cad->wall); - sa_push(list, data_cad->roof); - sa_push(list, data_cad->floor); - sa_push(list, data_cad->habitable_cavity); - sa_push(list, data_cad->fake_ground); - if (data_cad->foundation) sa_push(list, data_cad->foundation); - if (data_cad->intermediate_floor) sa_push(list, data_cad->intermediate_floor); - if (data_cad->external_insulation) sa_push(list, data_cad->external_insulation); - if (data_cad->internal_insulation) sa_push(list, data_cad->internal_insulation); - if (data_cad->roof_insulation) sa_push(list, data_cad->roof_insulation); - if (data_cad->floor_insulation) sa_push(list, data_cad->floor_insulation); - if (data_cad->attic_cavity) sa_push(list, data_cad->attic_cavity); - if (data_cad->crawlspace_cavity) sa_push(list, data_cad->crawlspace_cavity); - if (data_cad->glass) sa_push(list, data_cad->glass); - - - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_boundary_wall")); - boundaryname = str_get(&name); - ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list), - &data_cad->wall, 1, &bound)); - sa_push(*boundary, bound); - - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_boundary_roof")); - boundaryname = str_get(&name); - ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list), - &data_cad->roof, 1, &bound)); - sa_push(*boundary, bound); - - if (data_cad->glass) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_boundary_glass")); - boundaryname = str_get(&name); - ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list), - &data_cad->glass, 1, &bound)); - sa_push(*boundary, bound); - } - - if (data_cad->external_insulation) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_boundary_ext_insulation")); - boundaryname = str_get(&name); - ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list), - &data_cad->external_insulation, 1, &bound)); - sa_push(*boundary, bound); - } - - if (data_cad->internal_insulation) { - size_t count = 0; - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_boundary_int_insulation")); - boundaryname = str_get(&name); - ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list), - &data_cad->internal_insulation, 1, &bound)); - ERR(scad_geometry_get_count(bound, &count)); - if (count>0) sa_push(*boundary, bound); - } - -exit: - if (is_init) str_release(&name); - if (list) sa_release(list); - return res; -error: - goto exit; -} - -static res_T -build_connection - (const char* prefix, - struct data_cad_model1* data_cad, - struct scad_geometry*** connection) -{ - res_T res = RES_OK; - struct scad_geometry* connect = NULL; - size_t count = 0; - char* cname = NULL; - struct str name; - int is_init = 0; - - if (!prefix || !data_cad || !connection) { - res = RES_BAD_ARG; - goto error; - } - - str_init(NULL, &name); - is_init = 1; - -#define CREATE_CONNECT(G1,G2,SUFFIX) ERR(str_set(&name, prefix));\ - ERR(str_append(&name, SUFFIX));\ - cname = str_get(&name);\ - ERR(scad_geometries_common_boundaries\ - (cname,\ - &data_cad->G1, 1,\ - &data_cad->G2, 1,\ - &connect));\ - ERR(scad_geometry_get_count(connect, &count)); \ - if (count>0) sa_push(*connection, connect); - - - /* -------------------------------------------------------------------------*/ - /* habitable cavity connections */ - /* -------------------------------------------------------------------------*/ - - /* with floor */ - CREATE_CONNECT(habitable_cavity,floor,"_C_cavity_floor"); - - /* with wall */ - CREATE_CONNECT(habitable_cavity,wall,"_C_cavity_wall"); - - /* with glass */ - if (data_cad->glass) { - CREATE_CONNECT(habitable_cavity,glass,"_C_cavity_glass"); - } - - /* with internal insulation */ - if (data_cad->internal_insulation) { - CREATE_CONNECT(habitable_cavity,internal_insulation,"_C_cavity_internal_insulation"); - } - - /* with roof insulation */ - if (data_cad->roof_insulation) { - CREATE_CONNECT(habitable_cavity,roof_insulation,"_C_roof_insulation"); - } else { - /* with roof */ - CREATE_CONNECT(habitable_cavity,roof,"_C_cavity_roof"); - } - - /* with intermediate floor */ - if (data_cad->intermediate_floor) { - CREATE_CONNECT(habitable_cavity,intermediate_floor,"_C_cavity_intermediate_floor"); - } - - /* -------------------------------------------------------------------------*/ - /* crawlspace cavity connections */ - /* -------------------------------------------------------------------------*/ - - if (data_cad->crawlspace_cavity) { - /* with floor insulation */ - if (data_cad->floor_insulation) { - CREATE_CONNECT(crawlspace_cavity, floor_insulation,"_C_crawlspace_insulation"); - } else { - /* with floor */ - CREATE_CONNECT(crawlspace_cavity, floor,"_C_crawlspace_floor"); - } - - /* with wall */ - CREATE_CONNECT(crawlspace_cavity, foundation,"_C_crawlspace_foundation"); - } - - /* -------------------------------------------------------------------------*/ - /* attic cavity connections */ - /* -------------------------------------------------------------------------*/ - - if (data_cad->attic_cavity) { - /* with roof */ - CREATE_CONNECT(attic_cavity, roof,"_C_attic_roof"); - - /* with roof insulation */ - CREATE_CONNECT(attic_cavity, roof_insulation,"_C_attic_insulation"); - - /* with wall */ - CREATE_CONNECT(attic_cavity, wall,"_C_attic_wall"); - } - -#undef CREATE_CONNECT - -exit: - if (is_init) str_release(&name); - return res; -error: - goto exit; -} - -static res_T -build_footprint - (struct scpr_polygon* pg, struct scad_geometry** footprint) -{ - res_T res = RES_OK; - size_t nverts = 0; - - if (!pg || !footprint) { - res = RES_BAD_ARG; - goto error; - } - - ERR(scpr_polygon_get_vertices_count(pg, 0, &nverts)); - ERR(scad_add_polygon( - NULL, get_position_pg, pg, 0, nverts, footprint)); - -exit: - return res; -error: - goto exit; - -} - -static res_T -build_fake_ground - (struct data_cad_model1* cad, - struct scpr_polygon* pg, - const double depth, - struct scad_geometry** ground) -{ - res_T res = RES_OK; - double dir[3] = {0, 0, 0}; - struct scpr_polygon* pg_offset = NULL; - struct scad_geometry** list = NULL; - struct scad_geometry* footprint = NULL; - struct scad_geometry* geom = NULL; - - if (!cad || !pg || !ground ) { - res = RES_BAD_ARG; - goto error; - } - - if (cad->foundation) sa_push(list, cad->foundation); - if (cad->attic_cavity) sa_push(list, cad->attic_cavity); - if (cad->floor) sa_push(list, cad->floor); - if (cad->floor_insulation) sa_push(list, cad->floor_insulation); - - ERR(scpr_polygon_create_copy(NULL, pg, &pg_offset)); - ERR(scpr_offset_polygon(pg_offset, 0.1, SCPR_JOIN_MITER)); - - ERR(build_footprint(pg_offset, &footprint)); - - dir[2] = -depth*1.1; - ERR(scad_geometry_extrude(footprint, NULL, dir, &geom)); - - ERR(scad_cut_geometries(NULL, &geom, 1, list, sa_size(list), ground)); - -exit: - if (pg_offset) scpr_polygon_ref_put(pg_offset); - if (list) sa_release(list); - if (footprint) scad_geometry_delete(footprint); - if (geom) scad_geometry_delete(geom); - return res; -error: - goto exit; -} - - -static res_T -building_ground_connection - (const char* prefix, - struct data_cad_model1* cad, - struct scad_geometry** connection) -{ - res_T res = RES_OK; - char* cname = NULL; - struct str name; - int is_init = 0; - struct scad_geometry** list = NULL; - struct scad_geometry* list_boundary = NULL; - struct scad_geometry* footprint = NULL; - - if (!prefix || !cad || !connection) { - res = RES_BAD_ARG; - goto error; - } - - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_C_building_ground")); - cname = str_get(&name); - - if (cad->foundation) sa_push(list, cad->foundation); - if (cad->attic_cavity) sa_push(list, cad->attic_cavity); - if (cad->floor) sa_push(list, cad->floor); - if (cad->floor_insulation) sa_push(list, cad->floor_insulation); - if (cad->external_insulation) sa_push(list, cad->external_insulation); - - ERR(scad_geometries_common_boundaries( - cname, list, sa_size(list), - &cad->fake_ground, 1, - connection)); - -exit: - if (list) sa_release(list); - if (is_init) str_release(&name); - if (list_boundary) scad_geometry_delete(list_boundary); - if (footprint) scad_geometry_delete(footprint); - return res; -error: - goto exit; -} - -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ - -res_T -init_model1 - (struct building* building, struct htable_building_params* htparams) -{ - res_T res = RES_OK; - struct data_model1 data; - struct building_params* params; - - params = htable_building_params_find(htparams, building->data_name); - if (params == NULL) { - res = RES_BAD_ARG; - goto error; - } - - if (params->model != building->model) { - res = RES_BAD_ARG; - goto error; - } - - data = *(struct data_model1*)params->data; - building->data = malloc(sizeof(struct data_model1)); - if (!building->data) { - res = RES_MEM_ERR; - goto error; - } - *(struct data_model1*)(building->data) = data; - building->build_cad = &build_cad_model1; - building->export_stl = &export_stl_model1; - building->release = &release_model1; - building->build_footprint = &build_footprint_model1; - -exit: - return res; -error: - goto exit; -} - -res_T -build_cad_model1(struct building* building) -{ - res_T res = RES_OK; - size_t id = building->id; - enum model_type model = building->model; - double height = building->height; - struct scpr_polygon* pg = building->pg; - struct data_model1* data = (struct data_model1 *)building->data; - struct data_cad_model1* data_cad; - struct str prefix; - int is_init = 0; - - if (!building) { - res = RES_BAD_ARG; - goto error; - } - - str_init(NULL, &prefix); - is_init = 1; - ERR(str_set(&prefix, "building_")); - ERR(str_append_printf(&prefix, "%lu_", (unsigned long)id)); - ERR(str_append(&prefix, model_str[model])); - - data_cad = malloc(sizeof(struct data_cad_model1)); - data_cad->wall = NULL; - data_cad->roof = NULL; - data_cad->floor = NULL; - data_cad->intermediate_floor = NULL; - data_cad->habitable_cavity = NULL; - data_cad->crawlspace_cavity = NULL; - data_cad->attic_cavity = NULL; - data_cad->internal_insulation = NULL; - data_cad->external_insulation = NULL; - data_cad->floor_insulation = NULL; - data_cad->roof_insulation = NULL; - data_cad->foundation = NULL; - data_cad->glass = NULL; - data_cad->ground_connection = NULL; - data_cad->boundary = NULL; - data_cad->connection = NULL; - building->data_cad = (struct data_cad_model1*)data_cad; - - /* build mandatories elements : - - floor - - wall - - roof - */ - - ERR(build_floor(str_cget(&prefix), pg, data, &data_cad->floor)); - - ERR(build_wall(str_cget(&prefix), "wall", pg, height, data, &data_cad->wall)); - - ERR(build_roof(str_cget(&prefix), pg, height, data, &data_cad->roof)); - - /* build optionnal elements : - - foundation - - intermediate floor - - external insulation - - internal insulation - - roof insulation - - floor insulation - */ - - if (data->foundation > 0) { - double depth = -data->foundation; - ERR(build_wall( - str_cget(&prefix), "foundation", pg, depth, data, &data_cad->foundation)); - } else { - data_cad->foundation = NULL; - } - - if (data->inter_floor_n > 0) { - ERR(build_inter_floor( - str_cget(&prefix), pg, height, data, &data_cad->intermediate_floor)); - } else { - data_cad->intermediate_floor = NULL; - } - - if (data->ext_insulation > 0) { - ERR(build_ext_insulation( - str_cget(&prefix), pg, height, data, &data_cad->external_insulation)); - } else { - data_cad->external_insulation = NULL; - } - - if (data->int_insulation > 0) { - ERR(build_int_insulation( - str_cget(&prefix), pg, height, data, data_cad->intermediate_floor, - &data_cad->internal_insulation)); - } else { - data_cad->internal_insulation = NULL; - } - - if (data->roof_insulation > 0) { - ERR(build_roof_insulation( - str_cget(&prefix), pg, height, data, &data_cad->roof_insulation)); - } else { - data_cad->roof_insulation = NULL; - } - - if (data->floor_insulation > 0) { - ERR(build_floor_insulation( - str_cget(&prefix), pg, data, &data_cad->floor_insulation)); - } else { - data_cad->floor_insulation = NULL; - } - - /* build cavities : - - attic - - habitable - - crawlspace - */ - - if (data->attic > 0) { - ERR(build_attic( - str_cget(&prefix), pg, height, data, &data_cad->attic_cavity)); - } else { - data_cad->attic_cavity = NULL; - } - - ERR(build_habitable( - str_cget(&prefix), pg, height, data, data_cad->intermediate_floor, - &data_cad->habitable_cavity)); - - if (data->crawl > 0) { - ERR(build_crawlspace( - str_cget(&prefix), pg, data, &data_cad->crawlspace_cavity)); - } else { - data_cad->crawlspace_cavity = NULL; - } - - /* windows */ - if (data->glass_ratio > 0) { - ERR(build_windows(str_cget(&prefix), data, data_cad)); - } - - /* fake ground */ - ERR(build_fake_ground(data_cad, pg, data->foundation, &data_cad->fake_ground)); - - ERR(scad_scene_partition()); - - /* build ground/buildind connection */ - ERR(building_ground_connection(str_cget(&prefix), data_cad, - &data_cad->ground_connection)); - - /* build boundaries */ - data_cad->boundary = NULL; - ERR(build_boundary(str_cget(&prefix), data_cad, &data_cad->boundary)); - - /* build connections */ - data_cad->connection = NULL; - ERR(build_connection(str_cget(&prefix), data_cad, &data_cad->connection)); - -exit: - if (is_init) str_release(&prefix); - return res; -error: - goto exit; -} - -res_T -build_footprint_model1 - (struct building* building, - struct scad_geometry** footprint) -{ - res_T res = RES_OK; - struct scpr_polygon* pg = building->pg; - - if (!building || !footprint) { - res = RES_BAD_ARG; - goto error; - } - - ERR(build_footprint(pg, footprint)); - -exit: - return res; -error: - goto exit; -} - -res_T -export_stl_model1 - (const struct building* building, const int binary) -{ - res_T res = RES_OK; - struct data_cad_model1* data_cad = (struct data_cad_model1 *)building->data_cad; - size_t i = 0; - - /* floor export */ - ERR(scad_stl_export(data_cad->floor, NULL, binary)); - - /* wall export */ - ERR(scad_stl_export(data_cad->wall, NULL, binary)); - - /* roof export */ - ERR(scad_stl_export(data_cad->roof, NULL, binary)); - - /* foundation export */ - if (data_cad->foundation) { - ERR(scad_stl_export(data_cad->foundation, NULL, binary)); - } - - /* glass export */ - if (data_cad->glass) { - ERR(scad_stl_export(data_cad->glass, NULL, binary)); - } - - /* intermediate floor export*/ - if (data_cad->intermediate_floor) { - ERR(scad_stl_export(data_cad->intermediate_floor, NULL, binary)); - } - - /* internal insulation export*/ - if (data_cad->internal_insulation) { - ERR(scad_stl_export(data_cad->internal_insulation, NULL, binary)); - } - - /* external insulation export*/ - if (data_cad->external_insulation) { - ERR(scad_stl_export(data_cad->external_insulation, NULL, binary)); - } - - /* roof insulation export*/ - if (data_cad->roof_insulation) { - ERR(scad_stl_export(data_cad->roof_insulation, NULL, binary)); - } - - /* floor insulation export*/ - if (data_cad->floor_insulation) { - ERR(scad_stl_export(data_cad->floor_insulation, NULL, binary)); - } - - /* attic cavity export*/ - if (data_cad->attic_cavity) { - ERR(scad_stl_export(data_cad->attic_cavity, NULL, binary)); - } - - /* habitable cavity export*/ - ERR(scad_stl_export(data_cad->habitable_cavity, NULL, binary)); - - /* crawlspace cavity export*/ - if (data_cad->crawlspace_cavity) { - ERR(scad_stl_export(data_cad->crawlspace_cavity, NULL, binary)); - } - - /* boundary export*/ - for (i=0; i<sa_size(data_cad->boundary); ++i) { - ERR(scad_stl_export(data_cad->boundary[i], NULL, binary)); - } - - /* connections export*/ - for (i=0; i<sa_size(data_cad->connection); ++i) { - ERR(scad_stl_export(data_cad->connection[i], NULL, binary)); - } - - /* ground/building connection export*/ - ERR(scad_stl_export(data_cad->ground_connection, NULL, binary)); - -exit: - return res; -error: - goto exit; -} - -res_T -release_model1 - (struct building* building) -{ - res_T res = RES_OK; - struct data_model1* data = (struct data_model1 *)building->data; - struct data_cad_model1* data_cad = (struct data_cad_model1 *)building->data_cad; - - scpr_polygon_ref_put(building->pg); - - str_release(building->data_name); - - if (data_cad->boundary) sa_release(data_cad->boundary); - if (data_cad->connection) sa_release(data_cad->connection); - if (data) free(data); - if (data_cad) free(data_cad); - - return res; -} diff --git a/src/cg_building_model1.h b/src/cg_building_model1.h @@ -1,89 +0,0 @@ -/* 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 BUILDING_MODEL1_H -#define BUILDING_MODEL1_H - -#include <rsys/rsys.h> - -struct scad_geometry; - -struct building; -struct htable_building_params; -struct building_params; - -/* specific data for model 0 */ -struct data_model1 { - 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)*/ - double glass_ratio; /* in [0, 1] */ -}; - -struct data_cad_model1 { - struct scad_geometry* wall; - struct scad_geometry* roof; - struct scad_geometry* floor; - struct scad_geometry* foundation; /* can be NULL */ - struct scad_geometry* intermediate_floor; /* can be NULL */ - struct scad_geometry* habitable_cavity; - struct scad_geometry* crawlspace_cavity; /* can be NULL */ - struct scad_geometry* attic_cavity; /* can be NULL */ - struct scad_geometry* internal_insulation; /* can be NULL */ - struct scad_geometry* external_insulation; /* can be NULL */ - struct scad_geometry* floor_insulation; /* can be NULL */ - struct scad_geometry* roof_insulation; /* can be NULL */ - struct scad_geometry* glass; - struct scad_geometry* fake_ground;/*not exported, used for ground connection*/ - struct scad_geometry* ground_connection; - struct scad_geometry** boundary; - struct scad_geometry** connection; - size_t n_connection; -}; - -res_T -init_model1 - (struct building* building, struct htable_building_params* htparams); - -res_T -build_cad_model1(struct building* building); - -res_T -build_footprint_model1 - (struct building* building, - struct scad_geometry** footprint); - -res_T -export_stl_model1 - (const struct building* building, const int binary); - -res_T -release_model1 - (struct building* building); - -#endif /* BUILDING_MODEL1_H */ diff --git a/src/cg_city.c b/src/cg_city.c @@ -35,34 +35,34 @@ city_init(struct logger* logger, struct city* city, struct args* args) res_T res = RES_OK; size_t i=0; struct txtrdr* reader = NULL; - struct htable_building_params ht_params; + struct htable_parameter_set catalog; city->binary_export = args->binary_export; - ERR(txtrdr_file(NULL, args->city_model_file, '#', &reader)); + ERR(txtrdr_file(NULL, args->city_filename, '#', &reader)); ERR(parse_city(logger, reader, city)); - ERR(parse_building_params(logger, &ht_params)); + ERR(parse_catalog(logger, &catalog)); for (i=0; i<city->n ; ++i) { city->building[i].release = NULL; - switch(city->building[i].model) { - case model0: + switch(city->building[i].constructive_mode) { + case mode_0: city->building[i].init = &init_model0; break; - case model1: + case mode_1: city->building[i].init = &init_model1; break; default: res = RES_BAD_ARG; goto error; } - ERR(city->building[i].init(&city->building[i], &ht_params)); + ERR(city->building[i].init(&city->building[i], &catalog)); } exit: txtrdr_ref_put(reader); - htable_building_params_release(&ht_params); + htable_parameter_set_release(&catalog); return res; error: goto exit; diff --git a/src/cg_constructive_mode_0.c b/src/cg_constructive_mode_0.c @@ -0,0 +1,572 @@ +/* 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_building.h" + +#include <rsys/str.h> +#include <star/scad.h> +#include <star/scpr.h> + +static void get_position_pg + (const size_t ivert, double pos[2], void* ctx) +{ + struct scpr_polygon* pg = ctx; + ASSERT(pos && pg); + CHK(scpr_polygon_get_position(pg, 0, ivert, pos) == RES_OK); +} + +static res_T +build_floor_footprint + (struct scpr_polygon* pg, + struct scad_geometry** footprint) +{ + res_T res = RES_OK; + size_t nverts; + ERR(scpr_polygon_get_vertices_count(pg, 0, &nverts)); + ERR(scad_add_polygon(NULL, get_position_pg, pg, 0, nverts, footprint)); + +exit: + return res; +error: + goto exit; +} + +static res_T +build_floor + (const char* prefix, + struct scpr_polygon* pg, + struct building* b, + struct scad_geometry** floor) +{ + res_T res = RES_OK; + double e; + struct data_set_cmode_0* data; + struct scad_geometry* footprint = NULL; + double d[3] = {0, 0, 0}; + char* floorname = NULL; + struct str name; + int is_init = 0; + + data = (struct data_set_cmode_0*)b->data; + e = data->floor; + + str_init(NULL, &name); + is_init = 1; + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_floor")); + floorname = str_get(&name); + } + + ERR(build_floor_footprint(pg, &footprint)); + + d[2] = e; + ERR(scad_geometry_extrude(footprint, floorname, d, floor)); + +exit: + scad_geometry_delete(footprint); + if (is_init) str_release(&name); + return res; +error: + goto exit; +} + +static res_T +build_roof + (const char* prefix, + const struct building* b, + const struct scad_geometry* floor, + struct scad_geometry** roof) +{ + res_T res = RES_OK; + double height; + double e; + double d[3] = {0, 0, 0}; + struct data_set_cmode_0* data; + /*struct data_cad_model0* data_cad;*/ + char* roofname = NULL; + struct str name; + int is_init = 0; + + str_init(NULL, &name); + is_init = 1; + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_roof")); + roofname = str_get(&name); + } + + height = b->height; + data = (struct data_set_cmode_0*)b->data; + /*data_cad = (struct data_cad_model0*)b->data_cad;*/ + e = data->floor; + + ERR(scad_geometry_copy(floor, roofname, roof)); + d[2] = height - e ; + ERR(scad_geometry_translate(*roof, d)); + +exit: + if (is_init) str_release(&name); + return res; +error: + goto exit; +} + +static res_T +build_wall_footprint + (struct scpr_polygon* pg, + struct scpr_polygon* pg_int, + struct scad_geometry** footprint) +{ + res_T res = RES_OK; + /*struct data_cad_model0* data_cad;*/ + struct scad_geometry* polygon = NULL; + struct scad_geometry* polygon_int = NULL; + size_t nverts, nverts_int; + + ERR(scpr_polygon_get_vertices_count(pg, 0, &nverts)); + ERR(scad_add_polygon(NULL, get_position_pg, pg, 0, nverts, &polygon)); + + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts_int)); + ERR(scad_add_polygon(NULL, get_position_pg, pg_int, 0, nverts_int, &polygon_int)); + + ERR(scad_cut_geometries(NULL, &polygon, 1, &polygon_int, 1, footprint)); + +exit: + if(polygon) scad_geometry_delete(polygon); + if(polygon_int) scad_geometry_delete(polygon_int); + return res; +error: + goto exit; +} + +static res_T +build_wall + (const char* prefix, + struct scpr_polygon* pg, + struct scpr_polygon* pg_int, + struct building* b, + struct scad_geometry** wall) +{ + res_T res = RES_OK; + double height; + struct scad_geometry* footprint = NULL; + double d[3] = {0, 0, 0}; + char* wallname = NULL; + struct str name; + int is_init = 0; + + height = b->height; + + str_init(NULL, &name); + is_init = 1; + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_wall")); + wallname = str_get(&name); + } + + ERR(build_wall_footprint(pg, pg_int, &footprint)); + + d[2] = height; + ERR(scad_geometry_extrude(footprint, wallname, d, wall)); + +exit: + if(footprint) scad_geometry_delete(footprint); + if (is_init) str_release(&name); + return res; +error: + goto exit; +} + +static res_T +build_cavity + (const char* prefix, + struct scpr_polygon* pg, + const struct building* b, + struct scad_geometry** cavity) +{ + res_T res = RES_OK; + double e, height; + struct data_set_cmode_0* data; + double d[3] = {0, 0, 0}; + struct scad_geometry* polygon = NULL; + char* cavityname = NULL; + struct str name; + int is_init = 0; + size_t nverts; + + height = b->height; + data = (struct data_set_cmode_0*)b->data; + e = data->floor; + + str_init(NULL, &name); + is_init = 1; + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_cavity")); + cavityname = str_get(&name); + } + + ERR(scpr_polygon_get_vertices_count(pg, 0, &nverts)); + ERR(scad_add_polygon(NULL, get_position_pg, pg, e, nverts, &polygon)); + + d[2] = height - e; + ERR(scad_geometry_extrude(polygon, cavityname, d, cavity)); + +exit: + if(polygon) scad_geometry_delete(polygon); + if (is_init) str_release(&name); + return res; +error: + goto exit; +} + +static res_T +build_connection + (const char* prefix, + struct data_cad_cmode_0* cad) +{ + res_T res = RES_OK; + char* cname = NULL; + struct str name; + int is_init = 0; + + cad->connection = malloc(3 * sizeof(struct scad_geometry*)); + cad->n_connection = 3; + + /* cavity/floor connection */ + str_init(NULL, &name); + is_init = 1; + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_C_cavity_floor")); + cname = str_get(&name); + } + + ERR(scad_geometries_common_boundaries + (cname, + &cad->cavity, 1, + &cad->floor, 1, + &cad->connection[0])); + + /* cavity/wall connection */ + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_C_cavity_wall")); + cname = str_get(&name); + } + + ERR(scad_geometries_common_boundaries + (cname, + &cad->cavity, 1, + &cad->wall, 1, + &cad->connection[1])); + + /* cavity/roof connection */ + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_C_cavity_roof")); + cname = str_get(&name); + } + + ERR(scad_geometries_common_boundaries + (cname, + &cad->cavity, 1, + &cad->roof, 1, + &cad->connection[2])); + +exit: + if (is_init) str_release(&name); + return res; +error: + goto exit; +} + +static res_T +build_boundary + (const char* prefix, + struct data_cad_cmode_0* cad) +{ + res_T res = RES_OK; + struct scad_geometry** list = NULL; + struct scad_geometry* boundary = NULL; + /*struct scad_geometry* footprint = NULL;*/ + char* cname = NULL; + struct str name; + int is_init = 0; + + list = malloc(4 * sizeof(struct scad_geometry*)); + list[0] = cad->floor; + list[1] = cad->wall; + list[2] = cad->roof; + list[3] = cad->cavity; + + str_init(NULL, &name); + is_init = 1; + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_boundary")); + cname = str_get(&name); + } + + ERR(scad_geometry_boundary(NULL, list, 4, &boundary)); + + ERR(scad_cut_geometries(cname, &boundary, 1, &cad->ground_connection, 1, + &cad->boundary)); + +exit: + if(boundary) scad_geometry_delete(boundary); + /*if(footprint) scad_geometry_delete(footprint);*/ + if (list) free(list); + if (is_init) str_release(&name); + return res; +error: + goto exit; +} + +static res_T +building_ground_connection + (const char* prefix, + struct scpr_polygon* pg, + const double e, + struct scad_geometry** connection) +{ + res_T res = RES_OK; + struct scpr_polygon* pg_int = NULL; + struct scad_geometry* geom[2]; + char* cname = NULL; + struct str name; + int is_init = 0; + + if (prefix) { + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_C_building_ground")); + cname = str_get(&name); + } + + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -e, SCPR_JOIN_MITER)); + + ERR(build_wall_footprint(pg, pg_int, &geom[0])); + ERR(build_floor_footprint(pg, &geom[1])); + + ERR(scad_fragment_geometries(cname, &geom[0], 1, &geom[1], 1, connection)); + +exit: + if(is_init) str_release(&name); + if(geom[0]) scad_geometry_delete(geom[0]); + if(geom[1]) scad_geometry_delete(geom[1]); + if(pg_int) scpr_polygon_ref_put(pg_int); + return res; +error: + goto exit; +} + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +res_T +init_model0 + (struct building* building, struct htable_parameter_set* catalog) +{ + res_T res = RES_OK; + struct data_set_cmode_0 data; + struct parameter_set* params; + + params = htable_parameter_set_find(catalog, building->constructive_mode_name); + if (params == NULL) { + res = RES_BAD_ARG; + goto error; + } + + if (params->constructive_mode != building->constructive_mode) { + res = RES_BAD_ARG; + goto error; + } + + data = *(struct data_set_cmode_0*)params->data; + building->data = malloc(sizeof(struct data_set_cmode_0)); + if (!building->data) { + res = RES_MEM_ERR; + goto error; + } + *(struct data_set_cmode_0*)(building->data) = data; + building->build_cad = &build_cad_model0; + building->export_stl = &export_stl_model0; + building->release = &release_model0; + building->build_footprint = &build_footprint_model0; + +exit: + return res; +error: + goto exit; +} + +res_T +build_cad_model0(struct building* building) +{ + res_T res = RES_OK; + size_t id = building->id; + enum constructive_mode_type model = building->constructive_mode; + double height = building->height; + struct scpr_polygon* pg = building->pg; + struct scpr_polygon* pg_int = NULL; + struct data_set_cmode_0* data = (struct data_set_cmode_0 *)building->data; + struct data_cad_cmode_0* data_cad; + double e_wall; + struct str prefix; + int is_init = 0; + + if (!building) { + res = RES_BAD_ARG; + goto error; + } + + if (height <= 0 || data->wall <= 0 || data->floor <= 0) { + res = RES_BAD_ARG; + goto error; + } + + str_init(NULL, &prefix); + is_init = 1; + ERR(str_set(&prefix, "building_")); + ERR(str_append_printf(&prefix, "%lu_", (unsigned long)id)); + ERR(str_append(&prefix, constructive_mode_name[model])); + + data_cad = malloc(sizeof(struct data_cad_cmode_0)); + building->data_cad = (struct data_cad_cmode_0*)data_cad; + + e_wall = data->wall; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -e_wall, SCPR_JOIN_MITER)); + + /* build floor with pg_int */ + ERR(build_floor(str_cget(&prefix), pg_int, building, &data_cad->floor)); + + /* roof is a translated copy of floor */ + ERR(build_roof(str_cget(&prefix), building, data_cad->floor, &data_cad->roof)); + + /* build wall with pg and pg_int */ + ERR(build_wall(str_cget(&prefix), pg, pg_int, building, &data_cad->wall)); + + /* build cavity */ + ERR(build_cavity(str_cget(&prefix), pg_int, building, &data_cad->cavity)); + + ERR(scad_scene_partition()); + + /* build ground/building connection */ + ERR(building_ground_connection(str_cget(&prefix), pg, e_wall, + &data_cad->ground_connection)); + + /* build boundary */ + ERR(build_boundary(str_cget(&prefix), building->data_cad)); + + /* build cavity/floor connectiona*/ + ERR(build_connection(str_cget(&prefix), building->data_cad)); + + +exit: + if(is_init) str_release(&prefix); + if(pg_int) scpr_polygon_ref_put(pg_int); + return res; +error: + goto exit; +} + +res_T +build_footprint_model0 + (struct building* building, + 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; + double e_wall; + + e_wall = data->wall; + + ERR(building_ground_connection(NULL, pg, e_wall, footprint)); + +exit: + return res; +error: + goto exit; +} + +res_T +export_stl_model0 + (const struct building* building, const int binary) +{ + res_T res = RES_OK; + struct data_cad_cmode_0* data_cad = (struct data_cad_cmode_0 *)building->data_cad; + size_t i; + + /* floor export */ + ERR(scad_stl_export(data_cad->floor, NULL, binary)); + + /* roof export */ + ERR(scad_stl_export(data_cad->roof, NULL, binary)); + + /* wall export */ + ERR(scad_stl_export(data_cad->wall, NULL, binary)); + + /* cavity export */ + ERR(scad_stl_export(data_cad->cavity, NULL, binary)); + + /* connection export */ + for (i=0; i<data_cad->n_connection; ++i) { + ERR(scad_stl_export(data_cad->connection[i], NULL, binary)); + } + + /* boundary export */ + ERR(scad_stl_export(data_cad->boundary, NULL, binary)); + + /* footprint export */ + ERR(scad_stl_export(data_cad->ground_connection, NULL, binary)); + +exit: + return res; +error: + goto exit; +} + +res_T +release_model0 + (struct building* building) +{ + res_T res = RES_OK; + + struct data_set_cmode_0* data = (struct data_set_cmode_0 *)building->data; + struct data_cad_cmode_0* data_cad = (struct data_cad_cmode_0 *)building->data_cad; + + scpr_polygon_ref_put(building->pg); + + str_release(building->constructive_mode_name); + + if (data_cad->connection) free(data_cad->connection); + if (data) free(data); + if (data_cad) free(data_cad); + + return res; +} diff --git a/src/cg_constructive_mode_0.h b/src/cg_constructive_mode_0.h @@ -0,0 +1,68 @@ +/* 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 BUILDING_MODEL0_H +#define BUILDING_MODEL0_H + +#include <rsys/rsys.h> + +struct scad_geometry; + +struct building; +struct htable_parameter_set; +struct parameter_set; + +/* specific data for model 0 */ +struct data_set_cmode_0 { + double wall; /* wall thickness */ + double floor; /* floor thickness */ +}; + +struct data_cad_cmode_0 { + struct scad_geometry* wall; + struct scad_geometry* roof; + struct scad_geometry* floor; + struct scad_geometry* cavity; + struct scad_geometry* boundary; + struct scad_geometry** connection; + struct scad_geometry* ground_connection; + size_t n_connection; +}; + +res_T +init_model0 + (struct building* building, struct htable_parameter_set* catalog); + +res_T +build_cad_model0(struct building* building); + +res_T +build_footprint_model0 + (struct building* building, + struct scad_geometry** footprint); + +res_T +export_stl_model0 + (const struct building* building, const int binary); + +res_T +release_model0 + (struct building* building); + +#endif /* BUILDING_MODEL0_H */ diff --git a/src/cg_constructive_mode_1.c b/src/cg_constructive_mode_1.c @@ -0,0 +1,1523 @@ +/* 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_building.h" + +#include <rsys/str.h> +#include <rsys/stretchy_array.h> +#include <star/scad.h> +#include <star/scpr.h> + +static void get_position_pg + (const size_t ivert, double pos[2], void* ctx) +{ + struct scpr_polygon* pg = ctx; + ASSERT(pos && pg); + CHK(scpr_polygon_get_position(pg, 0, ivert, pos) == RES_OK); +} + +static res_T +build_floor + (const char* prefix, + const struct scpr_polygon* pg, + const struct data_set_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 offset = 0; + struct scpr_polygon* pg_int = NULL; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + double d[3] = {0, 0, 0}; + char* floorname = NULL; + struct str name; + int is_init = 0; + + if (!pg || !data || !floor) { + res = RES_BAD_ARG; + goto error; + } + + if (prefix) { + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_floor")); + floorname = str_get(&name); + } + + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + + /*footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + ERR(scad_add_polygon(NULL, get_position_pg, pg_int, 0, nverts, &footprint)); + + d[2] = -e_floor; + ERR(scad_geometry_extrude(footprint, floorname, d, floor)); + +exit: + scad_geometry_delete(footprint); + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + return res; +error: + goto exit; +} + +static res_T +build_wall + (const char* prefix, + const char* suffix, + const struct scpr_polygon* pg, + const double height, + const struct data_set_cmode_1* data, + struct scad_geometry** wall) +{ + res_T res = RES_OK; + double e_wall = data->wall; + double e_insulation = data->ext_insulation; + double offset = 0; + struct scpr_polygon* pg_int = NULL; + struct scpr_polygon* pg_ext = NULL; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + struct scad_geometry* footprint_int = NULL; + struct scad_geometry* footprint_ext = NULL; + double d[3] = {0, 0, 0}; + char* wallname = NULL; + struct str name; + int is_init = 0; + + if (!pg || !data || !wall) { + res = RES_BAD_ARG; + goto error; + } + + if (prefix) { + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + if (suffix) { + ERR(str_append(&name, "_")); + ERR(str_append(&name, suffix)); + } + wallname = str_get(&name); + } + + offset = e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_ext)); + ERR(scpr_offset_polygon(pg_ext, -offset, SCPR_JOIN_MITER)); + + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + + /*wall footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_ext, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg_ext, 0, nverts, &footprint_ext)); + + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, 0, nverts, &footprint_int)); + + ERR(scad_cut_geometries( + NULL, &footprint_ext, 1, &footprint_int, 1, &footprint)); + + d[2] = height; + ERR(scad_geometry_extrude(footprint, wallname, d, wall)); + +exit: + scad_geometry_delete(footprint); + scad_geometry_delete(footprint_int); + scad_geometry_delete(footprint_ext); + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + if (pg_ext) scpr_polygon_ref_put(pg_ext); + return res; +error: + goto exit; +} + +static res_T +build_int_insulation + (const char* prefix, + const struct scpr_polygon* pg, + const double height, + const struct data_set_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 offset = 0; + struct scpr_polygon* pg_int = NULL; + struct scpr_polygon* pg_ext = NULL; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + struct scad_geometry* footprint_int = NULL; + struct scad_geometry* footprint_ext = NULL; + struct scad_geometry* geom = NULL; + double d[3] = {0, 0, 0}; + char* insulationname = NULL; + struct str name; + int is_init = 0; + + if (!pg || !data || !insulation) { + res = RES_BAD_ARG; + goto error; + } + + if (prefix) { + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_int_insulation")); + insulationname = str_get(&name); + } + + offset = e_ext_insulation + e_wall; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_ext)); + ERR(scpr_offset_polygon(pg_ext, -offset, SCPR_JOIN_MITER)); + + offset = e_ext_insulation + e_wall + e_int_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + + /* insulation footprint */ + ERR(scpr_polygon_get_vertices_count(pg_ext, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg_ext, 0, nverts, &footprint_ext)); + + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, 0, nverts, &footprint_int)); + + ERR(scad_cut_geometries( + NULL, &footprint_ext, 1, &footprint_int, 1, &footprint)); + + d[2] = height - e_roof - attic - e_roof_insulation; + ERR(scad_geometry_extrude(footprint, NULL, d, &geom)); + + if (inter_floor) { + ERR(scad_cut_geometries( + insulationname, &geom, 1, &inter_floor, 1, insulation)); + } else { + ERR(scad_geometry_copy(geom, insulationname, insulation)); + } + + +exit: + scad_geometry_delete(footprint); + scad_geometry_delete(footprint_int); + scad_geometry_delete(footprint_ext); + scad_geometry_delete(geom); + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + if (pg_ext) scpr_polygon_ref_put(pg_ext); + return res; +error: + goto exit; +} + +static res_T +build_roof + (const char* prefix, + const struct scpr_polygon* pg, + const double height, + const struct data_set_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 offset = 0; + double z_roof = 0; + struct scpr_polygon* pg_int = NULL; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + double d[3] = {0, 0, 0}; + char* roofname = NULL; + struct str name; + int is_init = 0; + + if (!pg || !data || !roof) { + res = RES_BAD_ARG; + goto error; + } + + if (prefix) { + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_roof")); + roofname = str_get(&name); + } + + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + + /*footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + z_roof = height - e_roof; + ERR(scad_add_polygon(NULL, get_position_pg, pg_int, z_roof, nverts, &footprint)); + + d[2] = e_roof; + ERR(scad_geometry_extrude(footprint, roofname, d, roof)); + +exit: + scad_geometry_delete(footprint); + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + return res; +error: + goto exit; +} + +static res_T +build_roof_insulation + (const char* prefix, + const struct scpr_polygon* pg, + const double height, + const struct data_set_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 offset = 0; + double z_insulation = 0; + struct scpr_polygon* pg_int = NULL; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + double d[3] = {0, 0, 0}; + char* insulationname = NULL; + struct str name; + int is_init = 0; + + if (!pg || !data || !insulation) { + res = RES_BAD_ARG; + goto error; + } + + if (prefix) { + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_roof_insulation")); + insulationname = str_get(&name); + } + + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + + /*footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + z_insulation = height - e_roof - attic - e_roof_insulation; + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, z_insulation, nverts, &footprint)); + + d[2] = e_roof_insulation; + ERR(scad_geometry_extrude(footprint, insulationname, d, insulation)); + +exit: + scad_geometry_delete(footprint); + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + return res; +error: + goto exit; +} + +static res_T +build_floor_insulation + (const char* prefix, + const struct scpr_polygon* pg, + const struct data_set_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 offset = 0; + double z_insulation = 0; + struct scpr_polygon* pg_int = NULL; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + double d[3] = {0, 0, 0}; + char* insulationname = NULL; + struct str name; + int is_init = 0; + + if (!pg || !data || !insulation) { + res = RES_BAD_ARG; + goto error; + } + + if (prefix) { + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_floor_insulation")); + insulationname = str_get(&name); + } + + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + + /*footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + z_insulation = - e_floor - e_floor_insulation; + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, z_insulation, nverts, &footprint)); + + d[2] = e_floor_insulation; + ERR(scad_geometry_extrude(footprint, insulationname, d, insulation)); + +exit: + scad_geometry_delete(footprint); + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + return res; +error: + goto exit; +} +static res_T +build_inter_floor + (const char* prefix, + const struct scpr_polygon* pg, + const double height, + const struct data_set_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; + double offset = 0; + double z_floor = 0; + double h_cavity = 0; + struct scpr_polygon* pg_int = NULL; + size_t nverts = 0; + struct scad_geometry** floor_list = NULL; + double d[3] = {0, 0, 0}; + char* floorname = NULL; + struct str name; + int is_init = 0; + + if (!pg || !data || !inter_floor) { + res = RES_BAD_ARG; + goto error; + } + + if (prefix) { + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_inter_floor")); + floorname = str_get(&name); + } + + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + + h_cavity = height - e_roof - attic - e_roof_ins - (double)floor_n*e_floor; + z_floor = h_cavity/(double)(1 + floor_n); + d[2] = e_floor; + for (i=0; i< floor_n; ++i) { + struct scad_geometry* floor = NULL; + struct scad_geometry* footprint = NULL; + + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, z_floor, nverts, &footprint)); + ERR(scad_geometry_extrude(footprint, NULL, d, &floor)); + sa_push(floor_list, floor); + ERR(scad_geometry_delete(footprint)); + z_floor += h_cavity/(double)(1 + floor_n) + e_floor; + } + + ERR(scad_fuse_geometries( + floorname, + floor_list, sa_size(floor_list), + floor_list, sa_size(floor_list), + inter_floor)); + +exit: + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + if (floor_list) { + for (i=0; i< floor_n; ++i) { + scad_geometry_delete(floor_list[i]); + } + sa_release(floor_list); + } + return res; +error: + goto exit; +} +static res_T +build_ext_insulation + (const char* prefix, + const struct scpr_polygon* pg, + const double height, + const struct data_set_cmode_1* data, + struct scad_geometry** insulation) +{ + res_T res = RES_OK; + double e_insulation = data->ext_insulation; + double offset = 0; + struct scpr_polygon* pg_int = NULL; + struct scpr_polygon* pg_ext = NULL; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + struct scad_geometry* footprint_int = NULL; + struct scad_geometry* footprint_ext = NULL; + double d[3] = {0, 0, 0}; + char* insulationname = NULL; + struct str name; + int is_init = 0; + + if (!pg || !data || !insulation) { + res = RES_BAD_ARG; + goto error; + } + + if (prefix) { + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_ext_insulation")); + insulationname = str_get(&name); + } + + offset = e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_polygon_create_copy(NULL, pg, &pg_ext)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + + /*insulation footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_ext, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg_ext, 0, nverts, &footprint_ext)); + + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, 0, nverts, &footprint_int)); + + ERR(scad_cut_geometries( + NULL, &footprint_ext, 1, &footprint_int, 1, &footprint)); + + d[2] = height; + ERR(scad_geometry_extrude(footprint, insulationname, d, insulation)); + +exit: + scad_geometry_delete(footprint); + scad_geometry_delete(footprint_int); + scad_geometry_delete(footprint_ext); + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + if (pg_ext) scpr_polygon_ref_put(pg_ext); + return res; +error: + goto exit; +} + +static res_T +build_crawlspace + (const char* prefix, + const struct scpr_polygon* pg, + const struct data_set_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 offset = 0; + double z_crawl= 0; + struct scpr_polygon* pg_int = NULL; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + double d[3] = {0, 0, 0}; + char* crawlname = NULL; + struct str name; + int is_init = 0; + + if (!pg || !data || !crawlspace) { + res = RES_BAD_ARG; + goto error; + } + + if (prefix) { + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_crawlspace")); + crawlname = str_get(&name); + } + + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + + /*footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + z_crawl = - e_floor - e_floor_insulation - e_crawl; + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, z_crawl, nverts, &footprint)); + + d[2] = e_crawl; + ERR(scad_geometry_extrude(footprint, crawlname, d, crawlspace)); + +exit: + scad_geometry_delete(footprint); + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + return res; +error: + goto exit; +} + +static res_T +build_habitable + (const char* prefix, + const struct scpr_polygon* pg, + const double height, + const struct data_set_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 offset = 0; + struct scpr_polygon* pg_int = NULL; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + struct scad_geometry* geom = NULL; + double d[3] = {0, 0, 0}; + char* cavityname = NULL; + struct str name; + int is_init = 0; + + if (!pg || !data || !cavity) { + res = RES_BAD_ARG; + goto error; + } + + if (prefix) { + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_cavity")); + cavityname = str_get(&name); + } + + offset = e_wall + e_ext_insulation + e_int_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + + /*footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, 0, nverts, &footprint)); + + d[2] = height - e_roof - e_attic - e_roof_insulation; + ERR(scad_geometry_extrude(footprint, NULL, d, &geom)); + if (floor) { + ERR(scad_cut_geometries( + cavityname, &geom, 1, &floor, 1, cavity)); + } else { + ERR(scad_geometry_copy(geom, cavityname, cavity)); + } + +exit: + scad_geometry_delete(footprint); + scad_geometry_delete(geom); + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + return res; +error: + goto exit; +} + +static res_T +build_attic + (const char* prefix, + const struct scpr_polygon* pg, + const double height, + const struct data_set_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 offset = 0; + double z_attic = 0; + struct scpr_polygon* pg_int = NULL; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + double d[3] = {0, 0, 0}; + char* atticname = NULL; + struct str name; + int is_init = 0; + + if (!pg || !data || !attic) { + res = RES_BAD_ARG; + goto error; + } + + if (prefix) { + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_attic")); + atticname = str_get(&name); + } + + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + + /*footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + z_attic = height - e_roof - e_attic; + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, z_attic, nverts, &footprint)); + + d[2] = e_attic; + ERR(scad_geometry_extrude(footprint, atticname, d, attic)); + +exit: + scad_geometry_delete(footprint); + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + return res; +error: + goto exit; +} + +static res_T +build_windows + (const char* prefix, + const struct data_set_cmode_1* data, + struct data_cad_cmode_1* data_cad) +{ + res_T res = RES_OK; + size_t i = 0; + double N[3]; + double dir[3]; + double scale[3]; + struct scad_geometry* surface = NULL; + struct scad_geometry* hole = NULL; + struct scad_geometry** hole_list = NULL; + struct scad_geometry* geom = NULL; + struct scad_geometry* bcavity = NULL; + struct scad_geometry** list = NULL; + struct scad_geometry* glass = NULL; + struct scad_geometry** glass_list = NULL; + size_t list_n = 0; + char* name = NULL; + struct str gname; + int is_init = 0; + + if (!data || !data_cad) { + res = RES_BAD_ARG; + goto error; + } + + scale[0] = sqrt(data->glass_ratio); + scale[1] = scale[0]; + scale[2] = scale[0]; + + /* windows are build from the vertical faces of habitable cavities */ + ERR(scad_geometry_boundary(NULL, &data_cad->habitable_cavity, 1, &bcavity)); + ERR(scad_geometry_explode(bcavity, NULL, &list, &list_n)); + + for (i=0; i<list_n; ++i){ + double* center = NULL; + size_t center_n = 0; + + ERR(scad_geometry_get_centerofmass(list[i], &center, &center_n)); + + ERR(scad_geometry_normal(list[i], center, N, NULL, &surface)); + + if (N[2] != 0) { + ERR(scad_geometry_delete(surface)); + surface = NULL; + continue; /* keep only vertical face */ + } + + 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); + ERR(scad_geometry_extrude(surface, NULL, dir, &hole)); + sa_push(hole_list, hole); + + dir[0] = N[0] * 0.024; + dir[1] = N[1] * 0.024; + dir[2] = N[2] * 0.024; + ERR(scad_geometry_extrude(surface, NULL, dir, &glass)); + sa_push(glass_list, glass); + + ERR(scad_geometry_delete(surface)); + surface = NULL; + } + + /* wall perforation */ + ERR(scad_geometry_get_name(data_cad->wall, &name)); + ERR(scad_cut_geometries( + NULL, &data_cad->wall, 1, hole_list, sa_size(hole_list), &geom)); + ERR(scad_geometry_delete(data_cad->wall)); + /*data_cad->wall = geom;*/ + ERR(scad_geometry_copy(geom, name, &data_cad->wall)); + ERR(scad_geometry_delete(geom)); + geom = NULL; + + /* internal insulation perforation */ + if (data_cad->internal_insulation) { + ERR(scad_geometry_get_name(data_cad->internal_insulation, &name)); + ERR(scad_cut_geometries( + NULL, &data_cad->internal_insulation, 1, + hole_list, sa_size(hole_list), &geom)); + ERR(scad_geometry_delete(data_cad->internal_insulation)); + ERR(scad_geometry_copy(geom, name, &data_cad->internal_insulation)); + ERR(scad_geometry_delete(geom)); + geom = NULL; + } + + /* external insulation perforation */ + if (data_cad->external_insulation) { + ERR(scad_geometry_get_name(data_cad->external_insulation, &name)); + ERR(scad_cut_geometries( + NULL, &data_cad->external_insulation, 1, + hole_list, sa_size(hole_list), &geom)); + ERR(scad_geometry_delete(data_cad->external_insulation)); + ERR(scad_geometry_copy(geom, name, &data_cad->external_insulation)); + ERR(scad_geometry_delete(geom)); + geom = NULL; + } + + /* build glass */ + if (prefix) { + str_init(NULL, &gname); + is_init = 1; + ERR(str_set(&gname, prefix)); + ERR(str_append(&gname, "_glass")); + } + + ERR(scad_fuse_geometries(str_cget(&gname), glass_list, 1, + glass_list+1, sa_size(glass_list) - 1, &data_cad->glass)); + +exit: + for (i=0 ; i<list_n; ++i) { + scad_geometry_delete(list[i]); + } + for (i=0 ; i<sa_size(hole_list); ++i) { + scad_geometry_delete(hole_list[i]); + } + for (i=0 ; i<sa_size(glass_list); ++i) { + scad_geometry_delete(glass_list[i]); + } + if (hole_list) sa_release(hole_list); + if (glass_list) sa_release(glass_list); + if (surface) scad_geometry_delete(surface); + if (geom) scad_geometry_delete(geom); + if (bcavity) scad_geometry_delete(bcavity); + /*scad_synchronize();*/ + if (name) free(name); + if (list) free(list); + if (is_init) str_release(&gname); + return res; +error: + goto exit; +} + +static res_T +build_boundary + (const char* prefix, + struct data_cad_cmode_1* data_cad, + struct scad_geometry*** boundary) +{ + res_T res = RES_OK; + struct scad_geometry** list = NULL; + struct scad_geometry* bound = NULL; + char* boundaryname = NULL; + struct str name; + int is_init = 0; + + if (!prefix || !data_cad || !boundary) { + res = RES_BAD_ARG; + goto error; + } + + str_init(NULL, &name); + is_init = 1; + + sa_push(list, data_cad->wall); + sa_push(list, data_cad->roof); + sa_push(list, data_cad->floor); + sa_push(list, data_cad->habitable_cavity); + sa_push(list, data_cad->fake_ground); + if (data_cad->foundation) sa_push(list, data_cad->foundation); + if (data_cad->intermediate_floor) sa_push(list, data_cad->intermediate_floor); + if (data_cad->external_insulation) sa_push(list, data_cad->external_insulation); + if (data_cad->internal_insulation) sa_push(list, data_cad->internal_insulation); + if (data_cad->roof_insulation) sa_push(list, data_cad->roof_insulation); + if (data_cad->floor_insulation) sa_push(list, data_cad->floor_insulation); + if (data_cad->attic_cavity) sa_push(list, data_cad->attic_cavity); + if (data_cad->crawlspace_cavity) sa_push(list, data_cad->crawlspace_cavity); + if (data_cad->glass) sa_push(list, data_cad->glass); + + + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_boundary_wall")); + boundaryname = str_get(&name); + ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list), + &data_cad->wall, 1, &bound)); + sa_push(*boundary, bound); + + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_boundary_roof")); + boundaryname = str_get(&name); + ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list), + &data_cad->roof, 1, &bound)); + sa_push(*boundary, bound); + + if (data_cad->glass) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_boundary_glass")); + boundaryname = str_get(&name); + ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list), + &data_cad->glass, 1, &bound)); + sa_push(*boundary, bound); + } + + if (data_cad->external_insulation) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_boundary_ext_insulation")); + boundaryname = str_get(&name); + ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list), + &data_cad->external_insulation, 1, &bound)); + sa_push(*boundary, bound); + } + + if (data_cad->internal_insulation) { + size_t count = 0; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_boundary_int_insulation")); + boundaryname = str_get(&name); + ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list), + &data_cad->internal_insulation, 1, &bound)); + ERR(scad_geometry_get_count(bound, &count)); + if (count>0) sa_push(*boundary, bound); + } + +exit: + if (is_init) str_release(&name); + if (list) sa_release(list); + return res; +error: + goto exit; +} + +static res_T +build_connection + (const char* prefix, + struct data_cad_cmode_1* data_cad, + struct scad_geometry*** connection) +{ + res_T res = RES_OK; + struct scad_geometry* connect = NULL; + size_t count = 0; + char* cname = NULL; + struct str name; + int is_init = 0; + + if (!prefix || !data_cad || !connection) { + res = RES_BAD_ARG; + goto error; + } + + str_init(NULL, &name); + is_init = 1; + +#define CREATE_CONNECT(G1,G2,SUFFIX) ERR(str_set(&name, prefix));\ + ERR(str_append(&name, SUFFIX));\ + cname = str_get(&name);\ + ERR(scad_geometries_common_boundaries\ + (cname,\ + &data_cad->G1, 1,\ + &data_cad->G2, 1,\ + &connect));\ + ERR(scad_geometry_get_count(connect, &count)); \ + if (count>0) sa_push(*connection, connect); + + + /* -------------------------------------------------------------------------*/ + /* habitable cavity connections */ + /* -------------------------------------------------------------------------*/ + + /* with floor */ + CREATE_CONNECT(habitable_cavity,floor,"_C_cavity_floor"); + + /* with wall */ + CREATE_CONNECT(habitable_cavity,wall,"_C_cavity_wall"); + + /* with glass */ + if (data_cad->glass) { + CREATE_CONNECT(habitable_cavity,glass,"_C_cavity_glass"); + } + + /* with internal insulation */ + if (data_cad->internal_insulation) { + CREATE_CONNECT(habitable_cavity,internal_insulation,"_C_cavity_internal_insulation"); + } + + /* with roof insulation */ + if (data_cad->roof_insulation) { + CREATE_CONNECT(habitable_cavity,roof_insulation,"_C_roof_insulation"); + } else { + /* with roof */ + CREATE_CONNECT(habitable_cavity,roof,"_C_cavity_roof"); + } + + /* with intermediate floor */ + if (data_cad->intermediate_floor) { + CREATE_CONNECT(habitable_cavity,intermediate_floor,"_C_cavity_intermediate_floor"); + } + + /* -------------------------------------------------------------------------*/ + /* crawlspace cavity connections */ + /* -------------------------------------------------------------------------*/ + + if (data_cad->crawlspace_cavity) { + /* with floor insulation */ + if (data_cad->floor_insulation) { + CREATE_CONNECT(crawlspace_cavity, floor_insulation,"_C_crawlspace_insulation"); + } else { + /* with floor */ + CREATE_CONNECT(crawlspace_cavity, floor,"_C_crawlspace_floor"); + } + + /* with wall */ + CREATE_CONNECT(crawlspace_cavity, foundation,"_C_crawlspace_foundation"); + } + + /* -------------------------------------------------------------------------*/ + /* attic cavity connections */ + /* -------------------------------------------------------------------------*/ + + if (data_cad->attic_cavity) { + /* with roof */ + CREATE_CONNECT(attic_cavity, roof,"_C_attic_roof"); + + /* with roof insulation */ + CREATE_CONNECT(attic_cavity, roof_insulation,"_C_attic_insulation"); + + /* with wall */ + CREATE_CONNECT(attic_cavity, wall,"_C_attic_wall"); + } + +#undef CREATE_CONNECT + +exit: + if (is_init) str_release(&name); + return res; +error: + goto exit; +} + +static res_T +build_footprint + (struct scpr_polygon* pg, struct scad_geometry** footprint) +{ + res_T res = RES_OK; + size_t nverts = 0; + + if (!pg || !footprint) { + res = RES_BAD_ARG; + goto error; + } + + ERR(scpr_polygon_get_vertices_count(pg, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg, 0, nverts, footprint)); + +exit: + return res; +error: + goto exit; + +} + +static res_T +build_fake_ground + (struct data_cad_cmode_1* cad, + struct scpr_polygon* pg, + const double depth, + struct scad_geometry** ground) +{ + res_T res = RES_OK; + double dir[3] = {0, 0, 0}; + struct scpr_polygon* pg_offset = NULL; + struct scad_geometry** list = NULL; + struct scad_geometry* footprint = NULL; + struct scad_geometry* geom = NULL; + + if (!cad || !pg || !ground ) { + res = RES_BAD_ARG; + goto error; + } + + if (cad->foundation) sa_push(list, cad->foundation); + if (cad->attic_cavity) sa_push(list, cad->attic_cavity); + if (cad->floor) sa_push(list, cad->floor); + if (cad->floor_insulation) sa_push(list, cad->floor_insulation); + + ERR(scpr_polygon_create_copy(NULL, pg, &pg_offset)); + ERR(scpr_offset_polygon(pg_offset, 0.1, SCPR_JOIN_MITER)); + + ERR(build_footprint(pg_offset, &footprint)); + + dir[2] = -depth*1.1; + ERR(scad_geometry_extrude(footprint, NULL, dir, &geom)); + + ERR(scad_cut_geometries(NULL, &geom, 1, list, sa_size(list), ground)); + +exit: + if (pg_offset) scpr_polygon_ref_put(pg_offset); + if (list) sa_release(list); + if (footprint) scad_geometry_delete(footprint); + if (geom) scad_geometry_delete(geom); + return res; +error: + goto exit; +} + + +static res_T +building_ground_connection + (const char* prefix, + struct data_cad_cmode_1* cad, + struct scad_geometry** connection) +{ + res_T res = RES_OK; + char* cname = NULL; + struct str name; + int is_init = 0; + struct scad_geometry** list = NULL; + struct scad_geometry* list_boundary = NULL; + struct scad_geometry* footprint = NULL; + + if (!prefix || !cad || !connection) { + res = RES_BAD_ARG; + goto error; + } + + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_C_building_ground")); + cname = str_get(&name); + + if (cad->foundation) sa_push(list, cad->foundation); + if (cad->attic_cavity) sa_push(list, cad->attic_cavity); + if (cad->floor) sa_push(list, cad->floor); + if (cad->floor_insulation) sa_push(list, cad->floor_insulation); + if (cad->external_insulation) sa_push(list, cad->external_insulation); + + ERR(scad_geometries_common_boundaries( + cname, list, sa_size(list), + &cad->fake_ground, 1, + connection)); + +exit: + if (list) sa_release(list); + if (is_init) str_release(&name); + if (list_boundary) scad_geometry_delete(list_boundary); + if (footprint) scad_geometry_delete(footprint); + return res; +error: + goto exit; +} + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +res_T +init_model1 + (struct building* building, struct htable_parameter_set* catalog) +{ + res_T res = RES_OK; + struct data_set_cmode_1 data; + struct parameter_set* params; + + params = htable_parameter_set_find(catalog, building->constructive_mode_name); + if (params == NULL) { + res = RES_BAD_ARG; + goto error; + } + + if (params->constructive_mode != building->constructive_mode) { + res = RES_BAD_ARG; + goto error; + } + + data = *(struct data_set_cmode_1*)params->data; + building->data = malloc(sizeof(struct data_set_cmode_1)); + if (!building->data) { + res = RES_MEM_ERR; + goto error; + } + *(struct data_set_cmode_1*)(building->data) = data; + building->build_cad = &build_cad_model1; + building->export_stl = &export_stl_model1; + building->release = &release_model1; + building->build_footprint = &build_footprint_model1; + +exit: + return res; +error: + goto exit; +} + +res_T +build_cad_model1(struct building* building) +{ + res_T res = RES_OK; + size_t id = building->id; + enum constructive_mode_type model = building->constructive_mode; + double height = building->height; + struct scpr_polygon* pg = building->pg; + struct data_set_cmode_1* data = (struct data_set_cmode_1 *)building->data; + struct data_cad_cmode_1* data_cad; + struct str prefix; + int is_init = 0; + + if (!building) { + res = RES_BAD_ARG; + goto error; + } + + str_init(NULL, &prefix); + is_init = 1; + ERR(str_set(&prefix, "building_")); + ERR(str_append_printf(&prefix, "%lu_", (unsigned long)id)); + ERR(str_append(&prefix, constructive_mode_name[model])); + + data_cad = malloc(sizeof(struct data_cad_cmode_1)); + data_cad->wall = NULL; + data_cad->roof = NULL; + data_cad->floor = NULL; + data_cad->intermediate_floor = NULL; + data_cad->habitable_cavity = NULL; + data_cad->crawlspace_cavity = NULL; + data_cad->attic_cavity = NULL; + data_cad->internal_insulation = NULL; + data_cad->external_insulation = NULL; + data_cad->floor_insulation = NULL; + data_cad->roof_insulation = NULL; + data_cad->foundation = NULL; + data_cad->glass = NULL; + data_cad->ground_connection = NULL; + data_cad->boundary = NULL; + data_cad->connection = NULL; + building->data_cad = (struct data_cad_cmode_1*)data_cad; + + /* build mandatories elements : + - floor + - wall + - roof + */ + + ERR(build_floor(str_cget(&prefix), pg, data, &data_cad->floor)); + + ERR(build_wall(str_cget(&prefix), "wall", pg, height, data, &data_cad->wall)); + + ERR(build_roof(str_cget(&prefix), pg, height, data, &data_cad->roof)); + + /* build optionnal elements : + - foundation + - intermediate floor + - external insulation + - internal insulation + - roof insulation + - floor insulation + */ + + if (data->foundation > 0) { + double depth = -data->foundation; + ERR(build_wall( + str_cget(&prefix), "foundation", pg, depth, data, &data_cad->foundation)); + } else { + data_cad->foundation = NULL; + } + + if (data->inter_floor_n > 0) { + ERR(build_inter_floor( + str_cget(&prefix), pg, height, data, &data_cad->intermediate_floor)); + } else { + data_cad->intermediate_floor = NULL; + } + + if (data->ext_insulation > 0) { + ERR(build_ext_insulation( + str_cget(&prefix), pg, height, data, &data_cad->external_insulation)); + } else { + data_cad->external_insulation = NULL; + } + + if (data->int_insulation > 0) { + ERR(build_int_insulation( + str_cget(&prefix), pg, height, data, data_cad->intermediate_floor, + &data_cad->internal_insulation)); + } else { + data_cad->internal_insulation = NULL; + } + + if (data->roof_insulation > 0) { + ERR(build_roof_insulation( + str_cget(&prefix), pg, height, data, &data_cad->roof_insulation)); + } else { + data_cad->roof_insulation = NULL; + } + + if (data->floor_insulation > 0) { + ERR(build_floor_insulation( + str_cget(&prefix), pg, data, &data_cad->floor_insulation)); + } else { + data_cad->floor_insulation = NULL; + } + + /* build cavities : + - attic + - habitable + - crawlspace + */ + + if (data->attic > 0) { + ERR(build_attic( + str_cget(&prefix), pg, height, data, &data_cad->attic_cavity)); + } else { + data_cad->attic_cavity = NULL; + } + + ERR(build_habitable( + str_cget(&prefix), pg, height, data, data_cad->intermediate_floor, + &data_cad->habitable_cavity)); + + if (data->crawl > 0) { + ERR(build_crawlspace( + str_cget(&prefix), pg, data, &data_cad->crawlspace_cavity)); + } else { + data_cad->crawlspace_cavity = NULL; + } + + /* windows */ + if (data->glass_ratio > 0) { + ERR(build_windows(str_cget(&prefix), data, data_cad)); + } + + /* fake ground */ + ERR(build_fake_ground(data_cad, pg, data->foundation, &data_cad->fake_ground)); + + ERR(scad_scene_partition()); + + /* build ground/buildind connection */ + ERR(building_ground_connection(str_cget(&prefix), data_cad, + &data_cad->ground_connection)); + + /* build boundaries */ + data_cad->boundary = NULL; + ERR(build_boundary(str_cget(&prefix), data_cad, &data_cad->boundary)); + + /* build connections */ + data_cad->connection = NULL; + ERR(build_connection(str_cget(&prefix), data_cad, &data_cad->connection)); + +exit: + if (is_init) str_release(&prefix); + return res; +error: + goto exit; +} + +res_T +build_footprint_model1 + (struct building* building, + struct scad_geometry** footprint) +{ + res_T res = RES_OK; + struct scpr_polygon* pg = building->pg; + + if (!building || !footprint) { + res = RES_BAD_ARG; + goto error; + } + + ERR(build_footprint(pg, footprint)); + +exit: + return res; +error: + goto exit; +} + +res_T +export_stl_model1 + (const struct building* building, const int binary) +{ + res_T res = RES_OK; + struct data_cad_cmode_1* data_cad = (struct data_cad_cmode_1 *)building->data_cad; + size_t i = 0; + + /* floor export */ + ERR(scad_stl_export(data_cad->floor, NULL, binary)); + + /* wall export */ + ERR(scad_stl_export(data_cad->wall, NULL, binary)); + + /* roof export */ + ERR(scad_stl_export(data_cad->roof, NULL, binary)); + + /* foundation export */ + if (data_cad->foundation) { + ERR(scad_stl_export(data_cad->foundation, NULL, binary)); + } + + /* glass export */ + if (data_cad->glass) { + ERR(scad_stl_export(data_cad->glass, NULL, binary)); + } + + /* intermediate floor export*/ + if (data_cad->intermediate_floor) { + ERR(scad_stl_export(data_cad->intermediate_floor, NULL, binary)); + } + + /* internal insulation export*/ + if (data_cad->internal_insulation) { + ERR(scad_stl_export(data_cad->internal_insulation, NULL, binary)); + } + + /* external insulation export*/ + if (data_cad->external_insulation) { + ERR(scad_stl_export(data_cad->external_insulation, NULL, binary)); + } + + /* roof insulation export*/ + if (data_cad->roof_insulation) { + ERR(scad_stl_export(data_cad->roof_insulation, NULL, binary)); + } + + /* floor insulation export*/ + if (data_cad->floor_insulation) { + ERR(scad_stl_export(data_cad->floor_insulation, NULL, binary)); + } + + /* attic cavity export*/ + if (data_cad->attic_cavity) { + ERR(scad_stl_export(data_cad->attic_cavity, NULL, binary)); + } + + /* habitable cavity export*/ + ERR(scad_stl_export(data_cad->habitable_cavity, NULL, binary)); + + /* crawlspace cavity export*/ + if (data_cad->crawlspace_cavity) { + ERR(scad_stl_export(data_cad->crawlspace_cavity, NULL, binary)); + } + + /* boundary export*/ + for (i=0; i<sa_size(data_cad->boundary); ++i) { + ERR(scad_stl_export(data_cad->boundary[i], NULL, binary)); + } + + /* connections export*/ + for (i=0; i<sa_size(data_cad->connection); ++i) { + ERR(scad_stl_export(data_cad->connection[i], NULL, binary)); + } + + /* ground/building connection export*/ + ERR(scad_stl_export(data_cad->ground_connection, NULL, binary)); + +exit: + return res; +error: + goto exit; +} + +res_T +release_model1 + (struct building* building) +{ + res_T res = RES_OK; + struct data_set_cmode_1* data = (struct data_set_cmode_1 *)building->data; + struct data_cad_cmode_1* data_cad = (struct data_cad_cmode_1 *)building->data_cad; + + scpr_polygon_ref_put(building->pg); + + str_release(building->constructive_mode_name); + + if (data_cad->boundary) sa_release(data_cad->boundary); + if (data_cad->connection) sa_release(data_cad->connection); + if (data) free(data); + if (data_cad) free(data_cad); + + return res; +} diff --git a/src/cg_constructive_mode_1.h b/src/cg_constructive_mode_1.h @@ -0,0 +1,89 @@ +/* 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 BUILDING_MODEL1_H +#define BUILDING_MODEL1_H + +#include <rsys/rsys.h> + +struct scad_geometry; + +struct building; +struct htable_parameter_set; +struct parameter_set; + +/* 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)*/ + double glass_ratio; /* in [0, 1] */ +}; + +struct data_cad_cmode_1 { + struct scad_geometry* wall; + struct scad_geometry* roof; + struct scad_geometry* floor; + struct scad_geometry* foundation; /* can be NULL */ + struct scad_geometry* intermediate_floor; /* can be NULL */ + struct scad_geometry* habitable_cavity; + struct scad_geometry* crawlspace_cavity; /* can be NULL */ + struct scad_geometry* attic_cavity; /* can be NULL */ + struct scad_geometry* internal_insulation; /* can be NULL */ + struct scad_geometry* external_insulation; /* can be NULL */ + struct scad_geometry* floor_insulation; /* can be NULL */ + struct scad_geometry* roof_insulation; /* can be NULL */ + struct scad_geometry* glass; + struct scad_geometry* fake_ground;/*not exported, used for ground connection*/ + struct scad_geometry* ground_connection; + struct scad_geometry** boundary; + struct scad_geometry** connection; + size_t n_connection; +}; + +res_T +init_model1 + (struct building* building, struct htable_parameter_set* catalog); + +res_T +build_cad_model1(struct building* building); + +res_T +build_footprint_model1 + (struct building* building, + struct scad_geometry** footprint); + +res_T +export_stl_model1 + (const struct building* building, const int binary); + +res_T +release_model1 + (struct building* building); + +#endif /* BUILDING_MODEL1_H */ diff --git a/src/cg_main.c b/src/cg_main.c @@ -19,13 +19,14 @@ #include "cg.h" #include "cg_args.h" +#include "cg_building.h" #include "cg_city.h" #include <rsys/rsys.h> #include <rsys/logger.h> #include <rsys/mem_allocator.h> -char const* model_str [2] = { +char const* constructive_mode_name[CONSTRUCTIVE_MODES_COUNT__] = { "model0", "model1" }; diff --git a/src/cg_parsing.c b/src/cg_parsing.c @@ -71,13 +71,13 @@ error: goto exit; } -static enum model_type get_enum_value(char * val) +static enum constructive_mode_type get_enum_value(char * val) { int i=0; - for (i=0; i<MODEL_COUNT_; ++i) - if (!strcmp(model_str[i], val)) - return (enum model_type)i; - return MODEL_COUNT_; + for (i=0; i<CONSTRUCTIVE_MODES_COUNT__; ++i) + if (!strcmp(constructive_mode_name[i], val)) + return (enum constructive_mode_type)i; + return CONSTRUCTIVE_MODES_COUNT__; } static res_T @@ -271,10 +271,10 @@ parse_building else if (sscanf(line, "model=model%d", &m) == 1 ) { switch(m) { case 0: - building->model = model0; + building->constructive_mode = mode_0; break; case 1: - building->model = model1; + building->constructive_mode = mode_1; break; default: res = RES_BAD_ARG; @@ -283,9 +283,9 @@ parse_building } else if (sscanf(line, "data=%s", value) == 1 ) { - building->data_name = malloc(sizeof(struct str)); - str_init(NULL, building->data_name); - str_set(building->data_name, value); + building->constructive_mode_name = malloc(sizeof(struct str)); + str_init(NULL, building->constructive_mode_name); + str_set(building->constructive_mode_name, value); } /*if new section break*/ @@ -312,7 +312,7 @@ parse_building } /*check model*/ - if (building->model == MODEL_COUNT_) { + if (building->constructive_mode == CONSTRUCTIVE_MODES_COUNT__) { logger_print(logger, LOG_ERROR, "[model] not recognized.\n"); res = RES_BAD_ARG; @@ -367,44 +367,44 @@ error: } res_T -parse_building_params +parse_catalog (struct logger* logger, - struct htable_building_params* ht_params) + struct htable_parameter_set* catalog) { res_T res = RES_OK; - struct data_model0* data0; - struct data_model1* data1; - struct building_params* params0; + struct data_set_cmode_0* data0; + struct data_set_cmode_1* data1; + struct parameter_set* params0; (void)logger; - htable_building_params_init(NULL, ht_params); + htable_parameter_set_init(NULL, catalog); - params0 = malloc(2*sizeof(struct building_params)); + params0 = malloc(2*sizeof(struct parameter_set)); if (!params0) { res = RES_MEM_ERR; goto error; } - data0 = malloc(sizeof(struct data_model0)); + data0 = malloc(sizeof(struct data_set_cmode_0)); if (!data0) { res = RES_MEM_ERR; goto error; } - params0[0].model = model0; + params0[0].constructive_mode = mode_0; str_init(NULL, &params0[0].name); str_set(&params0[0].name, "b0"); data0->wall = 0.2; data0->floor = 0.3; - params0[0].data = malloc(sizeof(struct data_model0)); + params0[0].data = malloc(sizeof(struct data_set_cmode_0)); params0[0].data = (void*)data0; - ERR(htable_building_params_set(ht_params, &params0[0].name, &params0[0])); + ERR(htable_parameter_set_set(catalog, &params0[0].name, &params0[0])); - data1 = malloc(sizeof(struct data_model1)); + data1 = malloc(sizeof(struct data_set_cmode_1)); if (!data1) { res = RES_MEM_ERR; goto error; } - params0[1].model = model1; + params0[1].constructive_mode = mode_1; str_init(NULL, &params0[1].name); str_set(&params0[1].name, "b1"); data1->wall = 0.25; @@ -420,26 +420,25 @@ parse_building_params data1->crawl = 0; data1->attic = 0; data1->glass_ratio = 0.5; - params0[1].data = malloc(sizeof(struct data_model1)); + params0[1].data = malloc(sizeof(struct data_set_cmode_1)); params0[1].data = (void*)data1; - ERR(htable_building_params_set(ht_params, &params0[1].name, &params0[1])); + ERR(htable_parameter_set_set(catalog, &params0[1].name, &params0[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); return res; error: - htable_building_params_release(ht_params); + htable_parameter_set_release(catalog); goto exit; } res_T -release_params_building(struct building_params* params) +release_params_building(struct parameter_set* params) { res_T res = RES_OK; size_t i; diff --git a/src/cg_parsing.h b/src/cg_parsing.h @@ -26,10 +26,10 @@ struct txtrdr; struct logger; -struct htable_building_params; +struct htable_parameter_set; struct city; -struct building_params; +struct parameter_set; res_T parse_city @@ -38,11 +38,11 @@ parse_city struct city* city); res_T -parse_building_params +parse_catalog (struct logger* logger, - struct htable_building_params* ht_params); + struct htable_parameter_set* ht_params); res_T -release_params_building(struct building_params* params); +release_params_building(struct parameter_set* params); #endif /*PARSING_H*/