commit c54eda0196e7618e9052b63755afc541a74705c5
parent eb5fe8f2455c41328b7d37c2727962060468b4a8
Author: Benjamin Piaud <benjamin.piaud@meso-star.com>
Date: Tue, 17 Jan 2023 10:55:03 +0100
Merge remote-tracking branch 'refs/remotes/origin/develop' into develop
Diffstat:
28 files changed, 2927 insertions(+), 2866 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -106,8 +106,8 @@ set(CG2_FILES_SRC
cg_catalog_parsing.c
cg_city.c
cg_city_parsing.c
- cg_constructive_mode_0.c
- cg_constructive_mode_1.c
+ cg_construction_mode_0.c
+ cg_construction_mode_1.c
cg_ground.c
cg_main.c)
@@ -120,11 +120,11 @@ set(CG2_FILES_INC
cg_city.h
cg_city_parsing.h
cg_city_parsing_schemas.h
- cg_constructive_mode.h
- cg_constructive_mode_0.h
- cg_constructive_mode_0_parsing_schemas.h
- cg_constructive_mode_1.h
- cg_constructive_mode_1_parsing_schemas.h
+ cg_construction_mode.h
+ cg_construction_mode_0.h
+ cg_construction_mode_0_parsing_schemas.h
+ cg_construction_mode_1.h
+ cg_construction_mode_1_parsing_schemas.h
cg_default.h.in
cg_ground.h
cg_version.h.in)
diff --git a/doc/city_generator2-input.5.txt b/doc/city_generator2-input.5.txt
@@ -25,7 +25,7 @@
== NAME
-city_generator2-input - description of the input files formats for
+city_generator2-input - description of input file formats for
city_generator2(1)
== DESCRIPTION
@@ -33,53 +33,114 @@ city_generator2(1)
*city_generator2-input*(5) are the formats used by the *city_generator2*(1)
program to describe a city. They all rely on the yaml 1.1 syntax[1].
*city_generator2*(1) reads two different types of files: a single map file, and
-at least one catalog file. The followig two sections describe their formats.
+at least one catalog file. The next two sections describe their formats.
+
+Because these files are yaml files, they must comply with yaml syntax rules,
+including the hard part that is spacing. The following grammar rules that begin
+with a verbatim text must all start at column 1. From here, the amount of
+whitespace characters in verbatim text must be strictly observed. Also, text
+appearing between quote marks has to be used verbatim in the input, without the
+quote characters. Finally, text introduced by the *#* character in descriptions,
+when not verbatim, is a comment and is not part of the description.
[1] https://yaml.org/
=== CITY MAP FILE FORMAT
-b
+The city map file aims to describe the ground, that is currently limited to a
+single layer, with a depth, and the list of buildings on the ground. Each
+building is described in the same way, regardless of its construction mode, that
+is part of the description.
+
+==== GRAMMAR
+
+[verse]
+_______
+<city-map-file> ::= <ground-description>
+ <building-list>
+
+<ground-description> ::= "ground:"
+ " extent: " <extent>
+ " depth: " <depth>
+
+<building-list> ::= "building: "
+ <buildings>
+
+-------------------------------------
+
+<extent> ::= "[ <Xmin> "," <Ymin> "," <Xsize> "," <Ysize> ]
+
+<depth> ::= <REAL> # in ]0, INF)
+
+<Xmin> ::= <REAL>
+
+<Ymin> ::= <REAL>
+
+<buildings> ::= <building>
+ [ <buildings> ]
+
+<Xsize> ::= <REAL> # in ]0, INF)
+
+<Ysize> ::= <REAL> # in ]0, INF)
+
+-------------------------------------
+
+<building> ::= " -id: " <name>
+ " model: " <cmode-name>
+ " data: " <dataset-name>
+ " height: " <height>
+ " polygon: [" <vertices> "]" # At least 3 vertices
+
+<name> ::= STRING
+
+<cmode-name> ::= "construction_Mode_0" | "construction_Mode_1"
+
+<dataset-name> ::= STRING
+
+<height> ::= <REAL> # in ]0, INF)
+
+<vertices> ::= <vertex> [ "," <vertices> ]
+
+-------------------------------------
+
+<vertex> ::= "[" <X> "," <Y> "]"
+
+<X> ::= <REAL>
+
+<Y> ::= <REAL>
+
+______________
=== CATALOG FILE FORMATS
There are currently two different catalog file formats, identified by name, and
-the way city-generator is designed allows for additional catalog formats to be
+the way city-generator2 is designed allows for additional catalog formats to be
implemented.
-All catalog files contain the name of the constructive mode they add datasets
-to, and a list of datasets. What differs among catalog file formats is the
-format of the datasets. It is obviously expected that datasets use the format
-associated with the named constructive mode.
+All catalog files contain the name of the construction mode to which they add
+datasets, and a list of datasets. What differs between catalog file formats is
+the format of the datasets. It is obviously expected that datasets use the
+format associated with the named construction mode.
==== GRAMMAR
-Catalog files being yaml files, they must comply with yaml syntax rules,
-including the hard part that is spacing. The following grammar rules that start
-with a verbatim item are all expected to start at column 1. From there, the
-amount of whitespace characters in verbatim items must be strictly observed.
-Also, text appearing between quote marks has to be used verbatim in the input,
-with or without the quote characters. Finally, text introduced by the *#*
-character in descriptions, when not verbatim, is a comment and is not part of
-the description.
-
[verse]
_______
<catalog-file> ::= <catalog-file_0 > | <catalog-file_1>
-<catalog-file-0> ::= <constructive-mode-0>
- "sets:"
+<catalog-file-0> ::= <construction-mode-0>
+ "datasets:"
<datasets-0>
-<catalog-file-1> ::= <constructive-mode-1>
- "sets:"
+<catalog-file-1> ::= <construction-mode-1>
+ "datasets:"
<datasets-1>
-------------------------------------
-<constructive-mode-0> ::= "constructive_mode_type: Constructive_Mode_0"
+<construction-mode-0> ::= "construction_mode_type: construction_Mode_0"
-<constructive-mode-1> ::= "constructive_mode_type: Constructive_Mode_1"
+<construction-mode-1> ::= "construction_mode_type: construction_Mode_1"
-------------------------------------
diff --git a/doc/city_generator2.1.txt.in b/doc/city_generator2.1.txt.in
@@ -38,7 +38,7 @@ DESCRIPTION
*city_generator2* generates a city as 3D conformal meshes from an ascii
description. The description includes the city map (a description of the ground
and buildings in a yaml file), and at least one catalog file (a description of
-a set of datasets grouped by constructive modes). The provided description must
+a set of datasets grouped by construction modes). The provided description must
comply with the *city_generator2-input*(5) format.
The output of *city_generator2* is a set of *STL* files, either in ascii or in
@@ -65,16 +65,16 @@ MANDATORY OPTIONS
*-m* _file_::
Read a city map file which is a text file in yaml 1.1 format containing the
description of the ground and a list of buildings. The description of an
- individual building include its footprint and constructive mode among other
+ individual building include its footprint and construction mode among other
things.
Please refer to *city_generator2-input*(5) for more information on formats.
*-c* _file_::
Read a catalog file which is a text file in yaml 1.1 format containing datasets
- for a given constructive mode. All the datasets in a given file share the
- same constructive mode. If the city map uses more than one constructive mode,
+ for a given construction mode. All the datasets in a given file share the
+ same construction mode. If the city map uses more than one construction mode,
the different datasets must be provided in (at least) as many catalog files
- as there are constructive modes involved.
+ as there are construction modes involved.
Please refer to *city_generator2-input*(5) for more information on formats.
OTHER OPTIONS
diff --git a/src/cg_args.c b/src/cg_args.c
@@ -54,7 +54,7 @@ short_help(void)
"-m <city_map_filename>\n"
" Read a yaml file that describes the city map.\n"
"-c <filename>\n"
- " Read a yaml file containing datasets for a given constructive mode.\n"
+ " Read a yaml file containing datasets for a given construction mode.\n"
" Can be used more than once.\n"
"\nOther options\n"
"-------------\n"
diff --git a/src/cg_building.h b/src/cg_building.h
@@ -32,8 +32,8 @@ struct catalog;
struct building;
struct parsed_city_building;
-/* A type to store the functors of a constructive mode */
-struct constructive_mode_functors {
+/* A type to store the functors of a construction mode */
+struct construction_mode_functors {
res_T (*init)
(struct building* building,
struct mem_allocator* allocator,
@@ -53,30 +53,30 @@ struct constructive_mode_functors {
(struct mem_allocator* allocator, struct logger* logger, void* cad);
};
-/* A type to give an ID to constructive modes.
- * Add a new entry for each new constructive mode. */
-enum constructive_mode_type {
+/* A type to give an ID to construction modes.
+ * Add a new entry for each new construction mode. */
+enum construction_mode_type {
mode_0,
mode_1,
- CONSTRUCTIVE_MODES_COUNT__
+ Construction_MODES_COUNT__
};
-/* The name of the constructive modes, as expected in the city description. */
-extern char const* constructive_mode_name[CONSTRUCTIVE_MODES_COUNT__];
+/* The name of the construction modes, as expected in the city description. */
+extern char const* construction_mode_name[Construction_MODES_COUNT__];
/* The type of buildings as described in the city description */
struct building {
- /* constructive mode */
- struct constructive_mode_functors* functors;
- enum constructive_mode_type constructive_mode;
+ /* construction mode */
+ struct construction_mode_functors* functors;
+ enum construction_mode_type construction_mode;
- /* generic constructive mode data */
+ /* generic construction mode data */
int name_initialized;
struct str name;
double height;
struct scpr_polygon* pg;
- /* specific data depending to the constructive mode */
+ /* specific data depending to the construction mode */
void* data;
};
diff --git a/src/cg_catalog.c b/src/cg_catalog.c
@@ -21,10 +21,10 @@
#include "cg_building.h"
#include "cg_catalog.h"
#include "cg_catalog_parsing.h"
-#include "cg_constructive_mode_0.h"
-#include "cg_constructive_mode_1.h"
-#include "cg_constructive_mode_0_parsing_schemas.h"
-#include "cg_constructive_mode_1_parsing_schemas.h"
+#include "cg_construction_mode_0.h"
+#include "cg_construction_mode_1.h"
+#include "cg_construction_mode_0_parsing_schemas.h"
+#include "cg_construction_mode_1_parsing_schemas.h"
#include <rsys/rsys.h>
#include <rsys/mem_allocator.h>
@@ -43,8 +43,8 @@ find_first_filename
ASSERT(dataset_name && items && count > 0);
for(i = 0; i < count; i++) {
- if(items[i].constructive_mode != dataset_cmode) continue;
- switch(items[i].constructive_mode) {
+ if(items[i].construction_mode != dataset_cmode) continue;
+ switch(items[i].construction_mode) {
case mode_0: {
const struct parsed_catalog_cmode_0* prsd_0 = items[i].parsed_data;
for(j = 0; j < prsd_0->datasets_count; j++) {
@@ -104,7 +104,7 @@ create_catalog
items = darray_parsed_catalog_items_cdata_get(&parsed_catalog->catalog);
for(i = 0; i < count; i++) {
- switch(items[i].constructive_mode) {
+ switch(items[i].construction_mode) {
case mode_0: {
const struct parsed_catalog_cmode_0* parsed_0 = items[i].parsed_data;
for(j = 0; j < parsed_0->datasets_count; j++) {
diff --git a/src/cg_catalog.h b/src/cg_catalog.h
@@ -20,8 +20,8 @@
#ifndef FG_CATALOG__
#define FG_CATALOG__
-#include "cg_constructive_mode_0.h"
-#include "cg_constructive_mode_1.h"
+#include "cg_construction_mode_0.h"
+#include "cg_construction_mode_1.h"
struct mem_allocator;
struct logger;
diff --git a/src/cg_catalog_parsing.c b/src/cg_catalog_parsing.c
@@ -20,8 +20,8 @@
#include "cg.h"
#include "cg_args.h"
#include "cg_catalog_parsing.h"
-#include "cg_constructive_mode_0_parsing_schemas.h"
-#include "cg_constructive_mode_1_parsing_schemas.h"
+#include "cg_construction_mode_0_parsing_schemas.h"
+#include "cg_construction_mode_1_parsing_schemas.h"
#include "cg_city_parsing_schemas.h"
#include "cg_building.h"
@@ -36,9 +36,9 @@ get_schema_from_parsed_cmode
{
switch(parsed_cmode) {
case PARSED_CMODE_0:
- return &constructive_mode_0_schema;
+ return &construction_mode_0_schema;
case PARSED_CMODE_1:
- return &constructive_mode_1_schema;
+ return &construction_mode_1_schema;
default: FATAL("Invalid enum value.\n");
}
}
@@ -79,23 +79,23 @@ parse_catalog
for(i = 0; i < files_count; i++) {
const struct cyaml_schema_value* schema;
- /* Parse constructive mode only */
+ /* Parse construction mode only */
filename = darray_catalog_filenames_cdata_get(files_array)[i];
- err = cyaml_load_file(filename, config, &constructive_mode_schema,
+ err = cyaml_load_file(filename, config, &construction_mode_schema,
(void**)&parsed_cmode, NULL);
ERR(cyaml_err_to_res_T(err));
- /* Parse catalog items according to constructive mode */
+ /* Parse catalog items according to construction mode */
schema = get_schema_from_parsed_cmode(parsed_cmode->cmode_type);
err = cyaml_load_file(filename, config, schema, &items[i].parsed_data, NULL);
ERR(cyaml_err_to_res_T(err));
/* Set other fields*/
items[i].filename = filename;
- items[i].constructive_mode = parsed_cmode->cmode_type;
+ items[i].construction_mode = parsed_cmode->cmode_type;
/* Free tmp struct */
- err = cyaml_free(config, &constructive_mode_schema, parsed_cmode, 1);
+ err = cyaml_free(config, &construction_mode_schema, parsed_cmode, 1);
CHK(RES_OK == cyaml_err_to_res_T(err));
parsed_cmode = NULL;
filename = NULL;
@@ -134,7 +134,7 @@ release_parsed_catalog
items = darray_parsed_catalog_items_data_get(&parsed->catalog);
for(i = 0; i < count; i++) {
const struct cyaml_schema_value* schema
- = get_schema_from_parsed_cmode(items[i].constructive_mode);
+ = get_schema_from_parsed_cmode(items[i].construction_mode);
cyaml_err_t err = cyaml_free(config, schema, items[i].parsed_data, 1);
CHK(RES_OK == cyaml_err_to_res_T(err));
}
diff --git a/src/cg_catalog_parsing.h b/src/cg_catalog_parsing.h
@@ -20,7 +20,7 @@
#ifndef PARSING_H
#define PARSING_H
-#include "cg_constructive_modes_parsing_schemas.h"
+#include "cg_construction_modes_parsing_schemas.h"
#include <rsys/rsys.h>
#include <rsys/dynamic_array.h>
@@ -31,7 +31,7 @@ struct cyaml_config;
struct darray_catalog_filenames;
struct parsed_catalog_items {
- enum parsed_cmode_type constructive_mode;
+ enum parsed_cmode_type construction_mode;
char* filename;
void* parsed_data;
};
diff --git a/src/cg_city.c b/src/cg_city.c
@@ -19,8 +19,8 @@
#include "cg.h"
#include "cg_city.h"
-#include "cg_constructive_mode_0.h"
-#include "cg_constructive_mode_1.h"
+#include "cg_construction_mode_0.h"
+#include "cg_construction_mode_1.h"
#include "cg_ground.h"
#include "cg_catalog_parsing.h"
#include "cg_city_parsing.h"
@@ -92,7 +92,7 @@ create_city
city->ground_depth = parsed_city->ground.depth;
d4_set(city->ground_extent, parsed_city->ground.extent);
- /* create buildings depending on their constructive modes */
+ /* create buildings depending on their construction modes */
for (i = 0; i < city->buildings_count ; i++) {
struct parsed_city_building* parsed_data = parsed_city->city_building_list + i;
struct building* building = city->buildings + i;
diff --git a/src/cg_city_parsing_schemas.h b/src/cg_city_parsing_schemas.h
@@ -20,7 +20,7 @@
#ifndef FG_CITY_PARSING_SCHEMAS__
#define FG_CITY_PARSING_SCHEMAS__
-#include "cg_constructive_modes_parsing_schemas.h"
+#include "cg_construction_modes_parsing_schemas.h"
#include <rsys/str.h>
@@ -85,15 +85,15 @@ static const struct cyaml_schema_value double2_schema = {
};
static const cyaml_schema_field_t city_building_fields_schema[] = {
- CYAML_FIELD_STRING_PTR("id", /* TODO: rename "name" */
+ CYAML_FIELD_STRING_PTR("name",
CYAML_FLAG_POINTER, struct parsed_city_building, name, 0, CYAML_UNLIMITED),
- CYAML_FIELD_ENUM("model", /* TODO: rename "constructive_mode" */
+ CYAML_FIELD_ENUM("construction_mode",
CYAML_FLAG_CASE_INSENSITIVE, struct parsed_city_building, cmode_type,
city_building_types_strings, CYAML_ARRAY_LEN(city_building_types_strings)),
- CYAML_FIELD_STRING_PTR("data", /* TODO: rename "parameter_set" */
+ CYAML_FIELD_STRING_PTR("dataset",
CYAML_FLAG_POINTER, struct parsed_city_building, dataset_name, 0, CYAML_UNLIMITED),
{
- .key = "polygon", /*TODO: rename "external_polygon" */
+ .key = "footprint",
.value = {
.type = CYAML_SEQUENCE,
.flags = CYAML_FLAG_POINTER | CYAML_FLAG_FLOW,
@@ -123,7 +123,7 @@ static const cyaml_schema_field_t city_fields_schema[] = {
CYAML_FIELD_MAPPING("ground", CYAML_FLAG_DEFAULT,
struct parsed_city, ground, ground_fields_schema),
{
- .key = "building", /* TODO: rename "buildings" */
+ .key = "buildings",
.value = {
.type = CYAML_SEQUENCE,
.flags = CYAML_FLAG_POINTER,
diff --git a/src/cg_construction_mode.h b/src/cg_construction_mode.h
@@ -0,0 +1,54 @@
+/* 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 Construction_MODE_H__
+#define Construction_MODE_H__
+
+#include "cg_city_parsing_schemas.h"
+
+#include <rsys/rsys.h>
+#include <star/scpr.h>
+
+static void
+get_nverts(const size_t icomp, size_t* nverts, void* context)
+{
+ struct parsed_city_building* parsed_data = context;
+ ASSERT(icomp == 0); (void)icomp;
+ *nverts = parsed_data->vertice_count;
+}
+
+static void
+get_pos(const size_t icomp, const size_t ivert, double pos[2], void* context)
+{
+ struct parsed_city_building* parsed_data = context;
+ ASSERT(icomp == 0); (void)icomp;
+ pos[0] = parsed_data->vertice[ivert*2 + 0];
+ pos[1] = parsed_data->vertice[ivert*2 + 1];
+}
+
+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);
+}
+
+#endif
+
diff --git a/src/cg_construction_mode_0.c b/src/cg_construction_mode_0.c
@@ -0,0 +1,639 @@
+/* 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 "cg_catalog.h"
+#include "cg_city.h"
+#include "cg_city_parsing_schemas.h"
+#include "cg_construction_mode_0.h"
+#include "cg_construction_mode.h"
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+#include <rsys/logger.h>
+#include <star/scad.h>
+
+static res_T
+build_floor_footprint
+ (struct scpr_polygon* pg,
+ struct scad_geometry** footprint)
+{
+ res_T res = RES_OK;
+ size_t nverts;
+
+ ASSERT(pg && footprint);
+ 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 dataset_cmode_0* data;
+ struct scad_geometry* footprint = NULL;
+ double d[3] = {0, 0, 0};
+ char* floorname = NULL;
+ struct str name;
+ int is_init = 0;
+
+ ASSERT(pg && b && floor);
+
+ data = (struct dataset_cmode_0*)b->data;
+ e = data->floor_thickness;
+
+ str_init(NULL, &name);
+ is_init = 1;
+ if (prefix) {
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_S_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 dataset_cmode_0* data;
+ char* roofname = NULL;
+ struct str name;
+ int is_init = 0;
+
+ ASSERT(b && floor && roof);
+
+ str_init(NULL, &name);
+ is_init = 1;
+ if (prefix) {
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_S_roof"));
+ roofname = str_get(&name);
+ }
+
+ height = b->height;
+ data = (struct dataset_cmode_0*)b->data;
+ e = data->floor_thickness;
+
+ 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 scad_geometry* polygon = NULL;
+ struct scad_geometry* polygon_int = NULL;
+ size_t nverts, nverts_int;
+
+ ASSERT(pg && pg_int && footprint);
+
+ 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;
+
+ ASSERT(pg && pg_int && b && wall);
+
+ height = b->height;
+
+ str_init(NULL, &name);
+ is_init = 1;
+ if (prefix) {
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_S_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 dataset_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;
+
+ ASSERT(pg && b && cavity);
+
+ height = b->height;
+ data = (struct dataset_cmode_0*)b->data;
+ e = data->floor_thickness;
+
+ str_init(NULL, &name);
+ is_init = 1;
+ if (prefix) {
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_F_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 mem_allocator* allocator,
+ struct data_cad_cmode_0* cad)
+{
+ res_T res = RES_OK;
+ char* cname = NULL;
+ struct str name;
+ int is_init = 0;
+
+ ASSERT(allocator && cad);
+
+ cad->connection = MEM_CALLOC(allocator, 3, sizeof(struct scad_geometry*));
+ if(!cad->connection) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ 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 mem_allocator* allocator,
+ struct data_cad_cmode_0* cad)
+{
+ res_T res = RES_OK;
+ struct scad_geometry** list = NULL;
+ struct scad_geometry* boundary = NULL;
+ char* cname = NULL;
+ struct str name;
+ int is_init = 0;
+
+ ASSERT(allocator && cad);
+
+ list = MEM_ALLOC(allocator, 4 * sizeof(struct scad_geometry*));
+ if(!list) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ 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));
+ MEM_RM(allocator, 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] = { NULL, NULL };
+ char* cname = NULL;
+ struct str name;
+ int is_init = 0;
+
+ ASSERT(pg && e > 0 && connection);
+
+ 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_cmode_0
+ (struct building* building,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ struct parsed_city_building* parsed_data,
+ struct catalog* catalog)
+{
+ res_T res = RES_OK;
+ struct dataset_cmode_0* dataset;
+ struct str dataset_name;
+ int name_initialized = 0;
+ static struct construction_mode_functors functors_0
+ = {
+ &init_cmode_0,
+ &build_cad_cmode_0,
+ &build_footprint_cmode_0,
+ &export_stl_cmode_0,
+ &release_cad_cmode_0
+ };
+ (void)parsed_data;
+
+ if(!building || !allocator || !parsed_data || !catalog) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ building->construction_mode = mode_0;
+ building->functors = &functors_0;
+ building->height = parsed_data->height;
+ str_init(allocator, &building->name);
+ building->name_initialized = 1;
+ str_init(allocator, &dataset_name);
+ name_initialized = 1;
+ ERR(str_set(&building->name, parsed_data->name));
+ ERR(str_set(&dataset_name, parsed_data->dataset_name));
+
+ ERR(scpr_polygon_create(allocator, &building->pg));
+ ERR(scpr_polygon_setup_indexed_vertices(building->pg, 1, get_nverts, get_pos,
+ parsed_data));
+ dataset = htable_dataset_cmode_0_find(&catalog->catalog_0, &dataset_name);
+ if (dataset == NULL) {
+ ERR(logger_print(logger, LOG_ERROR,
+ "Unknown dataset name: '%s' used by building '%s'.\n",
+ str_cget(&dataset_name), str_cget(&building->name)));
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ building->data = dataset;
+
+exit:
+ if(name_initialized) str_release(&dataset_name);
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+build_cad_cmode_0
+ (struct building* building,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ void** cad)
+{
+ res_T res = RES_OK;
+ double height;
+ struct scpr_polygon* pg = NULL;
+ struct scpr_polygon* pg_int = NULL;
+ struct dataset_cmode_0* data = NULL;
+ struct data_cad_cmode_0* data_cad = NULL;
+ double e_wall;
+ const char* name;
+
+ if (!building || !allocator || !cad) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ height = building->height;
+ pg = building->pg;
+ data = (struct dataset_cmode_0 *)building->data;
+
+ if (height <= 0 || data->wall_thickness <= 0 || data->floor_thickness <= 0) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ data_cad = MEM_CALLOC(allocator, 1, sizeof(struct data_cad_cmode_0));
+ if(!data_cad) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+
+ e_wall = data->wall_thickness;
+ ERR(scpr_polygon_create_copy(NULL, pg, &pg_int));
+ ERR(scpr_offset_polygon(pg_int, -e_wall, SCPR_JOIN_MITER));
+
+ /* build floor with pg_int */
+ name = str_cget(&building->name);
+ ERR(build_floor(name, pg_int, building, &data_cad->floor));
+
+ /* roof is a translated copy of floor */
+ ERR(build_roof(name, building, data_cad->floor, &data_cad->roof));
+
+ /* build wall with pg and pg_int */
+ ERR(build_wall(name, pg, pg_int, building, &data_cad->wall));
+
+ /* build cavity */
+ ERR(build_cavity(name, pg_int, building, &data_cad->cavity));
+
+ ERR(scad_scene_partition());
+
+ /* build ground/building connection */
+ ERR(building_ground_connection(name, pg, e_wall, &data_cad->ground_connection));
+
+ /* build boundary */
+ ERR(build_boundary(name, allocator, data_cad));
+
+ /* build cavity/floor connectiona*/
+ ERR(build_connection(name, allocator, data_cad));
+
+exit:
+ if(pg_int) SCPR(polygon_ref_put(pg_int));
+ *(struct data_cad_cmode_0**)cad = data_cad;
+ return res;
+error:
+ if(data_cad) CHK(RES_OK == release_cad_cmode_0(allocator, logger, data_cad));
+ data_cad = NULL;
+ goto exit;
+}
+
+res_T
+build_footprint_cmode_0
+ (struct building* building,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ struct scad_geometry** footprint)
+{
+ res_T res = RES_OK;
+ struct scpr_polygon* pg = building->pg;
+ struct dataset_cmode_0* data = (struct dataset_cmode_0 *)building->data;
+ double e_wall;
+ (void)allocator; (void)logger;
+
+ if(!building || ! footprint) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ e_wall = data->wall_thickness;
+
+ ERR(building_ground_connection(NULL, pg, e_wall, footprint));
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+export_stl_cmode_0
+ (void* cad,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ const int binary)
+{
+ res_T res = RES_OK;
+ struct data_cad_cmode_0* data_cad = (struct data_cad_cmode_0*)cad;
+ size_t i;
+ (void)allocator; (void)logger;
+
+ if(!cad) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ /* 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_cad_cmode_0
+ (struct mem_allocator* allocator,
+ struct logger* logger,
+ void* cad)
+{
+ res_T res = RES_OK;
+ struct data_cad_cmode_0* data_cad = (struct data_cad_cmode_0 *)cad;
+ size_t i;
+ (void)logger;
+
+ if(!allocator || ! cad) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(data_cad->boundary) SCAD(geometry_delete(data_cad->boundary));
+ if(data_cad->cavity) SCAD(geometry_delete(data_cad->cavity));
+ if(data_cad->floor) SCAD(geometry_delete(data_cad->floor));
+ if(data_cad->ground_connection) SCAD(geometry_delete(data_cad->ground_connection));
+ if(data_cad->roof) SCAD(geometry_delete(data_cad->roof));
+ if(data_cad->wall) SCAD(geometry_delete(data_cad->wall));
+ for(i = 0; i < data_cad->n_connection; i++) {
+ SCAD(geometry_delete(data_cad->connection[i]));
+ }
+ MEM_RM(allocator, data_cad->connection);
+ MEM_RM(allocator, data_cad);
+
+exit:
+ return res;
+error:
+ goto exit;
+}
diff --git a/src/cg_construction_mode_0.h b/src/cg_construction_mode_0.h
@@ -0,0 +1,98 @@
+/* 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 Construction_MODE_0_H
+#define Construction_MODE_0_H
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+#include <rsys/hash_table.h>
+
+struct scad_geometry;
+struct building;
+struct mem_allocator;
+struct logger;
+struct parsed_city_building;
+struct catalog;
+
+/* specific data for construction mode 0 */
+struct dataset_cmode_0 {
+ double wall_thickness;
+ double floor_thickness;
+};
+
+#define HTABLE_NAME dataset_cmode_0
+#define HTABLE_DATA struct dataset_cmode_0
+#define HTABLE_KEY struct str
+#define HTABLE_KEY_FUNCTOR_INIT str_init
+#define HTABLE_KEY_FUNCTOR_RELEASE str_release
+#define HTABLE_KEY_FUNCTOR_COPY str_copy
+#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release
+#define HTABLE_KEY_FUNCTOR_COPY_AND_CLEAR str_copy_and_clear
+#define HTABLE_KEY_FUNCTOR_EQ str_eq
+#define HTABLE_KEY_FUNCTOR_HASH str_hash
+#include <rsys/hash_table.h>
+
+struct data_cad_cmode_0 {
+ struct scad_geometry* wall;
+ struct scad_geometry* roof;
+ 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_cmode_0
+ (struct building* building,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ struct parsed_city_building* parsed_data,
+ struct catalog* catalog);
+
+res_T
+build_cad_cmode_0
+ (struct building* building,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ void** cad);
+
+res_T
+build_footprint_cmode_0
+ (struct building* building,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ struct scad_geometry** footprint);
+
+res_T
+export_stl_cmode_0
+ (void* cad,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ const int binary);
+
+res_T
+release_cad_cmode_0
+ (struct mem_allocator* allocator,
+ struct logger* logger,
+ void* cad);
+
+#endif /* Construction_MODE_0_H */
diff --git a/src/cg_construction_mode_0_parsing_schemas.h b/src/cg_construction_mode_0_parsing_schemas.h
@@ -0,0 +1,87 @@
+/* Copyright (C) 2022 Université de Pau et des Pays de l'Adour UPPA
+ * Copyright (C) 2022 CNRS
+ * Copyright (C) 2022 Sorbonne Université
+ * Copyright (C) 2022 Université Paul Sabatier
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef FG_MODE0_PARSING_SCHEMAS__
+#define FG_MODE0_PARSING_SCHEMAS__
+
+#include <cyaml/cyaml.h>
+
+struct parsed_dataset_cmode_0 {
+ char* name;
+ double wall_thickness; /* must be > 0 */
+ double floor_thickness; /* must be > 0 */
+};
+
+/********************************************************/
+/* Types used for parsing and to define parsing schemas */
+/********************************************************/
+
+struct parsed_catalog_cmode_0 {
+ struct parsed_dataset_cmode_0* datasets;
+ size_t datasets_count;
+};
+
+static const cyaml_schema_field_t dataset_cmode_0_fields_schema[] = {
+ CYAML_FIELD_STRING_PTR("name", CYAML_FLAG_POINTER,
+ struct parsed_dataset_cmode_0, name, 0, CYAML_UNLIMITED),
+ CYAML_FIELD_FLOAT("wall_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_0, wall_thickness),
+ CYAML_FIELD_FLOAT("floor_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_0, floor_thickness),
+ CYAML_FIELD_END
+};
+
+static const struct cyaml_schema_value p_dataset_cmode_0_schema = {
+ CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_dataset_cmode_0,
+ dataset_cmode_0_fields_schema),
+};
+
+static const struct cyaml_schema_value dataset_cmode_0_schema = {
+ CYAML_VALUE_MAPPING(CYAML_FLAG_DEFAULT, struct parsed_dataset_cmode_0,
+ dataset_cmode_0_fields_schema),
+};
+
+static const cyaml_schema_field_t cmode_0_fields_schemas[] = {
+ CYAML_FIELD_IGNORE("contructive_mode_type", CYAML_FLAG_DEFAULT),
+ {
+ .key = "datasets",
+ .value = {
+ .type = CYAML_SEQUENCE,
+ .flags = CYAML_FLAG_POINTER,
+ .data_size = sizeof(struct parsed_dataset_cmode_0),
+ .sequence = {
+ .entry = &dataset_cmode_0_schema,
+ .min = 1,
+ .max = CYAML_UNLIMITED,
+ }
+ },
+ .data_offset = offsetof(struct parsed_catalog_cmode_0, datasets),
+ .count_size = sizeof(((struct parsed_catalog_cmode_0*)0)->datasets_count),
+ .count_offset = offsetof(struct parsed_catalog_cmode_0, datasets_count),
+ },
+ CYAML_FIELD_END
+};
+
+/* Top-level schema. The top level value for the construction mode is a mapping */
+static const cyaml_schema_value_t construction_mode_0_schema = {
+ CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_catalog_cmode_0,
+ cmode_0_fields_schemas),
+};
+
+#endif
diff --git a/src/cg_construction_mode_1.c b/src/cg_construction_mode_1.c
@@ -0,0 +1,1598 @@
+/* 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 "cg_catalog.h"
+#include "cg_city_parsing_schemas.h"
+#include "cg_construction_mode.h"
+#include "cg_construction_mode_1.h"
+
+#include <rsys/str.h>
+#include <rsys/logger.h>
+#include <star/scad.h>
+#include <star/scpr.h>
+
+static res_T
+build_floor
+ (const char* prefix,
+ struct mem_allocator* allocator,
+ const struct scpr_polygon* pg,
+ const struct dataset_cmode_1* data,
+ struct scad_geometry** floor)
+{
+ res_T res = RES_OK;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
+ double e_floor = data->floor_thickness;
+ double offset = 0;
+ struct scpr_polygon* pg_int = NULL;
+ size_t nverts = 0;
+ struct scad_geometry* footprint = NULL;
+ double d[3] = {0, 0, 0};
+ char* floorname = NULL;
+ struct str name;
+ int is_init = 0;
+
+ ASSERT(allocator && pg && data && floor);
+
+ if (prefix) {
+ str_init(allocator, &name);
+ is_init = 1;
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_S_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,
+ struct mem_allocator* allocator,
+ const struct scpr_polygon* pg,
+ const double height,
+ const struct dataset_cmode_1* data,
+ struct scad_geometry** wall)
+{
+ res_T res = RES_OK;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
+ double offset = 0;
+ struct scpr_polygon* pg_int = NULL;
+ struct scpr_polygon* pg_ext = NULL;
+ 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;
+
+ ASSERT(allocator && pg && data && wall);
+
+ if (prefix) {
+ str_init(allocator, &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,
+ struct mem_allocator* allocator,
+ const struct scpr_polygon* pg,
+ const double height,
+ const struct dataset_cmode_1* data,
+ struct scad_geometry* inter_floor,
+ struct scad_geometry** insulation)
+{
+ res_T res = RES_OK;
+ double e_wall = data->wall_thickness;
+ double e_roof = data->roof_thickness;
+ double e_roof_insulation = data->roof_insulation_thickness;
+ double attic = data->attic_height;
+ double e_ext_insulation = data->external_insulation_thickness;
+ double e_int_insulation = data->internal_insulation_thickness;
+ double offset = 0;
+ struct scpr_polygon* pg_int = NULL;
+ struct scpr_polygon* pg_ext = NULL;
+ 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;
+
+ ASSERT(allocator && pg && data && insulation);
+
+ if (prefix) {
+ str_init(allocator, &name);
+ is_init = 1;
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_S_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,
+ struct mem_allocator* allocator,
+ const struct scpr_polygon* pg,
+ const double height,
+ const struct dataset_cmode_1* data,
+ struct scad_geometry** roof)
+{
+ res_T res = RES_OK;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
+ double e_roof = data->roof_thickness;
+ double offset = 0;
+ double z_roof = 0;
+ struct scpr_polygon* pg_int = NULL;
+ 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;
+
+ ASSERT(allocator && pg && data && roof);
+
+ if (prefix) {
+ str_init(allocator, &name);
+ is_init = 1;
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_S_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,
+ struct mem_allocator* allocator,
+ const struct scpr_polygon* pg,
+ const double height,
+ const struct dataset_cmode_1* data,
+ struct scad_geometry** insulation)
+{
+ res_T res = RES_OK;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
+ double e_roof = data->roof_thickness;
+ double attic = data->attic_height;
+ double e_roof_insulation = data->roof_insulation_thickness;
+ double offset = 0;
+ double z_insulation = 0;
+ struct scpr_polygon* pg_int = NULL;
+ 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;
+
+ ASSERT(allocator && pg && data && insulation);
+
+ if (prefix) {
+ str_init(allocator, &name);
+ is_init = 1;
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_S_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,
+ struct mem_allocator* allocator,
+ const struct scpr_polygon* pg,
+ const struct dataset_cmode_1* data,
+ struct scad_geometry** insulation)
+{
+ res_T res = RES_OK;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
+ double e_floor = data->floor_thickness;
+ double e_floor_insulation = data->floor_insulation_thickness;
+ double offset = 0;
+ double z_insulation = 0;
+ struct scpr_polygon* pg_int = NULL;
+ 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;
+
+ ASSERT(allocator && pg && data && insulation);
+
+ if (prefix) {
+ str_init(allocator, &name);
+ is_init = 1;
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_S_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,
+ struct mem_allocator* allocator,
+ const struct scpr_polygon* pg,
+ const double height,
+ const struct dataset_cmode_1* data,
+ struct scad_geometry** inter_floor)
+{
+ res_T res = RES_OK;
+ size_t i = 0;
+ size_t floor_n = data->inter_floor_count;
+ double e_roof = data->roof_thickness;
+ double e_roof_ins = data->roof_insulation_thickness;
+ double attic = data->attic_height;
+ double e_floor = data->inter_floor_thickness;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
+ double offset = 0;
+ double z_floor = 0;
+ double h_cavity = 0;
+ struct scpr_polygon* pg_int = NULL;
+ size_t nverts = 0;
+ struct scad_geometry** floor_list = NULL;
+ struct darray_geometries floor_array;
+ double d[3] = {0, 0, 0};
+ char* floorname = NULL;
+ struct str name;
+ int is_init = 0;
+
+ ASSERT(allocator && pg && data && inter_floor);
+
+ darray_geometries_init(allocator, &floor_array);
+
+ if (prefix) {
+ str_init(allocator, &name);
+ is_init = 1;
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_S_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));
+ ERR(darray_geometries_push_back(&floor_array, &floor));
+ ERR(scad_geometry_delete(footprint));
+ z_floor += h_cavity/(double)(1 + floor_n) + e_floor;
+ }
+ ASSERT(darray_geometries_size_get(&floor_array) == floor_n);
+
+ floor_list = darray_geometries_data_get(&floor_array);
+ ERR(scad_fuse_geometries(floorname, floor_list, floor_n, floor_list, floor_n,
+ inter_floor));
+
+exit:
+ if (is_init) str_release(&name);
+ if (pg_int) SCPR(polygon_ref_put(pg_int));
+ floor_list = darray_geometries_data_get(&floor_array);
+ if(floor_list) {
+ for (i = 0; i < floor_n; i++) {
+ SCAD(geometry_delete(floor_list[i]));
+ }
+ darray_geometries_release(&floor_array);
+ }
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+build_ext_insulation
+ (const char* prefix,
+ struct mem_allocator* allocator,
+ const struct scpr_polygon* pg,
+ const double height,
+ const struct dataset_cmode_1* data,
+ struct scad_geometry** insulation)
+{
+ res_T res = RES_OK;
+ double e_insulation = data->external_insulation_thickness;
+ 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;
+
+ ASSERT(allocator && pg && data && insulation);
+
+ if (prefix) {
+ str_init(allocator, &name);
+ is_init = 1;
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_S_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,
+ struct mem_allocator* allocator,
+ const struct scpr_polygon* pg,
+ const struct dataset_cmode_1* data,
+ struct scad_geometry** crawlspace)
+{
+ res_T res = RES_OK;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
+ double e_crawl = data->crawl_height;
+ double e_floor = data->floor_thickness;
+ double e_floor_insulation = data->floor_insulation_thickness;
+ double offset = 0;
+ double z_crawl= 0;
+ struct scpr_polygon* pg_int = NULL;
+ 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;
+
+ ASSERT(allocator && pg && data && crawlspace);
+
+ if (prefix) {
+ str_init(allocator, &name);
+ is_init = 1;
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_F_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,
+ struct mem_allocator* allocator,
+ const struct scpr_polygon* pg,
+ const double height,
+ const struct dataset_cmode_1* data,
+ struct scad_geometry* floor,
+ struct scad_geometry** cavity)
+{
+ res_T res = RES_OK;
+ double e_wall = data->wall_thickness;
+ double e_ext_insulation = data->external_insulation_thickness;
+ double e_int_insulation = data->internal_insulation_thickness;
+ double e_roof = data->roof_thickness;
+ double e_roof_insulation = data->roof_insulation_thickness;
+ double e_attic = data->attic_height;
+ double offset = 0;
+ struct scpr_polygon* pg_int = NULL;
+ size_t nverts = 0;
+ 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;
+
+ ASSERT(allocator && pg && data && cavity);
+
+ if (prefix) {
+ str_init(allocator, &name);
+ is_init = 1;
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_F_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,
+ struct mem_allocator* allocator,
+ const struct scpr_polygon* pg,
+ const double height,
+ const struct dataset_cmode_1* data,
+ struct scad_geometry** attic)
+{
+ res_T res = RES_OK;
+ double e_wall = data->wall_thickness;
+ double e_insulation = data->external_insulation_thickness;
+ double e_roof = data->roof_thickness;
+ double e_attic = data->attic_height;
+ double offset = 0;
+ double z_attic = 0;
+ struct scpr_polygon* pg_int = NULL;
+ 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;
+
+ ASSERT(allocator && pg && data && attic);
+
+ if (prefix) {
+ str_init(allocator, &name);
+ is_init = 1;
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_F_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,
+ struct mem_allocator* allocator,
+ const struct dataset_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 darray_geometries hole_array;
+ 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;
+ struct darray_geometries glass_array;
+ size_t list_n = 0, array_n;
+ struct str gname;
+ int is_init = 0;
+
+ ASSERT(allocator && data && data_cad);
+
+ darray_geometries_init(allocator, &hole_array);
+ darray_geometries_init(allocator, &glass_array);
+
+ 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[3];
+ size_t center_n;
+
+ ERR(scad_geometry_get_count(list[i], ¢er_n));
+ ASSERT(center_n == 1);
+ ERR(scad_geometry_get_centerofmass(list[i], center));
+
+ 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_thickness
+ + data->internal_insulation_thickness + data->external_insulation_thickness);
+ dir[1] = 1.1*N[1] * (data->wall_thickness
+ + data->internal_insulation_thickness + data->external_insulation_thickness);
+ dir[2] = 1.1*N[2] * (data->wall_thickness
+ + data->internal_insulation_thickness + data->external_insulation_thickness);
+ ERR(scad_geometry_extrude(surface, NULL, dir, &hole));
+ ERR(darray_geometries_push_back(&hole_array, &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));
+ ERR(darray_geometries_push_back(&glass_array, &glass));
+
+ ERR(scad_geometry_delete(surface));
+ surface = NULL;
+ }
+ ASSERT(darray_geometries_size_get(&hole_array)
+ == darray_geometries_size_get(&glass_array));
+
+ hole_list = darray_geometries_data_get(&hole_array);
+ glass_list = darray_geometries_data_get(&glass_array);
+ array_n = darray_geometries_size_get(&hole_array);
+
+ /* wall perforation */
+ ERR(scad_cut_geometries(NULL, &data_cad->wall, 1,
+ hole_list, array_n, &geom));
+ ERR(scad_geometry_swap_names(data_cad->wall, geom));
+ ERR(scad_geometry_delete(data_cad->wall));
+ data_cad->wall = geom;
+ geom = NULL;
+
+ /* internal insulation perforation */
+ if (data_cad->internal_insulation) {
+ ERR(scad_cut_geometries(NULL, &data_cad->internal_insulation, 1,
+ hole_list, array_n, &geom));
+ ERR(scad_geometry_swap_names(data_cad->internal_insulation, geom));
+ ERR(scad_geometry_delete(data_cad->internal_insulation));
+ data_cad->internal_insulation = geom;
+ geom = NULL;
+ }
+
+ /* external insulation perforation */
+ if (data_cad->external_insulation) {
+ ERR(scad_cut_geometries(NULL, &data_cad->external_insulation, 1,
+ hole_list, array_n, &geom));
+ ERR(scad_geometry_swap_names(data_cad->external_insulation, geom));
+ ERR(scad_geometry_delete(data_cad->external_insulation));
+ data_cad->external_insulation = geom;
+ geom = NULL;
+ }
+
+ /* build glass */
+ if (prefix) {
+ str_init(allocator, &gname);
+ is_init = 1;
+ ERR(str_set(&gname, prefix));
+ ERR(str_append(&gname, "_S_glass"));
+ }
+
+ ERR(scad_fuse_geometries(str_cget(&gname), glass_list, 1,
+ glass_list+1, array_n - 1, &data_cad->glass));
+
+exit:
+ glass_list = darray_geometries_data_get(&glass_array);
+ for (i = 0 ; i < list_n; i++) {
+ SCAD(geometry_delete(list[i]));
+ }
+ for (i = 0 ; i < darray_geometries_size_get(&hole_array); i++) {
+ struct scad_geometry* h = darray_geometries_data_get(&hole_array)[i];
+ SCAD(geometry_delete(h));
+ }
+ for (i = 0 ; i <darray_geometries_size_get(&glass_array); i++) {
+ struct scad_geometry* g = darray_geometries_data_get(&glass_array)[i];
+ SCAD(geometry_delete(g));
+ }
+ darray_geometries_release(&hole_array);
+ darray_geometries_release(&glass_array);
+ if (surface) SCAD(geometry_delete(surface));
+ if (geom) SCAD(geometry_delete(geom));
+ if (bcavity) SCAD(geometry_delete(bcavity));
+ MEM_RM(allocator, list);
+ if (is_init) str_release(&gname);
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+build_boundary
+ (const char* prefix,
+ struct mem_allocator* allocator,
+ struct data_cad_cmode_1* data_cad,
+ struct darray_geometries* boundary)
+{
+ res_T res = RES_OK;
+ size_t count;
+ struct darray_geometries array;
+ struct scad_geometry** list = NULL;
+ struct darray_geometries bound_array;
+ struct scad_geometry* bound = NULL;
+ char* boundaryname = NULL;
+ struct str name;
+ int is_init = 0;
+
+ ASSERT(allocator && prefix && data_cad && boundary);
+
+ darray_geometries_init(allocator, &array);
+ darray_geometries_init(allocator, &bound_array);
+
+ str_init(allocator, &name);
+ is_init = 1;
+
+ /* Ensure enough room for all geometries without error nor mem move */
+ ERR(darray_geometries_reserve(&array, 14));
+ ERR(darray_geometries_push_back(&array, &data_cad->wall));
+ ERR(darray_geometries_push_back(&array, &data_cad->roof));
+ ERR(darray_geometries_push_back(&array, &data_cad->floor));
+ ERR(darray_geometries_push_back(&array, &data_cad->habitable_cavity));
+ ERR(darray_geometries_push_back(&array, &data_cad->fake_ground));
+ if (data_cad->foundation) {
+ ERR(darray_geometries_push_back(&array, &data_cad->foundation));
+ }
+ if (data_cad->intermediate_floor) {
+ ERR(darray_geometries_push_back(&array, &data_cad->intermediate_floor));
+ }
+ if (data_cad->external_insulation) {
+ ERR(darray_geometries_push_back(&array, &data_cad->external_insulation));
+ }
+ if (data_cad->internal_insulation) {
+ ERR(darray_geometries_push_back(&array, &data_cad->internal_insulation));
+ }
+ if (data_cad->roof_insulation) {
+ ERR(darray_geometries_push_back(&array, &data_cad->roof_insulation));
+ }
+ if (data_cad->floor_insulation) {
+ ERR(darray_geometries_push_back(&array, &data_cad->floor_insulation));
+ }
+ if (data_cad->attic_cavity) {
+ ERR(darray_geometries_push_back(&array, &data_cad->attic_cavity));
+ }
+ if (data_cad->crawlspace_cavity) {
+ ERR(darray_geometries_push_back(&array, &data_cad->crawlspace_cavity));
+ }
+ if (data_cad->glass) {
+ ERR(darray_geometries_push_back(&array, &data_cad->glass));
+ }
+
+ count = darray_geometries_size_get(&array);
+ list = darray_geometries_data_get(&array);
+
+ /* Ensure enough room for all geometries without error nor mem move */
+ ERR(darray_geometries_reserve(boundary, 5+darray_geometries_size_get(boundary)));
+
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_boundary_wall"));
+ boundaryname = str_get(&name);
+ ERR(scad_geometries_common_boundaries(boundaryname, list, count,
+ &data_cad->wall, 1, &bound));
+ ERR(darray_geometries_push_back(boundary, &bound));
+
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_boundary_roof"));
+ boundaryname = str_get(&name);
+ ERR(scad_geometries_common_boundaries(boundaryname, list, count,
+ &data_cad->roof, 1, &bound));
+ ERR(darray_geometries_push_back(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, count,
+ &data_cad->glass, 1, &bound));
+ ERR(darray_geometries_push_back(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, count,
+ &data_cad->external_insulation, 1, &bound));
+ ERR(darray_geometries_push_back(boundary, &bound));
+ }
+
+ if (data_cad->internal_insulation) {
+ size_t bcount = 0;
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_boundary_int_insulation"));
+ boundaryname = str_get(&name);
+ ERR(scad_geometries_common_boundaries(boundaryname, list, count,
+ &data_cad->internal_insulation, 1, &bound));
+ ERR(scad_geometry_get_count(bound, &bcount));
+ if (bcount > 0) {
+ ERR(darray_geometries_push_back(boundary, &bound));
+ } else {
+ SCAD(geometry_delete(bound));
+ }
+ }
+
+exit:
+ if (is_init) str_release(&name);
+ darray_geometries_release(&array);
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+build_connection
+ (const char* prefix,
+ struct mem_allocator* allocator,
+ struct data_cad_cmode_1* data_cad,
+ struct darray_geometries* 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;
+
+ ASSERT(allocator && prefix && data_cad && connection);
+
+ str_init(allocator, &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) { \
+ ERR(darray_geometries_push_back(connection, &connect)); \
+ } else { \
+ SCAD(geometry_delete(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;
+
+ ASSERT(pg && footprint);
+
+ 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 mem_allocator* allocator,
+ 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;
+ size_t count;
+ struct darray_geometries array;
+ struct scad_geometry** list = NULL;
+ struct scad_geometry* footprint = NULL;
+ struct scad_geometry* geom = NULL;
+
+ ASSERT(cad && pg && ground );
+
+ darray_geometries_init(allocator, &array);
+
+ /* Ensure enough room for all geometries without error nor mem move */
+ ERR(darray_geometries_reserve(&array, 4));
+ if (cad->foundation) {
+ ERR(darray_geometries_push_back(&array, &cad->foundation));
+ }
+ if (cad->crawlspace_cavity) {
+ ERR(darray_geometries_push_back(&array, &cad->crawlspace_cavity));
+ }
+ if (cad->floor) {
+ ERR(darray_geometries_push_back(&array, &cad->floor));
+ }
+ if (cad->floor_insulation) {
+ ERR(darray_geometries_push_back(&array, &cad->floor_insulation));
+ }
+
+ count = darray_geometries_size_get(&array);
+ list = darray_geometries_data_get(&array);
+
+ 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, count, ground));
+
+exit:
+ if (pg_offset) SCPR(polygon_ref_put(pg_offset));
+ darray_geometries_release(&array);
+ 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 mem_allocator* allocator,
+ 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;
+ size_t count;
+ struct darray_geometries array;
+ struct scad_geometry** list = NULL;
+ struct scad_geometry* list_boundary = NULL;
+ struct scad_geometry* footprint = NULL;
+
+ ASSERT(prefix && allocator && cad && connection);
+
+ darray_geometries_init(allocator, &array);
+
+ str_init(allocator, &name);
+ is_init = 1;
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_C_building_ground"));
+ cname = str_get(&name);
+
+ /* Ensure enough room for all geometries without error nor mem move */
+ ERR(darray_geometries_reserve(&array, 6));
+ if (cad->foundation) {
+ ERR(darray_geometries_push_back(&array, &cad->foundation));
+ }
+ if (cad->crawlspace_cavity) {
+ ERR(darray_geometries_push_back(&array, &cad->crawlspace_cavity));
+ }
+ if (cad->floor) {
+ ERR(darray_geometries_push_back(&array, &cad->floor));
+ }
+ if (cad->floor_insulation) {
+ ERR(darray_geometries_push_back(&array, &cad->floor_insulation));
+ }
+ if (cad->external_insulation) {
+ ERR(darray_geometries_push_back(&array, &cad->external_insulation));
+ }
+ if (cad->wall) {
+ ERR(darray_geometries_push_back(&array, &cad->wall));
+ }
+
+ count = darray_geometries_size_get(&array);
+ list = darray_geometries_data_get(&array);
+
+ ERR(scad_geometries_common_boundaries(cname, list,count, &cad->fake_ground, 1,
+ connection));
+
+exit:
+ darray_geometries_release(&array);
+ 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_cmode_1
+ (struct building* building,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ struct parsed_city_building* parsed_data,
+ struct catalog* catalog)
+{
+ res_T res = RES_OK;
+ struct dataset_cmode_1* dataset;
+ struct str dataset_name;
+ int name_initialized = 0;
+ static struct construction_mode_functors functors_1
+ = {
+ &init_cmode_1,
+ &build_cad_cmode_1,
+ &build_footprint_cmode_1,
+ &export_stl_cmode_1,
+ &release_cad_cmode_1
+ };
+ (void) parsed_data;
+
+ if(!building || !allocator || !parsed_data ||!catalog) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ building->construction_mode = mode_1;
+ building->functors = &functors_1;
+ building->height = parsed_data->height;
+ str_init(allocator, &building->name);
+ building->name_initialized = 1;
+ str_init(allocator, &dataset_name);
+ name_initialized = 1;
+ ERR(str_set(&building->name, parsed_data->name));
+ ERR(str_set(&dataset_name, parsed_data->dataset_name));
+
+ ERR(scpr_polygon_create(allocator, &building->pg));
+ ERR(scpr_polygon_setup_indexed_vertices(building->pg, 1, get_nverts, get_pos,
+ parsed_data));
+ dataset = htable_dataset_cmode_1_find(&catalog->catalog_1, &dataset_name);
+ if (dataset == NULL) {
+ ERR(logger_print(logger, LOG_ERROR,
+ "Unknown dataset name: '%s' used by building '%s'.\n",
+ str_cget(&dataset_name), str_cget(&building->name)));
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ building->data = dataset;
+
+exit:
+ if(name_initialized) str_release(&dataset_name);
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+build_cad_cmode_1
+ (struct building* building,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ void** cad)
+{
+ res_T res = RES_OK;
+ double height = building->height;
+ double depth = 0;
+ struct scpr_polygon* pg = building->pg;
+ struct dataset_cmode_1* data = (struct dataset_cmode_1 *)building->data;
+ struct data_cad_cmode_1* data_cad = NULL;
+ const char* name;
+
+ if (!building || !allocator || !cad) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ data_cad = MEM_CALLOC(allocator, 1, sizeof(struct data_cad_cmode_1));
+ if(!data_cad) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ darray_geometries_init(allocator, &data_cad->boundary);
+ darray_geometries_init(allocator, &data_cad->connection);
+
+ /* build mandatories elements :
+ - floor
+ - wall
+ - roof
+ */
+
+ name = str_cget(&building->name);
+ ERR(build_floor(name, allocator, pg, data, &data_cad->floor));
+
+ ERR(build_wall(name, "S_wall", allocator, pg, height, data, &data_cad->wall));
+
+ ERR(build_roof(name, allocator, pg, height, data, &data_cad->roof));
+
+ /* build optionnal elements :
+ - foundation
+ - intermediate floor
+ - external insulation
+ - internal insulation
+ - roof insulation
+ - floor insulation
+ */
+
+ if (data->foundation_depth > 0) {
+ depth = -data->foundation_depth;
+ ERR(build_wall(name, "S_foundation", allocator, pg, depth, data,
+ &data_cad->foundation));
+ }
+
+ if (data->inter_floor_count > 0) {
+ ERR(build_inter_floor(name, allocator, pg, height, data,
+ &data_cad->intermediate_floor));
+ }
+
+ if (data->external_insulation_thickness> 0) {
+ ERR(build_ext_insulation(name, allocator, pg, height, data,
+ &data_cad->external_insulation));
+ }
+
+ if (data->internal_insulation_thickness> 0) {
+ ERR(build_int_insulation(name, allocator, pg, height, data,
+ data_cad->intermediate_floor, &data_cad->internal_insulation));
+ }
+
+ if (data->roof_insulation_thickness > 0) {
+ ERR(build_roof_insulation(name, allocator, pg, height, data,
+ &data_cad->roof_insulation));
+ }
+
+ if (data->floor_insulation_thickness > 0) {
+ ERR(build_floor_insulation(name, allocator, pg, data,
+ &data_cad->floor_insulation));
+ }
+
+ /* build cavities :
+ - attic
+ - habitable
+ - crawlspace
+ */
+
+ if (data->attic_height > 0) {
+ ERR(build_attic(name, allocator, pg, height, data, &data_cad->attic_cavity));
+ }
+
+ ERR(build_habitable(name, allocator, pg, height, data,
+ data_cad->intermediate_floor, &data_cad->habitable_cavity));
+
+ if (data->crawl_height > 0) {
+ ERR(build_crawlspace(name, allocator, pg, data, &data_cad->crawlspace_cavity));
+ }
+
+ /* windows */
+ if (data->glass_ratio > 0) {
+ ERR(build_windows(name, allocator, data, data_cad));
+ }
+
+ /* fake ground */
+ depth = MMAX(data->foundation_depth,
+ data->floor_thickness + data->floor_insulation_thickness + data->crawl_height);
+ ERR(build_fake_ground(allocator, data_cad, pg, depth,
+ &data_cad->fake_ground));
+
+ ERR(scad_scene_partition());
+
+ /* build ground/buildind connection */
+ ERR(building_ground_connection(name, allocator, data_cad,
+ &data_cad->ground_connection));
+
+ /* build boundaries */
+ ERR(build_boundary(name, allocator, data_cad, &data_cad->boundary));
+
+ /* build connections */
+ ERR(build_connection(name, allocator, data_cad, &data_cad->connection));
+
+exit:
+ *(struct data_cad_cmode_1**)cad = data_cad;
+ return res;
+error:
+ if(data_cad) CHK(RES_OK == release_cad_cmode_1(allocator, logger, data_cad));
+ data_cad = NULL;
+ goto exit;
+}
+
+res_T
+build_footprint_cmode_1
+ (struct building* building,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ struct scad_geometry** footprint)
+{
+ res_T res = RES_OK;
+ struct scpr_polygon* pg = building->pg;
+ (void)allocator; (void)logger;
+
+ if (!building || !footprint) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ ERR(build_footprint(pg, footprint));
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+export_stl_cmode_1
+ (void* cad,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ const int binary)
+{
+ res_T res = RES_OK;
+ struct data_cad_cmode_1* data_cad = (struct data_cad_cmode_1 *)cad;
+ size_t i = 0;
+ (void)allocator; (void)logger;
+
+ if (!cad) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ /* 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 < darray_geometries_size_get(&data_cad->boundary); i++) {
+ struct scad_geometry* b = darray_geometries_data_get(&data_cad->boundary)[i];
+ ERR(scad_stl_export(b, NULL, binary));
+ }
+
+ /* connections export*/
+ for(i = 0; i < darray_geometries_size_get(&data_cad->connection); i++) {
+ struct scad_geometry* c = darray_geometries_data_get(&data_cad->connection)[i];
+ ERR(scad_stl_export(c, 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_cad_cmode_1
+ (struct mem_allocator* allocator,
+ struct logger* logger,
+ void* cad)
+{
+ res_T res = RES_OK;
+ struct data_cad_cmode_1* data_cad = (struct data_cad_cmode_1 *)cad;
+ size_t i;
+ (void)logger;
+
+ if (!allocator || !cad) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(data_cad->attic_cavity) SCAD(geometry_delete(data_cad->attic_cavity));
+ if(data_cad->crawlspace_cavity) SCAD(geometry_delete(data_cad->crawlspace_cavity));
+ if(data_cad->external_insulation) SCAD(geometry_delete(data_cad->external_insulation));
+ if(data_cad->fake_ground) SCAD(geometry_delete(data_cad->fake_ground));
+ if(data_cad->floor) SCAD(geometry_delete(data_cad->floor));
+ if(data_cad->floor_insulation) SCAD(geometry_delete(data_cad->floor_insulation));
+ if(data_cad->foundation) SCAD(geometry_delete(data_cad->foundation));
+ if(data_cad->glass) SCAD(geometry_delete(data_cad->glass));
+ if(data_cad->ground_connection) SCAD(geometry_delete(data_cad->ground_connection));
+ if(data_cad->habitable_cavity) SCAD(geometry_delete(data_cad->habitable_cavity));
+ if(data_cad->intermediate_floor) SCAD(geometry_delete(data_cad->intermediate_floor));
+ if(data_cad->internal_insulation) SCAD(geometry_delete(data_cad->internal_insulation));
+ if(data_cad->roof) SCAD(geometry_delete(data_cad->roof));
+ if(data_cad->roof_insulation) SCAD(geometry_delete(data_cad->roof_insulation));
+ if(data_cad->wall) SCAD(geometry_delete(data_cad->wall));
+ for(i = 0; i < darray_geometries_size_get(&data_cad->boundary); i++) {
+ struct scad_geometry* b = darray_geometries_data_get(&data_cad->boundary)[i];
+ ERR(scad_geometry_delete(b));
+ }
+ for(i = 0; i < darray_geometries_size_get(&data_cad->connection); i++) {
+ struct scad_geometry* c = darray_geometries_data_get(&data_cad->connection)[i];
+ ERR(scad_geometry_delete(c));
+ }
+ darray_geometries_release(&data_cad->boundary);
+ darray_geometries_release(&data_cad->connection);
+ MEM_RM(allocator, data_cad);
+
+exit:
+ return res;
+error:
+ goto exit;
+}
diff --git a/src/cg_construction_mode_1.h b/src/cg_construction_mode_1.h
@@ -0,0 +1,124 @@
+/* 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 Construction_MODE_1_H
+#define Construction_MODE_1_H
+
+#include <rsys/rsys.h>
+#include <rsys/str.h>
+#include <rsys/hash_table.h>
+#include <rsys/dynamic_array.h>
+
+struct scad_geometry;
+struct building;
+struct mem_allocator;
+struct logger;
+struct parsed_city_building;
+struct catalog;
+
+#define DARRAY_NAME geometries
+#define DARRAY_DATA struct scad_geometry*
+#include <rsys/dynamic_array.h>
+
+/* specific data for construction mode 1 */
+struct dataset_cmode_1 {
+ size_t inter_floor_count; /* can be 0 */
+ double wall_thickness; /* must be > 0 */
+ double floor_thickness; /* must be > 0 */
+ double inter_floor_thickness; /* must be > 0 */
+ double roof_thickness; /* must be > 0 */
+ double internal_insulation_thickness; /* can be 0 */
+ double external_insulation_thickness; /* can be 0 */
+ double floor_insulation_thickness; /* can be 0 */
+ double roof_insulation_thickness; /* can be 0 */
+ double foundation_depth; /* can be 0 */
+ double crawl_height; /* can be 0 */
+ double attic_height; /* can be 0 */
+ double glass_ratio; /* in [0, 1] */
+};
+
+#define HTABLE_NAME dataset_cmode_1
+#define HTABLE_DATA struct dataset_cmode_1
+#define HTABLE_KEY struct str
+#define HTABLE_KEY_FUNCTOR_INIT str_init
+#define HTABLE_KEY_FUNCTOR_RELEASE str_release
+#define HTABLE_KEY_FUNCTOR_COPY str_copy
+#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release
+#define HTABLE_KEY_FUNCTOR_COPY_AND_CLEAR str_copy_and_clear
+#define HTABLE_KEY_FUNCTOR_EQ str_eq
+#define HTABLE_KEY_FUNCTOR_HASH str_hash
+#include <rsys/hash_table.h>
+
+struct data_cad_cmode_1 {
+ struct scad_geometry* wall;
+ struct scad_geometry* roof;
+ 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 darray_geometries boundary;
+ struct darray_geometries connection;
+ size_t n_connection;
+};
+
+res_T
+init_cmode_1
+ (struct building* building,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ struct parsed_city_building* parsed_data,
+ struct catalog* catalog);
+
+res_T
+build_cad_cmode_1
+ (struct building* building,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ void** cad);
+
+res_T
+build_footprint_cmode_1
+ (struct building* building,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ struct scad_geometry** footprint);
+
+res_T
+export_stl_cmode_1
+ (void* cad,
+ struct mem_allocator* allocator,
+ struct logger* logger,
+ const int binary);
+
+res_T
+release_cad_cmode_1
+ (struct mem_allocator* allocator,
+ struct logger* logger,
+ void* cad);
+
+#endif /* Construction_MODE_1_H */
diff --git a/src/cg_construction_mode_1_parsing_schemas.h b/src/cg_construction_mode_1_parsing_schemas.h
@@ -0,0 +1,124 @@
+/* Copyright (C) 2022 Université de Pau et des Pays de l'Adour UPPA
+ * Copyright (C) 2022 CNRS
+ * Copyright (C) 2022 Sorbonne Université
+ * Copyright (C) 2022 Université Paul Sabatier
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef FG_MODE1_PARSING_SCHEMAS__
+#define FG_MODE1_PARSING_SCHEMAS__
+
+#include <cyaml/cyaml.h>
+
+#include <rsys/str.h>
+
+struct parsed_dataset_cmode_1 {
+ char* name;
+ size_t inter_floor_count; /* can be 0 */
+ double wall_thickness; /* must be > 0 */
+ double floor_thickness; /* must be > 0 */
+ double inter_floor_thickness; /* must be > 0 */
+ double roof_thickness; /* must be > 0 */
+ double internal_insulation_thickness; /* can be 0 */
+ double external_insulation_thickness; /* can be 0 */
+ double floor_insulation_thickness; /* can be 0 */
+ double roof_insulation_thickness; /* can be 0 */
+ double foundation_depth; /* can be 0 */
+ double crawl_height; /* can be 0 */
+ double attic_height; /* can be 0 */
+ double glass_ratio; /* in [0, 1] */
+};
+
+/********************************************************/
+/* Types used for parsing and to define parsing schemas */
+/********************************************************/
+
+struct parsed_catalog_cmode_1 {
+ struct parsed_dataset_cmode_1* datasets;
+ size_t datasets_count;
+};
+
+static const cyaml_schema_field_t dataset_cmode_1_fields_schema[] = {
+ CYAML_FIELD_STRING_PTR("name", CYAML_FLAG_POINTER,
+ struct parsed_dataset_cmode_1, name, 0, CYAML_UNLIMITED),
+ CYAML_FIELD_INT("inter_floor_count", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, inter_floor_count),
+ CYAML_FIELD_FLOAT("wall_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, wall_thickness),
+ CYAML_FIELD_FLOAT("floor_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, floor_thickness),
+ CYAML_FIELD_FLOAT("inter_floor_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, inter_floor_thickness),
+ CYAML_FIELD_FLOAT("roof_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, roof_thickness),
+ CYAML_FIELD_FLOAT("internal_insulation_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, internal_insulation_thickness),
+ CYAML_FIELD_FLOAT("external_insulation_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, external_insulation_thickness),
+ CYAML_FIELD_FLOAT("floor_insulation_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, floor_insulation_thickness),
+ CYAML_FIELD_FLOAT("roof_insulation_thickness", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, roof_insulation_thickness),
+ CYAML_FIELD_FLOAT("foundation_depth", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, foundation_depth),
+ CYAML_FIELD_FLOAT("crawl_height", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, crawl_height),
+ CYAML_FIELD_FLOAT("attic_height", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, attic_height),
+ CYAML_FIELD_FLOAT("glass_ratio", CYAML_FLAG_DEFAULT,
+ struct parsed_dataset_cmode_1, glass_ratio),
+ CYAML_FIELD_END
+};
+
+static const struct cyaml_schema_value p_dataset_cmode_1_schema = {
+ CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_dataset_cmode_1,
+ dataset_cmode_1_fields_schema),
+};
+
+static const struct cyaml_schema_value dataset_cmode_1_schema = {
+ CYAML_VALUE_MAPPING(CYAML_FLAG_DEFAULT, struct parsed_dataset_cmode_1,
+ dataset_cmode_1_fields_schema),
+};
+
+static const cyaml_schema_field_t cmode_1_fields_schemas[] = {
+ CYAML_FIELD_IGNORE("contructive_mode_type", CYAML_FLAG_DEFAULT),
+ {
+ .key = "datasets",
+ .value = {
+ .type = CYAML_SEQUENCE,
+ .flags = CYAML_FLAG_POINTER,
+ .data_size = sizeof(struct parsed_dataset_cmode_1),
+ .sequence = {
+ .entry = &dataset_cmode_1_schema,
+ .min = 1,
+ .max = CYAML_UNLIMITED,
+ }
+ },
+ .data_offset = offsetof(struct parsed_catalog_cmode_1, datasets),
+ .count_size = sizeof(((struct parsed_catalog_cmode_1*)0)->datasets_count),
+ .count_offset = offsetof(struct parsed_catalog_cmode_1, datasets_count),
+ },
+ CYAML_FIELD_END
+};
+
+/* Top-level schema. The top level value for the construction mode is a mapping.
+ * Its fields are defined in cmode_1_fields_schemas.
+ */
+static const cyaml_schema_value_t construction_mode_1_schema = {
+ CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_catalog_cmode_1,
+ cmode_1_fields_schemas),
+};
+
+#endif
diff --git a/src/cg_construction_modes_parsing_schemas.h b/src/cg_construction_modes_parsing_schemas.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 2022 Université de Pau et des Pays de l'Adour UPPA
+ * Copyright (C) 2022 CNRS
+ * Copyright (C) 2022 Sorbonne Université
+ * Copyright (C) 2022 Université Paul Sabatier
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef FG_CMODES_PARSING_SCHEMAS__
+#define FG_CMODES_PARSING_SCHEMAS__
+
+#include <cyaml/cyaml.h>
+
+/********************************************************/
+/* Types used for parsing and to define parsing schemas */
+/********************************************************/
+
+/* construction mode type */
+enum parsed_cmode_type {
+ PARSED_CMODE_0,
+ PARSED_CMODE_1,
+ PARSED_CMODE_TYPE_UNDEFINED
+};
+
+/* Mapping from "construction mode type" strings to enum parsed_cmode_type values for
+ * schema. */
+static const cyaml_strval_t city_building_types_strings[] = {
+ { "Construction_Mode_0", PARSED_CMODE_0 },
+ { "Construction_Mode_1", PARSED_CMODE_1 }
+};
+
+struct parsed_cmode {
+ enum parsed_cmode_type cmode_type;
+};
+
+static const cyaml_schema_field_t construction_mode_fields_schemas[] = {
+ CYAML_FIELD_ENUM("contructive_mode_type",
+ CYAML_FLAG_CASE_INSENSITIVE, struct parsed_cmode, cmode_type,
+ city_building_types_strings, CYAML_ARRAY_LEN(city_building_types_strings)),
+ CYAML_FIELD_IGNORE("datasets", CYAML_FLAG_DEFAULT),
+ CYAML_FIELD_END
+};
+
+/* Top-level schema. The top level value for the construction mode is a mapping */
+static const cyaml_schema_value_t construction_mode_schema = {
+ CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_cmode,
+ construction_mode_fields_schemas),
+};
+
+#endif
diff --git a/src/cg_constructive_mode.h b/src/cg_constructive_mode.h
@@ -1,54 +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 CONSTRUCTIVE_MODE_H__
-#define CONSTRUCTIVE_MODE_H__
-
-#include "cg_city_parsing_schemas.h"
-
-#include <rsys/rsys.h>
-#include <star/scpr.h>
-
-static void
-get_nverts(const size_t icomp, size_t* nverts, void* context)
-{
- struct parsed_city_building* parsed_data = context;
- ASSERT(icomp == 0); (void)icomp;
- *nverts = parsed_data->vertice_count;
-}
-
-static void
-get_pos(const size_t icomp, const size_t ivert, double pos[2], void* context)
-{
- struct parsed_city_building* parsed_data = context;
- ASSERT(icomp == 0); (void)icomp;
- pos[0] = parsed_data->vertice[ivert*2 + 0];
- pos[1] = parsed_data->vertice[ivert*2 + 1];
-}
-
-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);
-}
-
-#endif
-
diff --git a/src/cg_constructive_mode_0.c b/src/cg_constructive_mode_0.c
@@ -1,639 +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 "cg_catalog.h"
-#include "cg_city.h"
-#include "cg_city_parsing_schemas.h"
-#include "cg_constructive_mode_0.h"
-#include "cg_constructive_mode.h"
-
-#include <rsys/rsys.h>
-#include <rsys/str.h>
-#include <rsys/logger.h>
-#include <star/scad.h>
-
-static res_T
-build_floor_footprint
- (struct scpr_polygon* pg,
- struct scad_geometry** footprint)
-{
- res_T res = RES_OK;
- size_t nverts;
-
- ASSERT(pg && footprint);
- 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 dataset_cmode_0* data;
- struct scad_geometry* footprint = NULL;
- double d[3] = {0, 0, 0};
- char* floorname = NULL;
- struct str name;
- int is_init = 0;
-
- ASSERT(pg && b && floor);
-
- data = (struct dataset_cmode_0*)b->data;
- e = data->floor_thickness;
-
- str_init(NULL, &name);
- is_init = 1;
- if (prefix) {
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_S_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 dataset_cmode_0* data;
- char* roofname = NULL;
- struct str name;
- int is_init = 0;
-
- ASSERT(b && floor && roof);
-
- str_init(NULL, &name);
- is_init = 1;
- if (prefix) {
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_S_roof"));
- roofname = str_get(&name);
- }
-
- height = b->height;
- data = (struct dataset_cmode_0*)b->data;
- e = data->floor_thickness;
-
- 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 scad_geometry* polygon = NULL;
- struct scad_geometry* polygon_int = NULL;
- size_t nverts, nverts_int;
-
- ASSERT(pg && pg_int && footprint);
-
- 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;
-
- ASSERT(pg && pg_int && b && wall);
-
- height = b->height;
-
- str_init(NULL, &name);
- is_init = 1;
- if (prefix) {
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_S_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 dataset_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;
-
- ASSERT(pg && b && cavity);
-
- height = b->height;
- data = (struct dataset_cmode_0*)b->data;
- e = data->floor_thickness;
-
- str_init(NULL, &name);
- is_init = 1;
- if (prefix) {
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_F_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 mem_allocator* allocator,
- struct data_cad_cmode_0* cad)
-{
- res_T res = RES_OK;
- char* cname = NULL;
- struct str name;
- int is_init = 0;
-
- ASSERT(allocator && cad);
-
- cad->connection = MEM_CALLOC(allocator, 3, sizeof(struct scad_geometry*));
- if(!cad->connection) {
- res = RES_MEM_ERR;
- goto error;
- }
- 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 mem_allocator* allocator,
- struct data_cad_cmode_0* cad)
-{
- res_T res = RES_OK;
- struct scad_geometry** list = NULL;
- struct scad_geometry* boundary = NULL;
- char* cname = NULL;
- struct str name;
- int is_init = 0;
-
- ASSERT(allocator && cad);
-
- list = MEM_ALLOC(allocator, 4 * sizeof(struct scad_geometry*));
- if(!list) {
- res = RES_MEM_ERR;
- goto error;
- }
- 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));
- MEM_RM(allocator, 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] = { NULL, NULL };
- char* cname = NULL;
- struct str name;
- int is_init = 0;
-
- ASSERT(pg && e > 0 && connection);
-
- 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_cmode_0
- (struct building* building,
- struct mem_allocator* allocator,
- struct logger* logger,
- struct parsed_city_building* parsed_data,
- struct catalog* catalog)
-{
- res_T res = RES_OK;
- struct dataset_cmode_0* dataset;
- struct str dataset_name;
- int name_initialized = 0;
- static struct constructive_mode_functors functors_0
- = {
- &init_cmode_0,
- &build_cad_cmode_0,
- &build_footprint_cmode_0,
- &export_stl_cmode_0,
- &release_cad_cmode_0
- };
- (void)parsed_data;
-
- if(!building || !allocator || !parsed_data || !catalog) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- building->constructive_mode = mode_0;
- building->functors = &functors_0;
- building->height = parsed_data->height;
- str_init(allocator, &building->name);
- building->name_initialized = 1;
- str_init(allocator, &dataset_name);
- name_initialized = 1;
- ERR(str_set(&building->name, parsed_data->name));
- ERR(str_set(&dataset_name, parsed_data->dataset_name));
-
- ERR(scpr_polygon_create(allocator, &building->pg));
- ERR(scpr_polygon_setup_indexed_vertices(building->pg, 1, get_nverts, get_pos,
- parsed_data));
- dataset = htable_dataset_cmode_0_find(&catalog->catalog_0, &dataset_name);
- if (dataset == NULL) {
- ERR(logger_print(logger, LOG_ERROR,
- "Unknown dataset name: '%s' used by building '%s'.\n",
- str_cget(&dataset_name), str_cget(&building->name)));
- res = RES_BAD_ARG;
- goto error;
- }
-
- building->data = dataset;
-
-exit:
- if(name_initialized) str_release(&dataset_name);
- return res;
-error:
- goto exit;
-}
-
-res_T
-build_cad_cmode_0
- (struct building* building,
- struct mem_allocator* allocator,
- struct logger* logger,
- void** cad)
-{
- res_T res = RES_OK;
- double height;
- struct scpr_polygon* pg = NULL;
- struct scpr_polygon* pg_int = NULL;
- struct dataset_cmode_0* data = NULL;
- struct data_cad_cmode_0* data_cad = NULL;
- double e_wall;
- const char* name;
-
- if (!building || !allocator || !cad) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- height = building->height;
- pg = building->pg;
- data = (struct dataset_cmode_0 *)building->data;
-
- if (height <= 0 || data->wall_thickness <= 0 || data->floor_thickness <= 0) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- data_cad = MEM_CALLOC(allocator, 1, sizeof(struct data_cad_cmode_0));
- if(!data_cad) {
- res = RES_MEM_ERR;
- goto error;
- }
-
- e_wall = data->wall_thickness;
- ERR(scpr_polygon_create_copy(NULL, pg, &pg_int));
- ERR(scpr_offset_polygon(pg_int, -e_wall, SCPR_JOIN_MITER));
-
- /* build floor with pg_int */
- name = str_cget(&building->name);
- ERR(build_floor(name, pg_int, building, &data_cad->floor));
-
- /* roof is a translated copy of floor */
- ERR(build_roof(name, building, data_cad->floor, &data_cad->roof));
-
- /* build wall with pg and pg_int */
- ERR(build_wall(name, pg, pg_int, building, &data_cad->wall));
-
- /* build cavity */
- ERR(build_cavity(name, pg_int, building, &data_cad->cavity));
-
- ERR(scad_scene_partition());
-
- /* build ground/building connection */
- ERR(building_ground_connection(name, pg, e_wall, &data_cad->ground_connection));
-
- /* build boundary */
- ERR(build_boundary(name, allocator, data_cad));
-
- /* build cavity/floor connectiona*/
- ERR(build_connection(name, allocator, data_cad));
-
-exit:
- if(pg_int) SCPR(polygon_ref_put(pg_int));
- *(struct data_cad_cmode_0**)cad = data_cad;
- return res;
-error:
- if(data_cad) CHK(RES_OK == release_cad_cmode_0(allocator, logger, data_cad));
- data_cad = NULL;
- goto exit;
-}
-
-res_T
-build_footprint_cmode_0
- (struct building* building,
- struct mem_allocator* allocator,
- struct logger* logger,
- struct scad_geometry** footprint)
-{
- res_T res = RES_OK;
- struct scpr_polygon* pg = building->pg;
- struct dataset_cmode_0* data = (struct dataset_cmode_0 *)building->data;
- double e_wall;
- (void)allocator; (void)logger;
-
- if(!building || ! footprint) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- e_wall = data->wall_thickness;
-
- ERR(building_ground_connection(NULL, pg, e_wall, footprint));
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-res_T
-export_stl_cmode_0
- (void* cad,
- struct mem_allocator* allocator,
- struct logger* logger,
- const int binary)
-{
- res_T res = RES_OK;
- struct data_cad_cmode_0* data_cad = (struct data_cad_cmode_0*)cad;
- size_t i;
- (void)allocator; (void)logger;
-
- if(!cad) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- /* 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_cad_cmode_0
- (struct mem_allocator* allocator,
- struct logger* logger,
- void* cad)
-{
- res_T res = RES_OK;
- struct data_cad_cmode_0* data_cad = (struct data_cad_cmode_0 *)cad;
- size_t i;
- (void)logger;
-
- if(!allocator || ! cad) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- if(data_cad->boundary) SCAD(geometry_delete(data_cad->boundary));
- if(data_cad->cavity) SCAD(geometry_delete(data_cad->cavity));
- if(data_cad->floor) SCAD(geometry_delete(data_cad->floor));
- if(data_cad->ground_connection) SCAD(geometry_delete(data_cad->ground_connection));
- if(data_cad->roof) SCAD(geometry_delete(data_cad->roof));
- if(data_cad->wall) SCAD(geometry_delete(data_cad->wall));
- for(i = 0; i < data_cad->n_connection; i++) {
- SCAD(geometry_delete(data_cad->connection[i]));
- }
- MEM_RM(allocator, data_cad->connection);
- MEM_RM(allocator, data_cad);
-
-exit:
- return res;
-error:
- goto exit;
-}
diff --git a/src/cg_constructive_mode_0.h b/src/cg_constructive_mode_0.h
@@ -1,98 +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 CONSTRUCTIVE_MODE_0_H
-#define CONSTRUCTIVE_MODE_0_H
-
-#include <rsys/rsys.h>
-#include <rsys/str.h>
-#include <rsys/hash_table.h>
-
-struct scad_geometry;
-struct building;
-struct mem_allocator;
-struct logger;
-struct parsed_city_building;
-struct catalog;
-
-/* specific data for constructive mode 0 */
-struct dataset_cmode_0 {
- double wall_thickness;
- double floor_thickness;
-};
-
-#define HTABLE_NAME dataset_cmode_0
-#define HTABLE_DATA struct dataset_cmode_0
-#define HTABLE_KEY struct str
-#define HTABLE_KEY_FUNCTOR_INIT str_init
-#define HTABLE_KEY_FUNCTOR_RELEASE str_release
-#define HTABLE_KEY_FUNCTOR_COPY str_copy
-#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release
-#define HTABLE_KEY_FUNCTOR_COPY_AND_CLEAR str_copy_and_clear
-#define HTABLE_KEY_FUNCTOR_EQ str_eq
-#define HTABLE_KEY_FUNCTOR_HASH str_hash
-#include <rsys/hash_table.h>
-
-struct data_cad_cmode_0 {
- struct scad_geometry* wall;
- struct scad_geometry* roof;
- 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_cmode_0
- (struct building* building,
- struct mem_allocator* allocator,
- struct logger* logger,
- struct parsed_city_building* parsed_data,
- struct catalog* catalog);
-
-res_T
-build_cad_cmode_0
- (struct building* building,
- struct mem_allocator* allocator,
- struct logger* logger,
- void** cad);
-
-res_T
-build_footprint_cmode_0
- (struct building* building,
- struct mem_allocator* allocator,
- struct logger* logger,
- struct scad_geometry** footprint);
-
-res_T
-export_stl_cmode_0
- (void* cad,
- struct mem_allocator* allocator,
- struct logger* logger,
- const int binary);
-
-res_T
-release_cad_cmode_0
- (struct mem_allocator* allocator,
- struct logger* logger,
- void* cad);
-
-#endif /* CONSTRUCTIVE_MODE_0_H */
diff --git a/src/cg_constructive_mode_0_parsing_schemas.h b/src/cg_constructive_mode_0_parsing_schemas.h
@@ -1,87 +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 FG_MODE0_PARSING_SCHEMAS__
-#define FG_MODE0_PARSING_SCHEMAS__
-
-#include <cyaml/cyaml.h>
-
-struct parsed_dataset_cmode_0 {
- char* name;
- double wall_thickness; /* must be > 0 */
- double floor_thickness; /* must be > 0 */
-};
-
-/********************************************************/
-/* Types used for parsing and to define parsing schemas */
-/********************************************************/
-
-struct parsed_catalog_cmode_0 {
- struct parsed_dataset_cmode_0* datasets;
- size_t datasets_count;
-};
-
-static const cyaml_schema_field_t dataset_cmode_0_fields_schema[] = {
- CYAML_FIELD_STRING_PTR("name", CYAML_FLAG_POINTER,
- struct parsed_dataset_cmode_0, name, 0, CYAML_UNLIMITED),
- CYAML_FIELD_FLOAT("wall_thickness", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_0, wall_thickness),
- CYAML_FIELD_FLOAT("floor_thickness", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_0, floor_thickness),
- CYAML_FIELD_END
-};
-
-static const struct cyaml_schema_value p_dataset_cmode_0_schema = {
- CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_dataset_cmode_0,
- dataset_cmode_0_fields_schema),
-};
-
-static const struct cyaml_schema_value dataset_cmode_0_schema = {
- CYAML_VALUE_MAPPING(CYAML_FLAG_DEFAULT, struct parsed_dataset_cmode_0,
- dataset_cmode_0_fields_schema),
-};
-
-static const cyaml_schema_field_t cmode_0_fields_schemas[] = {
- CYAML_FIELD_IGNORE("contructive_mode_type", CYAML_FLAG_DEFAULT),
- {
- .key = "sets",
- .value = {
- .type = CYAML_SEQUENCE,
- .flags = CYAML_FLAG_POINTER,
- .data_size = sizeof(struct parsed_dataset_cmode_0),
- .sequence = {
- .entry = &dataset_cmode_0_schema,
- .min = 1,
- .max = CYAML_UNLIMITED,
- }
- },
- .data_offset = offsetof(struct parsed_catalog_cmode_0, datasets),
- .count_size = sizeof(((struct parsed_catalog_cmode_0*)0)->datasets_count),
- .count_offset = offsetof(struct parsed_catalog_cmode_0, datasets_count),
- },
- CYAML_FIELD_END
-};
-
-/* Top-level schema. The top level value for the constructive mode is a mapping */
-static const cyaml_schema_value_t constructive_mode_0_schema = {
- CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_catalog_cmode_0,
- cmode_0_fields_schemas),
-};
-
-#endif
diff --git a/src/cg_constructive_mode_1.c b/src/cg_constructive_mode_1.c
@@ -1,1598 +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 "cg_catalog.h"
-#include "cg_city_parsing_schemas.h"
-#include "cg_constructive_mode.h"
-#include "cg_constructive_mode_1.h"
-
-#include <rsys/str.h>
-#include <rsys/logger.h>
-#include <star/scad.h>
-#include <star/scpr.h>
-
-static res_T
-build_floor
- (const char* prefix,
- struct mem_allocator* allocator,
- const struct scpr_polygon* pg,
- const struct dataset_cmode_1* data,
- struct scad_geometry** floor)
-{
- res_T res = RES_OK;
- double e_wall = data->wall_thickness;
- double e_insulation = data->external_insulation_thickness;
- double e_floor = data->floor_thickness;
- double offset = 0;
- struct scpr_polygon* pg_int = NULL;
- size_t nverts = 0;
- struct scad_geometry* footprint = NULL;
- double d[3] = {0, 0, 0};
- char* floorname = NULL;
- struct str name;
- int is_init = 0;
-
- ASSERT(allocator && pg && data && floor);
-
- if (prefix) {
- str_init(allocator, &name);
- is_init = 1;
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_S_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,
- struct mem_allocator* allocator,
- const struct scpr_polygon* pg,
- const double height,
- const struct dataset_cmode_1* data,
- struct scad_geometry** wall)
-{
- res_T res = RES_OK;
- double e_wall = data->wall_thickness;
- double e_insulation = data->external_insulation_thickness;
- double offset = 0;
- struct scpr_polygon* pg_int = NULL;
- struct scpr_polygon* pg_ext = NULL;
- 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;
-
- ASSERT(allocator && pg && data && wall);
-
- if (prefix) {
- str_init(allocator, &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,
- struct mem_allocator* allocator,
- const struct scpr_polygon* pg,
- const double height,
- const struct dataset_cmode_1* data,
- struct scad_geometry* inter_floor,
- struct scad_geometry** insulation)
-{
- res_T res = RES_OK;
- double e_wall = data->wall_thickness;
- double e_roof = data->roof_thickness;
- double e_roof_insulation = data->roof_insulation_thickness;
- double attic = data->attic_height;
- double e_ext_insulation = data->external_insulation_thickness;
- double e_int_insulation = data->internal_insulation_thickness;
- double offset = 0;
- struct scpr_polygon* pg_int = NULL;
- struct scpr_polygon* pg_ext = NULL;
- 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;
-
- ASSERT(allocator && pg && data && insulation);
-
- if (prefix) {
- str_init(allocator, &name);
- is_init = 1;
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_S_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,
- struct mem_allocator* allocator,
- const struct scpr_polygon* pg,
- const double height,
- const struct dataset_cmode_1* data,
- struct scad_geometry** roof)
-{
- res_T res = RES_OK;
- double e_wall = data->wall_thickness;
- double e_insulation = data->external_insulation_thickness;
- double e_roof = data->roof_thickness;
- double offset = 0;
- double z_roof = 0;
- struct scpr_polygon* pg_int = NULL;
- 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;
-
- ASSERT(allocator && pg && data && roof);
-
- if (prefix) {
- str_init(allocator, &name);
- is_init = 1;
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_S_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,
- struct mem_allocator* allocator,
- const struct scpr_polygon* pg,
- const double height,
- const struct dataset_cmode_1* data,
- struct scad_geometry** insulation)
-{
- res_T res = RES_OK;
- double e_wall = data->wall_thickness;
- double e_insulation = data->external_insulation_thickness;
- double e_roof = data->roof_thickness;
- double attic = data->attic_height;
- double e_roof_insulation = data->roof_insulation_thickness;
- double offset = 0;
- double z_insulation = 0;
- struct scpr_polygon* pg_int = NULL;
- 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;
-
- ASSERT(allocator && pg && data && insulation);
-
- if (prefix) {
- str_init(allocator, &name);
- is_init = 1;
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_S_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,
- struct mem_allocator* allocator,
- const struct scpr_polygon* pg,
- const struct dataset_cmode_1* data,
- struct scad_geometry** insulation)
-{
- res_T res = RES_OK;
- double e_wall = data->wall_thickness;
- double e_insulation = data->external_insulation_thickness;
- double e_floor = data->floor_thickness;
- double e_floor_insulation = data->floor_insulation_thickness;
- double offset = 0;
- double z_insulation = 0;
- struct scpr_polygon* pg_int = NULL;
- 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;
-
- ASSERT(allocator && pg && data && insulation);
-
- if (prefix) {
- str_init(allocator, &name);
- is_init = 1;
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_S_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,
- struct mem_allocator* allocator,
- const struct scpr_polygon* pg,
- const double height,
- const struct dataset_cmode_1* data,
- struct scad_geometry** inter_floor)
-{
- res_T res = RES_OK;
- size_t i = 0;
- size_t floor_n = data->inter_floor_count;
- double e_roof = data->roof_thickness;
- double e_roof_ins = data->roof_insulation_thickness;
- double attic = data->attic_height;
- double e_floor = data->inter_floor_thickness;
- double e_wall = data->wall_thickness;
- double e_insulation = data->external_insulation_thickness;
- double offset = 0;
- double z_floor = 0;
- double h_cavity = 0;
- struct scpr_polygon* pg_int = NULL;
- size_t nverts = 0;
- struct scad_geometry** floor_list = NULL;
- struct darray_geometries floor_array;
- double d[3] = {0, 0, 0};
- char* floorname = NULL;
- struct str name;
- int is_init = 0;
-
- ASSERT(allocator && pg && data && inter_floor);
-
- darray_geometries_init(allocator, &floor_array);
-
- if (prefix) {
- str_init(allocator, &name);
- is_init = 1;
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_S_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));
- ERR(darray_geometries_push_back(&floor_array, &floor));
- ERR(scad_geometry_delete(footprint));
- z_floor += h_cavity/(double)(1 + floor_n) + e_floor;
- }
- ASSERT(darray_geometries_size_get(&floor_array) == floor_n);
-
- floor_list = darray_geometries_data_get(&floor_array);
- ERR(scad_fuse_geometries(floorname, floor_list, floor_n, floor_list, floor_n,
- inter_floor));
-
-exit:
- if (is_init) str_release(&name);
- if (pg_int) SCPR(polygon_ref_put(pg_int));
- floor_list = darray_geometries_data_get(&floor_array);
- if(floor_list) {
- for (i = 0; i < floor_n; i++) {
- SCAD(geometry_delete(floor_list[i]));
- }
- darray_geometries_release(&floor_array);
- }
- return res;
-error:
- goto exit;
-}
-
-static res_T
-build_ext_insulation
- (const char* prefix,
- struct mem_allocator* allocator,
- const struct scpr_polygon* pg,
- const double height,
- const struct dataset_cmode_1* data,
- struct scad_geometry** insulation)
-{
- res_T res = RES_OK;
- double e_insulation = data->external_insulation_thickness;
- 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;
-
- ASSERT(allocator && pg && data && insulation);
-
- if (prefix) {
- str_init(allocator, &name);
- is_init = 1;
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_S_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,
- struct mem_allocator* allocator,
- const struct scpr_polygon* pg,
- const struct dataset_cmode_1* data,
- struct scad_geometry** crawlspace)
-{
- res_T res = RES_OK;
- double e_wall = data->wall_thickness;
- double e_insulation = data->external_insulation_thickness;
- double e_crawl = data->crawl_height;
- double e_floor = data->floor_thickness;
- double e_floor_insulation = data->floor_insulation_thickness;
- double offset = 0;
- double z_crawl= 0;
- struct scpr_polygon* pg_int = NULL;
- 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;
-
- ASSERT(allocator && pg && data && crawlspace);
-
- if (prefix) {
- str_init(allocator, &name);
- is_init = 1;
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_F_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,
- struct mem_allocator* allocator,
- const struct scpr_polygon* pg,
- const double height,
- const struct dataset_cmode_1* data,
- struct scad_geometry* floor,
- struct scad_geometry** cavity)
-{
- res_T res = RES_OK;
- double e_wall = data->wall_thickness;
- double e_ext_insulation = data->external_insulation_thickness;
- double e_int_insulation = data->internal_insulation_thickness;
- double e_roof = data->roof_thickness;
- double e_roof_insulation = data->roof_insulation_thickness;
- double e_attic = data->attic_height;
- double offset = 0;
- struct scpr_polygon* pg_int = NULL;
- size_t nverts = 0;
- 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;
-
- ASSERT(allocator && pg && data && cavity);
-
- if (prefix) {
- str_init(allocator, &name);
- is_init = 1;
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_F_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,
- struct mem_allocator* allocator,
- const struct scpr_polygon* pg,
- const double height,
- const struct dataset_cmode_1* data,
- struct scad_geometry** attic)
-{
- res_T res = RES_OK;
- double e_wall = data->wall_thickness;
- double e_insulation = data->external_insulation_thickness;
- double e_roof = data->roof_thickness;
- double e_attic = data->attic_height;
- double offset = 0;
- double z_attic = 0;
- struct scpr_polygon* pg_int = NULL;
- 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;
-
- ASSERT(allocator && pg && data && attic);
-
- if (prefix) {
- str_init(allocator, &name);
- is_init = 1;
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_F_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,
- struct mem_allocator* allocator,
- const struct dataset_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 darray_geometries hole_array;
- 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;
- struct darray_geometries glass_array;
- size_t list_n = 0, array_n;
- struct str gname;
- int is_init = 0;
-
- ASSERT(allocator && data && data_cad);
-
- darray_geometries_init(allocator, &hole_array);
- darray_geometries_init(allocator, &glass_array);
-
- 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[3];
- size_t center_n;
-
- ERR(scad_geometry_get_count(list[i], ¢er_n));
- ASSERT(center_n == 1);
- ERR(scad_geometry_get_centerofmass(list[i], center));
-
- 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_thickness
- + data->internal_insulation_thickness + data->external_insulation_thickness);
- dir[1] = 1.1*N[1] * (data->wall_thickness
- + data->internal_insulation_thickness + data->external_insulation_thickness);
- dir[2] = 1.1*N[2] * (data->wall_thickness
- + data->internal_insulation_thickness + data->external_insulation_thickness);
- ERR(scad_geometry_extrude(surface, NULL, dir, &hole));
- ERR(darray_geometries_push_back(&hole_array, &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));
- ERR(darray_geometries_push_back(&glass_array, &glass));
-
- ERR(scad_geometry_delete(surface));
- surface = NULL;
- }
- ASSERT(darray_geometries_size_get(&hole_array)
- == darray_geometries_size_get(&glass_array));
-
- hole_list = darray_geometries_data_get(&hole_array);
- glass_list = darray_geometries_data_get(&glass_array);
- array_n = darray_geometries_size_get(&hole_array);
-
- /* wall perforation */
- ERR(scad_cut_geometries(NULL, &data_cad->wall, 1,
- hole_list, array_n, &geom));
- ERR(scad_geometry_swap_names(data_cad->wall, geom));
- ERR(scad_geometry_delete(data_cad->wall));
- data_cad->wall = geom;
- geom = NULL;
-
- /* internal insulation perforation */
- if (data_cad->internal_insulation) {
- ERR(scad_cut_geometries(NULL, &data_cad->internal_insulation, 1,
- hole_list, array_n, &geom));
- ERR(scad_geometry_swap_names(data_cad->internal_insulation, geom));
- ERR(scad_geometry_delete(data_cad->internal_insulation));
- data_cad->internal_insulation = geom;
- geom = NULL;
- }
-
- /* external insulation perforation */
- if (data_cad->external_insulation) {
- ERR(scad_cut_geometries(NULL, &data_cad->external_insulation, 1,
- hole_list, array_n, &geom));
- ERR(scad_geometry_swap_names(data_cad->external_insulation, geom));
- ERR(scad_geometry_delete(data_cad->external_insulation));
- data_cad->external_insulation = geom;
- geom = NULL;
- }
-
- /* build glass */
- if (prefix) {
- str_init(allocator, &gname);
- is_init = 1;
- ERR(str_set(&gname, prefix));
- ERR(str_append(&gname, "_S_glass"));
- }
-
- ERR(scad_fuse_geometries(str_cget(&gname), glass_list, 1,
- glass_list+1, array_n - 1, &data_cad->glass));
-
-exit:
- glass_list = darray_geometries_data_get(&glass_array);
- for (i = 0 ; i < list_n; i++) {
- SCAD(geometry_delete(list[i]));
- }
- for (i = 0 ; i < darray_geometries_size_get(&hole_array); i++) {
- struct scad_geometry* h = darray_geometries_data_get(&hole_array)[i];
- SCAD(geometry_delete(h));
- }
- for (i = 0 ; i <darray_geometries_size_get(&glass_array); i++) {
- struct scad_geometry* g = darray_geometries_data_get(&glass_array)[i];
- SCAD(geometry_delete(g));
- }
- darray_geometries_release(&hole_array);
- darray_geometries_release(&glass_array);
- if (surface) SCAD(geometry_delete(surface));
- if (geom) SCAD(geometry_delete(geom));
- if (bcavity) SCAD(geometry_delete(bcavity));
- MEM_RM(allocator, list);
- if (is_init) str_release(&gname);
- return res;
-error:
- goto exit;
-}
-
-static res_T
-build_boundary
- (const char* prefix,
- struct mem_allocator* allocator,
- struct data_cad_cmode_1* data_cad,
- struct darray_geometries* boundary)
-{
- res_T res = RES_OK;
- size_t count;
- struct darray_geometries array;
- struct scad_geometry** list = NULL;
- struct darray_geometries bound_array;
- struct scad_geometry* bound = NULL;
- char* boundaryname = NULL;
- struct str name;
- int is_init = 0;
-
- ASSERT(allocator && prefix && data_cad && boundary);
-
- darray_geometries_init(allocator, &array);
- darray_geometries_init(allocator, &bound_array);
-
- str_init(allocator, &name);
- is_init = 1;
-
- /* Ensure enough room for all geometries without error nor mem move */
- ERR(darray_geometries_reserve(&array, 14));
- ERR(darray_geometries_push_back(&array, &data_cad->wall));
- ERR(darray_geometries_push_back(&array, &data_cad->roof));
- ERR(darray_geometries_push_back(&array, &data_cad->floor));
- ERR(darray_geometries_push_back(&array, &data_cad->habitable_cavity));
- ERR(darray_geometries_push_back(&array, &data_cad->fake_ground));
- if (data_cad->foundation) {
- ERR(darray_geometries_push_back(&array, &data_cad->foundation));
- }
- if (data_cad->intermediate_floor) {
- ERR(darray_geometries_push_back(&array, &data_cad->intermediate_floor));
- }
- if (data_cad->external_insulation) {
- ERR(darray_geometries_push_back(&array, &data_cad->external_insulation));
- }
- if (data_cad->internal_insulation) {
- ERR(darray_geometries_push_back(&array, &data_cad->internal_insulation));
- }
- if (data_cad->roof_insulation) {
- ERR(darray_geometries_push_back(&array, &data_cad->roof_insulation));
- }
- if (data_cad->floor_insulation) {
- ERR(darray_geometries_push_back(&array, &data_cad->floor_insulation));
- }
- if (data_cad->attic_cavity) {
- ERR(darray_geometries_push_back(&array, &data_cad->attic_cavity));
- }
- if (data_cad->crawlspace_cavity) {
- ERR(darray_geometries_push_back(&array, &data_cad->crawlspace_cavity));
- }
- if (data_cad->glass) {
- ERR(darray_geometries_push_back(&array, &data_cad->glass));
- }
-
- count = darray_geometries_size_get(&array);
- list = darray_geometries_data_get(&array);
-
- /* Ensure enough room for all geometries without error nor mem move */
- ERR(darray_geometries_reserve(boundary, 5+darray_geometries_size_get(boundary)));
-
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_boundary_wall"));
- boundaryname = str_get(&name);
- ERR(scad_geometries_common_boundaries(boundaryname, list, count,
- &data_cad->wall, 1, &bound));
- ERR(darray_geometries_push_back(boundary, &bound));
-
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_boundary_roof"));
- boundaryname = str_get(&name);
- ERR(scad_geometries_common_boundaries(boundaryname, list, count,
- &data_cad->roof, 1, &bound));
- ERR(darray_geometries_push_back(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, count,
- &data_cad->glass, 1, &bound));
- ERR(darray_geometries_push_back(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, count,
- &data_cad->external_insulation, 1, &bound));
- ERR(darray_geometries_push_back(boundary, &bound));
- }
-
- if (data_cad->internal_insulation) {
- size_t bcount = 0;
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_boundary_int_insulation"));
- boundaryname = str_get(&name);
- ERR(scad_geometries_common_boundaries(boundaryname, list, count,
- &data_cad->internal_insulation, 1, &bound));
- ERR(scad_geometry_get_count(bound, &bcount));
- if (bcount > 0) {
- ERR(darray_geometries_push_back(boundary, &bound));
- } else {
- SCAD(geometry_delete(bound));
- }
- }
-
-exit:
- if (is_init) str_release(&name);
- darray_geometries_release(&array);
- return res;
-error:
- goto exit;
-}
-
-static res_T
-build_connection
- (const char* prefix,
- struct mem_allocator* allocator,
- struct data_cad_cmode_1* data_cad,
- struct darray_geometries* 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;
-
- ASSERT(allocator && prefix && data_cad && connection);
-
- str_init(allocator, &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) { \
- ERR(darray_geometries_push_back(connection, &connect)); \
- } else { \
- SCAD(geometry_delete(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;
-
- ASSERT(pg && footprint);
-
- 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 mem_allocator* allocator,
- 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;
- size_t count;
- struct darray_geometries array;
- struct scad_geometry** list = NULL;
- struct scad_geometry* footprint = NULL;
- struct scad_geometry* geom = NULL;
-
- ASSERT(cad && pg && ground );
-
- darray_geometries_init(allocator, &array);
-
- /* Ensure enough room for all geometries without error nor mem move */
- ERR(darray_geometries_reserve(&array, 4));
- if (cad->foundation) {
- ERR(darray_geometries_push_back(&array, &cad->foundation));
- }
- if (cad->crawlspace_cavity) {
- ERR(darray_geometries_push_back(&array, &cad->crawlspace_cavity));
- }
- if (cad->floor) {
- ERR(darray_geometries_push_back(&array, &cad->floor));
- }
- if (cad->floor_insulation) {
- ERR(darray_geometries_push_back(&array, &cad->floor_insulation));
- }
-
- count = darray_geometries_size_get(&array);
- list = darray_geometries_data_get(&array);
-
- 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, count, ground));
-
-exit:
- if (pg_offset) SCPR(polygon_ref_put(pg_offset));
- darray_geometries_release(&array);
- 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 mem_allocator* allocator,
- 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;
- size_t count;
- struct darray_geometries array;
- struct scad_geometry** list = NULL;
- struct scad_geometry* list_boundary = NULL;
- struct scad_geometry* footprint = NULL;
-
- ASSERT(prefix && allocator && cad && connection);
-
- darray_geometries_init(allocator, &array);
-
- str_init(allocator, &name);
- is_init = 1;
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_C_building_ground"));
- cname = str_get(&name);
-
- /* Ensure enough room for all geometries without error nor mem move */
- ERR(darray_geometries_reserve(&array, 6));
- if (cad->foundation) {
- ERR(darray_geometries_push_back(&array, &cad->foundation));
- }
- if (cad->crawlspace_cavity) {
- ERR(darray_geometries_push_back(&array, &cad->crawlspace_cavity));
- }
- if (cad->floor) {
- ERR(darray_geometries_push_back(&array, &cad->floor));
- }
- if (cad->floor_insulation) {
- ERR(darray_geometries_push_back(&array, &cad->floor_insulation));
- }
- if (cad->external_insulation) {
- ERR(darray_geometries_push_back(&array, &cad->external_insulation));
- }
- if (cad->wall) {
- ERR(darray_geometries_push_back(&array, &cad->wall));
- }
-
- count = darray_geometries_size_get(&array);
- list = darray_geometries_data_get(&array);
-
- ERR(scad_geometries_common_boundaries(cname, list,count, &cad->fake_ground, 1,
- connection));
-
-exit:
- darray_geometries_release(&array);
- 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_cmode_1
- (struct building* building,
- struct mem_allocator* allocator,
- struct logger* logger,
- struct parsed_city_building* parsed_data,
- struct catalog* catalog)
-{
- res_T res = RES_OK;
- struct dataset_cmode_1* dataset;
- struct str dataset_name;
- int name_initialized = 0;
- static struct constructive_mode_functors functors_1
- = {
- &init_cmode_1,
- &build_cad_cmode_1,
- &build_footprint_cmode_1,
- &export_stl_cmode_1,
- &release_cad_cmode_1
- };
- (void) parsed_data;
-
- if(!building || !allocator || !parsed_data ||!catalog) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- building->constructive_mode = mode_1;
- building->functors = &functors_1;
- building->height = parsed_data->height;
- str_init(allocator, &building->name);
- building->name_initialized = 1;
- str_init(allocator, &dataset_name);
- name_initialized = 1;
- ERR(str_set(&building->name, parsed_data->name));
- ERR(str_set(&dataset_name, parsed_data->dataset_name));
-
- ERR(scpr_polygon_create(allocator, &building->pg));
- ERR(scpr_polygon_setup_indexed_vertices(building->pg, 1, get_nverts, get_pos,
- parsed_data));
- dataset = htable_dataset_cmode_1_find(&catalog->catalog_1, &dataset_name);
- if (dataset == NULL) {
- ERR(logger_print(logger, LOG_ERROR,
- "Unknown dataset name: '%s' used by building '%s'.\n",
- str_cget(&dataset_name), str_cget(&building->name)));
- res = RES_BAD_ARG;
- goto error;
- }
-
- building->data = dataset;
-
-exit:
- if(name_initialized) str_release(&dataset_name);
- return res;
-error:
- goto exit;
-}
-
-res_T
-build_cad_cmode_1
- (struct building* building,
- struct mem_allocator* allocator,
- struct logger* logger,
- void** cad)
-{
- res_T res = RES_OK;
- double height = building->height;
- double depth = 0;
- struct scpr_polygon* pg = building->pg;
- struct dataset_cmode_1* data = (struct dataset_cmode_1 *)building->data;
- struct data_cad_cmode_1* data_cad = NULL;
- const char* name;
-
- if (!building || !allocator || !cad) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- data_cad = MEM_CALLOC(allocator, 1, sizeof(struct data_cad_cmode_1));
- if(!data_cad) {
- res = RES_MEM_ERR;
- goto error;
- }
- darray_geometries_init(allocator, &data_cad->boundary);
- darray_geometries_init(allocator, &data_cad->connection);
-
- /* build mandatories elements :
- - floor
- - wall
- - roof
- */
-
- name = str_cget(&building->name);
- ERR(build_floor(name, allocator, pg, data, &data_cad->floor));
-
- ERR(build_wall(name, "S_wall", allocator, pg, height, data, &data_cad->wall));
-
- ERR(build_roof(name, allocator, pg, height, data, &data_cad->roof));
-
- /* build optionnal elements :
- - foundation
- - intermediate floor
- - external insulation
- - internal insulation
- - roof insulation
- - floor insulation
- */
-
- if (data->foundation_depth > 0) {
- depth = -data->foundation_depth;
- ERR(build_wall(name, "S_foundation", allocator, pg, depth, data,
- &data_cad->foundation));
- }
-
- if (data->inter_floor_count > 0) {
- ERR(build_inter_floor(name, allocator, pg, height, data,
- &data_cad->intermediate_floor));
- }
-
- if (data->external_insulation_thickness> 0) {
- ERR(build_ext_insulation(name, allocator, pg, height, data,
- &data_cad->external_insulation));
- }
-
- if (data->internal_insulation_thickness> 0) {
- ERR(build_int_insulation(name, allocator, pg, height, data,
- data_cad->intermediate_floor, &data_cad->internal_insulation));
- }
-
- if (data->roof_insulation_thickness > 0) {
- ERR(build_roof_insulation(name, allocator, pg, height, data,
- &data_cad->roof_insulation));
- }
-
- if (data->floor_insulation_thickness > 0) {
- ERR(build_floor_insulation(name, allocator, pg, data,
- &data_cad->floor_insulation));
- }
-
- /* build cavities :
- - attic
- - habitable
- - crawlspace
- */
-
- if (data->attic_height > 0) {
- ERR(build_attic(name, allocator, pg, height, data, &data_cad->attic_cavity));
- }
-
- ERR(build_habitable(name, allocator, pg, height, data,
- data_cad->intermediate_floor, &data_cad->habitable_cavity));
-
- if (data->crawl_height > 0) {
- ERR(build_crawlspace(name, allocator, pg, data, &data_cad->crawlspace_cavity));
- }
-
- /* windows */
- if (data->glass_ratio > 0) {
- ERR(build_windows(name, allocator, data, data_cad));
- }
-
- /* fake ground */
- depth = MMAX(data->foundation_depth,
- data->floor_thickness + data->floor_insulation_thickness + data->crawl_height);
- ERR(build_fake_ground(allocator, data_cad, pg, depth,
- &data_cad->fake_ground));
-
- ERR(scad_scene_partition());
-
- /* build ground/buildind connection */
- ERR(building_ground_connection(name, allocator, data_cad,
- &data_cad->ground_connection));
-
- /* build boundaries */
- ERR(build_boundary(name, allocator, data_cad, &data_cad->boundary));
-
- /* build connections */
- ERR(build_connection(name, allocator, data_cad, &data_cad->connection));
-
-exit:
- *(struct data_cad_cmode_1**)cad = data_cad;
- return res;
-error:
- if(data_cad) CHK(RES_OK == release_cad_cmode_1(allocator, logger, data_cad));
- data_cad = NULL;
- goto exit;
-}
-
-res_T
-build_footprint_cmode_1
- (struct building* building,
- struct mem_allocator* allocator,
- struct logger* logger,
- struct scad_geometry** footprint)
-{
- res_T res = RES_OK;
- struct scpr_polygon* pg = building->pg;
- (void)allocator; (void)logger;
-
- if (!building || !footprint) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- ERR(build_footprint(pg, footprint));
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-res_T
-export_stl_cmode_1
- (void* cad,
- struct mem_allocator* allocator,
- struct logger* logger,
- const int binary)
-{
- res_T res = RES_OK;
- struct data_cad_cmode_1* data_cad = (struct data_cad_cmode_1 *)cad;
- size_t i = 0;
- (void)allocator; (void)logger;
-
- if (!cad) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- /* 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 < darray_geometries_size_get(&data_cad->boundary); i++) {
- struct scad_geometry* b = darray_geometries_data_get(&data_cad->boundary)[i];
- ERR(scad_stl_export(b, NULL, binary));
- }
-
- /* connections export*/
- for(i = 0; i < darray_geometries_size_get(&data_cad->connection); i++) {
- struct scad_geometry* c = darray_geometries_data_get(&data_cad->connection)[i];
- ERR(scad_stl_export(c, 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_cad_cmode_1
- (struct mem_allocator* allocator,
- struct logger* logger,
- void* cad)
-{
- res_T res = RES_OK;
- struct data_cad_cmode_1* data_cad = (struct data_cad_cmode_1 *)cad;
- size_t i;
- (void)logger;
-
- if (!allocator || !cad) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- if(data_cad->attic_cavity) SCAD(geometry_delete(data_cad->attic_cavity));
- if(data_cad->crawlspace_cavity) SCAD(geometry_delete(data_cad->crawlspace_cavity));
- if(data_cad->external_insulation) SCAD(geometry_delete(data_cad->external_insulation));
- if(data_cad->fake_ground) SCAD(geometry_delete(data_cad->fake_ground));
- if(data_cad->floor) SCAD(geometry_delete(data_cad->floor));
- if(data_cad->floor_insulation) SCAD(geometry_delete(data_cad->floor_insulation));
- if(data_cad->foundation) SCAD(geometry_delete(data_cad->foundation));
- if(data_cad->glass) SCAD(geometry_delete(data_cad->glass));
- if(data_cad->ground_connection) SCAD(geometry_delete(data_cad->ground_connection));
- if(data_cad->habitable_cavity) SCAD(geometry_delete(data_cad->habitable_cavity));
- if(data_cad->intermediate_floor) SCAD(geometry_delete(data_cad->intermediate_floor));
- if(data_cad->internal_insulation) SCAD(geometry_delete(data_cad->internal_insulation));
- if(data_cad->roof) SCAD(geometry_delete(data_cad->roof));
- if(data_cad->roof_insulation) SCAD(geometry_delete(data_cad->roof_insulation));
- if(data_cad->wall) SCAD(geometry_delete(data_cad->wall));
- for(i = 0; i < darray_geometries_size_get(&data_cad->boundary); i++) {
- struct scad_geometry* b = darray_geometries_data_get(&data_cad->boundary)[i];
- ERR(scad_geometry_delete(b));
- }
- for(i = 0; i < darray_geometries_size_get(&data_cad->connection); i++) {
- struct scad_geometry* c = darray_geometries_data_get(&data_cad->connection)[i];
- ERR(scad_geometry_delete(c));
- }
- darray_geometries_release(&data_cad->boundary);
- darray_geometries_release(&data_cad->connection);
- MEM_RM(allocator, data_cad);
-
-exit:
- return res;
-error:
- goto exit;
-}
diff --git a/src/cg_constructive_mode_1.h b/src/cg_constructive_mode_1.h
@@ -1,124 +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 CONSTRUCTIVE_MODE_1_H
-#define CONSTRUCTIVE_MODE_1_H
-
-#include <rsys/rsys.h>
-#include <rsys/str.h>
-#include <rsys/hash_table.h>
-#include <rsys/dynamic_array.h>
-
-struct scad_geometry;
-struct building;
-struct mem_allocator;
-struct logger;
-struct parsed_city_building;
-struct catalog;
-
-#define DARRAY_NAME geometries
-#define DARRAY_DATA struct scad_geometry*
-#include <rsys/dynamic_array.h>
-
-/* specific data for constructive mode 1 */
-struct dataset_cmode_1 {
- size_t inter_floor_count; /* can be 0 */
- double wall_thickness; /* must be > 0 */
- double floor_thickness; /* must be > 0 */
- double inter_floor_thickness; /* must be > 0 */
- double roof_thickness; /* must be > 0 */
- double internal_insulation_thickness; /* can be 0 */
- double external_insulation_thickness; /* can be 0 */
- double floor_insulation_thickness; /* can be 0 */
- double roof_insulation_thickness; /* can be 0 */
- double foundation_depth; /* can be 0 */
- double crawl_height; /* can be 0 */
- double attic_height; /* can be 0 */
- double glass_ratio; /* in [0, 1] */
-};
-
-#define HTABLE_NAME dataset_cmode_1
-#define HTABLE_DATA struct dataset_cmode_1
-#define HTABLE_KEY struct str
-#define HTABLE_KEY_FUNCTOR_INIT str_init
-#define HTABLE_KEY_FUNCTOR_RELEASE str_release
-#define HTABLE_KEY_FUNCTOR_COPY str_copy
-#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release
-#define HTABLE_KEY_FUNCTOR_COPY_AND_CLEAR str_copy_and_clear
-#define HTABLE_KEY_FUNCTOR_EQ str_eq
-#define HTABLE_KEY_FUNCTOR_HASH str_hash
-#include <rsys/hash_table.h>
-
-struct data_cad_cmode_1 {
- struct scad_geometry* wall;
- struct scad_geometry* roof;
- 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 darray_geometries boundary;
- struct darray_geometries connection;
- size_t n_connection;
-};
-
-res_T
-init_cmode_1
- (struct building* building,
- struct mem_allocator* allocator,
- struct logger* logger,
- struct parsed_city_building* parsed_data,
- struct catalog* catalog);
-
-res_T
-build_cad_cmode_1
- (struct building* building,
- struct mem_allocator* allocator,
- struct logger* logger,
- void** cad);
-
-res_T
-build_footprint_cmode_1
- (struct building* building,
- struct mem_allocator* allocator,
- struct logger* logger,
- struct scad_geometry** footprint);
-
-res_T
-export_stl_cmode_1
- (void* cad,
- struct mem_allocator* allocator,
- struct logger* logger,
- const int binary);
-
-res_T
-release_cad_cmode_1
- (struct mem_allocator* allocator,
- struct logger* logger,
- void* cad);
-
-#endif /* CONSTRUCTIVE_MODE_1_H */
diff --git a/src/cg_constructive_mode_1_parsing_schemas.h b/src/cg_constructive_mode_1_parsing_schemas.h
@@ -1,124 +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 FG_MODE1_PARSING_SCHEMAS__
-#define FG_MODE1_PARSING_SCHEMAS__
-
-#include <cyaml/cyaml.h>
-
-#include <rsys/str.h>
-
-struct parsed_dataset_cmode_1 {
- char* name;
- size_t inter_floor_count; /* can be 0 */
- double wall_thickness; /* must be > 0 */
- double floor_thickness; /* must be > 0 */
- double inter_floor_thickness; /* must be > 0 */
- double roof_thickness; /* must be > 0 */
- double internal_insulation_thickness; /* can be 0 */
- double external_insulation_thickness; /* can be 0 */
- double floor_insulation_thickness; /* can be 0 */
- double roof_insulation_thickness; /* can be 0 */
- double foundation_depth; /* can be 0 */
- double crawl_height; /* can be 0 */
- double attic_height; /* can be 0 */
- double glass_ratio; /* in [0, 1] */
-};
-
-/********************************************************/
-/* Types used for parsing and to define parsing schemas */
-/********************************************************/
-
-struct parsed_catalog_cmode_1 {
- struct parsed_dataset_cmode_1* datasets;
- size_t datasets_count;
-};
-
-static const cyaml_schema_field_t dataset_cmode_1_fields_schema[] = {
- CYAML_FIELD_STRING_PTR("name", CYAML_FLAG_POINTER,
- struct parsed_dataset_cmode_1, name, 0, CYAML_UNLIMITED),
- CYAML_FIELD_INT("inter_floor_count", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_1, inter_floor_count),
- CYAML_FIELD_FLOAT("wall_thickness", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_1, wall_thickness),
- CYAML_FIELD_FLOAT("floor_thickness", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_1, floor_thickness),
- CYAML_FIELD_FLOAT("inter_floor_thickness", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_1, inter_floor_thickness),
- CYAML_FIELD_FLOAT("roof_thickness", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_1, roof_thickness),
- CYAML_FIELD_FLOAT("internal_insulation_thickness", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_1, internal_insulation_thickness),
- CYAML_FIELD_FLOAT("external_insulation_thickness", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_1, external_insulation_thickness),
- CYAML_FIELD_FLOAT("floor_insulation_thickness", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_1, floor_insulation_thickness),
- CYAML_FIELD_FLOAT("roof_insulation_thickness", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_1, roof_insulation_thickness),
- CYAML_FIELD_FLOAT("foundation_depth", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_1, foundation_depth),
- CYAML_FIELD_FLOAT("crawl_height", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_1, crawl_height),
- CYAML_FIELD_FLOAT("attic_height", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_1, attic_height),
- CYAML_FIELD_FLOAT("glass_ratio", CYAML_FLAG_DEFAULT,
- struct parsed_dataset_cmode_1, glass_ratio),
- CYAML_FIELD_END
-};
-
-static const struct cyaml_schema_value p_dataset_cmode_1_schema = {
- CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_dataset_cmode_1,
- dataset_cmode_1_fields_schema),
-};
-
-static const struct cyaml_schema_value dataset_cmode_1_schema = {
- CYAML_VALUE_MAPPING(CYAML_FLAG_DEFAULT, struct parsed_dataset_cmode_1,
- dataset_cmode_1_fields_schema),
-};
-
-static const cyaml_schema_field_t cmode_1_fields_schemas[] = {
- CYAML_FIELD_IGNORE("contructive_mode_type", CYAML_FLAG_DEFAULT),
- {
- .key = "sets",
- .value = {
- .type = CYAML_SEQUENCE,
- .flags = CYAML_FLAG_POINTER,
- .data_size = sizeof(struct parsed_dataset_cmode_1),
- .sequence = {
- .entry = &dataset_cmode_1_schema,
- .min = 1,
- .max = CYAML_UNLIMITED,
- }
- },
- .data_offset = offsetof(struct parsed_catalog_cmode_1, datasets),
- .count_size = sizeof(((struct parsed_catalog_cmode_1*)0)->datasets_count),
- .count_offset = offsetof(struct parsed_catalog_cmode_1, datasets_count),
- },
- CYAML_FIELD_END
-};
-
-/* Top-level schema. The top level value for the constructive mode is a mapping.
- * Its fields are defined in cmode_1_fields_schemas.
- */
-static const cyaml_schema_value_t constructive_mode_1_schema = {
- CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_catalog_cmode_1,
- cmode_1_fields_schemas),
-};
-
-#endif
diff --git a/src/cg_constructive_modes_parsing_schemas.h b/src/cg_constructive_modes_parsing_schemas.h
@@ -1,61 +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 FG_CMODES_PARSING_SCHEMAS__
-#define FG_CMODES_PARSING_SCHEMAS__
-
-#include <cyaml/cyaml.h>
-
-/********************************************************/
-/* Types used for parsing and to define parsing schemas */
-/********************************************************/
-
-/* constructive mode type */
-enum parsed_cmode_type {
- PARSED_CMODE_0,
- PARSED_CMODE_1,
- PARSED_CMODE_TYPE_UNDEFINED
-};
-
-/* Mapping from "constructive mode type" strings to enum parsed_cmode_type values for
- * schema. */
-static const cyaml_strval_t city_building_types_strings[] = {
- { "Constructive_Mode_0", PARSED_CMODE_0 },
- { "Constructive_Mode_1", PARSED_CMODE_1 }
-};
-
-struct parsed_cmode {
- enum parsed_cmode_type cmode_type;
-};
-
-static const cyaml_schema_field_t constructive_mode_fields_schemas[] = {
- CYAML_FIELD_ENUM("contructive_mode_type",
- CYAML_FLAG_CASE_INSENSITIVE, struct parsed_cmode, cmode_type,
- city_building_types_strings, CYAML_ARRAY_LEN(city_building_types_strings)),
- CYAML_FIELD_IGNORE("sets", CYAML_FLAG_DEFAULT),
- CYAML_FIELD_END
-};
-
-/* Top-level schema. The top level value for the constructive mode is a mapping */
-static const cyaml_schema_value_t constructive_mode_schema = {
- CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, struct parsed_cmode,
- constructive_mode_fields_schemas),
-};
-
-#endif
diff --git a/src/cg_main.c b/src/cg_main.c
@@ -24,8 +24,8 @@
#include "cg_city_parsing.h"
#include "cg_catalog.h"
#include "cg_catalog_parsing.h"
-#include "cg_constructive_mode_0_parsing_schemas.h"
-#include "cg_constructive_mode_1_parsing_schemas.h"
+#include "cg_construction_mode_0_parsing_schemas.h"
+#include "cg_construction_mode_1_parsing_schemas.h"
#include <cyaml/cyaml.h>