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 3c529a538e70f2c7d3463e2edab69e2eeb1e6bb1
parent f4b93bd2f8e08fdc0a27b3b988e77875fe7494e7
Author: Benjamin Piaud <benjamin.piaud@meso-star.com>
Date:   Tue,  4 Oct 2022 16:00:24 +0200

Work on boundary, conditions of building which implies modification in
footprint and add a local ground concept

Diffstat:
Msrc/cg_building.c | 415+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/cg_building.h | 1+
Msrc/cg_ground.c | 33+++++++++++++++++++++++++--------
Msrc/cg_ground.h | 3++-
4 files changed, 264 insertions(+), 188 deletions(-)

diff --git a/src/cg_building.c b/src/cg_building.c @@ -23,54 +23,65 @@ #define ERR(Expr) if((res = (Expr)) != RES_OK) goto error; else (void)0 +static res_T +build_slab_footprint + (const struct pg_polygon* pg, + struct scad_geometry** footprint) +{ + res_T res = RES_OK; + + ERR(scad_add_polygon + (NULL, /* Can be NULL */ + pg->x, + pg->y, + 0, + pg->n, /* size of x and y arrays */ + footprint)); + +exit: + return res; +error: + goto exit; +} static res_T build_slab -(const struct pg_polygon* pg, +(const char* prefix, + const struct pg_polygon* pg, struct building* b, struct scad_geometry** slab) { res_T res = RES_OK; - size_t id; - enum model model; double e; struct data_model0* data; struct scad_geometry* footprint; double d[3] = {0, 0, 0}; + char* slabname = NULL; struct str name; int is_init = 0; - id = b->id; - model = b->model; data = (struct data_model0*)b->data; e = data->slab; str_init(NULL, &name); is_init = 1; - ERR(str_set(&name, "building_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)id)); - ERR(str_append(&name, "_model_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)model)); - ERR(str_append(&name, "_slab")); - - ERR(scad_add_polygon - (NULL, /* Can be NULL */ - pg->x, - pg->y, - 0, - pg->n, /* size of x and y arrays */ - &footprint)); + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_slab")); + slabname = str_get(&name); + } + + ERR(build_slab_footprint(pg, &footprint)); d[2] = e; ERR(scad_geometry_extrude (footprint, - str_cget(&name), + slabname, d, slab)); - ERR(scad_geometry_delete(footprint)); - exit: + scad_geometry_delete(footprint); if (is_init) str_release(&name); return res; error: @@ -78,37 +89,38 @@ error: } static res_T -build_roof(const struct scad_geometry* slab, struct building* b) +build_roof + (const char* prefix, + const struct building* b, + const struct scad_geometry* slab, + struct scad_geometry** roof) { res_T res = RES_OK; - size_t id; - enum model model; double height; double e; double d[3] = {0, 0, 0}; struct data_model0* data; - struct data_cad_model0* data_cad; + /*struct data_cad_model0* data_cad;*/ + char* roofname = NULL; struct str name; int is_init = 0; - - id = b->id; - model = b->model; - height = b->height; - data = (struct data_model0*)b->data; - data_cad = (struct data_cad_model0*)b->data_cad; - e = data->slab; str_init(NULL, &name); is_init = 1; - ERR(str_set(&name, "building_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)id)); - ERR(str_append(&name, "_model_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)model)); - ERR(str_append(&name, "_roof")); + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_roof")); + roofname = str_get(&name); + } + + height = b->height; + data = (struct data_model0*)b->data; + /*data_cad = (struct data_cad_model0*)b->data_cad;*/ + e = data->slab; - ERR(scad_geometry_copy(slab, str_cget(&name), &data_cad->roof)); + ERR(scad_geometry_copy(slab, roofname, roof)); d[2] = height - e ; - ERR(scad_geometry_translate(data_cad->roof, d)); + ERR(scad_geometry_translate(*roof, d)); exit: if (is_init) str_release(&name); @@ -118,36 +130,15 @@ error: } static res_T -build_wall +build_wall_footprint (const struct pg_polygon* pg, const struct pg_polygon* pg_int, - struct building* b, - struct scad_geometry** wall) + struct scad_geometry** footprint) { res_T res = RES_OK; - size_t id; - enum model model; - double height; /*struct data_cad_model0* data_cad;*/ struct scad_geometry* polygon; struct scad_geometry* polygon_int; - struct scad_geometry* footprint; - double d[3] = {0, 0, 0}; - struct str name; - int is_init = 0; - - id = b->id; - model = b->model; - height = b->height; - /*data_cad = (struct data_cad_model0*)b->data_cad;*/ - - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, "building_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)id)); - ERR(str_append(&name, "_model_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)model)); - ERR(str_append(&name, "_wall")); ERR(scad_add_polygon (NULL, @@ -170,20 +161,55 @@ build_wall (NULL, &polygon, 1, &polygon_int, 1, - &footprint)); + footprint)); + + +exit: + scad_geometry_delete(polygon); + scad_geometry_delete(polygon_int); + return res; +error: + goto exit; +} + +static res_T +build_wall + (const char* prefix, + const struct pg_polygon* pg, + const struct pg_polygon* pg_int, + struct building* b, + struct scad_geometry** wall) +{ + res_T res = RES_OK; + double height; + struct scad_geometry* footprint; + double d[3] = {0, 0, 0}; + char* wallname = NULL; + struct str name; + int is_init = 0; + + height = b->height; + + str_init(NULL, &name); + is_init = 1; + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_wall")); + wallname = str_get(&name); + } + + ERR(build_wall_footprint(pg, pg_int, &footprint)); d[2] = height; ERR(scad_geometry_extrude (footprint, - str_cget(&name), + wallname, d, wall)); - ERR(scad_geometry_delete(polygon)); - ERR(scad_geometry_delete(polygon_int)); - ERR(scad_geometry_delete(footprint)); exit: + scad_geometry_delete(footprint); if (is_init) str_release(&name); return res; error: @@ -191,33 +217,32 @@ error: } static res_T -build_cavity(const struct pg_polygon* pg, struct building* b) +build_cavity + (const char* prefix, + const struct pg_polygon* pg, + const struct building* b, + struct scad_geometry** cavity) { res_T res = RES_OK; - size_t id; - enum model model; double e, height; struct data_model0* data; - struct data_cad_model0* data_cad; double d[3] = {0, 0, 0}; struct scad_geometry* polygon; + char* cavityname = NULL; struct str name; int is_init = 0; - id = b->id; - model = b->model; height = b->height; data = (struct data_model0*)b->data; - data_cad = (struct data_cad_model0*)b->data_cad; e = data->slab; str_init(NULL, &name); is_init = 1; - ERR(str_set(&name, "building_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)id)); - ERR(str_append(&name, "_model_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)model)); - ERR(str_append(&name, "_cavity")); + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_cavity")); + cavityname = str_get(&name); + } ERR(scad_add_polygon (NULL, /* Can be NULL */ @@ -230,13 +255,11 @@ build_cavity(const struct pg_polygon* pg, struct building* b) d[2] = height - e; ERR(scad_geometry_extrude (polygon, - str_cget(&name), + cavityname, d, - &data_cad->cavity)); - - ERR(scad_geometry_delete(polygon)); - + cavity)); exit: + scad_geometry_delete(polygon); if (is_init) str_release(&name); return res; error: @@ -244,62 +267,58 @@ error: } static res_T -build_connection(struct building* b) +build_connection + (const char* prefix, + struct data_cad_model0* cad) { res_T res = RES_OK; - size_t id; - enum model model; - struct data_cad_model0* data_cad; + char* cname = NULL; struct str name; int is_init = 0; - - id = b->id; - model = b->model; - data_cad = (struct data_cad_model0*)b->data_cad; - data_cad->connection = malloc(3 * sizeof(struct scad_geometry*)); - data_cad->n_connection = 3; + cad->connection = malloc(3 * sizeof(struct scad_geometry*)); + cad->n_connection = 3; /* cavity/slab connection */ str_init(NULL, &name); is_init = 1; - ERR(str_set(&name, "building_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)id)); - ERR(str_append(&name, "_model_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)model)); - ERR(str_append(&name, "_C_cavity_slab")); + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_C_cavity_slab")); + cname = str_get(&name); + } ERR(scad_geometries_common_boundaries - (str_cget(&name), - &data_cad->cavity, 1, - &data_cad->slab, 1, - &data_cad->connection[0])); + (cname, + &cad->cavity, 1, + &cad->slab, 1, + &cad->connection[0])); /* cavity/wall connection */ - ERR(str_set(&name, "building_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)id)); - ERR(str_append(&name, "_model_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)model)); - ERR(str_append(&name, "_C_cavity_wall")); + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_C_cavity_wall")); + cname = str_get(&name); + } ERR(scad_geometries_common_boundaries - (str_cget(&name), - &data_cad->cavity, 1, - &data_cad->wall, 1, - &data_cad->connection[1])); + (cname, + &cad->cavity, 1, + &cad->wall, 1, + &cad->connection[1])); /* cavity/roof connection */ - ERR(str_set(&name, "building_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)id)); - ERR(str_append(&name, "_model_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)model)); - ERR(str_append(&name, "_C_cavity_roof")); + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_C_cavity_roof")); + cname = str_get(&name); + } ERR(scad_geometries_common_boundaries - (str_cget(&name), - &data_cad->cavity, 1, - &data_cad->roof, 1, - &data_cad->connection[2])); + (cname, + &cad->cavity, 1, + &cad->roof, 1, + &cad->connection[2])); exit: if (is_init) str_release(&name); @@ -309,40 +328,82 @@ error: } static res_T -build_boundary(struct building* b) +build_ground +(struct pg_polygon* pg, + struct scad_geometry** ground) +{ + res_T res = RES_OK; + struct scad_geometry* footprint = NULL; + double dir[3] = {0, 0, -1}; + + ERR(scad_add_polygon + (NULL, + pg->x, + pg->y, + 0, + pg->n, + &footprint)); + + ERR(scad_geometry_extrude + (footprint, + NULL, + dir, + ground)); + +exit: + scad_geometry_delete(footprint); + return res; +error: + goto exit; +} + +static res_T +build_boundary + (const char* prefix, + struct data_cad_model0* cad) { res_T res = RES_OK; - size_t id; - enum model model; - struct data_cad_model0* data_cad; struct scad_geometry** list; + struct scad_geometry* boundary; + struct scad_geometry* footprint; + char* cname = NULL; struct str name; int is_init = 0; - - id = b->id; - model = b->model; - data_cad = (struct data_cad_model0*)b->data_cad; list = malloc(4 * sizeof(struct scad_geometry*)); - list[0] = data_cad->slab; - list[1] = data_cad->wall; - list[2] = data_cad->roof; - list[3] = data_cad->cavity; + list[0] = cad->slab; + list[1] = cad->wall; + list[2] = cad->roof; + list[3] = cad->cavity; str_init(NULL, &name); is_init = 1; - ERR(str_set(&name, "building_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)id)); - ERR(str_append(&name, "_model_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)model)); - ERR(str_append(&name, "_boundary")); + if (prefix) { + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_boundary")); + cname = str_get(&name); + } ERR(scad_geometry_boundary - (str_cget(&name), + (NULL, list, 4, - &data_cad->boundary)); + &boundary)); + + ERR(scad_geometries_common_boundaries + (NULL, + list, 4, + &cad->ground, 1, + &footprint)); + + ERR(scad_cut_geometries + (cname, + &boundary, 1, + &footprint, 1, + &cad->boundary)); exit: + scad_geometry_delete(boundary); + scad_geometry_delete(footprint); if (list) free(list); if (is_init) str_release(&name); return res; @@ -354,12 +415,16 @@ res_T build_cad_model0(struct building* building) { res_T res = RES_OK; + size_t id = building->id; + enum model model = building->model; double height = building->height; struct pg_polygon pg = building->pg[0]; struct pg_polygon pg_int, pg_ext; struct data_model0* data = (struct data_model0 *)building->data; struct data_cad_model0* data_cad; double e_wall; + struct str prefix; + int is_init = 0; if (!building) { res = RES_BAD_ARG; @@ -370,7 +435,14 @@ build_cad_model0(struct building* building) res = RES_BAD_ARG; goto error; } - + + str_init(NULL, &prefix); + is_init = 1; + ERR(str_set(&prefix, "building_")); + ERR(str_append_printf(&prefix, "%lu", (unsigned long)id)); + ERR(str_append(&prefix, "_model_")); + ERR(str_append_printf(&prefix, "%lu", (unsigned long)model)); + data_cad = malloc(sizeof(struct data_cad_model0)); building->data_cad = (struct data_cad_model0*)data_cad; @@ -378,26 +450,33 @@ build_cad_model0(struct building* building) ERR(pg_offset(&pg, e_wall, &pg_int, &pg_ext)); /* build slab with pg_int */ - ERR(build_slab(&pg_int, building, &data_cad->slab)); + ERR(build_slab(str_cget(&prefix), &pg_int, building, &data_cad->slab)); /* roof is a translated copy of slab */ - ERR(build_roof(data_cad->slab, building)); + ERR(build_roof(str_cget(&prefix), building, data_cad->slab, &data_cad->roof)); /* build wall with pg and pg_int */ - ERR(build_wall(&pg, &pg_int, building, &data_cad->wall)); + ERR(build_wall(str_cget(&prefix), &pg, &pg_int, building, &data_cad->wall)); + + /* build ground */ + /*This is a 'local' ground. It is required to build boundary condition. */ + /*It is not exported.*/ + ERR(build_ground(&pg, &data_cad->ground)); /* build cavity */ - ERR(build_cavity(&pg_int, building)); + ERR(build_cavity(str_cget(&prefix), &pg_int, building, &data_cad->cavity)); ERR(scad_scene_partition()); + /* build boundary */ + ERR(build_boundary(str_cget(&prefix), building->data_cad)); + /* build connection cavity/slab */ - ERR(build_connection(building)); + ERR(build_connection(str_cget(&prefix), building->data_cad)); - /* build boundary */ - ERR(build_boundary(building)); exit: + if (is_init) str_release(&prefix); pg_release(&pg_int); pg_release(&pg_ext); return res; @@ -416,38 +495,22 @@ build_footprint_model0 struct data_model0* data = (struct data_model0 *)building->data; double e_wall; struct scad_geometry* geom[2]; - enum model model = building->model; - size_t id = building->id; - struct str name; - int is_init = 0; - e_wall = data->wall; ERR(pg_offset(&pg, e_wall, &pg_int, &pg_ext)); - /* we simply add to the ground->scene the geometries in contact with ground */ - - ERR(build_slab(&pg_int, building, &geom[0])); - ERR(build_wall(&pg, &pg_int, building, &geom[1])); + ERR(build_wall_footprint(&pg, &pg_int, &geom[0])); + ERR(build_slab_footprint(&pg, &geom[1])); - str_init(NULL, &name); - is_init = 1; - ERR(str_set(&name, "building_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)id)); - ERR(str_append(&name, "_model_")); - ERR(str_append_printf(&name, "%lu", (unsigned long)model)); - ERR(str_append(&name, "_footprint")); - -/* ERR(scad_scene_create_group*/ - /*(scene,*/ - /*str_cget(&name), */ - /*3,*/ - /*geom,*/ - /*2,*/ - /*footprint));*/ + ERR(scad_fragment_geometries + (NULL, + &geom[0], 1, + &geom[1], 1, + footprint)); exit: - if (is_init) str_release(&name); + scad_geometry_delete(geom[0]); + scad_geometry_delete(geom[1]); pg_release(&pg_int); pg_release(&pg_ext); return res; @@ -482,9 +545,6 @@ export_stl_model0 /* boundary export */ ERR(scad_stl_export(data_cad->boundary, NULL, 0)); - - /* footprint export */ - /*ERR(scad_stl_export(building->footprint, NULL, 0)); */ exit: return res; @@ -512,8 +572,5 @@ release_model0 if (data) free(data); if (data_cad) free(data_cad); -exit: return res; -error: - goto exit; } diff --git a/src/cg_building.h b/src/cg_building.h @@ -63,6 +63,7 @@ struct data_cad_model0 { struct scad_geometry* roof; struct scad_geometry* slab; struct scad_geometry* cavity; + struct scad_geometry* ground; struct scad_geometry* boundary; struct scad_geometry** connection; size_t n_connection; diff --git a/src/cg_ground.c b/src/cg_ground.c @@ -31,6 +31,8 @@ ground_build_cad res_T res = RES_OK; double origin[3]; double extent[3]; + struct scad_geometry* ground_box = NULL; + struct scad_geometry* boundary = NULL; struct str name; int is_init = 0; @@ -60,13 +62,31 @@ ground_build_cad (str_cget(&name), origin, extent, - &ground->geometry)); - - ERR(scad_scene_partition()); + &ground_box)); + + ERR(scad_fragment_geometries + (NULL, + &ground_box, 1, + ground->footprint, ground->n, + &ground->geometry)); + + ERR(scad_geometry_boundary + (NULL, + &ground->geometry, 1, + &boundary)); + + ERR(scad_cut_geometries + ("B_ground", + &boundary, 1, + ground->footprint, ground->n, + &ground->boundary)); + /* TODO: do something for building with foundation. * without foundation, the mesh is conformal because ground->footprint include * geometry in contact with ground. */ /*ERR(scad_scene_conformal_mesh(ground->scene));*/ + ERR(scad_geometry_delete(ground_box)); + ERR(scad_geometry_delete(boundary)); exit: if (is_init) str_release(&name); @@ -81,7 +101,8 @@ ground_export_stl(const struct ground* ground) { res_T res = RES_OK; - ERR(scad_stl_export(ground->geometry, "ground", 0)); + ERR(scad_stl_export(ground->geometry, "S_ground", 0)); + ERR(scad_stl_export(ground->boundary, "B_ground", 0)); exit: return res; @@ -95,11 +116,7 @@ ground_release(struct ground* ground) { res_T res = RES_OK; - /*if (ground->scene) {ERR(scad_scene_ref_get(ground->scene));}*/ if (ground->footprint) free(ground->footprint); -exit: return res; -error: - goto exit; } diff --git a/src/cg_ground.h b/src/cg_ground.h @@ -33,11 +33,12 @@ struct ground { /* cad representation */ struct scad_scene* scene; struct scad_geometry* geometry; + struct scad_geometry* boundary; struct scad_geometry** footprint; /* list of building footprint */ size_t n; /* number of footprint */ }; -#define GROUND_NULL__ {{0,0,0,0}, 0, NULL, NULL, NULL, 0} +#define GROUND_NULL__ {{0,0,0,0}, 0, NULL, NULL, NULL, NULL, 0} static const struct ground GROUND_NULL = GROUND_NULL__; res_T