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 cb6fa1b39d2fd062c897769127a74866772c6295
parent dcac84e65e42d669730bb012f4061926528f3cb6
Author: Benjamin Piaud <benjamin.piaud@meso-star.com>
Date:   Thu, 23 Feb 2023 18:12:47 +0100

Continue adjoining which depends of mode. To avoid adjoining
foundations, their thickness are reduced. Change strategy of ground
connection for mode 0

Diffstat:
Mexample/catalog1.yaml | 10+++++-----
Mexample/city.yaml | 12+++++++++++-
Msrc/cg_building.c | 38++++++++++++--------------------------
Msrc/cg_building.h | 9++++++++-
Msrc/cg_construction_mode_0.c | 110++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Msrc/cg_construction_mode_0.h | 7+++++++
Msrc/cg_construction_mode_1.c | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Msrc/cg_construction_mode_1.h | 7+++++++
8 files changed, 180 insertions(+), 76 deletions(-)

diff --git a/example/catalog1.yaml b/example/catalog1.yaml @@ -6,14 +6,14 @@ datasets: floor_thickness: 0.3 inter_floor_thickness: 0.2 roof_thickness: 0.3 - internal_insulation_thickness: 0.1 + internal_insulation_thickness: 0. external_insulation_thickness: 0 - floor_insulation_thickness: 0.1 - roof_insulation_thickness: 0.2 + floor_insulation_thickness: 0. + roof_insulation_thickness: 0. foundation_depth: 2 crawl_height: 0. - attic_height: 0.5 - glass_ratio: 0.5 + attic_height: 0. + glass_ratio: 0. - name: b1b inter_floor_count: 1 wall_thickness: 0.3 diff --git a/example/city.yaml b/example/city.yaml @@ -1,5 +1,5 @@ ground: - extent: [ -20, 40, -20, 20 ] + extent: [ -40, 40, -40, 40 ] depth: 5 buildings: @@ -28,3 +28,13 @@ buildings: dataset: b0a footprint: [ [5, 0], [5, -5], [10, -5], [10, 0] ] height: 3.52056 + - name: bat_5 + construction_mode: Construction_Mode_1 + dataset: b1a + footprint: [ [22, -20], [22, -25], [27, -25], [27, -20] ] + height: 3.5 + - name: bat_6 + construction_mode: Construction_Mode_1 + dataset: b1a + footprint: [ [20, -20], [30, -20], [30, -10], [20, -10] ] + height: 8 diff --git a/src/cg_building.c b/src/cg_building.c @@ -19,30 +19,23 @@ #include "cg.h" #include "cg_building.h" -#include "cg_construction_mode.h" #include <rsys/stretchy_array.h> #include <star/scad.h> -#include <star/scpr.h> - -static void unused_functions(void){ - (void)&get_pos; - (void)&get_nverts; - return; -} res_T build_adjoining - (struct building** adjoining, + (struct mem_allocator* allocator, + struct logger* logger, + struct building** adjoining, const size_t adjoining_n, struct scad_geometry** geom) { res_T res = RES_OK; size_t i = 0; + struct scad_geometry* envelop = NULL; struct scad_geometry** envelop_list = NULL; - (void)&unused_functions; - if (!adjoining || adjoining_n < 1 || !geom) { res = RES_BAD_ARG; goto error; @@ -50,32 +43,25 @@ build_adjoining /* iterate over adjoining building */ for (i=0; i<adjoining_n; i++) { - size_t nverts = 0; - double height = adjoining[i]->height; - double d[3] = {0, 0, 0}; - struct scpr_polygon* pg = adjoining[i]->pg; - struct scad_geometry* envelop = NULL; - struct scad_geometry* footprint = NULL; - ERR(scpr_polygon_get_vertices_count(pg, 0, &nverts)); - ERR(scad_add_polygon(NULL, get_position_pg, pg, 0, nverts, &footprint)); - - d[2] = height; - ERR(scad_geometry_extrude(footprint, NULL, d, &envelop)); + ERR(adjoining[i]->functors->build_envelop(allocator, logger, + adjoining[i], &envelop)); + sa_push(envelop_list, envelop); - ERR(scad_geometry_delete(footprint)); - footprint = NULL; } /* fuse envelops in the same geometries */ - if (adjoining_n > 1) { + if (sa_size(envelop_list) > 1) { ERR(scad_fuse_geometries(NULL, envelop_list, 1, envelop_list+1, sa_size(envelop_list) - 1, geom)); } else { - *geom = envelop_list[0]; + ERR(scad_geometry_copy(envelop_list[0], NULL, geom)); } exit: + for (i=0; i<sa_size(envelop_list); ++i) { + scad_geometry_delete(envelop_list[i]); + } if (envelop_list) sa_release(envelop_list); return res; error: diff --git a/src/cg_building.h b/src/cg_building.h @@ -56,6 +56,11 @@ struct construction_mode_functors { struct logger* logger, struct building* building, struct scad_geometry** footprint); + res_T (*build_envelop) + (struct mem_allocator* allocator, + struct logger* logger, + struct building* building, + struct scad_geometry** envelop); res_T (*export_stl) (struct mem_allocator* allocator, struct logger* logger, @@ -96,7 +101,9 @@ struct building { res_T build_adjoining - (struct building** adjoining, + (struct mem_allocator* allocator, + struct logger* logger, + struct building** adjoining, const size_t adjoining_n, struct scad_geometry** geom); diff --git a/src/cg_construction_mode_0.c b/src/cg_construction_mode_0.c @@ -92,6 +92,25 @@ error: } 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 scpr_polygon* pg, struct scad_geometry** fake_ground) @@ -332,6 +351,7 @@ static res_T build_boundary (const char* prefix, struct mem_allocator* allocator, + struct scad_geometry* adjoining_cad, struct data_cad_cmode_0* data_cad) { res_T res = RES_OK; @@ -346,7 +366,7 @@ build_boundary str_init(allocator, &name); is_init = 1; - count = 5; + count = 6; list = MEM_ALLOC(allocator, count * sizeof(struct scad_geometry*)); if(!list) { res = RES_MEM_ERR; @@ -357,6 +377,11 @@ build_boundary list[2] = data_cad->roof; list[3] = data_cad->cavity; list[4] = data_cad->fake_ground; + if (adjoining_cad) { + list[5] = adjoining_cad; + } else { + count = 5; + } data_cad->boundary = MEM_ALLOC(allocator, 2 * sizeof(struct scad_geometry*)); @@ -382,43 +407,32 @@ error: static res_T building_ground_connection - (struct scpr_device* scpr, - struct mem_allocator* allocator, - struct scpr_polygon* pg, + (struct mem_allocator* allocator, const char* prefix, - const double e, + struct data_cad_cmode_0* cad, struct scad_geometry** connection) { res_T res = RES_OK; - struct scpr_polygon* pg_int = NULL; - struct scad_geometry* geom[2] = { NULL, NULL }; + struct scad_geometry* list[2] = { NULL, NULL }; char* cname = NULL; struct str name; int is_init = 0; - ASSERT(scpr && allocator && pg && e > 0 && connection); - - if (prefix) { - str_init(allocator, &name); - is_init = 1; - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_C_ground")); - cname = str_get(&name); - } - - ERR(scpr_polygon_create_copy(scpr, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -e, SCPR_JOIN_MITER)); + ASSERT(allocator && prefix && connection); - ERR(build_wall_footprint(pg, pg_int, &geom[0])); - ERR(build_floor_footprint(pg_int, &geom[1])); - - ERR(scad_fragment_geometries(cname, &geom[0], 1, &geom[1], 1, connection)); + str_init(allocator, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_C_ground")); + cname = str_get(&name); + list[0] = cad->wall; + list[1] = cad->floor; + + ERR(scad_geometries_common_boundaries(cname, list, 2, &cad->fake_ground, 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; @@ -448,6 +462,7 @@ init_cmode_0 &init_cmode_0, &build_cad_cmode_0, &build_footprint_cmode_0, + &build_envelop_cmode_0, &export_stl_cmode_0, &release_cad_cmode_0 }; @@ -555,17 +570,18 @@ build_cad_cmode_0 /* build adjoining envelop */ if (building->adjoining_n > 0) { - ERR(build_adjoining(building->adjoining, building->adjoining_n, &adjoining_cad)); + ERR(build_adjoining(allocator, logger, + building->adjoining, building->adjoining_n, &adjoining_cad)); } ERR(scad_scene_partition()); /* build ground/building connection */ - ERR(building_ground_connection(scpr, allocator, pg, name, e_wall, + ERR(building_ground_connection(allocator, name, data_cad, &data_cad->ground_connection)); /* build boundary */ - ERR(build_boundary(name, allocator, data_cad)); + ERR(build_boundary(name, allocator, adjoining_cad, data_cad)); /* build cavity/floor connectiona*/ ERR(build_connection(name, allocator, data_cad)); @@ -589,21 +605,45 @@ build_footprint_cmode_0 struct scad_geometry** footprint) { res_T res = RES_OK; - struct dataset_cmode_0* data = (struct dataset_cmode_0 *)building->data; - double e_wall; - (void)allocator; (void)logger; + (void)scpr; (void)allocator; (void)logger; if(!building || ! footprint) { res = RES_BAD_ARG; goto error; } - e_wall = data->wall_thickness; + ERR(build_footprint(building->pg, footprint)); + +exit: + return res; +error: + goto exit; +} - ERR(building_ground_connection(scpr, allocator, building->pg, NULL, e_wall, - footprint)); +res_T +build_envelop_cmode_0 + (struct mem_allocator* allocator, + struct logger* logger, + struct building* building, + struct scad_geometry** envelop) +{ + res_T res = RES_OK; + size_t nverts = 0; + double height = building->height; + double d[3] = {0, 0, 0}; + struct scpr_polygon* pg = building->pg; + struct scad_geometry* footprint = NULL; + + (void)allocator; (void)logger; + + ERR(scpr_polygon_get_vertices_count(pg, 0, &nverts)); + ERR(scad_add_polygon(NULL, get_position_pg, pg, 0, nverts, &footprint)); + + d[2] = height; + ERR(scad_geometry_extrude(footprint, NULL, d, envelop)); exit: + if (footprint) scad_geometry_delete(footprint); return res; error: goto exit; diff --git a/src/cg_construction_mode_0.h b/src/cg_construction_mode_0.h @@ -90,6 +90,13 @@ build_footprint_cmode_0 struct scad_geometry** footprint); res_T +build_envelop_cmode_0 + (struct mem_allocator* allocator, + struct logger* logger, + struct building* building, + struct scad_geometry** envelop); + +res_T export_stl_cmode_0 (struct mem_allocator* allocator, struct logger* logger, diff --git a/src/cg_construction_mode_1.c b/src/cg_construction_mode_1.c @@ -120,7 +120,12 @@ build_wall wallname = str_get(&name); } - offset = e_insulation; + if (strcmp(suffix, "S_foundation") == 0) { + offset = e_insulation + 0.9*e_wall; + } else { + offset = e_insulation; + } + ERR(scpr_polygon_create_copy(scpr, pg, &pg_ext)); ERR(scpr_offset_polygon(pg_ext, -offset, SCPR_JOIN_MITER)); @@ -912,6 +917,7 @@ build_boundary struct mem_allocator* allocator, const char* prefix, struct data_cad_cmode_1* data_cad, + struct scad_geometry* adjoining_cad, struct darray_geometries* boundary) { res_T res = RES_OK; @@ -934,7 +940,7 @@ build_boundary is_init = 1; /* Ensure enough room for all geometries without error nor mem move */ - ERR(darray_geometries_reserve(&array, 14)); + ERR(darray_geometries_reserve(&array, 15)); 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)); @@ -967,6 +973,9 @@ build_boundary if (data_cad->glass) { ERR(darray_geometries_push_back(&array, &data_cad->glass)); } + if (adjoining_cad) { + ERR(darray_geometries_push_back(&array, &adjoining_cad)); + } count = darray_geometries_size_get(&array); list = darray_geometries_data_get(&array); @@ -1165,6 +1174,7 @@ build_fake_ground struct data_cad_cmode_1* cad, struct scpr_polygon* pg, const double depth, + struct scad_geometry* adjoining_cad, struct scad_geometry** ground) { res_T res = RES_OK; @@ -1181,7 +1191,7 @@ build_fake_ground darray_geometries_init(allocator, &array); /* Ensure enough room for all geometries without error nor mem move */ - ERR(darray_geometries_reserve(&array, 4)); + ERR(darray_geometries_reserve(&array, 5)); if (cad->foundation) { ERR(darray_geometries_push_back(&array, &cad->foundation)); } @@ -1194,6 +1204,9 @@ build_fake_ground if (cad->floor_insulation) { ERR(darray_geometries_push_back(&array, &cad->floor_insulation)); } + if (adjoining_cad) { + ERR(darray_geometries_push_back(&array, &adjoining_cad)); + } count = darray_geometries_size_get(&array); list = darray_geometries_data_get(&array); @@ -1307,6 +1320,7 @@ init_cmode_1 &init_cmode_1, &build_cad_cmode_1, &build_footprint_cmode_1, + &build_envelop_cmode_1, &export_stl_cmode_1, &release_cad_cmode_1 }; @@ -1457,7 +1471,8 @@ build_cad_cmode_1 /* build adjoining envelop */ if (building->adjoining_n > 0) { - ERR(build_adjoining(building->adjoining, building->adjoining_n, &adjoining_cad)); + ERR(build_adjoining(allocator, logger, + building->adjoining, building->adjoining_n, &adjoining_cad)); } /* windows */ @@ -1468,23 +1483,25 @@ build_cad_cmode_1 /* fake ground */ depth = MMAX(data->foundation_depth, data->floor_thickness + data->floor_insulation_thickness + data->crawl_height); - ERR(build_fake_ground(scpr, allocator, data_cad, pg, depth, - &data_cad->fake_ground)); + ERR(build_fake_ground(scpr, allocator, data_cad, pg, depth, adjoining_cad, + &data_cad->fake_ground)); + ERR(scad_scene_partition()); - /* build ground/buildind connection */ + /* build ground/building connection */ ERR(building_ground_connection(scpr, allocator, name, data_cad, &data_cad->ground_connection)); /* build boundaries */ - ERR(build_boundary(scpr, allocator, name, data_cad, &data_cad->boundary)); + ERR(build_boundary(scpr, allocator, name, data_cad, adjoining_cad, &data_cad->boundary)); /* build connections */ ERR(build_connection(scpr, allocator, name, data_cad, &data_cad->connection)); exit: *(struct data_cad_cmode_1**)cad = data_cad; + if (adjoining_cad) scad_geometry_delete(adjoining_cad); return res; error: if(data_cad) CHK(RES_OK == release_cad_cmode_1(allocator, logger, data_cad)); @@ -1517,6 +1534,36 @@ error: } res_T +build_envelop_cmode_1 + (struct mem_allocator* allocator, + struct logger* logger, + struct building* building, + struct scad_geometry** envelop) +{ + res_T res = RES_OK; + size_t nverts = 0; + double height = building->height; + double d[3] = {0, 0, 0}; + struct scpr_polygon* pg = building->pg; + struct scad_geometry* footprint = NULL; + + (void)allocator; (void)logger; + + ERR(scpr_polygon_get_vertices_count(pg, 0, &nverts)); + ERR(scad_add_polygon(NULL, get_position_pg, pg, 0, nverts, &footprint)); + + /* wall envelop */ + d[2] = height; + ERR(scad_geometry_extrude(footprint, NULL, d, envelop)); + +exit: + if (footprint) scad_geometry_delete(footprint); + return res; +error: + goto exit; +} + +res_T export_stl_cmode_1 (struct mem_allocator* allocator, struct logger* logger, diff --git a/src/cg_construction_mode_1.h b/src/cg_construction_mode_1.h @@ -115,6 +115,13 @@ build_footprint_cmode_1 struct scad_geometry** footprint); res_T +build_envelop_cmode_1 + (struct mem_allocator* allocator, + struct logger* logger, + struct building* building, + struct scad_geometry** envelop); + +res_T export_stl_cmode_1 (struct mem_allocator* allocator, struct logger* logger,