commit 9e8f1afac3d9e6120f59ce07e4853224f950efc1
parent f01864cac4e5947885dc199339cef5a98adbf816
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Wed, 11 Jan 2023 17:41:32 +0100
Improve memory management
Stop using default allocator and fix memory leaks
Diffstat:
2 files changed, 161 insertions(+), 89 deletions(-)
diff --git a/src/cg_constructive_mode_1.c b/src/cg_constructive_mode_1.c
@@ -26,7 +26,6 @@
#include <rsys/str.h>
#include <rsys/logger.h>
-#include <rsys/stretchy_array.h>
#include <star/scad.h>
#include <star/scpr.h>
@@ -424,6 +423,7 @@ build_inter_floor
struct scpr_polygon* pg_int = NULL;
size_t nverts = 0;
struct scad_geometry** floor_list = NULL;
+ struct darray_geometries floor_array;
double d[3] = {0, 0, 0};
char* floorname = NULL;
struct str name;
@@ -431,6 +431,8 @@ build_inter_floor
ASSERT(allocator && pg && data && inter_floor);
+ darray_geometries_init(allocator, &floor_array);
+
if (prefix) {
str_init(allocator, &name);
is_init = 1;
@@ -454,25 +456,25 @@ build_inter_floor
ERR(scad_add_polygon(
NULL, get_position_pg, pg_int, z_floor, nverts, &footprint));
ERR(scad_geometry_extrude(footprint, NULL, d, &floor));
- sa_push(floor_list, floor);
+ ERR(darray_geometries_push_back(&floor_array, &floor));
ERR(scad_geometry_delete(footprint));
z_floor += h_cavity/(double)(1 + floor_n) + e_floor;
}
+ ASSERT(darray_geometries_size_get(&floor_array) == floor_n);
- ERR(scad_fuse_geometries(
- floorname,
- floor_list, sa_size(floor_list),
- floor_list, sa_size(floor_list),
- inter_floor));
+ floor_list = darray_geometries_data_get(&floor_array);
+ ERR(scad_fuse_geometries(floorname, floor_list, floor_n, floor_list, floor_n,
+ inter_floor));
exit:
if (is_init) str_release(&name);
if (pg_int) SCPR(polygon_ref_put(pg_int));
- if (floor_list) {
+ floor_list = darray_geometries_data_get(&floor_array);
+ if(floor_list) {
for (i = 0; i < floor_n; i++) {
SCAD(geometry_delete(floor_list[i]));
}
- sa_release(floor_list);
+ darray_geometries_release(&floor_array);
}
return res;
error:
@@ -736,17 +738,22 @@ build_windows
struct scad_geometry* surface = NULL;
struct scad_geometry* hole = NULL;
struct scad_geometry** hole_list = NULL;
+ struct darray_geometries hole_array;
struct scad_geometry* geom = NULL;
struct scad_geometry* bcavity = NULL;
struct scad_geometry** list = NULL;
struct scad_geometry* glass = NULL;
struct scad_geometry** glass_list = NULL;
- size_t list_n = 0;
+ struct darray_geometries glass_array;
+ size_t list_n = 0, array_n;
struct str gname;
int is_init = 0;
ASSERT(allocator && data && data_cad);
+ darray_geometries_init(allocator, &hole_array);
+ darray_geometries_init(allocator, &glass_array);
+
scale[0] = sqrt(data->glass_ratio);
scale[1] = scale[0];
scale[2] = scale[0];
@@ -756,10 +763,12 @@ build_windows
ERR(scad_geometry_explode(bcavity, NULL, &list, &list_n));
for (i = 0; i < list_n; i++) {
- double* center = NULL;
- size_t center_n = 0;
+ double center[3];
+ size_t center_n;
- ERR(scad_geometry_get_centerofmass(list[i], ¢er, ¢er_n));
+ ERR(scad_geometry_get_count(list[i], ¢er_n));
+ ASSERT(center_n == 1);
+ ERR(scad_geometry_get_centerofmass(list[i], center));
ERR(scad_geometry_normal(list[i], center, N, NULL, &surface));
@@ -778,21 +787,27 @@ build_windows
dir[2] = 1.1*N[2] * (data->wall_thickness
+ data->internal_insulation_thickness + data->external_insulation_thickness);
ERR(scad_geometry_extrude(surface, NULL, dir, &hole));
- sa_push(hole_list, hole);
+ ERR(darray_geometries_push_back(&hole_array, &hole));
dir[0] = N[0] * 0.024;
dir[1] = N[1] * 0.024;
dir[2] = N[2] * 0.024;
ERR(scad_geometry_extrude(surface, NULL, dir, &glass));
- sa_push(glass_list, glass);
+ ERR(darray_geometries_push_back(&glass_array, &glass));
ERR(scad_geometry_delete(surface));
surface = NULL;
}
+ ASSERT(darray_geometries_size_get(&hole_array)
+ == darray_geometries_size_get(&glass_array));
+
+ hole_list = darray_geometries_data_get(&hole_array);
+ glass_list = darray_geometries_data_get(&glass_array);
+ array_n = darray_geometries_size_get(&hole_array);
/* wall perforation */
ERR(scad_cut_geometries(NULL, &data_cad->wall, 1,
- hole_list, sa_size(hole_list), &geom));
+ hole_list, array_n, &geom));
ERR(scad_geometry_swap_names(data_cad->wall, geom));
ERR(scad_geometry_delete(data_cad->wall));
data_cad->wall = geom;
@@ -801,7 +816,7 @@ build_windows
/* internal insulation perforation */
if (data_cad->internal_insulation) {
ERR(scad_cut_geometries(NULL, &data_cad->internal_insulation, 1,
- hole_list, sa_size(hole_list), &geom));
+ hole_list, array_n, &geom));
ERR(scad_geometry_swap_names(data_cad->internal_insulation, geom));
ERR(scad_geometry_delete(data_cad->internal_insulation));
data_cad->internal_insulation = geom;
@@ -811,7 +826,7 @@ build_windows
/* external insulation perforation */
if (data_cad->external_insulation) {
ERR(scad_cut_geometries(NULL, &data_cad->external_insulation, 1,
- hole_list, sa_size(hole_list), &geom));
+ hole_list, array_n, &geom));
ERR(scad_geometry_swap_names(data_cad->external_insulation, geom));
ERR(scad_geometry_delete(data_cad->external_insulation));
data_cad->external_insulation = geom;
@@ -827,20 +842,23 @@ build_windows
}
ERR(scad_fuse_geometries(str_cget(&gname), glass_list, 1,
- glass_list+1, sa_size(glass_list) - 1, &data_cad->glass));
+ glass_list+1, array_n - 1, &data_cad->glass));
exit:
+ glass_list = darray_geometries_data_get(&glass_array);
for (i = 0 ; i < list_n; i++) {
SCAD(geometry_delete(list[i]));
}
- for (i = 0 ; i < sa_size(hole_list); i++) {
- SCAD(geometry_delete(hole_list[i]));
+ for (i = 0 ; i < darray_geometries_size_get(&hole_array); i++) {
+ struct scad_geometry* h = darray_geometries_data_get(&hole_array)[i];
+ SCAD(geometry_delete(h));
}
- for (i = 0 ; i < sa_size(glass_list); i++) {
- SCAD(geometry_delete(glass_list[i]));
+ for (i = 0 ; i <darray_geometries_size_get(&glass_array); i++) {
+ struct scad_geometry* g = darray_geometries_data_get(&glass_array)[i];
+ SCAD(geometry_delete(g));
}
- if (hole_list) sa_release(hole_list);
- if (glass_list) sa_release(glass_list);
+ darray_geometries_release(&hole_array);
+ darray_geometries_release(&glass_array);
if (surface) SCAD(geometry_delete(surface));
if (geom) SCAD(geometry_delete(geom));
if (bcavity) SCAD(geometry_delete(bcavity));
@@ -856,10 +874,13 @@ build_boundary
(const char* prefix,
struct mem_allocator* allocator,
struct data_cad_cmode_1* data_cad,
- struct scad_geometry*** boundary)
+ struct darray_geometries* boundary)
{
res_T res = RES_OK;
+ size_t count;
+ struct darray_geometries array;
struct scad_geometry** list = NULL;
+ struct darray_geometries bound_array;
struct scad_geometry* bound = NULL;
char* boundaryname = NULL;
struct str name;
@@ -867,71 +888,90 @@ build_boundary
ASSERT(allocator && prefix && data_cad && boundary);
+ darray_geometries_init(allocator, &array);
+ darray_geometries_init(allocator, &bound_array);
+
str_init(allocator, &name);
is_init = 1;
- sa_push(list, data_cad->wall);
- sa_push(list, data_cad->roof);
- sa_push(list, data_cad->floor);
- sa_push(list, data_cad->habitable_cavity);
- sa_push(list, data_cad->fake_ground);
- if (data_cad->foundation) sa_push(list, data_cad->foundation);
- if (data_cad->intermediate_floor) sa_push(list, data_cad->intermediate_floor);
- if (data_cad->external_insulation) sa_push(list, data_cad->external_insulation);
- if (data_cad->internal_insulation) sa_push(list, data_cad->internal_insulation);
- if (data_cad->roof_insulation) sa_push(list, data_cad->roof_insulation);
- if (data_cad->floor_insulation) sa_push(list, data_cad->floor_insulation);
- if (data_cad->attic_cavity) sa_push(list, data_cad->attic_cavity);
- if (data_cad->crawlspace_cavity) sa_push(list, data_cad->crawlspace_cavity);
- if (data_cad->glass) sa_push(list, data_cad->glass);
-
+ /* Ensure enough room for all geometries without error nor mem move */
+ ERR(darray_geometries_reserve(&array, 14));
+ darray_geometries_push_back(&array, &data_cad->wall);
+ darray_geometries_push_back(&array, &data_cad->roof);
+ darray_geometries_push_back(&array, &data_cad->floor);
+ darray_geometries_push_back(&array, &data_cad->habitable_cavity);
+ darray_geometries_push_back(&array, &data_cad->fake_ground);
+ if (data_cad->foundation)
+ darray_geometries_push_back(&array, &data_cad->foundation);
+ if (data_cad->intermediate_floor)
+ darray_geometries_push_back(&array, &data_cad->intermediate_floor);
+ if (data_cad->external_insulation)
+ darray_geometries_push_back(&array, &data_cad->external_insulation);
+ if (data_cad->internal_insulation)
+ darray_geometries_push_back(&array, &data_cad->internal_insulation);
+ if (data_cad->roof_insulation)
+ darray_geometries_push_back(&array, &data_cad->roof_insulation);
+ if (data_cad->floor_insulation)
+ darray_geometries_push_back(&array, &data_cad->floor_insulation);
+ if (data_cad->attic_cavity)
+ darray_geometries_push_back(&array, &data_cad->attic_cavity);
+ if (data_cad->crawlspace_cavity)
+ darray_geometries_push_back(&array, &data_cad->crawlspace_cavity);
+ if (data_cad->glass)
+ darray_geometries_push_back(&array, &data_cad->glass);
+
+ count = darray_geometries_size_get(&array);
+ list = darray_geometries_data_get(&array);
+
+ /* Ensure enough room for all geometries without error nor mem move */
+ ERR(darray_geometries_reserve(boundary, 5+darray_geometries_size_get(boundary)));
ERR(str_set(&name, prefix));
ERR(str_append(&name, "_boundary_wall"));
boundaryname = str_get(&name);
- ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list),
+ ERR(scad_geometries_common_boundaries(boundaryname, list, count,
&data_cad->wall, 1, &bound));
- sa_push(*boundary, bound);
+ darray_geometries_push_back(boundary, &bound);
ERR(str_set(&name, prefix));
ERR(str_append(&name, "_boundary_roof"));
boundaryname = str_get(&name);
- ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list),
+ ERR(scad_geometries_common_boundaries(boundaryname, list, count,
&data_cad->roof, 1, &bound));
- sa_push(*boundary, bound);
+ darray_geometries_push_back(boundary, &bound);
if (data_cad->glass) {
ERR(str_set(&name, prefix));
ERR(str_append(&name, "_boundary_glass"));
boundaryname = str_get(&name);
- ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list),
+ ERR(scad_geometries_common_boundaries(boundaryname, list, count,
&data_cad->glass, 1, &bound));
- sa_push(*boundary, bound);
+ darray_geometries_push_back(boundary, &bound);
}
if (data_cad->external_insulation) {
ERR(str_set(&name, prefix));
ERR(str_append(&name, "_boundary_ext_insulation"));
boundaryname = str_get(&name);
- ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list),
+ ERR(scad_geometries_common_boundaries(boundaryname, list, count,
&data_cad->external_insulation, 1, &bound));
- sa_push(*boundary, bound);
+ darray_geometries_push_back(boundary, &bound);
}
if (data_cad->internal_insulation) {
- size_t count = 0;
+ size_t bcount = 0;
ERR(str_set(&name, prefix));
ERR(str_append(&name, "_boundary_int_insulation"));
boundaryname = str_get(&name);
- ERR(scad_geometries_common_boundaries(boundaryname, list, sa_size(list),
+ ERR(scad_geometries_common_boundaries(boundaryname, list, count,
&data_cad->internal_insulation, 1, &bound));
- ERR(scad_geometry_get_count(bound, &count));
- if (count>0) sa_push(*boundary, bound);
+ ERR(scad_geometry_get_count(bound, &bcount));
+ if (bcount>0) darray_geometries_push_back(boundary, &bound);
}
exit:
if (is_init) str_release(&name);
- if (list) sa_release(list);
+ darray_geometries_release(&array);
return res;
error:
goto exit;
@@ -942,7 +982,7 @@ build_connection
(const char* prefix,
struct mem_allocator* allocator,
struct data_cad_cmode_1* data_cad,
- struct scad_geometry*** connection)
+ struct darray_geometries* connection)
{
res_T res = RES_OK;
struct scad_geometry* connect = NULL;
@@ -965,7 +1005,7 @@ build_connection
&data_cad->G2, 1,\
&connect));\
ERR(scad_geometry_get_count(connect, &count)); \
- if (count>0) sa_push(*connection, connect);
+ if (count>0) { ERR(darray_geometries_push_back(connection, &connect)); }
/* -------------------------------------------------------------------------*/
@@ -1063,7 +1103,8 @@ error:
static res_T
build_fake_ground
- (struct data_cad_cmode_1* cad,
+ (struct mem_allocator* allocator,
+ struct data_cad_cmode_1* cad,
struct scpr_polygon* pg,
const double depth,
struct scad_geometry** ground)
@@ -1071,16 +1112,26 @@ build_fake_ground
res_T res = RES_OK;
double dir[3] = {0, 0, 0};
struct scpr_polygon* pg_offset = NULL;
+ size_t count;
+ struct darray_geometries array;
struct scad_geometry** list = NULL;
struct scad_geometry* footprint = NULL;
struct scad_geometry* geom = NULL;
ASSERT(cad && pg && ground );
- if (cad->foundation) sa_push(list, cad->foundation);
- if (cad->crawlspace_cavity) sa_push(list, cad->crawlspace_cavity);
- if (cad->floor) sa_push(list, cad->floor);
- if (cad->floor_insulation) sa_push(list, cad->floor_insulation);
+ darray_geometries_init(allocator, &array);
+
+ /* Ensure enough room for all geometries without error nor mem move */
+ ERR(darray_geometries_reserve(&array, 4));
+ if (cad->foundation) darray_geometries_push_back(&array, &cad->foundation);
+ if (cad->crawlspace_cavity) darray_geometries_push_back(&array, &cad->crawlspace_cavity);
+ if (cad->floor) darray_geometries_push_back(&array, &cad->floor);
+ if (cad->floor_insulation)
+ darray_geometries_push_back(&array, &cad->floor_insulation);
+
+ count = darray_geometries_size_get(&array);
+ list = darray_geometries_data_get(&array);
ERR(scpr_polygon_create_copy(NULL, pg, &pg_offset));
ERR(scpr_offset_polygon(pg_offset, 0.1, SCPR_JOIN_MITER));
@@ -1090,11 +1141,11 @@ build_fake_ground
dir[2] = -depth*1.1;
ERR(scad_geometry_extrude(footprint, NULL, dir, &geom));
- ERR(scad_cut_geometries(NULL, &geom, 1, list, sa_size(list), ground));
+ ERR(scad_cut_geometries(NULL, &geom, 1, list, count, ground));
exit:
if (pg_offset) SCPR(polygon_ref_put(pg_offset));
- if (list) sa_release(list);
+ darray_geometries_release(&array);
if (footprint) SCAD(geometry_delete(footprint));
if (geom) SCAD(geometry_delete(geom));
return res;
@@ -1113,32 +1164,41 @@ building_ground_connection
char* cname = NULL;
struct str name;
int is_init = 0;
+ size_t count;
+ struct darray_geometries array;
struct scad_geometry** list = NULL;
struct scad_geometry* list_boundary = NULL;
struct scad_geometry* footprint = NULL;
ASSERT(prefix && allocator && cad && connection);
+ darray_geometries_init(allocator, &array);
+
str_init(allocator, &name);
is_init = 1;
ERR(str_set(&name, prefix));
ERR(str_append(&name, "_C_building_ground"));
cname = str_get(&name);
- if (cad->foundation) sa_push(list, cad->foundation);
- if (cad->attic_cavity) sa_push(list, cad->attic_cavity);
- if (cad->floor) sa_push(list, cad->floor);
- if (cad->floor_insulation) sa_push(list, cad->floor_insulation);
- if (cad->external_insulation) sa_push(list, cad->external_insulation);
- if (cad->wall) sa_push(list, cad->wall);
-
- ERR(scad_geometries_common_boundaries(
- cname, list, sa_size(list),
- &cad->fake_ground, 1,
+ /* Ensure enough room for all geometries without error nor mem move */
+ ERR(darray_geometries_reserve(&array, 6));
+ if (cad->foundation) darray_geometries_push_back(&array, &cad->foundation);
+ if (cad->attic_cavity) darray_geometries_push_back(&array, &cad->attic_cavity);
+ if (cad->floor) darray_geometries_push_back(&array, &cad->floor);
+ if (cad->floor_insulation)
+ darray_geometries_push_back(&array, &cad->floor_insulation);
+ if (cad->external_insulation)
+ darray_geometries_push_back(&array, &cad->external_insulation);
+ if (cad->wall) darray_geometries_push_back(&array, &cad->wall);
+
+ count = darray_geometries_size_get(&array);
+ list = darray_geometries_data_get(&array);
+
+ ERR(scad_geometries_common_boundaries(cname, list,count, &cad->fake_ground, 1,
connection));
exit:
- if (list) sa_release(list);
+ darray_geometries_release(&array);
if (is_init) str_release(&name);
if (list_boundary) SCAD(geometry_delete(list_boundary));
if (footprint) SCAD(geometry_delete(footprint));
@@ -1234,6 +1294,8 @@ build_cad_cmode_1
res = RES_MEM_ERR;
goto error;
}
+ darray_geometries_init(allocator, &data_cad->boundary);
+ darray_geometries_init(allocator, &data_cad->connection);
/* build mandatories elements :
- floor
@@ -1311,9 +1373,10 @@ build_cad_cmode_1
}
/* fake ground */
- depth = MMAX(data->foundation_depth, data->floor_thickness
- + data->floor_insulation_thickness + data->crawl_height);
- ERR(build_fake_ground(data_cad, pg, depth, &data_cad->fake_ground));
+ depth = MMAX(data->foundation_depth,
+ data->floor_thickness + data->floor_insulation_thickness + data->crawl_height);
+ ERR(build_fake_ground(allocator, data_cad, pg, data->foundation_depth,
+ &data_cad->fake_ground));
ERR(scad_scene_partition());
@@ -1435,13 +1498,15 @@ export_stl_cmode_1
}
/* boundary export*/
- for(i = 0; i < sa_size(data_cad->boundary); i++) {
- ERR(scad_stl_export(data_cad->boundary[i], NULL, binary));
+ for(i = 0; i < darray_geometries_size_get(&data_cad->boundary); i++) {
+ struct scad_geometry* b = darray_geometries_data_get(&data_cad->boundary)[i];
+ ERR(scad_stl_export(b, NULL, binary));
}
/* connections export*/
- for(i = 0; i < sa_size(data_cad->connection); i++) {
- ERR(scad_stl_export(data_cad->connection[i], NULL, binary));
+ for(i = 0; i < darray_geometries_size_get(&data_cad->connection); i++) {
+ struct scad_geometry* c = darray_geometries_data_get(&data_cad->connection)[i];
+ ERR(scad_stl_export(c, NULL, binary));
}
/* ground/building connection export*/
@@ -1469,14 +1534,16 @@ release_cad_cmode_1
goto error;
}
- for(i = 0; i < sa_size(data_cad->boundary); i++) {
- ERR(scad_geometry_delete(data_cad->boundary[i]));
+ for(i = 0; i < darray_geometries_size_get(&data_cad->boundary); i++) {
+ struct scad_geometry* b = darray_geometries_data_get(&data_cad->boundary)[i];
+ ERR(scad_geometry_delete(b));
}
- for(i = 0; i < sa_size(data_cad->connection); i++) {
- ERR(scad_geometry_delete(data_cad->connection[i]));
+ for(i = 0; i < darray_geometries_size_get(&data_cad->connection); i++) {
+ struct scad_geometry* c = darray_geometries_data_get(&data_cad->connection)[i];
+ ERR(scad_geometry_delete(c));
}
- sa_release(data_cad->boundary);
- sa_release(data_cad->connection);
+ darray_geometries_release(&data_cad->boundary);
+ darray_geometries_release(&data_cad->connection);
MEM_RM(allocator, data_cad);
exit:
diff --git a/src/cg_constructive_mode_1.h b/src/cg_constructive_mode_1.h
@@ -23,6 +23,7 @@
#include <rsys/rsys.h>
#include <rsys/str.h>
#include <rsys/hash_table.h>
+#include <rsys/dynamic_array.h>
struct scad_geometry;
@@ -32,6 +33,10 @@ struct logger;
struct parsed_city_building;
struct catalog;
+#define DARRAY_NAME geometries
+#define DARRAY_DATA struct scad_geometry*
+#include <rsys/dynamic_array.h>
+
/* specific data for constructive mode 1 */
struct dataset_cmode_1 {
size_t inter_floor_count; /* can be 0 */
@@ -77,8 +82,8 @@ struct data_cad_cmode_1 {
struct scad_geometry* glass;
struct scad_geometry* fake_ground;/*not exported, used for ground connection*/
struct scad_geometry* ground_connection;
- struct scad_geometry** boundary;
- struct scad_geometry** connection;
+ struct darray_geometries boundary;
+ struct darray_geometries connection;
size_t n_connection;
};