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:
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], ¢er, ¢er_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], ¢er, ¢er_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, ¶ms0[0].name);
str_set(¶ms0[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, ¶ms0[0].name, ¶ms0[0]));
+ ERR(htable_parameter_set_set(catalog, ¶ms0[0].name, ¶ms0[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, ¶ms0[1].name);
str_set(¶ms0[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, ¶ms0[1].name, ¶ms0[1]));
+ ERR(htable_parameter_set_set(catalog, ¶ms0[1].name, ¶ms0[1]));
/* check coherence */
if (data1->roof_insulation <= 0) data1->attic = 0;
if (data1->inter_floor <= 0) data1->inter_floor_n = 0;
if (data1->inter_floor_n <= 0) data1->inter_floor = 0;
-
exit:
free(params0);
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*/