commit 658e729e85c490811ffbba960863893a88a114a5
parent cca195062af7ee688e59beac4cff8bd72ae2b262
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Tue, 21 Feb 2023 11:16:01 +0100
Decrease memory footprint
Diffstat:
4 files changed, 164 insertions(+), 84 deletions(-)
diff --git a/src/scpr_c.h b/src/scpr_c.h
@@ -23,7 +23,6 @@
#include <rsys/ref_count.h>
#include <rsys/double2.h>
#include <rsys/dynamic_array.h>
-#include <rsys/dynamic_array_size_t.h>
#include <rsys/hash_table.h>
#include <math.h>
@@ -31,6 +30,10 @@
#undef PI
#include <clipper2/clipper.h>
+#define DARRAY_NAME uint32
+#define DARRAY_DATA uint32_t
+#include <rsys/dynamic_array.h>
+
#define DARRAY_NAME int64
#define DARRAY_DATA int64_t
#include <rsys/dynamic_array.h>
@@ -59,7 +62,7 @@ vertex_eq(const struct vertex* a, const struct vertex* b)
/* Define the vertex to index hash table */
#define HTABLE_NAME vertex
-#define HTABLE_DATA size_t
+#define HTABLE_DATA uint32_t
#define HTABLE_KEY struct vertex
#define HTABLE_KEY_FUNCTOR_EQ vertex_eq
#include <rsys/hash_table.h>
@@ -85,15 +88,14 @@ struct scpr_polygon {
struct scpr_mesh {
struct darray_int64 coords;
- struct darray_size_t indices;
+ struct darray_uint32 indices;
ref_T ref;
struct scpr_device* device;
};
struct intersector_segment {
- scpr_polygon* polygon;
- size_t component, rank;
+ uint32_t component, first_vertex;
};
#define DARRAY_NAME segments
#define DARRAY_DATA struct intersector_segment
@@ -103,7 +105,7 @@ struct intersector_segment {
* darray.
* The count is the number of ends of the segment at some range_point. */
#define HTABLE_NAME segment_idx
-#define HTABLE_KEY size_t
+#define HTABLE_KEY uint32_t
#define HTABLE_DATA char
#include <rsys/hash_table.h>
@@ -150,7 +152,7 @@ range_point_copy_and_release
/* An htable to link a pointer to a range_point to an 1D coordinate */
#define HTABLE_NAME range_point_idx
#define HTABLE_KEY int64_t
-#define HTABLE_DATA size_t
+#define HTABLE_DATA uint32_t
#include <rsys/hash_table.h>
enum segment_interaction {
@@ -178,7 +180,7 @@ struct intersector_dimension {
/* An htable to store overlapping information */
struct intersector_segment_pair {
- size_t rank1, rank2;
+ uint32_t rank1, rank2;
};
static INLINE char
pair_eq
@@ -197,7 +199,7 @@ pair_eq
/* An htable to keep track of registered components */
struct intersector_component {
scpr_polygon* polygon;
- size_t component;
+ uint32_t component;
};
static FINLINE void
component_init(struct mem_allocator* alloc, struct intersector_component* key)
@@ -249,6 +251,15 @@ component_copy_and_release
#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE component_copy_and_release
#include <rsys/hash_table.h>
+#define DARRAY_NAME components
+#define DARRAY_DATA struct intersector_component
+#define DARRAY_FUNCTOR_INIT component_init
+#define DARRAY_FUNCTOR_EQ component_eq
+#define DARRAY_FUNCTOR_COPY component_copy
+#define DARRAY_FUNCTOR_RELEASE component_release
+#define DARRAY_FUNCTOR_COPY_AND_RELEASE component_copy_and_release
+#include <rsys/dynamic_array.h>
+
/* A set of segments from different polygons spatially sorted to help find
* (self-)intersections. */
struct scpr_intersector {
@@ -261,8 +272,10 @@ struct scpr_intersector {
* They are all the candidates for actual intersection plus some others that
* are just close, but are without interaction. */
struct htable_interacting_segments interacting_segments;
- /* All the registererd components */
+ /* All the registererd components (an htable to check for unicity and a darray
+ * to store the components with indexing capability) */
struct htable_registered_components registererd_components;
+ struct darray_components components;
ref_T ref;
};
diff --git a/src/scpr_intersector.c b/src/scpr_intersector.c
@@ -73,6 +73,7 @@ intersector_release(ref_T* ref)
SCPR(device_ref_put(intersector->device));
htable_interacting_segments_release(&intersector->interacting_segments);
htable_registered_components_release(&intersector->registererd_components);
+ darray_components_release(&intersector->components);
MEM_RM(allocator, intersector);
}
@@ -82,10 +83,10 @@ register_point
(struct scpr_intersector* intersector,
const int dim_idx,
const int64_t coord,
- const size_t seg_idx)
+ const uint32_t seg_idx)
{
- size_t* pidx;
- size_t rp_idx;
+ uint32_t* pidx;
+ uint32_t rp_idx;
struct intersector_dimension* dim;
struct intersector_range_point* sorted;
res_T res = RES_OK;
@@ -99,7 +100,7 @@ register_point
size_t count = darray_range_points_size_get(&dim->sorted);
ERR(darray_range_points_resize(&dim->sorted, 1+count));
sorted = darray_range_points_data_get(&dim->sorted);
- rp_idx = count;
+ rp_idx = (uint32_t)count;
sorted[rp_idx].coord = coord;
/* Register this segment at this range point */
ERR(htable_segment_idx_set(&sorted[rp_idx].segments, &seg_idx, &one));
@@ -154,14 +155,14 @@ sort_points
static void
init_segment_pair
(struct intersector_segment_pair* pair,
- const size_t seg_idx1,
- const size_t seg_idx2)
+ const uint32_t seg_idx1,
+ const uint32_t seg_idx2)
{
ASSERT(pair);
pair->rank1 = seg_idx1;
pair->rank2 = seg_idx2;
if(pair->rank1 > pair->rank2) {
- SWAP(ptrdiff_t, pair->rank1, pair->rank2);
+ SWAP(uint32_t, pair->rank1, pair->rank2);
}
}
@@ -176,8 +177,8 @@ segments_bbox_interacts_1_core
static int
segments_bbox_interacts_1
- (size_t seg_idx1,
- size_t seg_idx2,
+ (uint32_t seg_idx1,
+ uint32_t seg_idx2,
enum segment_interaction inter,
struct scpr_intersector* intersector)
{
@@ -185,22 +186,30 @@ segments_bbox_interacts_1
Clipper2Lib::Point64 *v11, * v12, *v21, *v22;
int64_t lower1, upper1, lower2, upper2;
size_t count, r11, r12, r21, r22;
+ const struct intersector_component* components;
+ struct scpr_polygon *polygon1, *polygon2;
+ uint32_t comp_idx1, comp_idx2;
segments = darray_segments_cdata_get(&intersector->segments);
seg1 = segments + seg_idx1;
seg2 = segments + seg_idx2;
+ components = darray_components_cdata_get(&intersector->components);
+ comp_idx1 = components[seg1->component].component;
+ comp_idx2 = components[seg2->component].component;
+ polygon1 = components[seg1->component].polygon;
+ polygon2 = components[seg2->component].polygon;
/* Get vertices */
- r11 = seg1->rank;
- SCPR(polygon_get_vertices_count(seg1->polygon, seg1->component, &count));
+ r11 = seg1->first_vertex;
+ SCPR(polygon_get_vertices_count(polygon1, comp_idx1, &count));
r12 = (r11 + 1) % count;
- r21 = seg2->rank;
- SCPR(polygon_get_vertices_count(seg2->polygon, seg2->component, &count));
+ r21 = seg2->first_vertex;
+ SCPR(polygon_get_vertices_count(polygon2, comp_idx2, &count));
r22 = (r21 + 1) % count;
- v11 = &seg1->polygon->paths[seg1->component][r11];
- v12 = &seg1->polygon->paths[seg1->component][r12];
- v21 = &seg2->polygon->paths[seg2->component][r21];
- v22 = &seg2->polygon->paths[seg2->component][r22];
+ v11 = &polygon1->paths[comp_idx1][r11];
+ v12 = &polygon1->paths[comp_idx1][r12];
+ v21 = &polygon2->paths[comp_idx2][r21];
+ v22 = &polygon2->paths[comp_idx2][r22];
if(inter & SOMETHING_X) {
lower1 = MMIN(v11->x, v12->x);
upper1 = MMAX(v11->x, v12->x);
@@ -218,8 +227,8 @@ segments_bbox_interacts_1
/* Register interaction of 2 segments along 1 dimension */
static res_T
register_segment_interaction
- (const size_t seg_idx1,
- const size_t seg_idx2,
+ (const uint32_t seg_idx1,
+ const uint32_t seg_idx2,
const int allow_pair_creation,
const enum segment_interaction inter,
struct scpr_intersector* intersector)
@@ -259,7 +268,7 @@ error:
* open_segments along 1 dimension */
static res_T
register_segment_interactions
- (const size_t seg_idx,
+ (const uint32_t seg_idx,
struct htable_segment_idx* open_segments,
const int allow_pair_creation,
const enum segment_interaction inter,
@@ -274,7 +283,7 @@ register_segment_interactions
htable_segment_idx_end(open_segments, &end);
/* Loop on segments using this point */
while(!htable_segment_idx_iterator_eq(&it, &end)) {
- size_t seg2_idx = *htable_segment_idx_iterator_key_get(&it);
+ uint32_t seg2_idx = *htable_segment_idx_iterator_key_get(&it);
ERR(register_segment_interaction(seg_idx, seg2_idx, allow_pair_creation,
inter, intersector));
htable_segment_idx_iterator_next(&it);
@@ -299,7 +308,7 @@ register_interaction
struct mem_allocator* allocator;
struct intersector_dimension* dimension;
char *begins = NULL, *ends = NULL;
- size_t* seg_index = NULL;
+ uint32_t* seg_index = NULL;
ASSERT(intersector);
allocator = intersector->device->allocator;
@@ -317,7 +326,7 @@ register_interaction
scount = htable_segment_idx_size_get(&point->segments);
begins = (char*)MEM_REALLOC(allocator, begins, scount * sizeof(*begins));
ends = (char*)MEM_REALLOC(allocator, ends, scount * sizeof(*ends));
- seg_index = (size_t*)MEM_REALLOC(allocator, seg_index,
+ seg_index = (uint32_t*)MEM_REALLOC(allocator, seg_index,
scount * sizeof(*seg_index));
if(!begins || !ends || !seg_index) {
res = RES_MEM_ERR;
@@ -328,7 +337,7 @@ register_interaction
htable_segment_idx_end(&point->segments, &end);
while(!htable_segment_idx_iterator_eq(&it, &end)) {
char c = *htable_segment_idx_iterator_data_get(&it);
- size_t seg_idx = *htable_segment_idx_iterator_key_get(&it);
+ uint32_t seg_idx = *htable_segment_idx_iterator_key_get(&it);
if(c == 2) { /* Both ends of the segment at this point */
ends[s] = begins[s] = 1;
} else {
@@ -474,26 +483,36 @@ check_two_segments_intersection
(const struct intersector_segment* seg1,
const struct intersector_segment* seg2,
struct scpr_intersector_check_callbacks* callbacks,
+ struct scpr_intersector* intersector,
void* data)
{
res_T res = RES_OK;
size_t count, r11, r12, r21, r22;
Clipper2Lib::Point64 *v11, * v12, *v21, *v22;
int ccw1, ccw2, ccw3, ccw4, ovflw = 0;
+ const struct intersector_component* components;
+ struct scpr_polygon *polygon1, *polygon2;
+ uint32_t comp_idx1, comp_idx2;
ASSERT(seg1 && seg2 && callbacks);
+ components = darray_components_cdata_get(&intersector->components);
+ comp_idx1 = components[seg1->component].component;
+ comp_idx2 = components[seg2->component].component;
+ polygon1 = components[seg1->component].polygon;
+ polygon2 = components[seg2->component].polygon;
+
/* Get vertices */
- r11 = seg1->rank;
- ERR(scpr_polygon_get_vertices_count(seg1->polygon, seg1->component, &count));
+ r11 = seg1->first_vertex;
+ ERR(scpr_polygon_get_vertices_count(polygon1, comp_idx1, &count));
r12 = (r11 + 1) % count;
- r21 = seg2->rank;
- ERR(scpr_polygon_get_vertices_count(seg2->polygon, seg2->component, &count));
+ r21 = seg2->first_vertex;
+ ERR(scpr_polygon_get_vertices_count(polygon2, comp_idx2, &count));
r22 = (r21 + 1) % count;
- v11 = &seg1->polygon->paths[seg1->component][r11];
- v12 = &seg1->polygon->paths[seg1->component][r12];
- v21 = &seg2->polygon->paths[seg2->component][r21];
- v22 = &seg2->polygon->paths[seg2->component][r22];
+ v11 = &polygon1->paths[comp_idx1][r11];
+ v12 = &polygon1->paths[comp_idx1][r12];
+ v21 = &polygon2->paths[comp_idx2][r21];
+ v22 = &polygon2->paths[comp_idx2][r22];
ASSERT(segments_bbox_interacts(v11, v12, v21, v22));
/* Test triangles orientation */
@@ -511,13 +530,13 @@ check_two_segments_intersection
}
else if(ccw1 == 0 && ccw2 == 0 && ccw3 == 0 && ccw4 == 0) {
/* Colinear segments */
- callbacks->colinear_segments(seg1->polygon, seg1->component, seg1->rank,
- seg2->polygon, seg2->component, seg2->rank, data);
+ callbacks->colinear_segments(polygon1, comp_idx1, seg1->first_vertex,
+ polygon2, comp_idx2, seg2->first_vertex, data);
}
else if(ccw1 * ccw2 < 0 && ccw3 * ccw4 < 0) {
/* Basic segment intersection */
- callbacks->simple_intersection(seg1->polygon, seg1->component, seg1->rank,
- seg2->polygon, seg2->component, seg2->rank, data);
+ callbacks->simple_intersection(polygon1, comp_idx1, seg1->first_vertex,
+ polygon2, comp_idx2, seg2->first_vertex, data);
}
exit:
@@ -553,7 +572,7 @@ check_interacting_pairs
= htable_interacting_segments_iterator_key_get(&it);
const struct intersector_segment* seg1 = segments + pair->rank1;
const struct intersector_segment* seg2 = segments + pair->rank2;
- ERR(check_two_segments_intersection(seg1, seg2, callbacks, data));
+ ERR(check_two_segments_intersection(seg1, seg2, callbacks, intersector, data));
}
htable_interacting_segments_iterator_next(&it);
}
@@ -595,6 +614,7 @@ scpr_intersector_create
init_dimension(allocator, intersector->dimensions + 1, OVERLAP_Y, CONTACT_Y);
htable_interacting_segments_init(allocator, &intersector->interacting_segments);
htable_registered_components_init(allocator, &intersector->registererd_components);
+ darray_components_init(allocator, &intersector->components);
exit:
if(out_intersector) *out_intersector = intersector;
@@ -632,18 +652,20 @@ scpr_intersector_register_component
const size_t icomponent)
{
res_T res = RES_OK;
- size_t prev_count, new_count, i;
+ uint32_t i;
+ size_t new_count, prev_count, c;
struct intersector_component comp;
char *found, one = 1;
- if(!intersector || !polygon || icomponent >= polygon->paths.size()) {
+ if(!intersector || !polygon || icomponent >= polygon->paths.size())
+ {
res = RES_BAD_ARG;
goto error;
}
/* Check single registration */
comp.polygon = polygon;
- comp.component = icomponent;
+ comp.component = (uint32_t)icomponent;
found = htable_registered_components_find(&intersector->registererd_components,
&comp);
if(found) {
@@ -652,21 +674,37 @@ scpr_intersector_register_component
res = RES_BAD_ARG;
goto error;
}
- htable_registered_components_set(&intersector->registererd_components, &comp,
- &one);
+ c = htable_registered_components_size_get(&intersector->registererd_components);
+ if(c >= UINT32_MAX) {
+ logger_print(intersector->device->logger, LOG_ERROR,
+ "Too many components registered.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ ASSERT(c == darray_components_size_get(&intersector->components));
+ ERR(htable_registered_components_set(&intersector->registererd_components,
+ &comp, &one));
+ ERR(darray_components_push_back(&intersector->components, &comp));
prev_count = darray_segments_size_get(&intersector->segments);
+ ASSERT(prev_count <= UINT32_MAX);
new_count = polygon->paths[icomponent].size();
- ERR(darray_segments_resize(&intersector->segments, prev_count + new_count));
+ if(prev_count + new_count > UINT32_MAX) {
+ logger_print(intersector->device->logger, LOG_ERROR,
+ "Too many segments registered.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ ERR(darray_segments_resize(&intersector->segments,
+ (uint32_t)(prev_count + new_count)));
for(i = 0; i < new_count; i++) {
Clipper2Lib::Point64 *p0, *p1;
- size_t seg_idx = prev_count + i;
+ uint32_t seg_idx = (uint32_t)(prev_count + i);
struct intersector_segment* segment
= darray_segments_data_get(&intersector->segments) + seg_idx;
- segment->polygon = polygon;
- segment->component = icomponent;
- segment->rank = i;
+ segment->component = (uint32_t)c;
+ segment->first_vertex = i;
p0 = &polygon->paths[icomponent][i];
p1 = &polygon->paths[icomponent][(i+1)%new_count];
ERR(register_point(intersector, 0, p0->x, seg_idx));
diff --git a/src/scpr_mesh.c b/src/scpr_mesh.c
@@ -17,6 +17,7 @@
#include "scpr_c.h"
#include <rsys/mem_allocator.h>
+#include <rsys/logger.h>
#include <polygon.h>
#undef PI
@@ -82,11 +83,11 @@ static res_T
register_vertex
(const int64_t pos[2],
struct darray_int64* coords,
- struct darray_size_t* indices,
+ struct darray_uint32* indices,
struct htable_vertex* vertices)
{
struct vertex v;
- size_t* pid, id;
+ uint32_t* pid, id;
unsigned i;
res_T res = RES_OK;
ASSERT(pos && coords && indices && vertices);
@@ -103,14 +104,15 @@ register_vertex
} else {
const size_t count = darray_int64_size_get(coords);
+ ASSERT(count <= UINT32_MAX);
ERR(darray_int64_resize(coords, count+2/*#coords*/));
for(i = 0; i < 2; i++) darray_int64_data_get(coords)[count+i] = pos[i];
- id = count / 2;
+ id = (uint32_t)count / 2;
ERR(htable_vertex_set(vertices, &v, &id));
}
- ERR(darray_size_t_push_back(indices, &id));
+ ERR(darray_uint32_push_back(indices, &id));
exit:
return res;
@@ -122,7 +124,7 @@ static FINLINE res_T
register_triangle
(int64_t tri[3][2],
struct darray_int64* coords, /* Vertex buffer */
- struct darray_size_t* indices, /* Index buffer */
+ struct darray_uint32* indices, /* Index buffer */
struct htable_vertex* vertices) /* Map a vertex to its index */
{
size_t ivert;
@@ -143,7 +145,7 @@ register_paths
(struct scpr_device* dev,
const Clipper2Lib::Paths64& paths,
struct darray_int64* coords, /* Vertex buffer */
- struct darray_size_t* indices, /* Index buffer */
+ struct darray_uint32* indices, /* Index buffer */
struct htable_vertex* vertices, /* Map a vertex to its index */
struct polygon* polygon) /* Used to triangulate the clipped polygons */
{
@@ -237,7 +239,7 @@ mesh_release(ref_T* ref)
allocator = mesh->device->allocator;
SCPR(device_ref_put(mesh->device));
darray_int64_release(&mesh->coords);
- darray_size_t_release(&mesh->indices);
+ darray_uint32_release(&mesh->indices);
MEM_RM(allocator, mesh);
}
@@ -267,7 +269,7 @@ scpr_mesh_create
mesh->device = dev;
SCPR(device_ref_get(dev));
darray_int64_init(dev->allocator, &mesh->coords);
- darray_size_t_init(dev->allocator, &mesh->indices);
+ darray_uint32_init(dev->allocator, &mesh->indices);
exit:
if(out_mesh) *out_mesh = mesh;
@@ -307,8 +309,8 @@ scpr_mesh_setup_indexed_vertices
void* data)
{
int64_t* pos = NULL;
- size_t* ids = NULL;
- size_t i;
+ uint32_t* ids = NULL;
+ size_t i, j;
res_T res = RES_OK;
if(!mesh || !ntris || !get_indices || !nverts || !get_position || !data) {
@@ -316,8 +318,22 @@ scpr_mesh_setup_indexed_vertices
goto error;
}
+ if(ntris > UINT32_MAX) {
+ logger_print(mesh->device->logger, LOG_ERROR,
+ "Too many triangles.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(nverts > UINT32_MAX) {
+ logger_print(mesh->device->logger, LOG_ERROR,
+ "Too many vertices.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
ERR(darray_int64_resize(&mesh->coords, nverts*2/*#coords per vertex*/));
- ERR(darray_size_t_resize(&mesh->indices, ntris*3/*#vertices per triangle*/));
+ ERR(darray_uint32_resize(&mesh->indices, ntris*3/*#vertices per triangle*/));
/* Fetch mesh positions */
pos = darray_int64_data_get(&mesh->coords);
@@ -328,15 +344,15 @@ scpr_mesh_setup_indexed_vertices
}
/* Fetch mesh indices */
- ids = darray_size_t_data_get(&mesh->indices);
+ ids = darray_uint32_data_get(&mesh->indices);
FOR_EACH(i, 0, ntris) {
- get_indices(i, ids + i*3, data);
- if(ids[i*3+0] >= nverts
- || ids[i*3+1] >= nverts
- || ids[i*3+2] >= nverts) {
+ size_t tmp[3];
+ get_indices(i, tmp, data);
+ if(tmp[0] >= nverts || tmp[1] >= nverts || tmp[2] >= nverts) {
res = RES_BAD_ARG;
goto error;
}
+ for(j = 0; j < 3; j++) ids[i*3 + j] = (uint32_t)tmp[j];
}
exit:
@@ -344,7 +360,7 @@ exit:
error:
if(mesh) {
darray_int64_clear(&mesh->coords);
- darray_size_t_clear(&mesh->indices);
+ darray_uint32_clear(&mesh->indices);
}
goto exit;
}
@@ -362,8 +378,8 @@ res_T
scpr_mesh_get_triangles_count(const struct scpr_mesh* mesh, size_t* ntris)
{
if(!mesh || !ntris) return RES_BAD_ARG;
- ASSERT((darray_size_t_size_get(&mesh->indices)%3/*#vertices per triangle*/)==0);
- *ntris = darray_size_t_size_get(&mesh->indices) / 3/*#vertices per triangle*/;
+ ASSERT((darray_uint32_size_get(&mesh->indices)%3/*#vertices per triangle*/)==0);
+ *ntris = darray_uint32_size_get(&mesh->indices) / 3/*#vertices per triangle*/;
return RES_OK;
}
@@ -376,9 +392,9 @@ scpr_mesh_get_indices
if(!mesh || !ids) return RES_BAD_ARG;
SCPR(mesh_get_triangles_count(mesh, &ntris));
if(itri >= ntris) return RES_BAD_ARG;
- ids[0] = darray_size_t_cdata_get(&mesh->indices)[i+0];
- ids[1] = darray_size_t_cdata_get(&mesh->indices)[i+1];
- ids[2] = darray_size_t_cdata_get(&mesh->indices)[i+2];
+ ids[0] = darray_uint32_cdata_get(&mesh->indices)[i+0];
+ ids[1] = darray_uint32_cdata_get(&mesh->indices)[i+1];
+ ids[2] = darray_uint32_cdata_get(&mesh->indices)[i+2];
return RES_OK;
}
@@ -407,7 +423,7 @@ scpr_mesh_clip
int64_t lower[2], upper[2];
struct polygon* polygon = NULL; /* Use to triangulate clipped polygons */
struct darray_int64 coords; /* Coordinates of the clipped mesh */
- struct darray_size_t indices; /* Indices of the clipped mesh */
+ struct darray_uint32 indices; /* Indices of the clipped mesh */
struct htable_vertex vertices; /* Map a coordinate to its index */
Clipper2Lib::Clipper64 clipper;
Clipper2Lib::Paths64 output; /* Contour of the clipped polgyon */
@@ -427,7 +443,7 @@ scpr_mesh_clip
clip_type = scpr_operation_to_clip_type(op);
darray_int64_init(allocator, &coords);
- darray_size_t_init(allocator, &indices);
+ darray_uint32_init(allocator, &indices);
htable_vertex_init(allocator, &vertices);
if(aabb_is_degenerated(poly_desc->lower, poly_desc->upper)) goto exit;
@@ -491,12 +507,12 @@ scpr_mesh_clip
}
ERR(darray_int64_copy_and_clear(&mesh->coords, &coords));
- ERR(darray_size_t_copy_and_clear(&mesh->indices, &indices));
+ ERR(darray_uint32_copy_and_clear(&mesh->indices, &indices));
exit:
if(polygon) POLYGON(ref_put(polygon));
darray_int64_release(&coords);
- darray_size_t_release(&indices);
+ darray_uint32_release(&indices);
htable_vertex_release(&vertices);
return res;
error:
diff --git a/src/scpr_polygon.c b/src/scpr_polygon.c
@@ -172,7 +172,7 @@ scpr_polygon_ref_put
res_T
scpr_polygon_setup_indexed_vertices
(struct scpr_polygon* polygon,
- const size_t ncomponents, /* #connex components */
+ const size_t ncomponents,
void (*get_nverts)(const size_t icomponent, size_t *nverts, void* ctx),
void (*get_position)
(const size_t icomponent, const size_t ivert, double pos[2], void* ctx),
@@ -189,6 +189,13 @@ scpr_polygon_setup_indexed_vertices
goto error;
}
+ if(ncomponents > UINT32_MAX) {
+ logger_print(polygon->device->logger, LOG_ERROR,
+ "Too many components.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
dev = polygon->device;
TRY(paths.resize(ncomponents));
@@ -197,6 +204,12 @@ scpr_polygon_setup_indexed_vertices
/* Get count for connex component c */
get_nverts(c, &nverts, data);
+ if(nverts > UINT32_MAX) {
+ logger_print(polygon->device->logger, LOG_ERROR,
+ "Too many vertices for component %zu.\n", c);
+ res = RES_BAD_ARG;
+ goto error;
+ }
TRY(paths[c].resize(nverts));
/* Fetch polygon positions for connex component c */