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 51b00620d8f6aae71415dff12f2ee916cdc68da6
parent cb6fa1b39d2fd062c897769127a74866772c6295
Author: Benjamin Piaud <benjamin.piaud@meso-star.com>
Date:   Tue, 28 Feb 2023 16:27:57 +0100

Replace adjoining fusion by list of adjoining. That ensures conformal
mesh.

Diffstat:
Mexample/catalog1.yaml | 8++++----
Mexample/city.yaml | 10+++++-----
Msrc/cg_building.c | 31++++++++++++++-----------------
Msrc/cg_building.h | 2+-
Msrc/cg_construction_mode_0.c | 37++++++++++++++++++++++++-------------
Msrc/cg_construction_mode_1.c | 41+++++++++++++++++++++++------------------
6 files changed, 71 insertions(+), 58 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. + internal_insulation_thickness: 0.1 external_insulation_thickness: 0 - floor_insulation_thickness: 0. - roof_insulation_thickness: 0. + floor_insulation_thickness: 0.1 + roof_insulation_thickness: 0.2 foundation_depth: 2 crawl_height: 0. attic_height: 0. - glass_ratio: 0. + glass_ratio: 0.5 - name: b1b inter_floor_count: 1 wall_thickness: 0.3 diff --git a/example/city.yaml b/example/city.yaml @@ -4,8 +4,8 @@ ground: buildings: - name: bat_0 - construction_mode: Construction_Mode_0 - dataset: b0a + construction_mode: Construction_Mode_1 + dataset: b1a footprint: [ [0, 0], [10, 0], [10, 10], [0, 10] ] height: 5.52056 - name: bat_1 @@ -24,9 +24,9 @@ buildings: footprint: [ [20, 0], [20, -5], [25, -5], [25, 0] ] height: 3.52056 - name: bat_4 - construction_mode: Construction_Mode_0 - dataset: b0a - footprint: [ [5, 0], [5, -5], [10, -5], [10, 0] ] + construction_mode: Construction_Mode_1 + dataset: b1a + footprint: [ [5, 0], [5, -5], [12, -5], [12, 0] ] height: 3.52056 - name: bat_5 construction_mode: Construction_Mode_1 diff --git a/src/cg_building.c b/src/cg_building.c @@ -29,11 +29,10 @@ build_adjoining struct logger* logger, struct building** adjoining, const size_t adjoining_n, - struct scad_geometry** geom) + struct scad_geometry*** geom) { res_T res = RES_OK; size_t i = 0; - struct scad_geometry* envelop = NULL; struct scad_geometry** envelop_list = NULL; if (!adjoining || adjoining_n < 1 || !geom) { @@ -41,29 +40,27 @@ build_adjoining goto error; } + envelop_list = MEM_CALLOC(allocator, adjoining_n, sizeof(struct scad_geometry*)); + if(!envelop_list) { + res = RES_MEM_ERR; + goto error; + } + /* iterate over adjoining building */ for (i=0; i<adjoining_n; i++) { ERR(adjoining[i]->functors->build_envelop(allocator, logger, - adjoining[i], &envelop)); - - sa_push(envelop_list, envelop); + adjoining[i], envelop_list + i)); } - /* fuse envelops in the same geometries */ - if (sa_size(envelop_list) > 1) { - ERR(scad_fuse_geometries(NULL, envelop_list, 1, - envelop_list+1, sa_size(envelop_list) - 1, geom)); - } else { - 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); + if (envelop_list) *geom = envelop_list; return res; error: + for (i=0; i<adjoining_n; i++) { + if (envelop_list[i]) scad_geometry_delete(envelop_list[i]); + } + if (envelop_list) MEM_RM(allocator, envelop_list); + envelop_list = NULL; goto exit; } diff --git a/src/cg_building.h b/src/cg_building.h @@ -105,6 +105,6 @@ build_adjoining struct logger* logger, struct building** adjoining, const size_t adjoining_n, - struct scad_geometry** geom); + struct scad_geometry*** geom); #endif /* BUILDING_H */ diff --git a/src/cg_construction_mode_0.c b/src/cg_construction_mode_0.c @@ -351,7 +351,8 @@ static res_T build_boundary (const char* prefix, struct mem_allocator* allocator, - struct scad_geometry* adjoining_cad, + struct scad_geometry** adjoining_cad, + size_t adjoining_n, struct data_cad_cmode_0* data_cad) { res_T res = RES_OK; @@ -360,13 +361,14 @@ build_boundary char* boundaryname = NULL; struct str name; int is_init = 0; + size_t i = 0; ASSERT(allocator && prefix && data_cad); str_init(allocator, &name); is_init = 1; - count = 6; + count = 5 + adjoining_n; list = MEM_ALLOC(allocator, count * sizeof(struct scad_geometry*)); if(!list) { res = RES_MEM_ERR; @@ -377,13 +379,15 @@ 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; + for (i=0; i<adjoining_n; i++) { + list[5+i] = adjoining_cad[i]; } data_cad->boundary = MEM_ALLOC(allocator, 2 * sizeof(struct scad_geometry*)); + if(!data_cad->boundary) { + res = RES_MEM_ERR; + goto error; + } ERR(str_set(&name, prefix)); ERR(str_append(&name, "_B_walls")); @@ -526,7 +530,9 @@ build_cad_cmode_0 struct data_cad_cmode_0* data_cad = NULL; double e_wall; const char* name; - struct scad_geometry* adjoining_cad = NULL; + struct scad_geometry** adjoining_cad = NULL; + size_t i = 0; + size_t adjoining_n = building->adjoining_n; if (!building || !allocator || !cad) { res = RES_BAD_ARG; @@ -565,15 +571,16 @@ build_cad_cmode_0 /* build cavity */ ERR(build_cavity(name, pg_int, building, &data_cad->cavity)); - /* build fake ground */ - ERR(build_fake_ground(pg, &data_cad->fake_ground)); /* build adjoining envelop */ - if (building->adjoining_n > 0) { + if (adjoining_n > 0) { ERR(build_adjoining(allocator, logger, - building->adjoining, building->adjoining_n, &adjoining_cad)); + building->adjoining, adjoining_n, &adjoining_cad)); } + /* build fake ground */ + ERR(build_fake_ground(pg, &data_cad->fake_ground)); + ERR(scad_scene_partition()); /* build ground/building connection */ @@ -581,7 +588,7 @@ build_cad_cmode_0 &data_cad->ground_connection)); /* build boundary */ - ERR(build_boundary(name, allocator, adjoining_cad, data_cad)); + ERR(build_boundary(name, allocator, adjoining_cad, adjoining_n, data_cad)); /* build cavity/floor connectiona*/ ERR(build_connection(name, allocator, data_cad)); @@ -589,6 +596,10 @@ build_cad_cmode_0 exit: if(pg_int) SCPR(polygon_ref_put(pg_int)); *(struct data_cad_cmode_0**)cad = data_cad; + for (i=0 ; i<adjoining_n; i++) { + if (adjoining_cad[i]) scad_geometry_delete(adjoining_cad[i]); + } + if (adjoining_cad) MEM_RM(allocator, adjoining_cad); return res; error: if(data_cad) CHK(RES_OK == release_cad_cmode_0(allocator, logger, data_cad)); @@ -688,7 +699,7 @@ export_stl_cmode_0 ERR(scad_stl_export(data_cad->boundary[1], NULL, 0, binary)); /* footprint export */ - ERR(scad_stl_export(data_cad->ground_connection, NULL, 0, binary)); + ERR(scad_stl_export(data_cad->ground_connection, NULL, 1, binary)); exit: return res; diff --git a/src/cg_construction_mode_1.c b/src/cg_construction_mode_1.c @@ -121,7 +121,7 @@ build_wall } if (strcmp(suffix, "S_foundation") == 0) { - offset = e_insulation + 0.9*e_wall; + offset = e_insulation + 0.1*e_wall; } else { offset = e_insulation; } @@ -746,7 +746,8 @@ build_windows const char* prefix, const struct dataset_cmode_1* data, struct data_cad_cmode_1* data_cad, - struct scad_geometry* adjoining_cad) + struct scad_geometry** adjoining_cad, + size_t adjoining_n) { res_T res = RES_OK; size_t i = 0; @@ -812,7 +813,7 @@ build_windows /* check if hole intersect adjoining_cad */ /* push only if no intersect */ if (adjoining_cad) { - ERR(scad_intersect_geometries(NULL, &hole, 1, &adjoining_cad, 1, + ERR(scad_intersect_geometries(NULL, &hole, 1, adjoining_cad, adjoining_n, &hole_adjoining_intersect)); ERR(scad_geometry_get_count(hole_adjoining_intersect, &count)); } else { @@ -917,7 +918,8 @@ build_boundary struct mem_allocator* allocator, const char* prefix, struct data_cad_cmode_1* data_cad, - struct scad_geometry* adjoining_cad, + struct scad_geometry** adjoining_cad, + size_t adjoining_n, struct darray_geometries* boundary) { res_T res = RES_OK; @@ -929,6 +931,7 @@ build_boundary char* boundaryname = NULL; struct str name; int is_init = 0; + size_t i = 0; (void)scpr; ASSERT(allocator && prefix && data_cad && boundary); @@ -940,7 +943,7 @@ build_boundary is_init = 1; /* Ensure enough room for all geometries without error nor mem move */ - ERR(darray_geometries_reserve(&array, 15)); + ERR(darray_geometries_reserve(&array, 14 + adjoining_n)); 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)); @@ -973,8 +976,8 @@ 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)); + for (i=0; i<adjoining_n; i++) { + ERR(darray_geometries_push_back(&array, adjoining_cad + i)); } count = darray_geometries_size_get(&array); @@ -1174,7 +1177,6 @@ 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; @@ -1191,7 +1193,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, 5)); + ERR(darray_geometries_reserve(&array, 4)); if (cad->foundation) { ERR(darray_geometries_push_back(&array, &cad->foundation)); } @@ -1204,9 +1206,6 @@ 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); @@ -1383,7 +1382,9 @@ build_cad_cmode_1 struct dataset_cmode_1* data = (struct dataset_cmode_1 *)building->data; struct data_cad_cmode_1* data_cad = NULL; const char* name; - struct scad_geometry* adjoining_cad = NULL; + struct scad_geometry** adjoining_cad = NULL; + size_t i = 0; + size_t adjoining_n = building->adjoining_n; if (!building || !allocator || !cad) { res = RES_BAD_ARG; @@ -1477,15 +1478,15 @@ build_cad_cmode_1 /* windows */ if (data->glass_ratio > 0) { - ERR(build_windows(scpr, allocator, name, data, data_cad, adjoining_cad)); + ERR(build_windows(scpr, allocator, name, data, data_cad, + adjoining_cad, adjoining_n)); } /* 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, adjoining_cad, - &data_cad->fake_ground)); + ERR(build_fake_ground(scpr, allocator, data_cad, pg, depth, &data_cad->fake_ground)); ERR(scad_scene_partition()); @@ -1494,14 +1495,18 @@ build_cad_cmode_1 &data_cad->ground_connection)); /* build boundaries */ - ERR(build_boundary(scpr, allocator, name, data_cad, adjoining_cad, &data_cad->boundary)); + ERR(build_boundary(scpr, allocator, name, data_cad, adjoining_cad, adjoining_n, + &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); + for (i=0; i<adjoining_n; i++) { + if (adjoining_cad[i]) scad_geometry_delete(adjoining_cad[i]); + } + if (adjoining_cad) MEM_RM(allocator, adjoining_cad); return res; error: if(data_cad) CHK(RES_OK == release_cad_cmode_1(allocator, logger, data_cad));