commit fe205d708689b01f2d47071ff6e4f19d0b684b25
parent ef70db214a639d840b26604be31de2e39701fe0a
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 26 Jul 2018 16:54:45 +0200
For saving purpose. Not finished
Diffstat:
4 files changed, 237 insertions(+), 566 deletions(-)
diff --git a/src/senc2d_descriptor_c.h b/src/senc2d_descriptor_c.h
@@ -26,22 +26,22 @@
struct senc2d_scene;
struct mem_allocator;
-struct segment_part {
- /* The connex component part in which each side is. */
- part_id_t part[2];
+struct segment_comp {
+ /* The connex component in which each side is. */
+ component_id_t component[2];
};
static void
-segment_part_init(struct mem_allocator* alloc, struct segment_part* seg) {
+segment_comp_init(struct mem_allocator* alloc, struct segment_comp* seg) {
int i;
(void)alloc;
ASSERT(seg);
- FOR_EACH(i, 0, 2) seg->part[i] = PART_NULL__;
+ FOR_EACH(i, 0, 2) seg->component[i] = COMPONENT_NULL__;
}
-#define DARRAY_NAME segment_part
-#define DARRAY_DATA struct segment_part
-#define DARRAY_FUNCTOR_INIT segment_part_init
+#define DARRAY_NAME segment_comp
+#define DARRAY_DATA struct segment_comp
+#define DARRAY_FUNCTOR_INIT segment_comp_init
#include <rsys/dynamic_array.h>
struct segment_enc {
diff --git a/src/senc2d_internal_types.h b/src/senc2d_internal_types.h
@@ -81,21 +81,15 @@ typedef uint32_t enclosure_id_t;
/* Component IDs use the same type than enclosure IDs */
typedef enclosure_id_t component_id_t;
-#define COMPONENT_MAX__ (UINT32_MAX - 2) /* To allow special values */
+#define COMPONENT_MAX__ (UINT32_MAX - 3) /* To allow special values */
#define COMPONENT_NULL__ UINT32_MAX
-/* Special part values */
+/* Special values */
#define CC_GROUP_ROOT_NONE UINT32_MAX
#define CC_GROUP_ROOT_INFINITE (UINT32_MAX - 1)
+#define CC_IN_STACK (UINT32_MAX - 2)
#define CC_GROUP_ID_NONE UINT32_MAX
#define CC_ID_NONE UINT32_MAX
-/* Part IDs use the same type than Component IDs */
-typedef component_id_t part_id_t;
-#define PART_MAX__ (UINT32_MAX - 2) /* To allow special values */
-#define PART_NULL__ UINT32_MAX
-/* Special part values */
-#define PART_IN_STACK (UINT32_MAX - 1)
-
/* This one is used as an index to arrays */
enum side_id {
SIDE_FRONT = 0,
diff --git a/src/senc2d_scene_analyze.c b/src/senc2d_scene_analyze.c
@@ -32,12 +32,6 @@
#include <limits.h>
#include <stdlib.h>
-#define PART_DESCRIPTOR_NULL__ {\
- 0, PART_NULL__, VRTX_NULL__, 0, MEDIUM_NULL__,\
- { SEG_NULL__, 0}\
-}
-const struct part_descriptor PART_DESCRIPTOR_NULL = PART_DESCRIPTOR_NULL__;
-
#define CC_DESCRIPTOR_NULL__ {\
CHAR_MAX, VRTX_NULL__, 0,\
CC_ID_NONE, CC_GROUP_ROOT_NONE, ENCLOSURE_NULL__,\
@@ -64,37 +58,39 @@ static FINLINE res_T
add_side_to_stack
(const struct senc2d_scene* scn,
struct darray_side_id* stack,
- struct segment_part* segments_part,
+ struct segment_comp* segments_comp,
const side_id_t side_id)
{
(void)scn;
- seg_id_t seg = SEGSIDE_2_SEG(side_id);
- enum side_flag sf = SEGSIDE_2_SIDE(side_id);
- ASSERT(scn && segments_part && stack
+ ASSERT(scn && segments_comp && stack
&& side_id < SIDE_MAX__ && side_id < 2 * scn->nusegs);
- ASSERT(segments_part[seg].part[sf] == PART_NULL__);
- segments_part[seg].part[sf] = PART_IN_STACK;
- return darray_side_id_push_back(stack, &side_id);
+ {
+ seg_id_t seg = SEGSIDE_2_SEG(side_id);
+ enum side_flag sf = SEGSIDE_2_SIDE(side_id);
+ ASSERT(segments_comp[seg].component[sf] == COMPONENT_NULL__);
+ segments_comp[seg].component[sf] = CC_IN_STACK;
+ return darray_side_id_push_back(stack, &side_id);
+ }
}
static side_id_t
-get_side_not_in_connex_part
+get_side_not_in_connex_component
(const seg_id_t last_side,
const struct segside* segsides,
- const struct segment_part* segments_part,
- side_id_t* first_side_not_in_part,
+ struct segment_comp* segments_comp,
+ side_id_t* first_side_not_in_component,
const medium_id_t medium)
{
- ASSERT(segsides && segments_part && first_side_not_in_part);
+ ASSERT(segsides && segments_comp && first_side_not_in_component);
{
- side_id_t i = *first_side_not_in_part;
+ side_id_t i = *first_side_not_in_component;
while(i <= last_side
&& (segsides[i].medium != medium
- || (segments_part[SEGSIDE_2_SEG(i)].part[SEGSIDE_2_SIDE(i)]
- <= PART_MAX__))) {
+ || (segments_comp[SEGSIDE_2_SEG(i)].component[SEGSIDE_2_SIDE(i)]
+ <= COMPONENT_MAX__))) {
++i;
}
- *first_side_not_in_part = i + 1;
+ *first_side_not_in_component = i + 1;
if(i > last_side) return SIDE_NULL__;
return i;
}
@@ -102,20 +98,21 @@ get_side_not_in_connex_part
static FINLINE side_id_t
get_side_from_stack
- (const struct segment_part* segments_part,
+ (struct segment_comp* segments_comp,
struct darray_side_id* stack)
{
- side_id_t id;
- size_t sz;
- (void) segments_part;
- ASSERT(segments_part && stack);
- sz = darray_side_id_size_get(stack);
- ASSERT(sz);
- id = darray_side_id_cdata_get(stack)[sz - 1];
- ASSERT(segments_part[SEGSIDE_2_SEG(id)].part[SEGSIDE_2_SIDE(id)]
- == PART_IN_STACK);
- darray_side_id_pop_back(stack);
- return id;
+ ASSERT(segments_comp && stack);
+ (void)segments_comp;
+ {
+ side_id_t id;
+ size_t sz = darray_side_id_size_get(stack);
+ ASSERT(sz);
+ id = darray_side_id_cdata_get(stack)[sz - 1];
+ ASSERT(segments_comp[SEGSIDE_2_SEG(id)].component[SEGSIDE_2_SIDE(id)]
+ == CC_IN_STACK);
+ darray_side_id_pop_back(stack);
+ return id;
+ }
}
static void
@@ -138,22 +135,6 @@ get_scn_position(const unsigned ivert, float pos[2], void* ctx) {
f2_set_d2(pos, pt->vec);
}
-static component_id_t FINLINE
-part2comp
- (const struct darray_component_id* part2comp_table,
- const part_id_t part)
-{
- if(!part2comp_table) return part;
- ASSERT(part < darray_component_id_size_get(part2comp_table));
- return darray_component_id_cdata_get(part2comp_table)[part];
-}
-
-struct filter_context {
- const struct darray_segment_part* segments_part;
- const struct darray_component_id* part2comp_table;
- component_id_t* self_hit_component;
-};
-
static int
self_hit_filter
(const struct s2d_hit* hit,
@@ -162,26 +143,19 @@ self_hit_filter
void* ray_data,
void* filter_data)
{
- struct filter_context* context = ray_data;
- const struct darray_segment_part* segments_part;
- const struct darray_component_id* part2comp_table;
- const component_id_t* origin_component;
- const struct segment_part* hit_seg_part;
+ const struct darray_segment_comp* segments_comp = filter_data;
+ const component_id_t* origin_component = ray_data;
+ const struct segment_comp* hit_seg_comp;
enum side_id hit_side;
- part_id_t hit_part;
component_id_t hit_component;
- (void)ray_org; (void)ray_dir; (void)filter_data;
- ASSERT(hit && context && context);
- segments_part = context->segments_part;
- part2comp_table = context->part2comp_table;
- origin_component = context->self_hit_component;
- ASSERT(hit->prim.prim_id < darray_segment_part_size_get(segments_part));
- hit_seg_part = darray_segment_part_cdata_get(segments_part)
+ (void)ray_org; (void)ray_dir;
+ ASSERT(hit && segments_comp && origin_component);
+ ASSERT(hit->prim.prim_id < darray_segment_comp_size_get(segments_comp));
+ hit_seg_comp = darray_segment_comp_cdata_get(segments_comp)
+ hit->prim.prim_id;
hit_side = (hit->normal[1] > 0) ? SIDE_FRONT : SIDE_BACK;
- hit_part = hit_seg_part->part[hit_side];
- hit_component = part2comp(part2comp_table, hit_part);
+ hit_component = hit_seg_comp->component[hit_side];
/* If self hit, distance should be small */
ASSERT(hit_component != *origin_component || hit->distance < 1e-6);
@@ -189,14 +163,14 @@ self_hit_filter
}
static void
-extract_connex_parts
+extract_connex_components
(struct senc2d_descriptor* desc,
struct segside* segsides,
- struct darray_ptr_part_descriptor* connex_parts,
+ struct darray_ptr_component_descriptor* connex_components,
const struct darray_segment_tmp* segments_tmp_array,
- struct darray_segment_part* segments_part_array,
+ struct darray_segment_comp* segments_comp_array,
struct s2d_scene_view** s2d_view,
- ATOMIC* part_count,
+ ATOMIC* component_count,
/* Shared error status.
* We accept to overwritte an error with a different error */
res_T* res)
@@ -210,24 +184,34 @@ extract_connex_parts
struct darray_side_id ids_of_sides_around_max_y_vertex;
const union double2* positions;
const struct segment_tmp* segments_tmp;
- struct segment_part* segments_part;
- size_t sz;
+ size_t ii, sz;
+ res_T res2 = RES_OK;
+ /* Per-thread component table to allow sync-free access; to be merged */
+ struct darray_segment_comp local_comp_array;
+ struct segment_comp* local_comp;
- ASSERT(segsides && desc && connex_parts && segments_tmp_array
- && segments_part_array && s2d_view && part_count && res);
+ ASSERT(segsides && desc && connex_components && segments_tmp_array
+ && segments_comp_array && s2d_view && component_count && res);
alloc = descriptor_get_allocator(desc);
scn = desc->scene;
positions = darray_position_cdata_get(&scn->vertices);
segments_tmp = darray_segment_tmp_cdata_get(segments_tmp_array);
- segments_part = darray_segment_part_data_get(segments_part_array);
darray_side_id_init(alloc, &stack);
darray_side_id_init(alloc, &ids_of_sides_around_max_y_vertex);
+ darray_segment_comp_init(alloc, &local_comp_array);
+ res2 = darray_segment_comp_resize(&local_comp_array, scn->nusegs);
+ if(res2 != RES_OK) {
+ *res = res2;
+ return;
+ }
+ local_comp = darray_segment_comp_data_get(&local_comp_array);
+
#ifndef NDEBUG
#pragma omp single
{
seg_id_t s_;
- ASSERT(darray_ptr_part_descriptor_size_get(connex_parts) == 0);
+ ASSERT(darray_ptr_component_descriptor_size_get(connex_components) == 0);
FOR_EACH(s_, 0, scn->nusegs) {
const struct segment_in* seg_in =
darray_segment_in_cdata_get(&scn->segments_in) + s_;
@@ -243,26 +227,28 @@ extract_connex_parts
} /* Implicit barrier here */
#endif
- /* We loop on sides to build parts of connex components. */
+ /* We loop on sides to build connex components. */
#pragma omp for schedule(dynamic) nowait
for(mm = 0; mm < (int64_t)scn->nmeds; mm++) { /* Process all media */
const medium_id_t m = (medium_id_t)mm;
- struct part_descriptor* part;
+ struct cc_descriptor* cc;
/* Any not-already-used side is used as a starting point */
const struct side_range* media_use =
darray_side_range_cdata_get(&scn->media_use) + m;
- side_id_t first_side_not_in_part = media_use->first;
+ side_id_t first_side_not_in_component = media_use->first;
+ double max_y_ny;
const seg_id_t last_side = media_use->last;
+ char one = 1;
ATOMIC id;
if(*res != RES_OK) continue;
- if(first_side_not_in_part == SIDE_NULL__)
+ if(first_side_not_in_component == SIDE_NULL__)
continue; /* Unused medium */
- ASSERT(first_side_not_in_part < 2 * scn->nusegs);
+ ASSERT(first_side_not_in_component < 2 * scn->nusegs);
ASSERT(darray_side_id_size_get(&stack) == 0);
- for(;;) { /* Process all parts for this medium */
- const side_id_t start_side_id = get_side_not_in_connex_part
- (last_side, segsides, segments_part, &first_side_not_in_part, m);
+ for(;;) { /* Process all components for this medium */
+ const side_id_t start_side_id = get_side_not_in_connex_component
+ (last_side, segsides, local_comp, &first_side_not_in_component, m);
side_id_t crt_side_id = start_side_id;
side_id_t last_side_id = start_side_id;
double max_y = -DBL_MAX;
@@ -283,36 +269,37 @@ extract_connex_parts
}
#endif
- /* Create and init a new part */
- part = MEM_ALLOC(alloc, sizeof(struct part_descriptor));
- if(!part) {
+ /* Create and init a new component */
+ cc = MEM_ALLOC(alloc, sizeof(struct cc_descriptor));
+ if(!cc) {
*res = RES_MEM_ERR;
continue;
}
- part_descriptor_init(alloc, part);
+ cc_descriptor_init(alloc, cc);
ASSERT(m == segsides[start_side_id].medium);
- id = ATOMIC_INCR(part_count) - 1;
- ASSERT(id <= PART_MAX__);
- part->part_id = (part_id_t)id;
- part->side_range.first = start_side_id;
- part->medium = m;
-
- for(;;) { /* Process all sides of this part */
+ id = ATOMIC_INCR(component_count) - 1;
+ ASSERT(id <= COMPONENT_MAX__);
+ cc->cc_id = (component_id_t)id;
+ cc->side_range.first = start_side_id;
+ /* First medium of the component */
+ htable_media_set(&cc->media, &m, &one);
+
+ for(;;) { /* Process all sides of this component */
int i;
enum side_flag crt_side_flag = SEGSIDE_2_SIDE(crt_side_id);
struct segside* crt_side = segsides + crt_side_id;
const seg_id_t crt_seg_id = SEGSIDE_2_SEG(crt_side_id);
const struct segment_in* seg_in =
darray_segment_in_cdata_get(&scn->segments_in) + crt_seg_id;
- struct segment_part* seg_part = segments_part + crt_seg_id;
+ struct segment_comp* seg_comp = local_comp + crt_seg_id;
const struct segment_tmp* const seg_tmp = segments_tmp + crt_seg_id;
+ res_T tmp_res;
ASSERT(crt_seg_id < scn->nusegs);
- ASSERT(seg_in->medium[crt_side_flag] == part->medium);
if(*res != RES_OK) break;
/* Record Ymax information
- * Keep track of the appropriate vertex of the part in order
+ * Keep track of the appropriate vertex of the component in order
* to cast a ray at the component grouping step of the algorithm.
* The most appropriate vertex is (the) one with the greater Y
* coordinate. */
@@ -322,97 +309,135 @@ extract_connex_parts
/* New vertex: reset list of sides */
darray_side_id_clear(&ids_of_sides_around_max_y_vertex);
- /* Select one vertex with y == max_y */
+ /* Select a vertex with y == max_y */
if(max_y == positions[seg_in->vertice_id[0]].pos.y) {
- part->max_y_vrtx_id = seg_in->vertice_id[0];
+ cc->max_y_vrtx_id = seg_in->vertice_id[0];
} else {
ASSERT(max_y == positions[seg_in->vertice_id[1]].pos.y);
- part->max_y_vrtx_id = seg_in->vertice_id[1];
+ cc->max_y_vrtx_id = seg_in->vertice_id[1];
}
/* List of sides using the vertex */
- *res = darray_side_id_push_back(&ids_of_sides_around_max_y_vertex,
+ tmp_res = darray_side_id_push_back(&ids_of_sides_around_max_y_vertex,
&crt_side_id);
+ if(tmp_res != RES_OK) *res = tmp_res;
} else if(max_y == seg_tmp->max_y) {
/* Does this segment use the currently selected max_y vertex? */
FOR_EACH(i, 0, 2) {
- if(part->max_y_vrtx_id == seg_in->vertice_id[i]) {
+ if(cc->max_y_vrtx_id == seg_in->vertice_id[i]) {
/* List of sides using the vertex */
- *res = darray_side_id_push_back(&ids_of_sides_around_max_y_vertex,
+ tmp_res = darray_side_id_push_back(&ids_of_sides_around_max_y_vertex,
&crt_side_id);
+ if(tmp_res != RES_OK) *res = tmp_res;
break;
}
}
}
if(*res != RES_OK) break;
- /* Record crt_side both as part and segment level */
- part->side_count++;
- ASSERT(seg_part->part[crt_side_flag] > PART_MAX__);
- seg_part->part[crt_side_flag] = part->part_id;
+ /* Record crt_side both as component and segment level */
+ cc->side_count++;
+ ASSERT(seg_comp->component[crt_side_flag] > COMPONENT_MAX__);
+ seg_comp->component[crt_side_flag] = cc->cc_id;
/* Store neighbours' sides in a stack */
FOR_EACH(i, 0, 2) {
side_id_t neighbour_id = crt_side->facing_side_id[i];
seg_id_t nbour_seg_id = SEGSIDE_2_SEG(neighbour_id);
seg_id_t nbour_side_id = SEGSIDE_2_SIDE(neighbour_id);
- struct segment_part* nbour_part = segments_part + nbour_seg_id;
+ struct segment_comp* nbour_comp = local_comp + nbour_seg_id;
const struct segside* neighbour = segsides + neighbour_id;
- if(neighbour->medium != crt_side->medium) {
- /* Not the same medium: will be included in another computation.
- * If the id of the part including it is already known
- * record it for a further merge. In the opposite, the other
- * computation will reach the very same point at a point in time
- * when it will have the information: it will then do the job. */
- if(nbour_part->part[nbour_side_id] <= PART_MAX__) {
- res_T tmp_res;
- char one = 1;
- tmp_res = htable_part_id_set(&part->parts_to_merge_with,
- &nbour_part->part[nbour_side_id], &one);
- if(tmp_res != RES_OK) *res = tmp_res;
- if(*res != RES_OK) break;
- }
+ if(neighbour->medium < m) {
+ /* Not the same medium.
+ * Neighbour's medium id is less than current medium: the whole
+ * component is to be processed by another thread (possibly the one
+ * associated with neighbour's medium). */
+
+
+
continue;
}
- if(nbour_part->part[nbour_side_id] != PART_NULL__) {
+ if(nbour_comp->component[nbour_side_id] != COMPONENT_NULL__) {
#ifndef NDEBUG
- /* If already affected must be to the same part */
- ASSERT(nbour_part->part[nbour_side_id] == PART_IN_STACK
- || nbour_part->part[nbour_side_id] == part->part_id);
+ /* If already affected must be to the same component */
+ ASSERT(nbour_comp->component[nbour_side_id] == CC_IN_STACK
+ || nbour_comp->component[nbour_side_id] == cc->cc_id);
#endif
continue; /* Already processed */
}
- *res = add_side_to_stack(scn, &stack, segments_part, neighbour_id);
+ tmp_res = add_side_to_stack(scn, &stack, local_comp, neighbour_id);
+ if(tmp_res != RES_OK) *res = tmp_res;
if(*res != RES_OK) break;
}
if(*res != RES_OK) break;
if(darray_side_id_size_get(&stack) == 0)
- break; /* Empty stack => part is done! */
- crt_side_id = get_side_from_stack(segments_part, &stack);
+ break; /* Empty stack => component is done! */
+ crt_side_id = get_side_from_stack(local_comp, &stack);
last_side_id = MMAX(last_side_id, crt_side_id);
}
if(*res != RES_OK) {
- MEM_RM(alloc, part);
- part = NULL;
+ MEM_RM(alloc, cc);
+ cc = NULL;
break;
}
- part->side_range.last = last_side_id;
- /* Need to synchronize connex_parts growth as this global structure
+ /* Keep track of this new connex component */
+ cc->side_range.last = last_side_id;
+
+ /* Compute the normal at the max_y vertex. */
+ max_y_ny = 0;
+ sz = darray_side_id_size_get(&ids_of_sides_around_max_y_vertex);
+ FOR_EACH(ii, 0, sz) {
+ const side_id_t side_id =
+ darray_side_id_cdata_get(&ids_of_sides_around_max_y_vertex)[ii];
+ const seg_id_t seg_id = SEGSIDE_2_SEG(side_id);
+ const struct segment_in* seg_in =
+ darray_segment_in_cdata_get(&scn->segments_in) + seg_id;
+ struct segment_comp* seg_comp = local_comp + seg_id;
+ const union double2* vertices =
+ darray_position_cdata_get(&scn->vertices);
+ double edge[2], normal[2], norm;
+
+ /* To garanty that segments with 2 sides in the component total to 0
+ * regardless of numeric accuracy, we need to prevent them to
+ * contribute (remember than x + y - x - y can be non-zero). */
+ ASSERT(seg_comp->component[SIDE_FRONT] == cc->cc_id
+ || seg_comp->component[SIDE_BACK] == cc->cc_id);
+ if(seg_comp->component[SIDE_FRONT] == seg_comp->component[SIDE_BACK])
+ continue;
+
+ d2_sub(edge, vertices[seg_in->vertice_id[1]].vec,
+ vertices[seg_in->vertice_id[0]].vec);
+ d2(normal, edge[1], -edge[0]);
+ norm = d2_normalize(normal, normal);
+ ASSERT(norm); (void)norm;
+
+ /* Geometrical normal points toward the back side */
+ if(SEGSIDE_IS_FRONT(side_id)) {
+ max_y_ny -= normal[1];
+ } else {
+ max_y_ny += normal[1];
+ }
+ }
+ if(*res != RES_OK) break;
+ cc->is_outer_border = (max_y_ny < 0);
+
+ /* Need to synchronize connex_components growth as this global structure
* is accessed by multipe threads */
#pragma omp critical
{
- struct part_descriptor** parts;
- sz = darray_ptr_part_descriptor_size_get(connex_parts);
- if(sz <= part->part_id) {
- res_T tmp_res = darray_ptr_part_descriptor_resize(connex_parts,
- 1 + part->part_id);
+ struct cc_descriptor** components;
+ sz = darray_ptr_component_descriptor_size_get(connex_components);
+ if(sz <= cc->cc_id) {
+ res_T tmp_res = darray_ptr_component_descriptor_resize(connex_components,
+ 1 + cc->cc_id);
if(tmp_res != RES_OK) *res = tmp_res;
}
if(*res == RES_OK) {
/* Don't set the pointer before resize as this can lead to move data */
- parts = darray_ptr_part_descriptor_data_get(connex_parts);
- ASSERT(parts[part->part_id] == NULL);
- parts[part->part_id] = part;
+ components =
+ darray_ptr_component_descriptor_data_get(connex_components);
+ ASSERT(components[cc->cc_id] == NULL);
+ components[cc->cc_id] = cc;
}
}
}
@@ -445,7 +470,8 @@ extract_connex_parts
OK2(s2d_line_segments_setup_indexed_vertices(s2d_shp,
(unsigned)desc->scene->nusegs, get_scn_indices,
(unsigned)desc->scene->nuverts, &attribs, 1, desc->scene));
- s2d_line_segments_set_hit_filter_function(s2d_shp, self_hit_filter, NULL);
+ s2d_line_segments_set_hit_filter_function(s2d_shp, self_hit_filter,
+ darray_segment_comp_data_get(segments_comp_array));
OK2(s2d_scene_attach_shape(s2d_scn, s2d_shp));
OK2(s2d_scene_view_create(s2d_scn, S2D_TRACE, s2d_view));
tmp_error:
@@ -462,18 +488,19 @@ extract_connex_parts
#pragma omp single
{
seg_id_t s_;
- part_id_t p;
- ASSERT(ATOMIC_GET(part_count) ==
- (int)darray_ptr_part_descriptor_size_get(connex_parts));
+ component_id_t c;
+ ASSERT(ATOMIC_GET(component_count) ==
+ (int)darray_ptr_component_descriptor_size_get(connex_components));
FOR_EACH(s_, 0, scn->nusegs) {
- struct segment_part* seg_part = segments_part + s_;
- ASSERT(seg_part->part[SIDE_FRONT] != PART_NULL__);
- ASSERT(seg_part->part[SIDE_BACK] != PART_NULL__);
+ struct segment_comp* seg_comp =
+ darray_segment_comp_data_get(segments_comp_array) + s_;
+ ASSERT(seg_comp->component[SIDE_FRONT] != COMPONENT_NULL__);
+ ASSERT(seg_comp->component[SIDE_BACK] != COMPONENT_NULL__);
}
- FOR_EACH(p, 0, ATOMIC_GET(part_count)) {
- struct part_descriptor** parts =
- darray_ptr_part_descriptor_data_get(connex_parts);
- ASSERT(parts[p] != NULL && parts[p]->part_id == p);
+ FOR_EACH(c, 0, ATOMIC_GET(component_count)) {
+ struct cc_descriptor** components =
+ darray_ptr_component_descriptor_data_get(connex_components);
+ ASSERT(components[c] != NULL && components[c]->cc_id == c);
}
ASSERT(desc->segment_count == scn->nusegs);
} /* Implicit barrier here */
@@ -481,231 +508,13 @@ extract_connex_parts
}
static void
-merge_connex_parts
- (struct senc2d_descriptor* desc,
- const struct darray_segment_part* segments_part,
- const struct darray_ptr_part_descriptor* connex_parts,
- struct darray_ptr_component_descriptor* connex_components,
- struct darray_component_id* part2comp_table,
- ATOMIC* component_count,
- /* Shared error status. */
- res_T* res)
-{
- /* This function is called from an omp parallel block and executed
- * concurrently. */
- struct part_descriptor* const* parts;
- const union double2* vertices;
- struct mem_allocator* alloc;
- component_id_t* p2c;
- char one = 1;
- size_t tmp;
- part_id_t part_count;
- int64_t ppp;
- ASSERT(desc && segments_part && connex_parts && connex_components
- && part2comp_table && component_count && res);
-
- alloc = descriptor_get_allocator(desc);
- parts = darray_ptr_part_descriptor_cdata_get(connex_parts);
- tmp = darray_ptr_part_descriptor_size_get(connex_parts);
- vertices = darray_position_cdata_get(&desc->scene->vertices);
- p2c = darray_component_id_data_get(part2comp_table);
- ASSERT(tmp <= PART_MAX__);
- part_count = (component_id_t)tmp;
-
- /* Propagate merge information accross parts
- * The goal is to have all part aware of any part with a higher id */
- #pragma omp single
- for (ppp = 0; ppp < (int64_t) part_count; ppp++) {
- part_id_t pid = (part_id_t)ppp;
- struct part_descriptor* part = parts[pid];
- struct htable_part_id_iterator it, end;
- res_T tmp_res = RES_OK;
- if(*res != RES_OK) continue;
- htable_part_id_begin(&part->parts_to_merge_with, &it);
- htable_part_id_end(&part->parts_to_merge_with, &end);
- while(!htable_part_id_iterator_eq(&it, &end)) {
- part_id_t* did = htable_part_id_iterator_key_get(&it);
- struct part_descriptor* d;
- ASSERT(did && *did < part_count && *did != part->part_id);
- htable_part_id_iterator_next(&it);
- if(*did > part->part_id) {
- parts[*did]->not_head_of_group = 1;
- continue;
- }
- part->not_head_of_group = 1;
-
- d = parts[*did];
- tmp_res =
- htable_part_id_set(&d->parts_to_merge_with, &part->part_id, &one);
- if(tmp_res != RES_OK) {
- *res = tmp_res;
- break;
- }
- }
- /* Add self */
- tmp_res =
- htable_part_id_set(&part->parts_to_merge_with, &part->part_id, &one);
- if(tmp_res != RES_OK) {
- *res = tmp_res;
- continue;
- }
- } /* Implicit barrier here */
-
- /* Merge the parts to create components */
- #pragma omp for
- for(ppp = 0; ppp < (int64_t)part_count; ppp++) {
- part_id_t pid = (part_id_t)ppp;
- struct cc_descriptor* cc = NULL;
- struct part_descriptor* part = parts[pid];
- struct htable_part_id_iterator beg, it, end;
- double max_y = -DBL_MAX;
- vrtx_id_t max_y_vrtx_id = VRTX_NULL__;
- double edge[2], normal[2], norm, max_y_ny = 0;
- double comp_max_y;
- ATOMIC id;
- res_T tmp_res = RES_OK;
-
- if(*res != RES_OK) continue;
- if(part->not_head_of_group) continue;
-
- /* Create the component to hold merged data */
- cc = MEM_ALLOC(alloc, sizeof(struct cc_descriptor));
- if(!cc) {
- *res = RES_MEM_ERR;
- continue;
- }
-
- cc_descriptor_init(alloc, cc);
- id = ATOMIC_INCR(component_count) - 1;
- ASSERT(id <= COMPONENT_MAX__);
- cc->cc_id = (component_id_t)id;
-
- /* Need to synchronize connex_components growth as this global structure
- * is accessed by multipe threads */
- #pragma omp critical
- {
- struct cc_descriptor** components;
- size_t sz = darray_ptr_component_descriptor_size_get(connex_components);
- if(sz <= cc->cc_id) {
- res_T r = darray_ptr_component_descriptor_resize(connex_components,
- 1 + cc->cc_id);
- if(r != RES_OK) *res = r;
- }
- if(*res == RES_OK) {
- /* Don't set the pointer before resize as this can lead to move data */
- components = darray_ptr_component_descriptor_data_get(connex_components);
- ASSERT(components[cc->cc_id] == NULL);
- components[cc->cc_id] = cc;
- }
- }
- if(*res != RES_OK) goto tmp_error;
-
- /* Find max y accross parts and process counts */
- htable_part_id_begin(&part->parts_to_merge_with, &beg);
- htable_part_id_end(&part->parts_to_merge_with, &end);
- it = beg;
- while(!htable_part_id_iterator_eq(&it, &end)) {
- part_id_t* did = htable_part_id_iterator_key_get(&it);
- struct part_descriptor* d;
- htable_part_id_iterator_next(&it);
-
- ASSERT(did);
- d = parts[*did];
-
- p2c[*did] = cc->cc_id;
-
- cc->side_count += d->side_count;
- cc->side_range.first = MMIN(cc->side_range.first, d->side_range.first);
- cc->side_range.last = MMAX(cc->side_range.last, d->side_range.last);
- tmp_res = htable_media_set(&cc->media, &d->medium, &one);
- if(tmp_res != RES_OK) {
- *res = tmp_res;
- goto tmp_error;
- }
-
- comp_max_y = vertices[d->max_y_vrtx_id].pos.y;
- if(max_y < comp_max_y) {
- max_y = comp_max_y;
- max_y_vrtx_id = d->max_y_vrtx_id;
- }
- }
- ASSERT(max_y_vrtx_id != VRTX_NULL__);
- cc->max_y_vrtx_id = max_y_vrtx_id;
-
- /* Process the parts with max_y as max y value to compute local normal
- * at max_y_vrtx_id vertex from sides sharing it */
- it = beg;
- while(!htable_part_id_iterator_eq(&it, &end)) {
- part_id_t* did = htable_part_id_iterator_key_get(&it);
- struct part_descriptor* d = parts[*did];
- side_id_t side_id;
- htable_part_id_iterator_next(&it);
-
- comp_max_y = vertices[d->max_y_vrtx_id].pos.y;
- if(max_y != comp_max_y) continue;
- FOR_EACH(side_id, d->side_range.first, d->side_range.last) {
- const seg_id_t seg_id = SEGSIDE_2_SEG(side_id);
- enum side_flag side_flag = SEGSIDE_2_SIDE(side_id);
- const struct segment_in* seg_in =
- darray_segment_in_cdata_get(&desc->scene->segments_in) + seg_id;
- const struct segment_part* seg_part =
- darray_segment_part_cdata_get(segments_part) + seg_id;
-
- /* To garanty that segments with 2 sides in the component total to 0
- * regardless of numeric accuracy, we need to prevent them to
- * contribute (remember than x + y - x - y can be non-zero). */
- if(part2comp(part2comp_table, seg_part->part[SIDE_FRONT]) ==
- part2comp(part2comp_table, seg_part->part[SIDE_BACK]))
- continue;
- /* Is this side a member of the component? */
- if(seg_part->part[side_flag] != d->part_id) continue;
- /* Does this segment use the currently selected max_y vertex? */
- if(max_y_vrtx_id != seg_in->vertice_id[0]
- && max_y_vrtx_id != seg_in->vertice_id[1])
- continue;
-
- /* This segments' normal contributes to the local normal */
- d2_sub(edge, vertices[seg_in->vertice_id[1]].vec,
- vertices[seg_in->vertice_id[0]].vec);
- d2(normal, edge[1], -edge[0]);
- norm = d2_normalize(normal, normal);
- ASSERT(norm); (void)norm;
-
- /* Geometrical normal points toward the back side */
- if(SEGSIDE_IS_FRONT(side_id)) {
- max_y_ny -= normal[1];
- } else {
- max_y_ny += normal[1];
- }
- }
- }
-
- /* All this computation was to set this flag!
- * Note that it cannot be computed from the flags of the parts of the
- * component as we need to filter segments whom 2 sides belongs to
- * the component (to ensure n + -n = 0) but each side was member of 2
- * different parts. */
- cc->is_outer_border = (max_y_ny < 0);
- continue;
- tmp_error:
- MEM_RM(alloc, cc);
- *res = tmp_res;
- continue;
- }
-
- return;
-}
-
-static void
group_connex_components
(struct senc2d_descriptor* desc,
struct segside* segsides,
- struct darray_segment_part* segments_part,
+ struct darray_segment_comp* segments_comp,
struct darray_ptr_component_descriptor* connex_components,
- struct darray_component_id* part2comp_table,
struct s2d_scene_view* s2d_view,
ATOMIC* next_enclosure_id,
- ATOMIC* infinity_first_cc,
/* Shared error status.
* We accept to overwritte an error with a different error */
res_T* res)
@@ -717,12 +526,10 @@ group_connex_components
size_t tmp;
component_id_t cc_count;
int64_t ccc;
- struct filter_context context;
-
(void)segsides;
- ASSERT(desc && segsides && segments_part && connex_components && part2comp_table
- && s2d_view && next_enclosure_id && infinity_first_cc && res);
+ ASSERT(desc && segsides && segments_comp && connex_components
+ && s2d_view && next_enclosure_id && res);
ASSERT(desc->enclosures_count == 1);
descriptors = darray_ptr_component_descriptor_data_get(connex_components);
@@ -730,8 +537,6 @@ group_connex_components
ASSERT(tmp <= COMPONENT_MAX__);
cc_count = (component_id_t)tmp;
positions = darray_position_cdata_get(&desc->scene->vertices);
- context.segments_part = segments_part;
- context.part2comp_table = part2comp_table;
/* Cast rays to find links between connex components */
#pragma omp for
@@ -764,28 +569,23 @@ group_connex_components
f2_set_d2(origin, max_vrtx);
/* Self-hit data: self hit if hit this component "on the other side" */
- context.self_hit_component = &self_hit_component;
tmp_res = s2d_scene_view_trace_ray(s2d_view, origin, dir, range,
- &context, &hit);
+ &self_hit_component, &hit);
if(tmp_res != RES_OK) {
*res = tmp_res;
continue;
}
/* If no hit, the component is facing an infinite medium */
if(S2D_HIT_NONE(&hit)) {
- struct cc_descriptor* inf_first_cc;
cc->cc_group_root = CC_GROUP_ROOT_INFINITE;
cc->enclosure_id = 0;
- /* Keep track of the first component facing infinity */
- ATOMIC_CAS(infinity_first_cc, (ATOMIC)cc, (ATOMIC)NULL);
- inf_first_cc = (struct cc_descriptor*)ATOMIC_GET(infinity_first_cc);
} else {
/* If hit, group this component */
const seg_id_t hit_seg_id = (seg_id_t)hit.prim.prim_id;
/* const struct segment_in* hit_seg_in =
darray_segment_in_cdata_get(&desc->scene->segments_in) + hit_seg_id; */
- const struct segment_part* hit_seg_part =
- darray_segment_part_cdata_get(segments_part) + hit_seg_id;
+ const struct segment_comp* hit_seg_comp =
+ darray_segment_comp_cdata_get(segments_comp) + hit_seg_id;
enum side_id hit_side = (hit.normal[1] > 0) ? SIDE_FRONT : SIDE_BACK;
/* const side_id_t hit_side_id
= SEGIDxSIDE_2_SEGSIDE(hit_seg_id, hit_side); */
@@ -793,8 +593,7 @@ group_connex_components
ASSERT(hit_seg_id < desc->scene->nusegs);
/* Not really the root until following links */
- cc->cc_group_root =
- part2comp(part2comp_table, hit_seg_part->part[hit_side]);
+ cc->cc_group_root = hit_seg_comp->component[hit_side];
ASSERT(cc->cc_group_root < cc_count);
}
}
@@ -1007,8 +806,7 @@ static void
build_result
(struct senc2d_descriptor* desc,
const struct darray_ptr_component_descriptor* connex_components,
- struct darray_component_id* part2comp_table,
- const struct darray_segment_part* segments_part_array,
+ const struct darray_segment_comp* segments_comp_array,
/* Shared error status.
* We accept to overwritte an error with a different error */
res_T* res)
@@ -1020,12 +818,12 @@ build_result
struct enclosure_data* enclosures;
const struct segment_in* segments_in;
struct segment_enc* segments_enc;
- const struct segment_part* segments_part;
+ const struct segment_comp* segments_comp;
struct htable_vrtx_id vtable;
int64_t sg;
int64_t ee;
- ASSERT(desc && connex_components && segments_part_array && res);
+ ASSERT(desc && connex_components && segments_comp_array && res);
alloc = descriptor_get_allocator(desc);
ASSERT(darray_ptr_component_descriptor_size_get(connex_components)
@@ -1033,7 +831,7 @@ build_result
cc_descriptors = darray_ptr_component_descriptor_cdata_get(connex_components);
enclosures = darray_enclosure_data_get(&desc->enclosures);
segments_in = darray_segment_in_cdata_get(&desc->scene->segments_in);
- segments_part = darray_segment_part_cdata_get(segments_part_array);
+ segments_comp = darray_segment_comp_cdata_get(segments_comp_array);
#pragma omp single
{
res_T tmp_res =
@@ -1047,10 +845,8 @@ build_result
#pragma omp for
for(sg = 0; sg < (int64_t)desc->scene->nusegs; sg++) {
seg_id_t s = (seg_id_t)sg;
- const part_id_t pf_id = segments_part[s].part[SIDE_FRONT];
- const part_id_t pb_id = segments_part[s].part[SIDE_BACK];
- const component_id_t cf_id = part2comp(part2comp_table, pf_id);
- const component_id_t cb_id = part2comp(part2comp_table, pb_id);
+ const component_id_t cf_id = segments_comp[s].component[SIDE_FRONT];
+ const component_id_t cb_id = segments_comp[s].component[SIDE_BACK];
const struct cc_descriptor* cf = cc_descriptors[cf_id];
const struct cc_descriptor* cb = cc_descriptors[cb_id];
const enclosure_id_t ef_id = cf->enclosure_id;
@@ -1194,15 +990,11 @@ senc2d_scene_analyze
char segments_tmp_initialized = 0;
/* Array of connex components.
* They are refered to by arrays of ids. */
- struct darray_ptr_part_descriptor connex_parts;
- char connex_parts_initialized = 0;
- struct darray_component_id part2comp_table;
- char part2comp_table_initialized = 0;
struct darray_ptr_component_descriptor connex_components;
char connex_components_initialized = 0;
- /* Store by-segment parts */
- struct darray_segment_part segments_part;
- char segments_part_initialized = 0;
+ /* Store by-segment components */
+ struct darray_segment_comp segments_comp;
+ char segments_comp_initialized = 0;
/* Array of vertices (segment ends). */
struct segside* segsides = NULL;
struct s2d_scene_view* s2d_view = NULL;
@@ -1210,13 +1002,8 @@ senc2d_scene_analyze
struct darray_neighbourhood neighbourhood_by_vertex;
char neighbourhood_by_vertex_initialized = 0;
/* Atomic counters to share beetwen threads */
- ATOMIC part_count = 0;
ATOMIC component_count = 0;
ATOMIC next_enclosure_id = 1;
- /* Used as args to have shared vars between threads in functions */
- static_assert(sizeof(intptr_t) == sizeof(ATOMIC),
- "Cannot use ATOMIC to store pointers");
- ATOMIC infinity_first_cc = (ATOMIC)NULL;
res_T res = RES_OK;
res_T res2 = RES_OK;
@@ -1266,14 +1053,15 @@ senc2d_scene_analyze
{
res_T tmp_res = RES_OK;
- darray_segment_part_init(scn->dev->allocator, &segments_part);
- segments_part_initialized = 1;
- OK2(darray_segment_part_resize(&segments_part, scn->nusegs));
- darray_ptr_part_descriptor_init(scn->dev->allocator,
- &connex_parts);
- connex_parts_initialized = 1;
+ darray_ptr_component_descriptor_init(scn->dev->allocator,
+ &connex_components);
+ connex_components_initialized = 1;
/* Just a hint; to limit contention */
- OK2(darray_ptr_part_descriptor_reserve(&connex_parts, 2 * scn->nmeds));
+ OK2(darray_ptr_component_descriptor_reserve(&connex_components,
+ 2 * scn->nmeds));
+ darray_segment_comp_init(scn->dev->allocator, &segments_comp);
+ segments_comp_initialized = 1;
+ OK2(darray_segment_comp_resize(&segments_comp, scn->nusegs));
tmp_error:
if(tmp_res != RES_OK) res2 = tmp_res;
}
@@ -1301,8 +1089,8 @@ senc2d_scene_analyze
} /* No barrier here */
/* Step 2: extract segment connex components */
- extract_connex_parts(desc, segsides, &connex_parts, &segments_tmp,
- &segments_part, &s2d_view, &part_count, &res);
+ extract_connex_components(desc, segsides, &connex_components,
+ &segments_tmp, &segments_comp, &s2d_view, &component_count, &res);
/* No barrier at the end of step 2: data used in step 2 cannot be
* released / data produced by step 2 cannot be used
* until next sync point */
@@ -1319,51 +1107,19 @@ senc2d_scene_analyze
goto error_;
}
- #pragma omp sections
+ /* One thread releases some data before going to step 3,
+ * the others go to step 3 without sync */
+ #pragma omp single nowait
{
- /* One thread releases some data */
- #pragma omp section
- {
- darray_segment_tmp_release(&segments_tmp);
- segments_tmp_initialized = 0;
- }
- /* Another allocates */
- #pragma omp section
- {
- res_T tmp_res = RES_OK;
- component_id_t* data;
- size_t parts_count = darray_ptr_part_descriptor_size_get(&connex_parts);
- size_t i;
-
- darray_component_id_init(scn->dev->allocator, &part2comp_table);
- part2comp_table_initialized = 1;
- tmp_res = darray_component_id_resize(&part2comp_table, parts_count);
- if(tmp_res != RES_OK) goto tmp2_error;
- data = darray_component_id_data_get(&part2comp_table);
- FOR_EACH(i, 0, parts_count) data[i] = PART_NULL__;
- darray_ptr_component_descriptor_init(scn->dev->allocator,
- &connex_components);
- connex_components_initialized = 1;
- /* Just a starting point */
- tmp_res = darray_ptr_component_descriptor_reserve(&connex_components,
- 2 * scn->nmeds);
- tmp2_error:
- if(tmp_res != RES_OK) res2 = tmp_res;
- }
- }
- /* Implicit barrier here */
-
- /* Step 3: merge parts */
- merge_connex_parts(desc, &segments_part, &connex_parts,
- &connex_components, &part2comp_table, &component_count, &res);
- /* Barrier at the end of step 3: data used in step 4 can be released /
- * data produced by step 4 can be used */
+ darray_segment_tmp_release(&segments_tmp);
+ segments_tmp_initialized = 0;
+ } /* No barrier here */
- /* Step 4: group components */
- group_connex_components(desc, segsides, &segments_part, &connex_components,
- &part2comp_table, s2d_view, &next_enclosure_id, &infinity_first_cc, &res);
- /* Barrier at the end of step 4: data used in step 4 can be released /
- * data produced by step 4 can be used */
+ /* Step 3: group components */
+ group_connex_components(desc, segsides, &segments_comp, &connex_components,
+ s2d_view, &next_enclosure_id, &res);
+ /* Barrier at the end of step 3: data used in step 3 can be released /
+ * data produced by step 3 can be used */
if(res != RES_OK) {
#pragma omp single nowait
@@ -1374,24 +1130,22 @@ senc2d_scene_analyze
goto error_;
}
- /* One thread releases some data before going to step 5,
- * the others go to step 5 without sync */
+ /* One thread releases some data before going to step 4,
+ * the others go to step 4 without sync */
#pragma omp single nowait
{
- custom_darray_ptr_part_descriptor_release(&connex_parts);
- connex_parts_initialized = 0;
if(s2d_view) S2D(scene_view_ref_put(s2d_view));
s2d_view = NULL;
} /* No barrier here */
- /* Step 5: Build result */
- build_result(desc, &connex_components, &part2comp_table, &segments_part, &res);
- /* No barrier at the end of step 5: data used in step 5 cannot be
- * released / data produced by step 5 cannot be used
+ /* Step 4: Build result */
+ build_result(desc, &connex_components, &segments_comp, &res);
+ /* No barrier at the end of step 4: data used in step 4 cannot be
+ * released / data produced by step 4 cannot be used
* until next sync point */
#pragma omp barrier
- /* Constraints on step 5 data are now met */
+ /* Constraints on step 4 data are now met */
if(res != RES_OK) {
#pragma omp single nowait
@@ -1411,13 +1165,8 @@ senc2d_scene_analyze
}
#pragma omp section
{
- darray_segment_part_release(&segments_part);
- segments_part_initialized = 0;
- }
-#pragma omp section
- {
- darray_component_id_release(&part2comp_table);
- part2comp_table_initialized = 0;
+ darray_segment_comp_release(&segments_comp);
+ segments_comp_initialized = 0;
}
} /* No barrier here */
error_:
@@ -1426,17 +1175,13 @@ error_:
if(res != RES_OK) goto error;
exit:
- if(connex_parts_initialized)
- custom_darray_ptr_part_descriptor_release(&connex_parts);
if(connex_components_initialized)
custom_darray_ptr_component_descriptor_release(&connex_components);
- if(connex_parts_initialized)
- custom_darray_ptr_part_descriptor_release(&connex_parts);
if(s2d_view) S2D(scene_view_ref_put(s2d_view));
if(neighbourhood_by_vertex_initialized)
darray_neighbourhood_release(&neighbourhood_by_vertex);
if(segments_tmp_initialized) darray_segment_tmp_release(&segments_tmp);
- if(segments_part_initialized) darray_segment_part_release(&segments_part);
+ if(segments_comp_initialized) darray_segment_comp_release(&segments_comp);
if(segsides) MEM_RM(scn->dev->allocator, segsides);
if(desc) *out_desc = desc;
diff --git a/src/senc2d_scene_analyze_c.h b/src/senc2d_scene_analyze_c.h
@@ -43,78 +43,10 @@ struct segside {
* front(seg_0), back(seg_0), front(seg_1), back(seg_1), ... */
};
-#define HTABLE_NAME part_id
-#define HTABLE_KEY part_id_t
-#define HTABLE_DATA char
-#include <rsys/hash_table.h>
-
#define DARRAY_NAME side_id
#define DARRAY_DATA side_id_t
#include <rsys/dynamic_array.h>
-/* Descriptors for parts of connex components.
- * Define lists of seg sides starting from a given head.
- * Also keeps the maximum y info of the component
- * along with the associated segment and vertex ids
- * and the list of media found */
-struct part_descriptor {
- char not_head_of_group;
- component_id_t part_id;
- vrtx_id_t max_y_vrtx_id; /* id of the vrtx with max y value */
- side_id_t side_count;
- medium_id_t medium;
- /* Range of sides member of this part */
- struct side_range side_range;
- /* Other parts that need to be merged with this one */
- struct htable_part_id parts_to_merge_with;
-};
-extern const struct part_descriptor PART_DESCRIPTOR_NULL;
-
-static FINLINE void
-part_descriptor_init
- (struct mem_allocator* alloc,
- struct part_descriptor* data)
-{
- ASSERT(data);
- (void) alloc;
- *data = PART_DESCRIPTOR_NULL;
- htable_part_id_init(alloc, &data->parts_to_merge_with);
-}
-
-static FINLINE void
-ptr_part_descriptor_init
- (struct mem_allocator* alloc,
- struct part_descriptor** data)
-{
- (void) alloc;
- ASSERT(data);
- *data = NULL;
-}
-
-#define DARRAY_NAME ptr_part_descriptor
-#define DARRAY_DATA struct part_descriptor*
-#define DARRAY_FUNCTOR_INIT ptr_part_descriptor_init
-#include <rsys/dynamic_array.h>
-
-/* Need allocator to free array elts: cannot rely on standard
-* darray release stuff */
-static FINLINE void
-custom_darray_ptr_part_descriptor_release
- (struct darray_ptr_part_descriptor* array)
-{
- size_t c, cc_count;
- struct part_descriptor** components;
- if(!array) return;
- cc_count = darray_ptr_part_descriptor_size_get(array);
- components = darray_ptr_part_descriptor_data_get(array);
- FOR_EACH(c, 0, cc_count) {
- if(!components[c]) continue;
- htable_part_id_release(&components[c]->parts_to_merge_with);
- MEM_RM(array->allocator, components[c]);
- }
- darray_ptr_part_descriptor_release(array);
-}
-
/* Descriptors for connex components.
* Define lists of seg sides starting from a given head.
* Also keeps the maximum y info of the component
@@ -129,7 +61,7 @@ struct cc_descriptor {
component_id_t cc_id;
component_id_t cc_group_root;
enclosure_id_t enclosure_id;
- /* Range of sides member of this part */
+ /* Range of sides member of this component */
struct side_range side_range;
/* Media used by this component */
struct htable_media media;