city_generator2

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

commit 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:
Msrc/cg_building_model1.c | 210+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/cg_building_model1.h | 2++
Msrc/cg_parsing.c | 14++++++++------
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], &center, &center_n)); + + ERR(scad_geometry_normal(list[i], center, N, NULL, &surface)); + + if (N[2] != 0) { + ERR(scad_geometry_delete(surface)); + surface = NULL; + continue; /* keep only vertical face */ + } + + ERR(scad_geometry_dilate(surface, center, scale)); + + dir[0] = 1.1*N[0] * (data->wall + data->int_insulation + data->ext_insulation); + dir[1] = 1.1*N[1] * (data->wall + data->int_insulation + data->ext_insulation); + dir[2] = 1.1*N[2] * (data->wall + data->int_insulation + data->ext_insulation); + ERR(scad_geometry_extrude(surface, NULL, dir, &hole)); + sa_push(hole_list, hole); + + dir[0] = N[0] * 0.024; + dir[1] = N[1] * 0.024; + dir[2] = N[2] * 0.024; + ERR(scad_geometry_extrude(surface, NULL, dir, &glass)); + sa_push(glass_list, glass); + + ERR(scad_geometry_delete(surface)); + surface = NULL; + } + + /* wall perforation */ + ERR(scad_geometry_get_name(data_cad->wall, &name)); + ERR(scad_cut_geometries( + NULL, &data_cad->wall, 1, hole_list, sa_size(hole_list), &geom)); + ERR(scad_geometry_delete(data_cad->wall)); + /*data_cad->wall = geom;*/ + ERR(scad_geometry_copy(geom, name, &data_cad->wall)); + ERR(scad_geometry_delete(geom)); + geom = NULL; + + /* internal insulation perforation */ + if (data_cad->internal_insulation) { + ERR(scad_geometry_get_name(data_cad->internal_insulation, &name)); + ERR(scad_cut_geometries( + NULL, &data_cad->internal_insulation, 1, + hole_list, sa_size(hole_list), &geom)); + ERR(scad_geometry_delete(data_cad->internal_insulation)); + ERR(scad_geometry_copy(geom, name, &data_cad->internal_insulation)); + ERR(scad_geometry_delete(geom)); + geom = NULL; + } + + /* external insulation perforation */ + if (data_cad->external_insulation) { + ERR(scad_geometry_get_name(data_cad->external_insulation, &name)); + ERR(scad_cut_geometries( + NULL, &data_cad->external_insulation, 1, + hole_list, sa_size(hole_list), &geom)); + ERR(scad_geometry_delete(data_cad->external_insulation)); + ERR(scad_geometry_copy(geom, name, &data_cad->external_insulation)); + ERR(scad_geometry_delete(geom)); + geom = NULL; + } + + /* build glass */ + 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, &params0[1].name, &params0[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: