commit 460fb9bb0a856a877bb5ee235435d8bf43440f81
parent 8f605f525e20c791cea7433a7022625b1c8e7d98
Author: Benjamin Piaud <benjamin.piaud@meso-star.com>
Date: Thu, 1 Dec 2022 10:16:59 +0100
Add windows in model1. Windows are just simple glazing for the moment
Diffstat:
3 files changed, 205 insertions(+), 21 deletions(-)
diff --git a/src/cg_building_model1.c b/src/cg_building_model1.c
@@ -740,6 +740,136 @@ error:
}
static res_T
+build_windows
+ (const char* prefix,
+ const struct data_model1* data,
+ struct data_cad_model1* data_cad)
+{
+ res_T res = RES_OK;
+ size_t i = 0;
+ double N[3];
+ double dir[3];
+ double scale[3];
+ struct scad_geometry* surface = NULL;
+ struct scad_geometry* hole = NULL;
+ struct scad_geometry** hole_list = NULL;
+ struct scad_geometry* geom = NULL;
+ struct scad_geometry* bcavity = NULL;
+ struct scad_geometry** list = NULL;
+ struct scad_geometry* glass = NULL;
+ struct scad_geometry** glass_list = NULL;
+ size_t list_n = 0;
+ char* name = NULL;
+ struct str gname;
+ int is_init = 0;
+
+ scale[0] = sqrt(data->glass_ratio);
+ scale[1] = scale[0];
+ scale[2] = scale[0];
+
+ /* windows are build from the vertical faces of habitable cavities */
+ ERR(scad_geometry_boundary(NULL, &data_cad->habitable_cavity, 1, &bcavity));
+ ERR(scad_geometry_explode(bcavity, NULL, &list, &list_n));
+
+ for (i=0; i<list_n; ++i){
+ double* center = NULL;
+ size_t center_n = 0;
+
+ ERR(scad_geometry_get_centerofmass(list[i], ¢er, ¢er_n));
+
+ ERR(scad_geometry_normal(list[i], center, N, NULL, &surface));
+
+ if (N[2] != 0) {
+ ERR(scad_geometry_delete(surface));
+ surface = NULL;
+ continue; /* keep only vertical face */
+ }
+
+ ERR(scad_geometry_dilate(surface, center, scale));
+
+ dir[0] = 1.1*N[0] * (data->wall + data->int_insulation + data->ext_insulation);
+ dir[1] = 1.1*N[1] * (data->wall + data->int_insulation + data->ext_insulation);
+ dir[2] = 1.1*N[2] * (data->wall + data->int_insulation + data->ext_insulation);
+ ERR(scad_geometry_extrude(surface, NULL, dir, &hole));
+ sa_push(hole_list, hole);
+
+ dir[0] = N[0] * 0.024;
+ dir[1] = N[1] * 0.024;
+ dir[2] = N[2] * 0.024;
+ ERR(scad_geometry_extrude(surface, NULL, dir, &glass));
+ sa_push(glass_list, glass);
+
+ ERR(scad_geometry_delete(surface));
+ surface = NULL;
+ }
+
+ /* wall perforation */
+ ERR(scad_geometry_get_name(data_cad->wall, &name));
+ ERR(scad_cut_geometries(
+ NULL, &data_cad->wall, 1, hole_list, sa_size(hole_list), &geom));
+ ERR(scad_geometry_delete(data_cad->wall));
+ /*data_cad->wall = geom;*/
+ ERR(scad_geometry_copy(geom, name, &data_cad->wall));
+ ERR(scad_geometry_delete(geom));
+ geom = NULL;
+
+ /* internal insulation perforation */
+ if (data_cad->internal_insulation) {
+ ERR(scad_geometry_get_name(data_cad->internal_insulation, &name));
+ ERR(scad_cut_geometries(
+ NULL, &data_cad->internal_insulation, 1,
+ hole_list, sa_size(hole_list), &geom));
+ ERR(scad_geometry_delete(data_cad->internal_insulation));
+ ERR(scad_geometry_copy(geom, name, &data_cad->internal_insulation));
+ ERR(scad_geometry_delete(geom));
+ geom = NULL;
+ }
+
+ /* external insulation perforation */
+ if (data_cad->external_insulation) {
+ ERR(scad_geometry_get_name(data_cad->external_insulation, &name));
+ ERR(scad_cut_geometries(
+ NULL, &data_cad->external_insulation, 1,
+ hole_list, sa_size(hole_list), &geom));
+ ERR(scad_geometry_delete(data_cad->external_insulation));
+ ERR(scad_geometry_copy(geom, name, &data_cad->external_insulation));
+ ERR(scad_geometry_delete(geom));
+ geom = NULL;
+ }
+
+ /* build glass */
+ str_init(NULL, &gname);
+ is_init = 1;
+ ERR(str_set(&gname, prefix));
+ ERR(str_append(&gname, "_glass"));
+ ERR(scad_fuse_geometries(str_cget(&gname), glass_list, 1,
+ glass_list+1, sa_size(glass_list) - 1, &data_cad->glass));
+
+exit:
+ for (i=0 ; i<list_n; ++i) {
+ scad_geometry_delete(list[i]);
+ }
+ for (i=0 ; i<sa_size(hole_list); ++i) {
+ scad_geometry_delete(hole_list[i]);
+ }
+ for (i=0 ; i<sa_size(glass_list); ++i) {
+ scad_geometry_delete(glass_list[i]);
+ }
+ if (hole_list) sa_release(hole_list);
+ if (glass_list) sa_release(glass_list);
+ if (surface) scad_geometry_delete(surface);
+ if (geom) scad_geometry_delete(geom);
+ if (bcavity) scad_geometry_delete(bcavity);
+ /*scad_synchronize();*/
+ if (name) free(name);
+ if (list) free(list);
+ if (is_init) str_release(&gname);
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
build_boundary
(const char* prefix,
struct data_cad_model1* data_cad,
@@ -773,30 +903,52 @@ build_boundary
if (data_cad->floor_insulation) sa_push(list, data_cad->floor_insulation);
if (data_cad->attic_cavity) sa_push(list, data_cad->attic_cavity);
if (data_cad->crawlspace_cavity) sa_push(list, data_cad->crawlspace_cavity);
+ if (data_cad->glass) sa_push(list, data_cad->glass);
- ERR(scad_geometry_boundary(NULL, list, sa_size(list), &geom1));
-
- ERR(scad_geometry_boundary(NULL, &data_cad->external_insulation, 1, &geom2));
- ERR(str_set(&name, prefix));
- ERR(str_append(&name, "_boundary_ext_insulation"));
- boundaryname = str_get(&name);
- ERR(scad_intersect_geometries(boundaryname, &geom1, 1, &geom2, 1, &bound));
- sa_push(*boundary, bound);
- ERR(scad_geometry_boundary(NULL, &data_cad->wall, 1, &geom2));
ERR(str_set(&name, prefix));
ERR(str_append(&name, "_boundary_wall"));
boundaryname = str_get(&name);
- ERR(scad_intersect_geometries(boundaryname, &geom1, 1, &geom2, 1, &bound));
+ ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list),
+ &data_cad->wall, 1, &bound));
sa_push(*boundary, bound);
- ERR(scad_geometry_boundary(NULL, &data_cad->roof, 1, &geom2));
ERR(str_set(&name, prefix));
ERR(str_append(&name, "_boundary_roof"));
boundaryname = str_get(&name);
- ERR(scad_intersect_geometries(boundaryname, &geom1, 1, &geom2, 1, &bound));
+ ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list),
+ &data_cad->roof, 1, &bound));
sa_push(*boundary, bound);
-
+
+ if (data_cad->glass) {
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_boundary_glass"));
+ boundaryname = str_get(&name);
+ ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list),
+ &data_cad->glass, 1, &bound));
+ sa_push(*boundary, bound);
+ }
+
+ if (data_cad->external_insulation) {
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_boundary_ext_insulation"));
+ boundaryname = str_get(&name);
+ ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list),
+ &data_cad->external_insulation, 1, &bound));
+ sa_push(*boundary, bound);
+ }
+
+ if (data_cad->internal_insulation) {
+ size_t count = 0;
+ ERR(str_set(&name, prefix));
+ ERR(str_append(&name, "_boundary_int_insulation"));
+ boundaryname = str_get(&name);
+ ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list),
+ &data_cad->internal_insulation, 1, &bound));
+ ERR(scad_geometry_get_count(bound, &count));
+ if (count>0) sa_push(*boundary, bound);
+ }
+
exit:
if (is_init) str_release(&name);
if (list) sa_release(list);
@@ -850,6 +1002,11 @@ build_connection
/* 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");
@@ -975,12 +1132,27 @@ build_cad_model1(struct building* building)
ERR(str_append(&prefix, model_str[model]));
data_cad = malloc(sizeof(struct data_cad_model1));
+ data_cad->wall = NULL;
+ data_cad->roof = NULL;
+ data_cad->floor = NULL;
+ data_cad->intermediate_floor = NULL;
+ data_cad->habitable_cavity = NULL;
+ data_cad->crawlspace_cavity = NULL;
+ data_cad->attic_cavity = NULL;
+ data_cad->internal_insulation = NULL;
+ data_cad->external_insulation = NULL;
+ data_cad->floor_insulation = NULL;
+ data_cad->roof_insulation = NULL;
+ data_cad->glass = NULL;
+ data_cad->ground = NULL;
+ data_cad->boundary = NULL;
+ data_cad->connection = NULL;
building->data_cad = (struct data_cad_model1*)data_cad;
/* build mandatories elements :
- floor
- wall
- - roff
+ - roof
*/
ERR(build_floor(str_cget(&prefix), pg, data, &data_cad->floor));
@@ -1057,6 +1229,9 @@ build_cad_model1(struct building* building)
data_cad->crawlspace_cavity = NULL;
}
+ /* windows */
+ if (data->glass_ratio > 0) ERR(build_windows(str_cget(&prefix), data, data_cad));
+
ERR(scad_scene_partition());
/* build boundaries */
@@ -1113,6 +1288,11 @@ export_stl_model1
/* roof export */
ERR(scad_stl_export(data_cad->roof, 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));
@@ -1156,7 +1336,7 @@ export_stl_model1
ERR(scad_stl_export(data_cad->boundary[i], NULL, binary));
}
- /* boundary export*/
+ /* connections export*/
for (i=0; i<sa_size(data_cad->connection); ++i) {
ERR(scad_stl_export(data_cad->connection[i], NULL, binary));
}
diff --git a/src/cg_building_model1.h b/src/cg_building_model1.h
@@ -42,6 +42,7 @@ struct data_model1 {
double foundation; /* foundation depth >= 0 */
double crawl; /* crawl space height >= 0 */
double attic; /* attic height >= 0 (and only if roof insulation > 0)*/
+ double glass_ratio; /* in [0, 1] */
};
struct data_cad_model1 {
@@ -56,6 +57,7 @@ struct data_cad_model1 {
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* ground;
struct scad_geometry** boundary;
struct scad_geometry** connection;
diff --git a/src/cg_parsing.c b/src/cg_parsing.c
@@ -393,12 +393,13 @@ parse_building_params
data1->inter_floor_n = 1;
data1->roof = 0.3;
data1->int_insulation = 0.1;
- data1->ext_insulation = 0.12;
- data1->floor_insulation = 0.2;
- data1->roof_insulation = 0.3;
- data1->foundation = 1.2;
- data1->crawl = 0.5;
- data1->attic = 0.3;
+ data1->ext_insulation = 0.;
+ data1->floor_insulation = 0;
+ data1->roof_insulation = 0;
+ data1->foundation = 0;
+ data1->crawl = 0;
+ data1->attic = 0;
+ data1->glass_ratio = 0.5;
params0[1].data = malloc(sizeof(struct data_model1));
params0[1].data = (void*)data1;
ERR(htable_building_params_set(ht_params, ¶ms0[1].name, ¶ms0[1]));
@@ -406,6 +407,7 @@ parse_building_params
/* check coherence */
if (data1->roof_insulation <= 0) data1->attic = 0;
if (data1->inter_floor <= 0) data1->inter_floor_n = 0;
+ if (data1->inter_floor_n <= 0) data1->inter_floor = 0;
exit: