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:
| M | src/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,