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 56ff2aa6d83f5ba3de571cb1a03e14ce29db1430
parent d7baab343ba21feaf2a60b377cf8a8ac8df605d9
Author: Benjamin Piaud <benjamin.piaud@meso-star.com>
Date:   Thu, 20 Oct 2022 15:35:57 +0200

Modify parsing of polygon building to take in account complex polygons

Diffstat:
Msrc/cg_parsing.c | 106++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 75 insertions(+), 31 deletions(-)

diff --git a/src/cg_parsing.c b/src/cg_parsing.c @@ -73,23 +73,6 @@ static enum model get_enum_value(char * val) { return MODEL_COUNT_; } -static void -get_nverts(const size_t icomp, size_t* nverts, void* context) -{ - (void) icomp; (void)context; - *nverts = 4; -} - -static void -get_pos(const size_t icomp, const size_t ivert, double pos[2], void* context) -{ - const double* polygon = context; - - (void)icomp; - pos[0] = polygon[ivert*2 + 0]; - pos[1] = polygon[ivert*2 + 1]; -} - static res_T parse_ground (struct logger* logger, @@ -155,6 +138,73 @@ error: goto exit; } +struct polygon_context{ + double* pos; + size_t* nvert; + size_t ncomps; +}; + +static void +get_nverts(const size_t icomp, size_t* nverts, void* context) +{ + const struct polygon_context* pg_ctx = context; + *nverts = pg_ctx->nvert[icomp]; +} + +static void +get_pos(const size_t icomp, const size_t ivert, double pos[2], void* context) +{ + const struct polygon_context* pg_ctx = context; + size_t i, begin = 0; + + for (i=0; i<icomp; ++i) { + begin += pg_ctx->nvert[i]*2; + } + pos[0] = pg_ctx->pos[begin + ivert*2 + 0]; + pos[1] = pg_ctx->pos[begin + ivert*2 + 1]; +} + +static res_T +parse_polygon(const char* str, void* data) +{ + res_T res = RES_OK; + struct polygon_context* pg_ctx = data; + double value; + + ERR(cstr_to_double(str, &value)); + + pg_ctx->nvert[pg_ctx->ncomps] += 1; + sa_push(pg_ctx->pos, value); + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_polygon_list(const char* str, void* data) +{ + res_T res = RES_OK; + struct polygon_context* pg_ctx = data; + double* pos = NULL; + + sa_push(pg_ctx->nvert, 0); + ERR(cstr_parse_list(str, ',', parse_polygon, pg_ctx)); + if (pg_ctx->nvert[pg_ctx->ncomps]%2 != 0) { + res = RES_BAD_ARG; + goto error; + } else { + pg_ctx->nvert[pg_ctx->ncomps] /= 2; + } + pg_ctx->ncomps += 1; + +exit: + if (pos) sa_release(pos); + return res; +error: + goto exit; +} static res_T parse_building @@ -185,24 +235,19 @@ parse_building value = malloc(( strlen(line )) * sizeof(char)); if (sscanf(line, "polygon=%s", value) == 1 ) { - size_t sz = 0; - double polygon[8]; - if (cstr_to_list_double(value, ',', polygon, &sz, 8) - != RES_OK || sz != 8) { - logger_print(logger, LOG_ERROR, - "[polygon] extent value not valid: 8 values required.\n"); - res = RES_BAD_ARG; - if (value) free(value); - goto error; - } - + struct polygon_context pg_ctx = {NULL, NULL, 0}; + ERR(scpr_polygon_create(NULL, &building->pg)); + cstr_parse_list(value, ';', parse_polygon_list, &pg_ctx); ERR(scpr_polygon_setup_indexed_vertices( - building->pg, 1, + building->pg, pg_ctx.ncomps, get_nverts, get_pos, - polygon)); + &pg_ctx)); + + sa_release(pg_ctx.pos); + sa_release(pg_ctx.nvert); } if (sscanf(line, "model=%s", value) == 1 ) { @@ -241,7 +286,6 @@ error: goto exit; } - res_T parse_city (struct logger* logger,