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 9b26de0f9af9db89ae36523737c1746814a500d0
parent d800c78a978bdc4eaad8679623a9e28c632bf0fa
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 30 Dec 2022 14:57:32 +0100

Improve memory management

Avoid keeping invalid cad data after star-cad finalize/clear calls; replace some allocations by using custom allocator

Diffstat:
Msrc/cg_building.h | 11+++++------
Msrc/cg_city.c | 74++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Msrc/cg_city.h | 11++++++-----
Msrc/cg_constructive_mode_0.c | 79++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/cg_constructive_mode_0.h | 14++++++++++----
Msrc/cg_constructive_mode_1.c | 250++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/cg_constructive_mode_1.h | 14++++++++++----
Msrc/cg_ground.c | 47+++++++++++++++++++++++++++++++++++------------
Msrc/cg_ground.h | 27+++++++++++++++++----------
Msrc/cg_main.c | 15+++------------
10 files changed, 304 insertions(+), 238 deletions(-)

diff --git a/src/cg_building.h b/src/cg_building.h @@ -89,7 +89,6 @@ struct building { /* specific data depending to the constructive mode */ void* data; - void* data_cad; /* functors depending to the constructive mode */ res_T (*init) @@ -98,14 +97,14 @@ struct building { struct parsed_city_building* parsed_data, struct htable_parameter_set* catalog); res_T (*build_cad) - (struct building* building); + (struct building* building, struct mem_allocator* allocator, void** cad); res_T (*build_footprint) - (struct building* building, + (struct building* building, struct mem_allocator* allocator, struct scad_geometry** footprint); res_T (*export_stl) - (const struct building* building, const int binary); - res_T (*release) - (struct building* building); + (void* cad, const int binary); + res_T (*release_cad) + (struct mem_allocator* allocator, void* cad); }; #endif /* BUILDING_H */ diff --git a/src/cg_city.c b/src/cg_city.c @@ -20,6 +20,7 @@ #include "cg.h" #include "cg_city.h" #include "cg_constructive_mode_0.h" +#include "cg_ground.h" #include "cg_parsing.h" #include "cg_city_parsing.h" #include "cg_building.h" @@ -33,6 +34,8 @@ #include <rsys/stretchy_array.h> #include <rsys/double4.h> +#include <star/scpr.h> + #include <string.h> res_T @@ -66,10 +69,12 @@ city_create } city->allocator = allocator; + city->logger = logger; + city->verbosisty_level = args->verbosity_level; city->binary_export = args->binary_export; - city->ground.depth = parsed_city->ground.depth; - d4_set(city->ground.extent, parsed_city->ground.extent); + city->ground_depth = parsed_city->ground.depth; + d4_set(city->ground_extent, parsed_city->ground.extent); /* create buildings depending on their constructive modes */ for (i = 0; i < city->buildings_count ; ++i) { @@ -105,10 +110,15 @@ city_release(struct city* city) /* iterate on building */ for (i=0; i<city->buildings_count; ++i) { - ERR(city->buildings[i].release(&city->buildings[i])); - } + struct building* building = city->buildings + i; - ERR(ground_release(&city->ground)); + ERR(scpr_polygon_ref_put(building->pg)); + + if(building->names_initialized) { + str_release(&building->name); + str_release(&building->dataset_name); + } + } MEM_RM(city->allocator, city->buildings); MEM_RM(city->allocator, city); @@ -120,54 +130,70 @@ error: } res_T -city_cad_build(struct logger* logger, struct city* city) +city_cad_build(struct city* city) { res_T res = RES_OK; + struct scad_options options = SCAD_DEFAULT_OPTIONS__; + int scad_initialized = 0; size_t i; - (void)logger; - /* iterate on building */ + /* Initialize star-cad */ + ERR(scad_initialize(city->logger, city->allocator, city->verbosisty_level)); + scad_initialized = 1; + options.Mesh.MeshSizeFromPoints = 0; + ERR(scad_set_options(&options)); + + /* iterate on buildings */ for(i=0; i<city->buildings_count; ++i) { struct building* building = city->buildings + i; + struct data_cad_cmode_0* cad = NULL; /* create building */ - ERR(building->build_cad(building)); + ERR(building->build_cad(building, city->allocator, (void**)&cad)); ERR(scad_scene_mesh()); - ERR(building->export_stl(building, city->binary_export)); + ERR(building->export_stl(cad, city->binary_export)); + ERR(building->release_cad(city->allocator, cad)); + ERR(scad_scene_clear()); } exit: + if(scad_initialized) CHK(RES_OK == scad_finalize()); return res; error: goto exit; } res_T -city_ground_build(struct logger* logger, struct city* city) +city_ground_build(struct city* city) { res_T res = RES_OK; + struct scad_options options = SCAD_DEFAULT_OPTIONS__; + int scad_initialized = 0; + struct ground ground = GROUND_NULL__; size_t i; - (void)logger; - city->ground.footprints_count = city->buildings_count; - city->ground.footprint - = malloc(city->ground.footprints_count * sizeof(*city->ground.footprint)); - if(!city->ground.footprint) { - res = RES_MEM_ERR; - goto error; - } + ERR(ground_allocate(city->allocator, city->buildings_count, &ground)); + + /* Initialize star-cad */ + ERR(scad_initialize(city->logger, city->allocator, city->verbosisty_level)); + scad_initialized = 1; + options.Mesh.MeshSizeFromPoints = 0; + ERR(scad_set_options(&options)); - for(i = 0; i < city->ground.footprints_count ; ++i) { + /* iterate on buildings */ + for(i = 0; i < ground.footprints_count ; ++i) { struct building* building = city->buildings + i; - struct scad_geometry** footprint = city->ground.footprint + i; + struct scad_geometry** footprint = ground.footprints + i; /* create building footprint */ - ERR(building->build_footprint(building, footprint)); + ERR(building->build_footprint(building, city->allocator, footprint)); } - ERR(ground_build_cad(&city->ground)); + ERR(ground_build_cad(city, &ground)); ERR(scad_scene_mesh()); - ERR(ground_export_stl(&city->ground, city->binary_export)); + ERR(ground_export_stl(&ground, city->binary_export)); exit: + ground_release(city->allocator, &ground); + if(scad_initialized) CHK(RES_OK == scad_finalize()); return res; error: goto exit; diff --git a/src/cg_city.h b/src/cg_city.h @@ -60,12 +60,15 @@ log_err_fn(const char* msg, void* ctx) } struct city { + double ground_extent[4]; /* [xmin, xmax, ymin, ymax */ + double ground_depth; struct building* buildings; /* list of buildings */ size_t buildings_count; - struct ground ground; int binary_export; struct mem_allocator* allocator; + struct logger* logger; + int verbosisty_level; }; res_T @@ -78,13 +81,11 @@ city_create res_T city_cad_build - (struct logger* logger, - struct city* city); + (struct city* city); res_T city_ground_build - (struct logger* logger, - struct city* city); + (struct city* city); res_T city_release(struct city* city); diff --git a/src/cg_constructive_mode_0.c b/src/cg_constructive_mode_0.c @@ -26,7 +26,6 @@ #include <rsys/rsys.h> #include <rsys/str.h> #include <star/scad.h> -#include <star/scpr.h> static res_T build_floor_footprint @@ -77,7 +76,7 @@ build_floor ERR(scad_geometry_extrude(footprint, floorname, d, floor)); exit: - scad_geometry_delete(footprint); + SCAD(geometry_delete(footprint)); if (is_init) str_release(&name); return res; error: @@ -143,8 +142,8 @@ build_wall_footprint ERR(scad_cut_geometries(NULL, &polygon, 1, &polygon_int, 1, footprint)); exit: - if(polygon) scad_geometry_delete(polygon); - if(polygon_int) scad_geometry_delete(polygon_int); + if(polygon) SCAD(geometry_delete(polygon)); + if(polygon_int) SCAD(geometry_delete(polygon_int)); return res; error: goto exit; @@ -182,7 +181,7 @@ build_wall ERR(scad_geometry_extrude(footprint, wallname, d, wall)); exit: - if(footprint) scad_geometry_delete(footprint); + if(footprint) SCAD(geometry_delete(footprint)); if (is_init) str_release(&name); return res; error: @@ -225,7 +224,7 @@ build_cavity ERR(scad_geometry_extrude(polygon, cavityname, d, cavity)); exit: - if(polygon) scad_geometry_delete(polygon); + if(polygon) SCAD(geometry_delete(polygon)); if (is_init) str_release(&name); return res; error: @@ -235,6 +234,7 @@ error: static res_T build_connection (const char* prefix, + struct mem_allocator* allocator, struct data_cad_cmode_0* cad) { res_T res = RES_OK; @@ -242,7 +242,7 @@ build_connection struct str name; int is_init = 0; - cad->connection = malloc(3 * sizeof(struct scad_geometry*)); + cad->connection = MEM_CALLOC(allocator, 3, sizeof(struct scad_geometry*)); if(!cad->connection) { res = RES_MEM_ERR; goto error; @@ -300,17 +300,17 @@ error: static res_T build_boundary (const char* prefix, + struct mem_allocator* allocator, struct data_cad_cmode_0* cad) { res_T res = RES_OK; struct scad_geometry** list = NULL; struct scad_geometry* boundary = NULL; - /*struct scad_geometry* footprint = NULL;*/ char* cname = NULL; struct str name; int is_init = 0; - list = malloc(4 * sizeof(struct scad_geometry*)); + list = MEM_ALLOC(allocator, 4 * sizeof(struct scad_geometry*)); if(!list) { res = RES_MEM_ERR; goto error; @@ -334,9 +334,8 @@ build_boundary &cad->boundary)); exit: - if(boundary) scad_geometry_delete(boundary); - /*if(footprint) scad_geometry_delete(footprint);*/ - if (list) free(list); + if(boundary) SCAD(geometry_delete(boundary)); + MEM_RM(allocator, list); if (is_init) str_release(&name); return res; error: @@ -352,7 +351,7 @@ building_ground_connection { res_T res = RES_OK; struct scpr_polygon* pg_int = NULL; - struct scad_geometry* geom[2]; + struct scad_geometry* geom[2] = { NULL, NULL }; char* cname = NULL; struct str name; int is_init = 0; @@ -375,9 +374,9 @@ building_ground_connection exit: if(is_init) str_release(&name); - if(geom[0]) scad_geometry_delete(geom[0]); - if(geom[1]) scad_geometry_delete(geom[1]); - if(pg_int) scpr_polygon_ref_put(pg_int); + if(geom[0]) SCAD(geometry_delete(geom[0])); + if(geom[1]) SCAD(geometry_delete(geom[1])); + if(pg_int) SCPR(polygon_ref_put(pg_int)); return res; error: goto exit; @@ -401,7 +400,7 @@ init_model0 building->init = &init_model0; building->build_cad = &build_cad_model0; building->export_stl = &export_stl_model0; - building->release = &release_model0; + building->release_cad = &release_cad_model0; building->build_footprint = &build_footprint_model0; building->constructive_mode = mode_0; @@ -437,14 +436,17 @@ error: } res_T -build_cad_model0(struct building* building) +build_cad_model0 + (struct building* building, + struct mem_allocator* allocator, + void** cad) { res_T res = RES_OK; double height = building->height; struct scpr_polygon* pg = building->pg; struct scpr_polygon* pg_int = NULL; struct data_set_cmode_0* data = (struct data_set_cmode_0 *)building->data; - struct data_cad_cmode_0* data_cad; + struct data_cad_cmode_0* data_cad = NULL; double e_wall; const char* name; @@ -458,12 +460,11 @@ build_cad_model0(struct building* building) goto error; } - data_cad = calloc(1, sizeof(struct data_cad_cmode_0)); + data_cad = MEM_CALLOC(allocator, 1, sizeof(struct data_cad_cmode_0)); if(!data_cad) { res = RES_MEM_ERR; goto error; } - building->data_cad = (struct data_cad_cmode_0*)data_cad; e_wall = data->wall; ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); @@ -488,27 +489,32 @@ build_cad_model0(struct building* building) ERR(building_ground_connection(name, pg, e_wall, &data_cad->ground_connection)); /* build boundary */ - ERR(build_boundary(name, building->data_cad)); + ERR(build_boundary(name, allocator, data_cad)); /* build cavity/floor connectiona*/ - ERR(build_connection(name, building->data_cad)); + ERR(build_connection(name, allocator, data_cad)); exit: - if(pg_int) scpr_polygon_ref_put(pg_int); + if(pg_int) SCPR(polygon_ref_put(pg_int)); + *(struct data_cad_cmode_0**)cad = data_cad; return res; error: + CHK(RES_OK == release_cad_model0(allocator, data_cad)); + data_cad = NULL; goto exit; } res_T build_footprint_model0 (struct building* building, + struct mem_allocator* allocator, struct scad_geometry** footprint) { res_T res = RES_OK; struct scpr_polygon* pg = building->pg; struct data_set_cmode_0* data = (struct data_set_cmode_0 *)building->data; double e_wall; + (void)allocator; e_wall = data->wall; @@ -522,10 +528,10 @@ error: res_T export_stl_model0 - (const struct building* building, const int binary) + (void* cad, const int binary) { res_T res = RES_OK; - struct data_cad_cmode_0* data_cad = (struct data_cad_cmode_0 *)building->data_cad; + struct data_cad_cmode_0* data_cad = (struct data_cad_cmode_0*)cad; size_t i; /* floor export */ @@ -558,26 +564,21 @@ error: } res_T -release_model0 - (struct building* building) +release_cad_model0 + (struct mem_allocator* allocator, + void* cad) { res_T res = RES_OK; - struct data_cad_cmode_0* data_cad = (struct data_cad_cmode_0 *)building->data_cad; - - scpr_polygon_ref_put(building->pg); + struct data_cad_cmode_0* data_cad = (struct data_cad_cmode_0 *)cad; - if(building->names_initialized) { - str_release(&building->name); - str_release(&building->dataset_name); - } if(data_cad) { size_t i; - if(data_cad->boundary) scad_geometry_delete(data_cad->boundary); + if(data_cad->boundary) SCAD(geometry_delete(data_cad->boundary)); for(i = 0; i < data_cad->n_connection; i++) { - scad_geometry_delete(data_cad->connection[i]); + SCAD(geometry_delete(data_cad->connection[i])); } - free(data_cad->connection); - free(data_cad); + MEM_RM(allocator, data_cad->connection); + MEM_RM(allocator, data_cad); } return res; diff --git a/src/cg_constructive_mode_0.h b/src/cg_constructive_mode_0.h @@ -55,19 +55,25 @@ init_model0 struct htable_parameter_set* catalog); res_T -build_cad_model0(struct building* building); +build_cad_model0 + (struct building* building, + struct mem_allocator* allocator, + void** cad); res_T build_footprint_model0 (struct building* building, + struct mem_allocator* allocator, struct scad_geometry** footprint); res_T export_stl_model0 - (const struct building* building, const int binary); + (void* cad, + const int binary); res_T -release_model0 - (struct building* building); +release_cad_model0 + (struct mem_allocator* allocator, + void* cad); #endif /* CONSTRUCTIVE_MODE_0_H */ diff --git a/src/cg_constructive_mode_1.c b/src/cg_constructive_mode_1.c @@ -21,6 +21,7 @@ #include "cg_building.h" #include "cg_city_parsing_schemas.h" #include "cg_constructive_mode.h" +#include "cg_constructive_mode_1.h" #include <rsys/str.h> #include <rsys/stretchy_array.h> @@ -30,6 +31,7 @@ static res_T build_floor (const char* prefix, + struct mem_allocator* allocator, const struct scpr_polygon* pg, const struct data_set_cmode_1* data, struct scad_geometry** floor) @@ -53,7 +55,7 @@ build_floor } if (prefix) { - str_init(NULL, &name); + str_init(allocator, &name); is_init = 1; ERR(str_set(&name, prefix)); ERR(str_append(&name, "_floor")); @@ -72,9 +74,9 @@ build_floor ERR(scad_geometry_extrude(footprint, floorname, d, floor)); exit: - scad_geometry_delete(footprint); + SCAD(geometry_delete(footprint)); if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); + if (pg_int) SCPR(polygon_ref_put(pg_int)); return res; error: goto exit; @@ -84,6 +86,7 @@ static res_T build_wall (const char* prefix, const char* suffix, + struct mem_allocator* allocator, const struct scpr_polygon* pg, const double height, const struct data_set_cmode_1* data, @@ -110,7 +113,7 @@ build_wall } if (prefix) { - str_init(NULL, &name); + str_init(allocator, &name); is_init = 1; ERR(str_set(&name, prefix)); if (suffix) { @@ -144,12 +147,12 @@ build_wall ERR(scad_geometry_extrude(footprint, wallname, d, wall)); exit: - scad_geometry_delete(footprint); - scad_geometry_delete(footprint_int); - scad_geometry_delete(footprint_ext); + SCAD(geometry_delete(footprint)); + SCAD(geometry_delete(footprint_int)); + SCAD(geometry_delete(footprint_ext)); if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); - if (pg_ext) scpr_polygon_ref_put(pg_ext); + if (pg_int) SCPR(polygon_ref_put(pg_int)); + if (pg_ext) SCPR(polygon_ref_put(pg_ext)); return res; error: goto exit; @@ -158,6 +161,7 @@ error: static res_T build_int_insulation (const char* prefix, + struct mem_allocator* allocator, const struct scpr_polygon* pg, const double height, const struct data_set_cmode_1* data, @@ -190,7 +194,7 @@ build_int_insulation } if (prefix) { - str_init(NULL, &name); + str_init(allocator, &name); is_init = 1; ERR(str_set(&name, prefix)); ERR(str_append(&name, "_int_insulation")); @@ -229,13 +233,13 @@ build_int_insulation exit: - scad_geometry_delete(footprint); - scad_geometry_delete(footprint_int); - scad_geometry_delete(footprint_ext); - scad_geometry_delete(geom); + SCAD(geometry_delete(footprint)); + SCAD(geometry_delete(footprint_int)); + SCAD(geometry_delete(footprint_ext)); + SCAD(geometry_delete(geom)); if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); - if (pg_ext) scpr_polygon_ref_put(pg_ext); + if (pg_int) SCPR(polygon_ref_put(pg_int)); + if (pg_ext) SCPR(polygon_ref_put(pg_ext)); return res; error: goto exit; @@ -244,6 +248,7 @@ error: static res_T build_roof (const char* prefix, + struct mem_allocator* allocator, const struct scpr_polygon* pg, const double height, const struct data_set_cmode_1* data, @@ -269,7 +274,7 @@ build_roof } if (prefix) { - str_init(NULL, &name); + str_init(allocator, &name); is_init = 1; ERR(str_set(&name, prefix)); ERR(str_append(&name, "_roof")); @@ -289,9 +294,9 @@ build_roof ERR(scad_geometry_extrude(footprint, roofname, d, roof)); exit: - scad_geometry_delete(footprint); + SCAD(geometry_delete(footprint)); if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); + if (pg_int) SCPR(polygon_ref_put(pg_int)); return res; error: goto exit; @@ -300,6 +305,7 @@ error: static res_T build_roof_insulation (const char* prefix, + struct mem_allocator* allocator, const struct scpr_polygon* pg, const double height, const struct data_set_cmode_1* data, @@ -327,7 +333,7 @@ build_roof_insulation } if (prefix) { - str_init(NULL, &name); + str_init(allocator, &name); is_init = 1; ERR(str_set(&name, prefix)); ERR(str_append(&name, "_roof_insulation")); @@ -348,9 +354,9 @@ build_roof_insulation ERR(scad_geometry_extrude(footprint, insulationname, d, insulation)); exit: - scad_geometry_delete(footprint); + SCAD(geometry_delete(footprint)); if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); + if (pg_int) SCPR(polygon_ref_put(pg_int)); return res; error: goto exit; @@ -359,6 +365,7 @@ error: static res_T build_floor_insulation (const char* prefix, + struct mem_allocator* allocator, const struct scpr_polygon* pg, const struct data_set_cmode_1* data, struct scad_geometry** insulation) @@ -384,7 +391,7 @@ build_floor_insulation } if (prefix) { - str_init(NULL, &name); + str_init(allocator, &name); is_init = 1; ERR(str_set(&name, prefix)); ERR(str_append(&name, "_floor_insulation")); @@ -405,9 +412,9 @@ build_floor_insulation ERR(scad_geometry_extrude(footprint, insulationname, d, insulation)); exit: - scad_geometry_delete(footprint); + SCAD(geometry_delete(footprint)); if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); + if (pg_int) SCPR(polygon_ref_put(pg_int)); return res; error: goto exit; @@ -415,6 +422,7 @@ error: static res_T build_inter_floor (const char* prefix, + struct mem_allocator* allocator, const struct scpr_polygon* pg, const double height, const struct data_set_cmode_1* data, @@ -446,7 +454,7 @@ build_inter_floor } if (prefix) { - str_init(NULL, &name); + str_init(allocator, &name); is_init = 1; ERR(str_set(&name, prefix)); ERR(str_append(&name, "_inter_floor")); @@ -481,10 +489,10 @@ build_inter_floor exit: if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); + if (pg_int) SCPR(polygon_ref_put(pg_int)); if (floor_list) { for (i=0; i< floor_n; ++i) { - scad_geometry_delete(floor_list[i]); + SCAD(geometry_delete(floor_list[i])); } sa_release(floor_list); } @@ -495,6 +503,7 @@ error: static res_T build_ext_insulation (const char* prefix, + struct mem_allocator* allocator, const struct scpr_polygon* pg, const double height, const struct data_set_cmode_1* data, @@ -520,7 +529,7 @@ build_ext_insulation } if (prefix) { - str_init(NULL, &name); + str_init(allocator, &name); is_init = 1; ERR(str_set(&name, prefix)); ERR(str_append(&name, "_ext_insulation")); @@ -548,12 +557,12 @@ build_ext_insulation ERR(scad_geometry_extrude(footprint, insulationname, d, insulation)); exit: - scad_geometry_delete(footprint); - scad_geometry_delete(footprint_int); - scad_geometry_delete(footprint_ext); + SCAD(geometry_delete(footprint)); + SCAD(geometry_delete(footprint_int)); + SCAD(geometry_delete(footprint_ext)); if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); - if (pg_ext) scpr_polygon_ref_put(pg_ext); + if (pg_int) SCPR(polygon_ref_put(pg_int)); + if (pg_ext) SCPR(polygon_ref_put(pg_ext)); return res; error: goto exit; @@ -562,6 +571,7 @@ error: static res_T build_crawlspace (const char* prefix, + struct mem_allocator* allocator, const struct scpr_polygon* pg, const struct data_set_cmode_1* data, struct scad_geometry** crawlspace) @@ -588,7 +598,7 @@ build_crawlspace } if (prefix) { - str_init(NULL, &name); + str_init(allocator, &name); is_init = 1; ERR(str_set(&name, prefix)); ERR(str_append(&name, "_crawlspace")); @@ -609,9 +619,9 @@ build_crawlspace ERR(scad_geometry_extrude(footprint, crawlname, d, crawlspace)); exit: - scad_geometry_delete(footprint); + SCAD(geometry_delete(footprint)); if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); + if (pg_int) SCPR(polygon_ref_put(pg_int)); return res; error: goto exit; @@ -620,6 +630,7 @@ error: static res_T build_habitable (const char* prefix, + struct mem_allocator* allocator, const struct scpr_polygon* pg, const double height, const struct data_set_cmode_1* data, @@ -649,7 +660,7 @@ build_habitable } if (prefix) { - str_init(NULL, &name); + str_init(allocator, &name); is_init = 1; ERR(str_set(&name, prefix)); ERR(str_append(&name, "_cavity")); @@ -675,10 +686,10 @@ build_habitable } exit: - scad_geometry_delete(footprint); - scad_geometry_delete(geom); + SCAD(geometry_delete(footprint)); + SCAD(geometry_delete(geom)); if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); + if (pg_int) SCPR(polygon_ref_put(pg_int)); return res; error: goto exit; @@ -687,6 +698,7 @@ error: static res_T build_attic (const char* prefix, + struct mem_allocator* allocator, const struct scpr_polygon* pg, const double height, const struct data_set_cmode_1* data, @@ -713,7 +725,7 @@ build_attic } if (prefix) { - str_init(NULL, &name); + str_init(allocator, &name); is_init = 1; ERR(str_set(&name, prefix)); ERR(str_append(&name, "_attic")); @@ -734,9 +746,9 @@ build_attic ERR(scad_geometry_extrude(footprint, atticname, d, attic)); exit: - scad_geometry_delete(footprint); + SCAD(geometry_delete(footprint)); if (is_init) str_release(&name); - if (pg_int) scpr_polygon_ref_put(pg_int); + if (pg_int) SCPR(polygon_ref_put(pg_int)); return res; error: goto exit; @@ -744,9 +756,10 @@ error: static res_T build_windows - (const char* prefix, - const struct data_set_cmode_1* data, - struct data_cad_cmode_1* data_cad) + (const char* prefix, + struct mem_allocator* allocator, + const struct data_set_cmode_1* data, + struct data_cad_cmode_1* data_cad) { res_T res = RES_OK; size_t i = 0; @@ -840,7 +853,7 @@ build_windows /* build glass */ if (prefix) { - str_init(NULL, &gname); + str_init(allocator, &gname); is_init = 1; ERR(str_set(&gname, prefix)); ERR(str_append(&gname, "_glass")); @@ -851,22 +864,20 @@ build_windows exit: for (i=0 ; i<list_n; ++i) { - scad_geometry_delete(list[i]); + SCAD(geometry_delete(list[i])); } for (i=0 ; i<sa_size(hole_list); ++i) { - scad_geometry_delete(hole_list[i]); + SCAD(geometry_delete(hole_list[i])); } for (i=0 ; i<sa_size(glass_list); ++i) { - scad_geometry_delete(glass_list[i]); + SCAD(geometry_delete(glass_list[i])); } if (hole_list) sa_release(hole_list); if (glass_list) sa_release(glass_list); - if (surface) scad_geometry_delete(surface); - if (geom) scad_geometry_delete(geom); - if (bcavity) scad_geometry_delete(bcavity); - /*scad_synchronize();*/ - if (name) free(name); - if (list) free(list); + if (surface) SCAD(geometry_delete(surface)); + if (geom) SCAD(geometry_delete(geom)); + if (bcavity) SCAD(geometry_delete(bcavity)); + MEM_RM(allocator, list); if (is_init) str_release(&gname); return res; error: @@ -876,6 +887,7 @@ error: static res_T build_boundary (const char* prefix, + struct mem_allocator* allocator, struct data_cad_cmode_1* data_cad, struct scad_geometry*** boundary) { @@ -891,7 +903,7 @@ build_boundary goto error; } - str_init(NULL, &name); + str_init(allocator, &name); is_init = 1; sa_push(list, data_cad->wall); @@ -964,6 +976,7 @@ error: static res_T build_connection (const char* prefix, + struct mem_allocator* allocator, struct data_cad_cmode_1* data_cad, struct scad_geometry*** connection) { @@ -979,7 +992,7 @@ build_connection goto error; } - str_init(NULL, &name); + str_init(allocator, &name); is_init = 1; #define CREATE_CONNECT(G1,G2,SUFFIX) ERR(str_set(&name, prefix));\ @@ -1126,10 +1139,10 @@ build_fake_ground ERR(scad_cut_geometries(NULL, &geom, 1, list, sa_size(list), ground)); exit: - if (pg_offset) scpr_polygon_ref_put(pg_offset); + if (pg_offset) SCPR(polygon_ref_put(pg_offset)); if (list) sa_release(list); - if (footprint) scad_geometry_delete(footprint); - if (geom) scad_geometry_delete(geom); + if (footprint) SCAD(geometry_delete(footprint)); + if (geom) SCAD(geometry_delete(geom)); return res; error: goto exit; @@ -1139,6 +1152,7 @@ error: static res_T building_ground_connection (const char* prefix, + struct mem_allocator* allocator, struct data_cad_cmode_1* cad, struct scad_geometry** connection) { @@ -1155,7 +1169,7 @@ building_ground_connection goto error; } - str_init(NULL, &name); + str_init(allocator, &name); is_init = 1; ERR(str_set(&name, prefix)); ERR(str_append(&name, "_C_building_ground")); @@ -1175,8 +1189,8 @@ building_ground_connection exit: if (list) sa_release(list); if (is_init) str_release(&name); - if (list_boundary) scad_geometry_delete(list_boundary); - if (footprint) scad_geometry_delete(footprint); + if (list_boundary) SCAD(geometry_delete(list_boundary)); + if (footprint) SCAD(geometry_delete(footprint)); return res; error: goto exit; @@ -1200,7 +1214,7 @@ init_model1 building->init = &init_model1; building->build_cad = &build_cad_model1; building->export_stl = &export_stl_model1; - building->release = &release_model1; + building->release_cad = &release_cad_model1; building->build_footprint = &build_footprint_model1; building->constructive_mode = mode_1; @@ -1236,13 +1250,16 @@ error: } res_T -build_cad_model1(struct building* building) +build_cad_model1 + (struct building* building, + struct mem_allocator* allocator, + void** cad) { res_T res = RES_OK; double height = building->height; struct scpr_polygon* pg = building->pg; struct data_set_cmode_1* data = (struct data_set_cmode_1 *)building->data; - struct data_cad_cmode_1* data_cad; + struct data_cad_cmode_1* data_cad = NULL; const char* name; if (!building) { @@ -1250,12 +1267,11 @@ build_cad_model1(struct building* building) goto error; } - data_cad = calloc(1, sizeof(struct data_cad_cmode_1)); + data_cad = MEM_CALLOC(allocator, 1, sizeof(struct data_cad_cmode_1)); if(!data_cad) { res = RES_MEM_ERR; goto error; } - building->data_cad = (struct data_cad_cmode_1*)data_cad; /* build mandatories elements : - floor @@ -1264,11 +1280,11 @@ build_cad_model1(struct building* building) */ name = str_cget(&building->name); - ERR(build_floor(name, pg, data, &data_cad->floor)); + ERR(build_floor(name, allocator, pg, data, &data_cad->floor)); - ERR(build_wall(name, "wall", pg, height, data, &data_cad->wall)); + ERR(build_wall(name, "wall", allocator, pg, height, data, &data_cad->wall)); - ERR(build_roof(name, pg, height, data, &data_cad->roof)); + ERR(build_roof(name, allocator, pg, height, data, &data_cad->roof)); /* build optionnal elements : - foundation @@ -1281,40 +1297,33 @@ build_cad_model1(struct building* building) if (data->foundation > 0) { double depth = -data->foundation; - ERR(build_wall(name, "foundation", pg, depth, data, &data_cad->foundation)); - } else { - data_cad->foundation = NULL; + ERR(build_wall(name, "foundation", allocator, pg, depth, data, + &data_cad->foundation)); } if (data->inter_floor_n > 0) { - ERR(build_inter_floor(name, pg, height, data, &data_cad->intermediate_floor)); - } else { - data_cad->intermediate_floor = NULL; + ERR(build_inter_floor(name, allocator, pg, height, data, + &data_cad->intermediate_floor)); } if (data->ext_insulation > 0) { - ERR(build_ext_insulation(name, pg, height, data, &data_cad->external_insulation)); - } else { - data_cad->external_insulation = NULL; + ERR(build_ext_insulation(name, allocator, pg, height, data, + &data_cad->external_insulation)); } if (data->int_insulation > 0) { - ERR(build_int_insulation(name, pg, height, data, data_cad->intermediate_floor, - &data_cad->internal_insulation)); - } else { - data_cad->internal_insulation = NULL; + ERR(build_int_insulation(name, allocator, pg, height, data, + data_cad->intermediate_floor, &data_cad->internal_insulation)); } if (data->roof_insulation > 0) { - ERR(build_roof_insulation(name, pg, height, data, &data_cad->roof_insulation)); - } else { - data_cad->roof_insulation = NULL; + ERR(build_roof_insulation(name, allocator, pg, height, data, + &data_cad->roof_insulation)); } if (data->floor_insulation > 0) { - ERR(build_floor_insulation(name, pg, data, &data_cad->floor_insulation)); - } else { - data_cad->floor_insulation = NULL; + ERR(build_floor_insulation(name, allocator, pg, data, + &data_cad->floor_insulation)); } /* build cavities : @@ -1324,23 +1333,19 @@ build_cad_model1(struct building* building) */ if (data->attic > 0) { - ERR(build_attic(name, pg, height, data, &data_cad->attic_cavity)); - } else { - data_cad->attic_cavity = NULL; + ERR(build_attic(name, allocator, pg, height, data, &data_cad->attic_cavity)); } - ERR(build_habitable(name, pg, height, data, data_cad->intermediate_floor, - &data_cad->habitable_cavity)); + ERR(build_habitable(name, allocator, pg, height, data, + data_cad->intermediate_floor, &data_cad->habitable_cavity)); if (data->crawl > 0) { - ERR(build_crawlspace(name, pg, data, &data_cad->crawlspace_cavity)); - } else { - data_cad->crawlspace_cavity = NULL; + ERR(build_crawlspace(name, allocator, pg, data, &data_cad->crawlspace_cavity)); } /* windows */ if (data->glass_ratio > 0) { - ERR(build_windows(name, data, data_cad)); + ERR(build_windows(name, allocator, data, data_cad)); } /* fake ground */ @@ -1349,29 +1354,33 @@ build_cad_model1(struct building* building) ERR(scad_scene_partition()); /* build ground/buildind connection */ - ERR(building_ground_connection(name, data_cad, &data_cad->ground_connection)); + ERR(building_ground_connection(name, allocator, data_cad, + &data_cad->ground_connection)); /* build boundaries */ - data_cad->boundary = NULL; - ERR(build_boundary(name, data_cad, &data_cad->boundary)); + ERR(build_boundary(name, allocator, data_cad, &data_cad->boundary)); /* build connections */ - data_cad->connection = NULL; - ERR(build_connection(name, data_cad, &data_cad->connection)); + ERR(build_connection(name, allocator, data_cad, &data_cad->connection)); exit: + *(struct data_cad_cmode_1**)cad = data_cad; return res; error: + CHK(RES_OK == release_cad_model1(allocator, data_cad)); + data_cad = NULL; goto exit; } res_T build_footprint_model1 (struct building* building, + struct mem_allocator* allocator, struct scad_geometry** footprint) { res_T res = RES_OK; struct scpr_polygon* pg = building->pg; + (void)allocator; if (!building || !footprint) { res = RES_BAD_ARG; @@ -1388,10 +1397,10 @@ error: res_T export_stl_model1 - (const struct building* building, const int binary) + (void* cad, const int binary) { res_T res = RES_OK; - struct data_cad_cmode_1* data_cad = (struct data_cad_cmode_1 *)building->data_cad; + struct data_cad_cmode_1* data_cad = (struct data_cad_cmode_1 *)cad; size_t i = 0; /* floor export */ @@ -1471,31 +1480,28 @@ error: } res_T -release_model1 - (struct building* building) +release_cad_model1 + (struct mem_allocator* allocator, + void* cad) { res_T res = RES_OK; - struct data_cad_cmode_1* data_cad = (struct data_cad_cmode_1 *)building->data_cad; - - scpr_polygon_ref_put(building->pg); - - if(building->names_initialized) { - str_release(&building->name); - str_release(&building->dataset_name); - } + struct data_cad_cmode_1* data_cad = (struct data_cad_cmode_1 *)cad; if(data_cad) { size_t i; for(i = 0; i < sa_size(data_cad->boundary); i++) { - scad_geometry_delete(data_cad->boundary[i]); + ERR(scad_geometry_delete(data_cad->boundary[i])); } - for(i = 0; i < data_cad->n_connection; i++) { - scad_geometry_delete(data_cad->connection[i]); + for(i = 0; i < sa_size(data_cad->connection); i++) { + ERR(scad_geometry_delete(data_cad->connection[i])); } sa_release(data_cad->boundary); sa_release(data_cad->connection); - free(data_cad); + MEM_RM(allocator, data_cad); } +exit: return res; +error: + goto exit; } diff --git a/src/cg_constructive_mode_1.h b/src/cg_constructive_mode_1.h @@ -76,19 +76,25 @@ init_model1 struct htable_parameter_set* catalog); res_T -build_cad_model1(struct building* building); +build_cad_model1 + (struct building* building, + struct mem_allocator* allocator, + void** cad); res_T build_footprint_model1 (struct building* building, + struct mem_allocator* allocator, struct scad_geometry** footprint); res_T export_stl_model1 - (const struct building* building, const int binary); + (void* cad, + const int binary); res_T -release_model1 - (struct building* building); +release_cad_model1 + (struct mem_allocator* allocator, + void* cad); #endif /* CONSTRUCTIVE_MODE_1_H */ diff --git a/src/cg_ground.c b/src/cg_ground.c @@ -18,6 +18,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "cg_ground.h" +#include "cg_city.h" #include "cg.h" #include <rsys/str.h> @@ -25,7 +26,8 @@ res_T ground_build_cad - (struct ground* ground) + (struct city* city, + struct ground* ground) { res_T res = RES_OK; double origin[3]; @@ -33,18 +35,18 @@ ground_build_cad struct scad_geometry* ground_box = NULL; struct scad_geometry* bound = NULL; - if (!ground) { + if (!city || !ground) { res = RES_BAD_ARG; goto error; } - origin[0] = ground->extent[0]; - origin[1] = ground->extent[2]; - origin[2] = -ground->depth; + origin[0] = city->ground_extent[0]; + origin[1] = city->ground_extent[2]; + origin[2] = -city->ground_depth; - extent[0] = ground->extent[1] - ground->extent[0]; - extent[1] = ground->extent[3] - ground->extent[2]; - extent[2] = ground->depth; + extent[0] = city->ground_extent[1] - city->ground_extent[0]; + extent[1] = city->ground_extent[3] - city->ground_extent[2]; + extent[2] = city->ground_depth; if (origin[2] > 0 || extent[0] < 0 || extent[1] < 0 || extent[2] < 0 ) { res = RES_BAD_ARG; @@ -55,10 +57,10 @@ ground_build_cad ERR(scad_geometry_boundary(NULL, &ground_box, 1, &bound)); ERR(scad_cut_geometries(NULL, &bound, 1, - ground->footprint, ground->footprints_count, &ground->boundary)); + ground->footprints, ground->footprints_count, &ground->boundary)); exit: - if (bound) scad_geometry_delete(bound); + if (bound) SCAD(geometry_delete(bound)); return res; error: goto exit; @@ -78,11 +80,32 @@ error: } res_T -ground_release(struct ground* ground) +ground_allocate + (struct mem_allocator* allocator, + const size_t count, + struct ground* ground) { res_T res = RES_OK; - if (ground->footprint) free(ground->footprint); + ground->footprints_count = count; + ground->footprints + = MEM_ALLOC(allocator, ground->footprints_count * sizeof(*ground->footprints)); + if(!ground->footprints) { + res = RES_MEM_ERR; + goto error; + } +exit: return res; +error: + goto exit; +} + +void +ground_release + (struct mem_allocator* allocator, + struct ground* ground) +{ + SCAD(geometry_delete(ground->boundary)); + MEM_RM(allocator, ground->footprints); } diff --git a/src/cg_ground.h b/src/cg_ground.h @@ -22,32 +22,39 @@ #include <rsys/rsys.h> +struct city; + struct scad_scene; struct scad_geometry; +struct mem_allocator; struct ground { - /* generic building data */ - double extent[4]; /* [xmin, xmax, ymin, ymax */ - double depth; - /* cad representation */ - struct scad_scene* scene; - struct scad_geometry* geometry; struct scad_geometry* boundary; - struct scad_geometry** footprint; /* list of building footprint */ + struct scad_geometry** footprints; /* list of building footprint */ size_t footprints_count; /* number of footprint */ }; -#define GROUND_NULL__ {{0,0,0,0}, 0, NULL, NULL, NULL, NULL, 0} +#define GROUND_NULL__ {NULL, NULL, 0} static const struct ground GROUND_NULL = GROUND_NULL__; res_T -ground_build_cad(struct ground* ground); +ground_build_cad + (struct city* city, + struct ground* ground); res_T ground_export_stl(const struct ground* ground, const int binary); res_T -ground_release(struct ground* ground); +ground_allocate + (struct mem_allocator* allocator, + const size_t count, + struct ground* ground); + +void +ground_release + (struct mem_allocator* allocator, + struct ground* ground); #endif /* GROUND */ diff --git a/src/cg_main.c b/src/cg_main.c @@ -102,8 +102,6 @@ int main .log_level = CYAML_LOG_WARNING, /* Logging errors and warnings only. */ .flags = CYAML_CFG_DEFAULT, }; - struct scad_options options = SCAD_DEFAULT_OPTIONS__; - int scad_initialized = 0; /* init allocator and logger */ ERR(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); @@ -135,12 +133,6 @@ int main if(args.verbosity_level < 3) logger_set_stream(&logger, LOG_OUTPUT, NULL, NULL); - /* Initialize star-cad */ - ERR(scad_initialize(&logger, &allocator, args.verbose)); - scad_initialized = 1; - options.Mesh.MeshSizeFromPoints = 0; - ERR(scad_set_options(&options)); - /* Parse city description. * No semantic validation is done at this stage */ ERR(parse_city(args.city_filename, &allocator, &logger, &config, &parsed_city)); @@ -157,14 +149,13 @@ int main ERR(release_parsed_city(&config, parsed_city)); parsed_city_initialized = 0; - ERR(city_ground_build(&logger, city)); - ERR(city_cad_build(&logger, city)); + ERR(city_ground_build(city)); + ERR(city_cad_build(city)); exit: if(cg_initialized) city_release(city); - if(parsed_city_initialized) release_parsed_city(&config, parsed_city); if(logger_initialized) logger_release(&logger); - if(scad_initialized) CHK(RES_OK == scad_finalize()); + if(parsed_city_initialized) release_parsed_city(&config, parsed_city); if(allocator_initialized) { check_memory_allocator(&allocator); mem_shutdown_proxy_allocator(&allocator);