commit 3a39415e7b52f5803263478aebe14334d6ada621
parent e4b7efbbd5d1578ca4ffac48b197e13699bccb5e
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Tue, 6 Mar 2018 17:32:49 +0100
Better lifetime management for some thread related data structures.
Diffstat:
1 file changed, 282 insertions(+), 281 deletions(-)
diff --git a/src/senc_scene_analyze.c b/src/senc_scene_analyze.c
@@ -149,7 +149,6 @@ extract_connex_components
const struct senc_scene* scn;
struct mem_allocator* alloc;
ATOMIC component_count = 0;
- int stack_initialised = 0;
int mm;
#ifndef NDEBUG
trg_id_t t;
@@ -179,226 +178,223 @@ extract_connex_components
}
#endif
- #pragma omp parallel for firstprivate(stack_initialised) schedule(dynamic)
- for(mm = 0; mm < scn->nmeds; mm++) { /* Process all media */
- const medium_id_t m = (medium_id_t)mm;
- struct cc_descriptor* cc;
+ #pragma omp parallel
+ {
struct darray_side_id stack;
- /* Any not-already-used side is used as a starting point */
- side_id_t first_side_not_in_component;
- if(res != RES_OK) continue;
- first_side_not_in_component
- = darray_side_range_cdata_get(&scn->media_use)[m].first;
- if(first_side_not_in_component == SIDE_NULL__)
- continue; /* Unused medium */
- ASSERT(first_side_not_in_component < 2 * scn->nutris);
- if(!stack_initialised) {
- stack_initialised = 1;
- darray_side_id_init(alloc, &stack);
- }
- ASSERT(darray_side_id_size_get(&stack) == 0);
- for(;;) { /* Process all components for this medium */
- const side_id_t start_side_id = get_side_not_in_connex_component(scn,
- trgsides, &first_side_not_in_component, m);
- side_id_t crt_side_id = start_side_id;
- side_id_t last_side_id = start_side_id;
- ASSERT(start_side_id == SIDE_NULL__ || start_side_id < 2 * scn->nutris);
- if(start_side_id == SIDE_NULL__) { /* start_side_id=SIDE_NULL__ => done! */
- if(stack_initialised) {
- stack_initialised = 0; /* TODO: don't recreate stack for same thread */
- darray_side_id_release(&stack);
- }
- break;
- }
- ASSERT(trgsides[start_side_id].list_id == FLAG_LIST_SIDE_LIST);
+ darray_side_id_init(alloc, &stack);
+
+ #pragma omp for schedule(dynamic)
+ for(mm = 0; mm < scn->nmeds; mm++) { /* Process all media */
+ const medium_id_t m = (medium_id_t)mm;
+ struct cc_descriptor* cc;
+ /* Any not-already-used side is used as a starting point */
+ side_id_t first_side_not_in_component;
+ if(res != RES_OK) continue;
+ first_side_not_in_component
+ = darray_side_range_cdata_get(&scn->media_use)[m].first;
+ if(first_side_not_in_component == SIDE_NULL__)
+ continue; /* Unused medium */
+ ASSERT(first_side_not_in_component < 2 * scn->nutris);
+ ASSERT(darray_side_id_size_get(&stack) == 0);
+ for(;;) { /* Process all components for this medium */
+ const side_id_t start_side_id = get_side_not_in_connex_component(scn,
+ trgsides, &first_side_not_in_component, m);
+ side_id_t crt_side_id = start_side_id;
+ side_id_t last_side_id = start_side_id;
+ ASSERT(start_side_id == SIDE_NULL__ || start_side_id < 2 * scn->nutris);
+ if(start_side_id == SIDE_NULL__) /* start_side_id=SIDE_NULL__ => done! */
+ break;
+ ASSERT(trgsides[start_side_id].list_id == FLAG_LIST_SIDE_LIST);
#ifndef NDEBUG
- {
- trg_id_t tid = TRGSIDE_2_TRG(start_side_id);
- enum side_flag s = TRGSIDE_2_SIDE(start_side_id);
- medium_id_t side_med = darray_triangle_in_data_get(&desc->scene->triangles_in)[tid].medium[s];
- ASSERT(side_med == m);
- }
+ {
+ trg_id_t tid = TRGSIDE_2_TRG(start_side_id);
+ enum side_flag s = TRGSIDE_2_SIDE(start_side_id);
+ medium_id_t side_med = darray_triangle_in_data_get(&desc->scene->triangles_in)[tid].medium[s];
+ ASSERT(side_med == m);
+ }
#endif
- /* Create and init a new component */
- cc = MEM_ALLOC(alloc, sizeof(struct cc_descriptor));
- if(!cc) {
- res = RES_MEM_ERR;
- goto error;
- }
- cc_descriptor_init(alloc, cc);
- ASSERT(m == trgsides[start_side_id].medium);
- cc->cc_id = (component_id_t)(ATOMIC_INCR(&component_count) - 1);
- cc->medium = m;
- cc->side_range.first = start_side_id;
-
- for(;;) { /* Process all sides of this component */
- int i;
- enum side_flag crt_side_flag = TRGSIDE_2_SIDE(crt_side_id);
- struct trgside* crt_side = trgsides + crt_side_id;
- const trg_id_t crt_trg_id = TRGSIDE_2_TRG(crt_side_id);
- const struct triangle_in* trg_in =
- darray_triangle_in_cdata_get(&scn->triangles_in) + crt_trg_id;
- struct triangle_comp* trg_comp =
- darray_triangle_comp_data_get(triangles_comp) + crt_trg_id;
- const struct triangle_tmp* const trg_tmp =
- darray_triangle_tmp_cdata_get(triangles_tmp_array) + crt_trg_id;
- const union double3* vertices =
- darray_position_cdata_get(&scn->vertices);
- ASSERT(crt_trg_id < scn->nutris);
- ASSERT(trgsides[crt_side_id].medium == m);
-
- /* Record Zmax information
- * Keep track of the appropriate vertex/side of the connex 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 Z
- * coordinate.
- * If more than one vertex/side has the same Z, we want the side that
- * most faces Z (that is the one with the greater nz).
- * This is mandatory to select the correct side when both sides of a
- * triangle are candidate. */
- if(cc->max_vrtx[2] <= trg_tmp->max_z) {
- /* Can either improve z or nz */
-
- if(cc->max_z_side_id == TRGSIDE_OPPOSITE(crt_side_id)) {
- /* Both sides are in cc and the opposite side is currently selected
- * Just keep the side with nz>0 */
- if(cc->max_z_nz < 0) {
- /* Change side! */
- cc->max_z_nz = -cc->max_z_nz;
- cc->max_z_side_id = crt_side_id;
- }
- } else {
- double edge0[3], edge1[3], normal[3], norm, side_nz;
- int process = 0;
-
- d3_sub(edge0, vertices[trg_in->vertice_id[1]].vec,
- vertices[trg_in->vertice_id[0]].vec);
- d3_sub(edge1, vertices[trg_in->vertice_id[2]].vec,
- vertices[trg_in->vertice_id[0]].vec);
- d3_cross(normal, edge0, edge1);
- norm = d3_normalize(normal, normal);
- ASSERT(norm); (void) norm;
-
- if(TRGSIDE_IS_FRONT(crt_side_id)) {
- side_nz = normal[2];
- process = 1;
+ /* Create and init a new component */
+ cc = MEM_ALLOC(alloc, sizeof(struct cc_descriptor));
+ if(!cc) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ cc_descriptor_init(alloc, cc);
+ ASSERT(m == trgsides[start_side_id].medium);
+ cc->cc_id = (component_id_t)(ATOMIC_INCR(&component_count) - 1);
+ cc->medium = m;
+ cc->side_range.first = start_side_id;
+
+ for(;;) { /* Process all sides of this component */
+ int i;
+ enum side_flag crt_side_flag = TRGSIDE_2_SIDE(crt_side_id);
+ struct trgside* crt_side = trgsides + crt_side_id;
+ const trg_id_t crt_trg_id = TRGSIDE_2_TRG(crt_side_id);
+ const struct triangle_in* trg_in =
+ darray_triangle_in_cdata_get(&scn->triangles_in) + crt_trg_id;
+ struct triangle_comp* trg_comp =
+ darray_triangle_comp_data_get(triangles_comp) + crt_trg_id;
+ const struct triangle_tmp* const trg_tmp =
+ darray_triangle_tmp_cdata_get(triangles_tmp_array) + crt_trg_id;
+ const union double3* vertices =
+ darray_position_cdata_get(&scn->vertices);
+ ASSERT(crt_trg_id < scn->nutris);
+ ASSERT(trgsides[crt_side_id].medium == m);
+
+ /* Record Zmax information
+ * Keep track of the appropriate vertex/side of the connex 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 Z
+ * coordinate.
+ * If more than one vertex/side has the same Z, we want the side that
+ * most faces Z (that is the one with the greater nz).
+ * This is mandatory to select the correct side when both sides of a
+ * triangle are candidate. */
+ if(cc->max_vrtx[2] <= trg_tmp->max_z) {
+ /* Can either improve z or nz */
+
+ if(cc->max_z_side_id == TRGSIDE_OPPOSITE(crt_side_id)) {
+ /* Both sides are in cc and the opposite side is currently selected
+ * Just keep the side with nz>0 */
+ if(cc->max_z_nz < 0) {
+ /* Change side! */
+ cc->max_z_nz = -cc->max_z_nz;
+ cc->max_z_side_id = crt_side_id;
+ }
} else {
- side_nz = -normal[2];
- process = 1;
- }
-
- if(process) {
- int change = 0;
- if(cc->max_vrtx[2] < trg_tmp->max_z) {
- change = 1; /* Try first to improve z */
- } else if (cc->max_z_nz <= 0 && fabs(cc->max_z_nz) < fabs(side_nz)) {
- change = 1; /* If nz <= 0, the more negative the better */
- } else if (cc->max_z_nz > 0 && cc->max_z_nz < side_nz) {
- change = 1; /* If nz > 0, the more positive the better */
+ double edge0[3], edge1[3], normal[3], norm, side_nz;
+ int process = 0;
+
+ d3_sub(edge0, vertices[trg_in->vertice_id[1]].vec,
+ vertices[trg_in->vertice_id[0]].vec);
+ d3_sub(edge1, vertices[trg_in->vertice_id[2]].vec,
+ vertices[trg_in->vertice_id[0]].vec);
+ d3_cross(normal, edge0, edge1);
+ norm = d3_normalize(normal, normal);
+ ASSERT(norm); (void) norm;
+
+ if(TRGSIDE_IS_FRONT(crt_side_id)) {
+ side_nz = normal[2];
+ process = 1;
+ } else {
+ side_nz = -normal[2];
+ process = 1;
}
- if(change) {
- cc->max_z_nz = side_nz;
- cc->max_z_side_id = crt_side_id;
- ASSERT(trg_tmp->max_z_vrtx_id < 3);
- ASSERT(trg_in->vertice_id[trg_tmp->max_z_vrtx_id] < scn->nverts);
- cc->max_z_vrtx_id = trg_in->vertice_id[trg_tmp->max_z_vrtx_id];
- ASSERT(trg_tmp->max_z == vertices[cc->max_z_vrtx_id].pos.z);
- d3_set(cc->max_vrtx, vertices[cc->max_z_vrtx_id].vec);
+ if(process) {
+ int change = 0;
+ if(cc->max_vrtx[2] < trg_tmp->max_z) {
+ change = 1; /* Try first to improve z */
+ } else if(cc->max_z_nz <= 0 && fabs(cc->max_z_nz) < fabs(side_nz)) {
+ change = 1; /* If nz <= 0, the more negative the better */
+ } else if(cc->max_z_nz > 0 && cc->max_z_nz < side_nz) {
+ change = 1; /* If nz > 0, the more positive the better */
+ }
+
+ if(change) {
+ cc->max_z_nz = side_nz;
+ cc->max_z_side_id = crt_side_id;
+ ASSERT(trg_tmp->max_z_vrtx_id < 3);
+ ASSERT(trg_in->vertice_id[trg_tmp->max_z_vrtx_id] < scn->nverts);
+ cc->max_z_vrtx_id = trg_in->vertice_id[trg_tmp->max_z_vrtx_id];
+ ASSERT(trg_tmp->max_z == vertices[cc->max_z_vrtx_id].pos.z);
+ d3_set(cc->max_vrtx, vertices[cc->max_z_vrtx_id].vec);
+ }
}
}
}
- }
- /* Record crt_side both as component and triangle level */
- cc->side_count++;
- trgsides[crt_side_id].list_id = FLAG_LIST_COMPONENT;
- ASSERT(trg_comp->component[crt_side_flag] == COMPONENT_NULL__);
- trg_comp->component[crt_side_flag] = cc->cc_id;
+ /* Record crt_side both as component and triangle level */
+ cc->side_count++;
+ trgsides[crt_side_id].list_id = FLAG_LIST_COMPONENT;
+ ASSERT(trg_comp->component[crt_side_flag] == COMPONENT_NULL__);
+ trg_comp->component[crt_side_flag] = cc->cc_id;
#ifndef NDEBUG
- crt_side->member_of_cc = cc->cc_id;
+ crt_side->member_of_cc = cc->cc_id;
#endif
- /* Store neighbour sides in a waiting stack */
- FOR_EACH(i, 0, 3) {
- side_id_t neighbour_id = crt_side->facing_side_id[i];
- trg_id_t nbour_trg_id = TRGSIDE_2_TRG(neighbour_id);
- const struct trgside* neighbour = trgsides + neighbour_id;
- CHK(m == crt_side->medium);
- if(neighbour->medium != crt_side->medium) {
- /* Found medium discontinuity! Model topology is broken. */
- const struct triangle_in* triangles_in
- = darray_triangle_in_cdata_get(&scn->triangles_in);
- const union double3* positions
- = darray_position_cdata_get(&scn->vertices);
- log_err(scn->dev,
- "Medium mismatch found between neighbour triangles %lu %s"
- " side and %u %s side.\n",
- (unsigned long)triangles_in[crt_trg_id].global_id,
- TRGSIDE_IS_FRONT(crt_side_id) ? "front" : "back",
- triangles_in[nbour_trg_id].global_id,
- TRGSIDE_IS_FRONT(neighbour_id) ? "front" : "back");
- log_err(scn->dev,
- "Triangle %lu:\n (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n",
- (unsigned long)triangles_in[crt_trg_id].global_id,
- SPLIT3(positions[triangles_in[crt_trg_id].vertice_id[0]].vec),
- SPLIT3(positions[triangles_in[crt_trg_id].vertice_id[1]].vec),
- SPLIT3(positions[triangles_in[crt_trg_id].vertice_id[2]].vec));
- log_err(scn->dev,
- "Triangle %lu:\n (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n",
- (unsigned long)triangles_in[nbour_trg_id].global_id,
- SPLIT3(positions[triangles_in[nbour_trg_id].vertice_id[0]].vec),
- SPLIT3(positions[triangles_in[nbour_trg_id].vertice_id[1]].vec),
- SPLIT3(positions[triangles_in[nbour_trg_id].vertice_id[2]].vec));
- log_err(desc->scene->dev, "Media: %lu VS %lu\n",
- (unsigned long)neighbour->medium, (unsigned long)crt_side->medium);
- res = RES_BAD_ARG;
- goto error;
- }
- if(neighbour->list_id == FLAG_LIST_COMPONENT) {
- /* Already processed */
+ /* Store neighbour sides in a waiting stack */
+ FOR_EACH(i, 0, 3) {
+ side_id_t neighbour_id = crt_side->facing_side_id[i];
+ trg_id_t nbour_trg_id = TRGSIDE_2_TRG(neighbour_id);
+ const struct trgside* neighbour = trgsides + neighbour_id;
+ CHK(m == crt_side->medium);
+ if(neighbour->medium != crt_side->medium) {
+ /* Found medium discontinuity! Model topology is broken. */
+ const struct triangle_in* triangles_in
+ = darray_triangle_in_cdata_get(&scn->triangles_in);
+ const union double3* positions
+ = darray_position_cdata_get(&scn->vertices);
+ log_err(scn->dev,
+ "Medium mismatch found between neighbour triangles %lu %s"
+ " side and %u %s side.\n",
+ (unsigned long)triangles_in[crt_trg_id].global_id,
+ TRGSIDE_IS_FRONT(crt_side_id) ? "front" : "back",
+ triangles_in[nbour_trg_id].global_id,
+ TRGSIDE_IS_FRONT(neighbour_id) ? "front" : "back");
+ log_err(scn->dev,
+ "Triangle %lu:\n (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n",
+ (unsigned long)triangles_in[crt_trg_id].global_id,
+ SPLIT3(positions[triangles_in[crt_trg_id].vertice_id[0]].vec),
+ SPLIT3(positions[triangles_in[crt_trg_id].vertice_id[1]].vec),
+ SPLIT3(positions[triangles_in[crt_trg_id].vertice_id[2]].vec));
+ log_err(scn->dev,
+ "Triangle %lu:\n (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n",
+ (unsigned long)triangles_in[nbour_trg_id].global_id,
+ SPLIT3(positions[triangles_in[nbour_trg_id].vertice_id[0]].vec),
+ SPLIT3(positions[triangles_in[nbour_trg_id].vertice_id[1]].vec),
+ SPLIT3(positions[triangles_in[nbour_trg_id].vertice_id[2]].vec));
+ log_err(desc->scene->dev, "Media: %lu VS %lu\n",
+ (unsigned long)neighbour->medium, (unsigned long)crt_side->medium);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if(neighbour->list_id == FLAG_LIST_COMPONENT) {
+ /* Already processed */
#ifndef NDEBUG
- ASSERT(neighbour->member_of_cc == cc->cc_id);
+ ASSERT(neighbour->member_of_cc == cc->cc_id);
#endif
- continue;
- }
- if(neighbour->list_id == FLAG_WAITING_STACK) {
- continue; /* Already processed */
+ continue;
+ }
+ if(neighbour->list_id == FLAG_WAITING_STACK) {
+ continue; /* Already processed */
+ }
+ add_side_to_stack(scn, &stack, trgsides, neighbour_id);
}
- add_side_to_stack(scn, &stack, trgsides, neighbour_id);
- }
- if(darray_side_id_size_get(&stack) == 0)
- break; /* Empty stack => connex component is done! */
- crt_side_id = get_side_from_stack(trgsides, &stack);
- last_side_id = MMAX(last_side_id, crt_side_id);
- }
- /* Keep track of this new connex component */
- cc->side_range.last = last_side_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 tmp_res = darray_ptr_component_descriptor_resize(connex_components,
- 1 + cc->cc_id);
- if(tmp_res != RES_OK) res = tmp_res;
+ if(darray_side_id_size_get(&stack) == 0)
+ break; /* Empty stack => connex component is done! */
+ crt_side_id = get_side_from_stack(trgsides, &stack);
+ last_side_id = MMAX(last_side_id, crt_side_id);
}
- 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;
+ /* Keep track of this new connex component */
+ cc->side_range.last = last_side_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 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 */
+ components =
+ darray_ptr_component_descriptor_data_get(connex_components);
+ ASSERT(components[cc->cc_id] == NULL);
+ components[cc->cc_id] = cc;
+ }
}
}
+ error:
+ continue; /* Cannot exit openmp block */
}
- error:
- continue; /* Cannot exit openmp block */
+ darray_side_id_release(&stack);
}
OK2(res, error_);
@@ -968,94 +964,99 @@ build_result
/* Resize/push operations on enclosure's fields are valid in the
* openmp block as a given enclosure is processed by a single thread */
- #pragma omp parallel for schedule(dynamic)
- for(ee = 0; ee < (int)desc->enclosures_count; ee++) {
- const enclosure_id_t e = (enclosure_id_t)ee;
- struct enclosure_data* enc = enclosures + e;
- const struct cc_descriptor* current = cc_descriptors[enc->first_component];
- struct htable_vrtx_id vtable; /* TODO: don't recreate vtable for same thread */
- trg_id_t fst_idx = 0;
- trg_id_t sgd_idx = enc->side_count;;
- trg_id_t t;
- ASSERT(enc->first_component
- < darray_ptr_component_descriptor_size_get(connex_components));
- ASSERT(ee <= ENCLOSURE_MAX__);
- ASSERT(current->cc_id == enc->first_component);
-
- if(res != RES_OK) continue;
- ASSERT(e <= UINT_MAX);
- enc->header.enclosure_id = (unsigned)e; /* Back to API type */
- ASSERT(current->enclosure_id == enc->header.enclosure_id);
- enc->header.is_infinite = (e == 0);
- enc->header.enclosed_medium
- = (unsigned)current->medium; /* Back to API type */
- ASSERT(enc->header.enclosed_medium < desc->scene->nmeds);
-
- /* Build side and vertex lists. */
- OK(darray_triangle_in_resize(&enc->sides, enc->side_count));
- /* Size is just a int */
- OK(darray_vrtx_id_reserve(&enc->vertices,
- enc->side_count / 2 + enc->side_count / 8));
- /* New vertex numbering scheme local to the enclosure */
+ #pragma omp parallel
+ {
+ struct htable_vrtx_id vtable;
htable_vrtx_id_init(alloc, &vtable);
- ASSERT(desc->scene->nutris
- == darray_triangle_in_size_get(&desc->scene->triangles_in));
- /* Put at the end the back-faces of triangles that also have their
- * front-face in the list. */
- for(t = TRGSIDE_2_TRG(enc->side_range.first);
- t <= TRGSIDE_2_TRG(enc->side_range.last);
- t++)
- {
- const struct triangle_in* trg_in = triangles_in + t;
- struct triangle_in* trg;
- unsigned vertice_id[3];
- int i;
- if(triangles_enc[t].enclosure[SIDE_FRONT] != e
- && triangles_enc[t].enclosure[SIDE_BACK] != e)
- continue;
- ++enc->header.unique_triangle_count;
- FOR_EACH(i, 0, 3) {
- vrtx_id_t* id = htable_vrtx_id_find(&vtable, trg_in->vertice_id + i);
- if(id) {
- vertice_id[i] = *id; /* Known vertex */
- } else {
- /* Create new association */
- size_t tmp = htable_vrtx_id_size_get(&vtable);
- ASSERT(tmp == darray_vrtx_id_size_get(&enc->vertices));
- ASSERT(tmp < VRTX_MAX__);
- vertice_id[i] = (vrtx_id_t)tmp;
- OK(htable_vrtx_id_set(&vtable, trg_in->vertice_id + i,
- vertice_id + i));
- OK(darray_vrtx_id_push_back(&enc->vertices, vertice_id + i));
- ++enc->header.vertices_count;
+ #pragma omp for schedule(dynamic)
+ for(ee = 0; ee < (int)desc->enclosures_count; ee++) {
+ const enclosure_id_t e = (enclosure_id_t)ee;
+ struct enclosure_data* enc = enclosures + e;
+ const struct cc_descriptor* current = cc_descriptors[enc->first_component];
+ trg_id_t fst_idx = 0;
+ trg_id_t sgd_idx = enc->side_count;;
+ trg_id_t t;
+ ASSERT(enc->first_component
+ < darray_ptr_component_descriptor_size_get(connex_components));
+ ASSERT(ee <= ENCLOSURE_MAX__);
+ ASSERT(current->cc_id == enc->first_component);
+
+ if(res != RES_OK) continue;
+ ASSERT(e <= UINT_MAX);
+ enc->header.enclosure_id = (unsigned)e; /* Back to API type */
+ ASSERT(current->enclosure_id == enc->header.enclosure_id);
+ enc->header.is_infinite = (e == 0);
+ enc->header.enclosed_medium
+ = (unsigned)current->medium; /* Back to API type */
+ ASSERT(enc->header.enclosed_medium < desc->scene->nmeds);
+
+ /* Build side and vertex lists. */
+ OK(darray_triangle_in_resize(&enc->sides, enc->side_count));
+ /* Size is just a int */
+ OK(darray_vrtx_id_reserve(&enc->vertices,
+ enc->side_count / 2 + enc->side_count / 8));
+ /* New vertex numbering scheme local to the enclosure */
+ htable_vrtx_id_clear(&vtable);
+ ASSERT(desc->scene->nutris
+ == darray_triangle_in_size_get(&desc->scene->triangles_in));
+ /* Put at the end the back-faces of triangles that also have their
+ * front-face in the list. */
+ for(t = TRGSIDE_2_TRG(enc->side_range.first);
+ t <= TRGSIDE_2_TRG(enc->side_range.last);
+ t++)
+ {
+ const struct triangle_in* trg_in = triangles_in + t;
+ struct triangle_in* trg;
+ unsigned vertice_id[3];
+ int i;
+ if(triangles_enc[t].enclosure[SIDE_FRONT] != e
+ && triangles_enc[t].enclosure[SIDE_BACK] != e)
+ continue;
+ ++enc->header.unique_triangle_count;
+
+ FOR_EACH(i, 0, 3) {
+ vrtx_id_t* id = htable_vrtx_id_find(&vtable, trg_in->vertice_id + i);
+ if(id) {
+ vertice_id[i] = *id; /* Known vertex */
+ } else {
+ /* Create new association */
+ size_t tmp = htable_vrtx_id_size_get(&vtable);
+ ASSERT(tmp == darray_vrtx_id_size_get(&enc->vertices));
+ ASSERT(tmp < VRTX_MAX__);
+ vertice_id[i] = (vrtx_id_t)tmp;
+ OK(htable_vrtx_id_set(&vtable, trg_in->vertice_id + i,
+ vertice_id + i));
+ OK(darray_vrtx_id_push_back(&enc->vertices, vertice_id + i));
+ ++enc->header.vertices_count;
+ }
}
+ ASSERT(triangles_enc[t].enclosure[SIDE_FRONT] == e
+ || triangles_enc[t].enclosure[SIDE_BACK] == e);
+ if(triangles_enc[t].enclosure[SIDE_FRONT] == e) {
+ ++enc->header.triangle_count;
+ trg = darray_triangle_in_data_get(&enc->sides) + fst_idx++;
+
+ FOR_EACH(i, 0, 2) trg->medium[i] = trg_in->medium[i];
+ trg->global_id = trg_in->global_id;
+ FOR_EACH(i, 0, 3) trg->vertice_id[i] = vertice_id[i];
+ }
+ if(triangles_enc[t].enclosure[SIDE_BACK] == e) {
+ ++enc->header.triangle_count;
+ trg = darray_triangle_in_data_get(&enc->sides) +
+ ((triangles_enc[t].enclosure[SIDE_FRONT] == e) ? --sgd_idx : fst_idx++);
+
+ FOR_EACH(i, 0, 2) trg->medium[i] = trg_in->medium[1 - i];
+ trg->global_id = trg_in->global_id;
+ FOR_EACH(i, 0, 3) trg->vertice_id[i] = vertice_id[2 - i];
+ }
+ if(fst_idx == sgd_idx) break;
}
- ASSERT(triangles_enc[t].enclosure[SIDE_FRONT] == e
- || triangles_enc[t].enclosure[SIDE_BACK] == e);
- if(triangles_enc[t].enclosure[SIDE_FRONT] == e) {
- ++enc->header.triangle_count;
- trg = darray_triangle_in_data_get(&enc->sides) + fst_idx++;
-
- FOR_EACH(i, 0, 2) trg->medium[i] = trg_in->medium[i];
- trg->global_id = trg_in->global_id;
- FOR_EACH(i, 0, 3) trg->vertice_id[i] = vertice_id[i];
- }
- if(triangles_enc[t].enclosure[SIDE_BACK] == e) {
- ++enc->header.triangle_count;
- trg = darray_triangle_in_data_get(&enc->sides) +
- ((triangles_enc[t].enclosure[SIDE_FRONT] == e) ? --sgd_idx : fst_idx++);
-
- FOR_EACH(i, 0, 2) trg->medium[i] = trg_in->medium[1 - i];
- trg->global_id = trg_in->global_id;
- FOR_EACH(i, 0, 3) trg->vertice_id[i] = vertice_id[2 - i];
- }
- if(fst_idx == sgd_idx) break;
+ error:
+ /* Cannot exit openmp block */
+ continue;
}
htable_vrtx_id_release(&vtable);
- error:
- /* Cannot exit openmp block */
- continue;
}
OK2(res, error_);