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:
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);