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 8e3ef49abe3495f0cc4c1d27dcd50bc2698661c2
parent a3cf8bd1f5f680e8b0c633af69ff63799f14d35d
Author: Benjamin Piaud <benjamin.piaud@meso-star.com>
Date:   Wed, 24 Aug 2022 16:36:57 +0200

Ground parsing and minor modif

Diffstat:
Msrc/cg_args.c | 8++++++--
Msrc/cg_building.c | 63+++++++++++++++++++++++++++++++++++++++++----------------------
Msrc/cg_city.c | 120++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Msrc/cg_city.h | 3+++
Msrc/cg_ground.c | 3+++
Msrc/cg_ground.h | 2++
Msrc/cg_main.c | 2+-
Msrc/cg_parsing.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Msrc/cg_parsing.h | 4++++
9 files changed, 197 insertions(+), 70 deletions(-)

diff --git a/src/cg_args.c b/src/cg_args.c @@ -26,10 +26,14 @@ parse_args(struct logger* logger, int argc, char** argv, struct args* args) { res_T res = RES_OK; int opt = 0; + int is_init1 = 0; + int is_init2 = 0; const char option_list[] = "b:c:"; str_init(NULL, &args->building_model_file); + is_init1 = 1; str_init(NULL, &args->city_model_file); + is_init2 = 1; while((opt = getopt(argc, argv, option_list)) != -1) { switch (opt) { @@ -64,8 +68,8 @@ parse_args(struct logger* logger, int argc, char** argv, struct args* args) exit: return res; error: - str_release(&args->building_model_file); - str_release(&args->city_model_file); + if (is_init1) str_release(&args->building_model_file); + if (is_init2) str_release(&args->city_model_file); goto exit; } diff --git a/src/cg_building.c b/src/cg_building.c @@ -36,6 +36,7 @@ build_slab struct scad_geometry* footprint; double d[3] = {0, 0, 0}; struct str name; + int is_init = 0; id = b->id; model = b->model; @@ -43,6 +44,7 @@ build_slab 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_")); @@ -66,6 +68,7 @@ build_slab slab)); exit: + if (is_init) str_release(&name); return res; error: goto exit; @@ -83,6 +86,7 @@ build_roof(const struct scad_geometry* slab, struct building* b) struct data_model0* data; struct data_cad_model0* data_cad; struct str name; + int is_init = 0; id = b->id; model = b->model; @@ -92,6 +96,7 @@ build_roof(const struct scad_geometry* slab, struct building* b) 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_")); @@ -103,6 +108,7 @@ build_roof(const struct scad_geometry* slab, struct building* b) ERR(scad_geometry_translate(data_cad->roof, d)); exit: + if (is_init) str_release(&name); return res; error: goto exit; @@ -126,6 +132,7 @@ build_wall struct scad_geometry* footprint; double d[3] = {0, 0, 0}; struct str name; + int is_init = 0; id = b->id; model = b->model; @@ -133,6 +140,7 @@ build_wall /*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_")); @@ -174,6 +182,7 @@ build_wall wall)); exit: + if (is_init) str_release(&name); return res; error: goto exit; @@ -191,6 +200,7 @@ build_cavity(const struct pg_polygon* pg, struct building* b) double d[3] = {0, 0, 0}; struct scad_geometry* polygon; struct str name; + int is_init = 0; id = b->id; model = b->model; @@ -200,6 +210,7 @@ build_cavity(const struct pg_polygon* pg, struct building* b) 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_")); @@ -223,6 +234,7 @@ build_cavity(const struct pg_polygon* pg, struct building* b) &data_cad->cavity)); exit: + if (is_init) str_release(&name); return res; error: goto exit; @@ -235,7 +247,8 @@ build_connection(struct building* b) size_t id; enum model model; struct data_cad_model0* data_cad; - struct str slab_name, wall_name, roof_name; + struct str name; + int is_init = 0; id = b->id; model = b->model; @@ -245,54 +258,54 @@ build_connection(struct building* b) data_cad->n_connection = 3; /* cavity/slab connection */ - str_init(NULL, &slab_name); - ERR(str_set(&slab_name, "building_")); - ERR(str_append_printf(&slab_name, "%lu", (unsigned long)id)); - ERR(str_append(&slab_name, "_model_")); - ERR(str_append_printf(&slab_name, "%lu", (unsigned long)model)); - ERR(str_append(&slab_name, "_C_cavity_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, "_C_cavity_slab")); ERR(scad_scene_geometries_common_boundaries (b->scene, - str_cget(&slab_name), + str_cget(&name), data_cad->cavity, data_cad->slab, &data_cad->connection[0], 0)); /* cavity/wall connection */ - str_init(NULL, &wall_name); - ERR(str_set(&wall_name, "building_")); - ERR(str_append_printf(&wall_name, "%lu", (unsigned long)id)); - ERR(str_append(&wall_name, "_model_")); - ERR(str_append_printf(&wall_name, "%lu", (unsigned long)model)); - ERR(str_append(&wall_name, "_C_cavity_wall")); + 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")); ERR(scad_scene_geometries_common_boundaries (b->scene, - str_cget(&wall_name), + str_cget(&name), data_cad->cavity, data_cad->wall, &data_cad->connection[1], 0)); /* cavity/roof connection */ - str_init(NULL, &roof_name); - ERR(str_set(&roof_name, "building_")); - ERR(str_append_printf(&roof_name, "%lu", (unsigned long)id)); - ERR(str_append(&roof_name, "_model_")); - ERR(str_append_printf(&roof_name, "%lu", (unsigned long)model)); - ERR(str_append(&roof_name, "_C_cavity_roof")); + 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")); ERR(scad_scene_geometries_common_boundaries (b->scene, - str_cget(&roof_name), + str_cget(&name), data_cad->cavity, data_cad->roof, &data_cad->connection[2], 0)); exit: + if (is_init) str_release(&name); return res; error: goto exit; @@ -307,6 +320,7 @@ build_boundary(struct building* b) struct data_cad_model0* data_cad; struct scad_geometry** list; struct str name; + int is_init = 0; id = b->id; model = b->model; @@ -319,6 +333,7 @@ build_boundary(struct building* b) list[3] = data_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_")); @@ -335,6 +350,7 @@ build_boundary(struct building* b) exit: if (list) free(list); + if (is_init) str_release(&name); return res; error: goto exit; @@ -414,6 +430,7 @@ build_footprint_model0 enum model model = building->model; size_t id = building->id; struct str name; + int is_init = 0; e_wall = data->wall; @@ -425,6 +442,7 @@ build_footprint_model0 ERR(build_wall(&pg, &pg_int, building, scene, &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_")); @@ -440,6 +458,7 @@ build_footprint_model0 footprint)); exit: + if (is_init) str_release(&name); pg_release(&pg_int); pg_release(&pg_ext); return res; diff --git a/src/cg_city.c b/src/cg_city.c @@ -18,6 +18,7 @@ #include <rsys/text_reader.h> #include <rsys/cstr.h> +#include <rsys/stretchy_array.h> #include "cg_city.h" #include "cg_parsing.h" @@ -29,6 +30,7 @@ city_init(struct logger* logger, struct city* city, struct args* args) struct txtrdr* reader = NULL; char* line = NULL; struct building* building = NULL; + struct building b; struct data_model0 data0, data1; /*struct ground ground;*/ @@ -38,6 +40,7 @@ city_init(struct logger* logger, struct city* city, struct args* args) parse: while (txtrdr_get_line(reader)){ line = txtrdr_get_line(reader); + ERR(strtolower(line, line)); /*if (strcmp(line, "[building]") == 0) {*/ /*parse_building(reader);*/ /*goto parse;*/ @@ -48,48 +51,91 @@ parse: ERR(txtrdr_read_line(reader)); } -#define NBUILD 2 - building = malloc(NBUILD * sizeof(struct building)); - - building[0].id = 0; - building[0].model = MODEL0; - building[0].height = 3; - building[0].polygon_count = 1; - building[0].pg = malloc(building[0].polygon_count * sizeof(struct pg_polygon)); - ERR(pg_init(&building[0].pg[0], 4)); - building[0].pg[0].x[0] = 0; building[0].pg[0].y[0] = 0; - building[0].pg[0].x[1] = 0; building[0].pg[0].y[1] = 10; - building[0].pg[0].x[2] = 10; building[0].pg[0].y[2] = 10; - building[0].pg[0].x[3] = 10; building[0].pg[0].y[3] = 0; - building[0].data = malloc(sizeof(struct data_model0)); + b.id = 0; + b.model = MODEL0; + b.height = 3; + b.polygon_count = 1; + b.pg = malloc(b.polygon_count * sizeof(struct pg_polygon)); + ERR(pg_init(&b.pg[0], 4)); + b.pg[0].x[0] = 0; b.pg[0].y[0] = 0; + b.pg[0].x[1] = 0; b.pg[0].y[1] = 10; + b.pg[0].x[2] = 10; b.pg[0].y[2] = 10; + b.pg[0].x[3] = 10; b.pg[0].y[3] = 0; + b.data = malloc(sizeof(struct data_model0)); data0.wall = 0.2; data0.slab = 0.3; - *(struct data_model0*)(building[0].data) = data0; - building[0].build_cad = &build_cad_model0; - building[0].export_stl = &export_stl_model0; - building[0].release = &release_model0; - building[0].build_footprint = &build_footprint_model0; + *(struct data_model0*)(b.data) = data0; + b.build_cad = &build_cad_model0; + b.export_stl = &export_stl_model0; + b.release = &release_model0; + b.build_footprint = &build_footprint_model0; - building[1].id = 1; - building[1].model = MODEL0; - building[1].height = 3.5; - building[1].polygon_count = 1; - building[1].pg = malloc(building[1].polygon_count * sizeof(struct pg_polygon)); - ERR(pg_init(&building[1].pg[0], 3)); - building[1].pg[0].x[0] = 20; building[1].pg[0].y[0] = 0; - building[1].pg[0].x[1] = 25; building[1].pg[0].y[1] = 10; - building[1].pg[0].x[2] = 30; building[1].pg[0].y[2] = 1; - building[1].data = malloc(sizeof(struct data_model0)); + sa_push(city->building, b); + + b.id = 1; + b.model = MODEL0; + b.height = 3.5; + b.polygon_count = 1; + b.pg = malloc(b.polygon_count * sizeof(struct pg_polygon)); + ERR(pg_init(&b.pg[0], 3)); + b.pg[0].x[0] = 20; b.pg[0].y[0] = 0; + b.pg[0].x[1] = 25; b.pg[0].y[1] = 10; + b.pg[0].x[2] = 30; b.pg[0].y[2] = 1; + b.data = malloc(sizeof(struct data_model0)); data1.wall = 0.15; data1.slab = 0.1; - *(struct data_model0*)(building[1].data) = data1; - building[1].build_cad = &build_cad_model0; - building[1].export_stl = &export_stl_model0; - building[1].release = &release_model0; - building[1].build_footprint = &build_footprint_model0; + *(struct data_model0*)(b.data) = data1; + b.build_cad = &build_cad_model0; + b.export_stl = &export_stl_model0; + b.release = &release_model0; + b.build_footprint = &build_footprint_model0; + + sa_push(city->building, b); + + city->n = sa_size(city->building); + +#define NBUILD 2 + /*building = malloc(NBUILD * sizeof(struct building)); */ + +/* building[0].id = 0;*/ + /*building[0].model = MODEL0;*/ + /*building[0].height = 3;*/ + /*building[0].polygon_count = 1;*/ + /*building[0].pg = malloc(building[0].polygon_count * sizeof(struct pg_polygon));*/ + /*ERR(pg_init(&building[0].pg[0], 4));*/ + /*building[0].pg[0].x[0] = 0; building[0].pg[0].y[0] = 0;*/ + /*building[0].pg[0].x[1] = 0; building[0].pg[0].y[1] = 10;*/ + /*building[0].pg[0].x[2] = 10; building[0].pg[0].y[2] = 10;*/ + /*building[0].pg[0].x[3] = 10; building[0].pg[0].y[3] = 0;*/ + /*building[0].data = malloc(sizeof(struct data_model0));*/ + /*data0.wall = 0.2;*/ + /*data0.slab = 0.3;*/ + /**(struct data_model0*)(building[0].data) = data0;*/ + /*building[0].build_cad = &build_cad_model0;*/ + /*building[0].export_stl = &export_stl_model0;*/ + /*building[0].release = &release_model0;*/ + /*building[0].build_footprint = &build_footprint_model0;*/ + +/* building[1].id = 1;*/ + /*building[1].model = MODEL0;*/ + /*building[1].height = 3.5;*/ + /*building[1].polygon_count = 1;*/ + /*building[1].pg = malloc(building[1].polygon_count * sizeof(struct pg_polygon));*/ + /*ERR(pg_init(&building[1].pg[0], 3));*/ + /*building[1].pg[0].x[0] = 20; building[1].pg[0].y[0] = 0;*/ + /*building[1].pg[0].x[1] = 25; building[1].pg[0].y[1] = 10;*/ + /*building[1].pg[0].x[2] = 30; building[1].pg[0].y[2] = 1;*/ + /*building[1].data = malloc(sizeof(struct data_model0));*/ + /*data1.wall = 0.15;*/ + /*data1.slab = 0.1;*/ + /**(struct data_model0*)(building[1].data) = data1;*/ + /*building[1].build_cad = &build_cad_model0;*/ + /*building[1].export_stl = &export_stl_model0;*/ + /*building[1].release = &release_model0;*/ + /*building[1].build_footprint = &build_footprint_model0;*/ - city->n = NBUILD; - city->building = building; + /*city->n = NBUILD;*/ + /*city->building = building;*/ /*city->ground.extent[0] = -100; */ /*city->ground.extent[1] = 100; */ @@ -124,7 +170,7 @@ city_release(struct city* city) ERR(ground_release(&city->ground)); if (city->scad_device) scad_device_ref_put(city->scad_device); - if (city->building) free(city->building); + if (city->building) sa_release(city->building); exit: return res; diff --git a/src/cg_city.h b/src/cg_city.h @@ -62,6 +62,9 @@ struct city { struct ground ground; }; +#define CITY_NULL__ {NULL, NULL, 0, GROUND_NULL} +static const struct city CITY_NULL = CITY_NULL__; + res_T city_init(struct logger* logger, struct city* city, struct args* arg); diff --git a/src/cg_ground.c b/src/cg_ground.c @@ -29,6 +29,7 @@ ground_build_cad double origin[3]; double extent[3]; struct str name; + int is_init = 0; if (!ground) { res = RES_BAD_ARG; @@ -49,6 +50,7 @@ ground_build_cad } str_init(NULL, &name); + is_init = 1; ERR(str_set(&name, "ground")); ERR(scad_scene_add_box @@ -64,6 +66,7 @@ ground_build_cad ERR(scad_scene_conformal_mesh(ground->scene)); exit: + if (is_init) str_release(&name); return res; error: goto exit; diff --git a/src/cg_ground.h b/src/cg_ground.h @@ -34,6 +34,8 @@ struct ground { size_t n; /* number of footprint */ }; +#define GROUND_NULL__ {{0,0,0,0}, 0, NULL, NULL, NULL, 0} +static const struct ground GROUND_NULL = GROUND_NULL__; res_T ground_build_cad diff --git a/src/cg_main.c b/src/cg_main.c @@ -25,7 +25,7 @@ int main int err = EXIT_SUCCESS; res_T res = RES_OK; struct args args; - struct city city; + struct city city = CITY_NULL; struct logger logger; ERR(logger_init(NULL, &logger)); diff --git a/src/cg_parsing.c b/src/cg_parsing.c @@ -44,6 +44,22 @@ remove_spaces(char *string) return string; } +res_T +strtolower(const char * src, char* dst ) { + res_T res = RES_OK; + + if (!src || !dst) { + res = RES_BAD_ARG; + goto error; + } + + while((*dst++ = (char)tolower(*src++ ))); + +exit: + return res; +error: + goto exit; +} res_T parse_ground @@ -53,28 +69,58 @@ parse_ground { res_T res = RES_OK; char* line = NULL; - char sec[64]; - double depth = 0; ERR(txtrdr_read_line(reader)); while (txtrdr_get_line(reader)){ + double depth = 0; + char* value = NULL; + line = remove_spaces(txtrdr_get_line(reader)); - if (sscanf(line, "DEPTH=%lf", &depth) == 1 ) { + ERR(strtolower(line, line)); + + if (sscanf(line, "depth=%lf", &depth) == 1 ) { ground->depth = depth; } - if (sscanf(line, "EXTENT=%s", sec) == 1 ) { + + value = malloc((1 + strlen(line )) * sizeof(char)); + if (sscanf(line, "extent=%s", value) == 1 ) { size_t sz = 0; - if (cstr_to_list_double(sec, ',', ground->extent, &sz, 4) + if (cstr_to_list_double(value, ',', ground->extent, &sz, 4) != RES_OK || sz != 4) { - logger_print(logger, LOG_ERROR, "[ground] EXTENT value not valid.\n"); + logger_print(logger, LOG_ERROR, + "[ground] extent value not valid: 4 values required.\n"); res = RES_BAD_ARG; + if (value) free(value); goto error; } } - if (sscanf(line, "[%[^]]", sec) == 1 ) goto exit; + if (value) free(value); + + /*if new section goto check and exit*/ + if (sscanf(line, "[%[^]]", value) == 1 ) { + goto check; + } ERR(txtrdr_read_line(reader)); } - + +check: + /*check depth*/ + if (ground->depth <= 0) { + logger_print(logger, LOG_ERROR, + "[ground] depth value not valid: must be > 0.\n"); + res = RES_BAD_ARG; + goto error; + } + + /*check extent*/ + if (ground->extent[0] >= ground->extent[1] + || ground->extent[2] >= ground->extent[3]) { + logger_print(logger, LOG_ERROR, + "[ground] extent value not valid: xmax must be > xmin and ymax must be > ymin.\n"); + res = RES_BAD_ARG; + goto error; + } + exit: return res; error: diff --git a/src/cg_parsing.h b/src/cg_parsing.h @@ -14,6 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <ctype.h> + #include <rsys/rsys.h> #include <rsys/text_reader.h> #include <rsys/logger.h> @@ -23,6 +25,8 @@ #ifndef PARSING_H #define PARSING_H +res_T strtolower(const char * src, char* dst ); + res_T parse_ground (struct logger* logger,