commit 4af7283136e223b9886c10cd88bdcb33f6bc12f5
parent c4da907213cc25d65b2bf37b9a3d944ffb6186d3
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Wed, 6 Mar 2024 17:40:51 +0100
Fix the too-small rejction mechanism for windows
Windows could previoulsy be rejected as being too small if their area
was less than 0.1 m^2. This proved inadequate for buildings with big
level's height.
The new rule only rely on the windows width, using a minimum that can be
set in cg_default.h.in (currently 0.1 m) or by changing its value at
build time.
Diffstat:
3 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -25,6 +25,8 @@ set(CG2_CLOSE_NEIGHBOR_DISTANCE "2" CACHE STRING
"Distance up to which windows are not generated")
set(CG2_MIN_DISTANCE_TO_MAP_LIMITS "2" CACHE STRING
"Minimum distance from a building to the map limit")
+set(CG2_MIN_WINDOWS_WIDTH "0.1" CACHE STRING
+ "Minimum width for a windows to be valid")
if(CMAKE_HOST_UNIX)
set(CG2_DOC "TROFF" CACHE STRING
diff --git a/src/cg_construction_mode_1.c b/src/cg_construction_mode_1.c
@@ -808,19 +808,33 @@ build_windows
struct scad_geometry* env = NULL;
struct scad_geometry* benv = NULL;
struct scad_geometry* problem = NULL;
+ size_t floor_n;
+ double e_roof, e_roof_ins, attic, h_wall, e_floor;
struct str name;
struct adjoining_data* adj;
+ struct city* city;
struct mem_allocator* allocator;
+ (void)removed_hor;
ASSERT(data && data_cad && adjoining_data);
- allocator = data_cad->building->city->allocator;
+ city = data_cad->building->city;
+ allocator = city->allocator;
adjoining_n = darray_adjoining_data_size_get(adjoining_data);
adj = darray_adjoining_data_data_get(adjoining_data);
darray_geometries_init(allocator, &hole_array);
darray_geometries_init(allocator, &glass_array);
str_init(allocator, &name);
+ /* Compute wall height to help compute the minimum for windows area */
+ floor_n = data->inter_floor_count;
+ e_roof = data->roof_thickness;
+ e_roof_ins = data->roof_insulation_thickness;
+ attic = data->attic_height;
+ e_floor = data->inter_floor_thickness;
+ h_wall = (data_cad->building->height- e_roof - attic - e_roof_ins
+ - (double)floor_n*e_floor) / (double)(floor_n + 1);
+
d3_splat(scale, sqrt(data->glass_ratio));
d3_splat(scale_, MMIN(1, 1.05 * sqrt(data->glass_ratio)));
@@ -860,7 +874,7 @@ build_windows
}
ERR(scad_geometry_get_mass(list[i], &mass));
- if(mass < 0.1) {
+ if(mass < CG2_MIN_WINDOWS_WIDTH * h_wall) {
/* this window would be too small */
ERR(scad_geometry_ref_put(surface));
surface = NULL;
@@ -971,23 +985,23 @@ build_windows
prefix = str_cget(&data_cad->building->name);
if(removed_count != 0) {
- logger_print(data_cad->building->city->logger, LOG_WARNING,
+ logger_print(city->logger, LOG_WARNING,
"Building '%s' has %zu/%zu windows removed:\n",
prefix, removed_count, removed_count + array_n);
if(removed_windows_sz != 0) {
- logger_print(data_cad->building->city->logger, LOG_WARNING,
+ logger_print(city->logger, LOG_WARNING,
"- %zu windows removed due to too small size.\n", removed_windows_sz);
}
if(removed_windows_adj != 0) {
- logger_print(data_cad->building->city->logger, LOG_WARNING,
+ logger_print(city->logger, LOG_WARNING,
"- %zu windows removed due to close neighbors.\n", removed_windows_adj);
}
if(removed_windows_self != 0) {
- logger_print(data_cad->building->city->logger, LOG_WARNING,
+ logger_print(city->logger, LOG_WARNING,
"- %zu windows removed due to self conflicts.\n", removed_windows_self);
}
} else {
- logger_print(data_cad->building->city->logger, LOG_OUTPUT,
+ logger_print(city->logger, LOG_OUTPUT,
"Building '%s' has no window removed (out of %zu).\n", prefix, array_n);
}
diff --git a/src/cg_default.h.in b/src/cg_default.h.in
@@ -23,5 +23,6 @@
#define CG2_ARGS_CHANGE_BINARY_DEFAULT_OPTION '@CG2_ARGS_CHANGE_BINARY_DEFAULT_OPTION@'
#define CG2_CLOSE_NEIGHBOR_DISTANCE @CG2_CLOSE_NEIGHBOR_DISTANCE@
#define CG2_MIN_DISTANCE_TO_MAP_LIMITS @CG2_MIN_DISTANCE_TO_MAP_LIMITS@
+#define CG2_MIN_WINDOWS_WIDTH @CG2_MIN_WINDOWS_WIDTH@
#endif