commit 980cb99ba865ddb2649c1f9bcc3273f3454724ff
parent 00b401cd586b47fa9bfa7a316b6ae428b94739eb
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 30 Jul 2020 18:35:29 +0200
Fix the senc3d_scene_get_max_medium API call
Diffstat:
7 files changed, 100 insertions(+), 53 deletions(-)
diff --git a/src/senc3d.h b/src/senc3d.h
@@ -188,7 +188,7 @@ senc3d_scene_create
const unsigned itri,
unsigned ids[SENC3D_GEOMETRY_DIMENSION],
void* context),
- /* User function that provides media ids for triangles */
+ /* User function that provides medium ids for triangles */
void(*get_media) /* Can be NULL <=> SENC3D_UNSPECIFIED_MEDIUM medium used */
(const unsigned itri, unsigned med[2], void* context),
/* Number of vertices */
@@ -242,9 +242,10 @@ senc3d_scene_get_vertex
const unsigned ivert,
double coord[SENC3D_GEOMETRY_DIMENSION]);
-/* Returns the greater medium id found in added geometry. In API calls using a
- * medium, any value in the [0 max_medium_id[ range is valid. However there can
- * be unused ids (no geometry refered to this medium id). */
+/* Returns the greater medium id found in geometry or SENC3D_UNSPECIFIED_MEDIUM
+ * if the geometry only used SENC3D_UNSPECIFIED_MEDIUM. Any value in range
+ * [0 max_medium_id[ as well as SENC3D_UNSPECIFIED_MEDIUM is valid in API calls
+ * requiring a medium (even if this medium id is unused). */
SENC3D_API res_T
senc3d_scene_get_max_medium
(const struct senc3d_scene* scene,
@@ -257,11 +258,11 @@ senc3d_scene_get_enclosure_count
unsigned* count);
/* Returns the number of enclosures that have some geometry refering to the
- * imed_th medium or SENC3D_UNSPECIFIED_MEDIUM. */
+ * medium med (including SENC3D_UNSPECIFIED_MEDIUM). */
SENC3D_API res_T
senc3d_scene_get_enclosure_count_by_medium
(const struct senc3d_scene* scene,
- const unsigned imed,
+ const unsigned med,
unsigned* count);
/* Returns the idx_th enclosure. */
@@ -271,12 +272,12 @@ senc3d_scene_get_enclosure
const unsigned idx,
struct senc3d_enclosure** enclosure);
-/* Returns the idx_th enclosure using the imed_th medium or
- * SENC3D_UNSPECIFIED_MEDIUM. */
+/* Returns the idx_th enclosure using the medium med (including
+ * SENC3D_UNSPECIFIED_MEDIUM). */
SENC3D_API res_T
senc3d_scene_get_enclosure_by_medium
(struct senc3d_scene* scene,
- const unsigned imed,
+ const unsigned med,
const unsigned idx,
struct senc3d_enclosure** enclosure);
@@ -376,7 +377,7 @@ senc3d_enclosure_get_triangle_id
unsigned* gid,
enum senc3d_side* side);
-/* Returns the id of the imed_th medium of an enclosure. */
+/* Returns the the imed_th medium id of an enclosure. */
SENC3D_API res_T
senc3d_enclosure_get_medium
(const struct senc3d_enclosure* enclosure,
diff --git a/src/senc3d_descriptor.c b/src/senc3d_descriptor.c
@@ -29,7 +29,16 @@ senc3d_scene_get_max_medium
(const struct senc3d_scene* scn, medium_id_t* max_medium_id)
{
if(!scn || !max_medium_id) return RES_BAD_ARG;
- *max_medium_id = scn->next_medium_idx - 1;
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == darray_side_range_size_get(&scn->media_use));
+ ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
+ if(darray_side_range_size_get(&scn->media_use) == 1)
+ *max_medium_id = SENC3D_UNSPECIFIED_MEDIUM;
+ else {
+ size_t sz = darray_side_range_size_get(&scn->media_use) - 2;
+ ASSERT(sz <= MEDIUM_MAX__);
+ *max_medium_id = (medium_id_t)sz;
+ }
return RES_OK;
}
@@ -55,13 +64,15 @@ senc3d_scene_get_enclosure_count_by_medium
size_t tmp;
size_t m_idx;
const struct darray_enc_id* enc_ids;
- if(!scn || !count
- || (imed != SENC3D_UNSPECIFIED_MEDIUM && imed >= scn->next_medium_idx))
+ if(!scn || !count) return RES_BAD_ARG;
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == darray_side_range_size_get(&scn->media_use));
+ ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
+ if(imed != SENC3D_UNSPECIFIED_MEDIUM
+ && imed >= darray_side_range_size_get(&scn->media_use))
return RES_BAD_ARG;
if(darray_trg_id_size_get(&scn->analyze.overlapping_ids))
return RES_BAD_OP;
- ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
- == 1 + scn->next_medium_idx);
m_idx = medium_id_2_medium_idx(imed);
enc_ids = darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium)
+ m_idx;
@@ -79,6 +90,9 @@ senc3d_scene_get_enclosure
{
struct senc3d_enclosure* enc;
if(!scn || !out_enc) return RES_BAD_ARG;
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == darray_side_range_size_get(&scn->media_use));
+ ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
if(darray_trg_id_size_get(&scn->analyze.overlapping_ids))
return RES_BAD_OP;
if(idx >= darray_enclosure_size_get(&scn->analyze.enclosures))
@@ -99,16 +113,18 @@ senc3d_scene_get_enclosure_by_medium
size_t m_idx;
const struct darray_enc_id* enc_ids;
enclosure_id_t index;
- if(!scn || !out_enc
- || (imed != SENC3D_UNSPECIFIED_MEDIUM && imed >= scn->next_medium_idx))
+ if(!scn || !out_enc) return RES_BAD_ARG;
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == darray_side_range_size_get(&scn->media_use));
+ ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
+ if(imed != SENC3D_UNSPECIFIED_MEDIUM
+ && imed >= darray_side_range_size_get(&scn->media_use))
return RES_BAD_ARG;
if(darray_trg_id_size_get(&scn->analyze.overlapping_ids))
return RES_BAD_OP;
- ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
- == 1 + scn->next_medium_idx);
m_idx = medium_id_2_medium_idx(imed);
- enc_ids =
- darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium) + m_idx;
+ enc_ids = darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium)
+ + m_idx;
if(idx >= darray_enc_id_size_get(enc_ids)) return RES_BAD_ARG;
index = darray_enc_id_cdata_get(enc_ids)[idx];
return senc3d_scene_get_enclosure(scn, index, out_enc);
@@ -123,6 +139,9 @@ senc3d_scene_get_triangle_enclosures
const struct triangle_enc* trg;
int i;
if(!enclosures || !scn) return RES_BAD_ARG;
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == darray_side_range_size_get(&scn->media_use));
+ ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
if(darray_trg_id_size_get(&scn->analyze.overlapping_ids))
return RES_BAD_OP;
if(itri >= darray_triangle_enc_size_get(&scn->analyze.triangles_enc))
@@ -140,6 +159,9 @@ senc3d_scene_get_frontier_segments_count
size_t tmp;
if(!scn || !count)
return RES_BAD_ARG;
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == darray_side_range_size_get(&scn->media_use));
+ ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
if(darray_trg_id_size_get(&scn->analyze.overlapping_ids))
return RES_BAD_OP;
tmp = darray_frontier_edge_size_get(&scn->analyze.frontiers);
@@ -159,6 +181,9 @@ senc3d_scene_get_frontier_segment
if(!vrtx_id || !scn || !trg_id
|| iseg >= darray_frontier_edge_size_get(&scn->analyze.frontiers))
return RES_BAD_ARG;
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == darray_side_range_size_get(&scn->media_use));
+ ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
if(darray_trg_id_size_get(&scn->analyze.overlapping_ids))
return RES_BAD_OP;
edge = darray_frontier_edge_cdata_get(&scn->analyze.frontiers) + iseg;
@@ -178,6 +203,9 @@ senc3d_scene_get_overlapping_triangles_count
size_t tmp;
if(!scn || !count)
return RES_BAD_ARG;
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == darray_side_range_size_get(&scn->media_use));
+ ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
tmp = darray_trg_id_size_get(&scn->analyze.overlapping_ids);
ASSERT(tmp <= VRTX_MAX__);
*count = (trg_id_t)tmp; /* Back to API type */
@@ -193,6 +221,9 @@ senc3d_scene_get_overlapping_triangle
if(!scn || !trg_id
|| idx >= darray_trg_id_size_get(&scn->analyze.overlapping_ids))
return RES_BAD_ARG;
+ ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
+ == darray_side_range_size_get(&scn->media_use));
+ ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
*trg_id = darray_trg_id_cdata_get(&scn->analyze.overlapping_ids)[idx];
return RES_OK;
}
\ No newline at end of file
diff --git a/src/senc3d_enclosure_data.h b/src/senc3d_enclosure_data.h
@@ -79,10 +79,10 @@ static FINLINE res_T
bool_array_of_media_merge
(struct darray_uchar* dst,
const uchar* src,
- const medium_id_t sz)
+ const size_t sz)
{
res_T res = RES_OK;
- medium_id_t i;
+ size_t i;
uchar* data_dst;
ASSERT(src && dst);
@@ -103,20 +103,19 @@ static FINLINE res_T
bool_array_of_media_to_darray_media
(struct darray_media* dst,
const struct darray_uchar* src,
- const medium_id_t next_medium_idx)
+ const size_t sz)
{
res_T res = RES_OK;
int64_t m_idx;
const uchar* data;
- ASSERT(src && dst);
+ ASSERT(src && dst && sz < INT64_MAX);
data = darray_uchar_cdata_get(src);
- ASSERT(next_medium_idx + 1 == darray_uchar_size_get(src));
+ ASSERT(sz == darray_uchar_size_get(src));
darray_media_clear(dst);
if(res != RES_OK) goto error;
- ASSERT(next_medium_idx <= MEDIUM_MAX__ + 1);
- FOR_EACH(m_idx, 0, 1 + (int64_t)next_medium_idx) {
+ FOR_EACH(m_idx, 0, (int64_t)sz) {
medium_id_t medium = medium_idx_2_medium_id(m_idx);
if(!data[m_idx]) continue;
res = darray_media_push_back(dst, &medium);
diff --git a/src/senc3d_scene.c b/src/senc3d_scene.c
@@ -99,7 +99,6 @@ senc3d_scene_create
scn->dev = dev;
scn->convention = conv;
scn->ntris = ntris;
- scn->next_medium_idx = 0;
scn->nverts = nverts;
darray_triangle_in_init(dev->allocator, &scn->triangles_in);
darray_position_init(dev->allocator, &scn->vertices);
@@ -206,10 +205,7 @@ senc3d_scene_create
struct side_range* media_use;
size_t m_idx = medium_id_2_medium_idx(med[s]);
tmp.medium[s] = med[s];
- if(m_idx >= scn->next_medium_idx) {
- medium_id_t medium;
- medium = (medium_id_t)m_idx;
- scn->next_medium_idx = medium;
+ if(m_idx >= darray_side_range_size_get(&scn->media_use)) {
OK(darray_side_range_resize(&scn->media_use, 1 + m_idx));
}
/* media_use 0 is for SENC3D_UNSPECIFIED_MEDIUM */
@@ -226,7 +222,7 @@ senc3d_scene_create
}
OK(darray_enc_ids_array_resize(&scn->analyze.enc_ids_array_by_medium,
- 1 + scn->next_medium_idx)); /* +1 is for unspecified */
+ darray_side_range_size_get(&scn->media_use)));
/* Proceed to the analyze */
OK(scene_analyze(scn));
diff --git a/src/senc3d_scene_analyze.c b/src/senc3d_scene_analyze.c
@@ -89,7 +89,7 @@ get_side_not_in_connex_component
ASSERT(trgsides && processed && first_side_not_in_component);
{
side_id_t i = *first_side_not_in_component;
- while (i <= last_side
+ while(i <= last_side
&& (trgsides[i].medium != medium
|| (processed[TRGSIDE_2_TRG(i)] & TRGSIDE_2_SIDEFLAG(i))))
++i;
@@ -273,9 +273,12 @@ extract_connex_components
#endif
/* We loop on sides to build connex components. */
+ ASSERT(darray_side_range_size_get(&scn->media_use) <= INT64_MAX);
#pragma omp for schedule(dynamic) nowait
/* Process all media, including unspecified */
- for(m_idx = 0; m_idx < 1 + (int64_t)scn->next_medium_idx; m_idx++) {
+ for(m_idx = 0; m_idx < (int64_t)darray_side_range_size_get(&scn->media_use);
+ m_idx++)
+ {
const medium_id_t medium = medium_idx_2_medium_id(m_idx);
/* media_use 0 is for SENC3D_UNSPECIFIED_MEDIUM, n+1 is for n */
const struct side_range* media_use =
@@ -328,10 +331,10 @@ extract_connex_components
/* Reuse array if possible, or create a new one */
if(current_media) {
/* current_media 0 is for SENC3D_UNSPECIFIED_MEDIUM, n+1 is for n */
- memset(current_media, 0, 1 + scn->next_medium_idx);
+ memset(current_media, 0, darray_side_range_size_get(&scn->media_use));
} else {
- current_media = MEM_CALLOC(alloc, 1 + scn->next_medium_idx,
- sizeof(*current_media));
+ current_media = MEM_CALLOC(alloc,
+ darray_side_range_size_get(&scn->media_use), sizeof(*current_media));
if(!current_media) {
*p_res = RES_MEM_ERR;
continue;
@@ -403,8 +406,7 @@ extract_connex_components
side_id_t used_side
= darray_side_id_cdata_get(¤t_component)[ii];
trg_id_t used_trg_id = TRGSIDE_2_TRG(used_side);
- enum side_flag used_side_flag
- = TRGSIDE_2_SIDEFLAG(used_side);
+ enum side_flag used_side_flag = TRGSIDE_2_SIDEFLAG(used_side);
uchar* used = processed + used_trg_id;
ASSERT(*used & (uchar)used_side_flag);
/* Set the used flag for sides in cancelled component as leading
@@ -771,7 +773,7 @@ group_connex_components
enc->side_range.last = MMAX(enc->side_range.last, cc->side_range.last);
enc->side_count += cc->side_count;
tmp_res = bool_array_of_media_merge(&enc->tmp_enclosed_media, cc->media,
- scn->next_medium_idx + 1);
+ darray_side_range_size_get(&scn->media_use));
if(tmp_res != RES_OK) {
*res = tmp_res;
break;
@@ -1017,9 +1019,9 @@ collect_and_link_neighbours
p_crt_side->medium = triangles_in[crt_id].medium[crt_side];
p_ccw_side->medium = triangles_in[ccw_id].medium[ccw_side];
ASSERT(p_crt_side->medium == SENC3D_UNSPECIFIED_MEDIUM
- || p_crt_side->medium < scn->next_medium_idx);
+ || p_crt_side->medium < darray_side_range_size_get(&scn->media_use) - 1);
ASSERT(p_ccw_side->medium == SENC3D_UNSPECIFIED_MEDIUM
- || p_ccw_side->medium < scn->next_medium_idx);
+ || p_ccw_side->medium < darray_side_range_size_get(&scn->media_use) - 1);
/* Detect triangles that could surround a hole:
* - single triangle on (one of) its edge
* - different media on its sides */
@@ -1171,9 +1173,10 @@ build_result
== enc->header.enclosure_id);
enc->header.is_infinite = (e == 0);
- ASSERT(enc->header.enclosed_media_count < 1 + scn->next_medium_idx);
- OK2(bool_array_of_media_to_darray_media
- (&enc->enclosed_media, &enc->tmp_enclosed_media, scn->next_medium_idx));
+ ASSERT(enc->header.enclosed_media_count
+ < darray_side_range_size_get(&scn->media_use));
+ OK2(bool_array_of_media_to_darray_media(&enc->enclosed_media,
+ &enc->tmp_enclosed_media, darray_side_range_size_get(&scn->media_use)));
ASSERT(darray_media_size_get(&enc->enclosed_media) <= MEDIUM_MAX__);
enc->header.enclosed_media_count
= (medium_id_t)darray_media_size_get(&enc->enclosed_media);
@@ -1184,11 +1187,13 @@ build_result
medium_id_t medium = darray_media_cdata_get(&enc->enclosed_media)[m];
size_t m_idx = medium_id_2_medium_idx(medium);
struct darray_enc_id* enc_ids_array_by_medium;
- ASSERT(medium == SENC3D_UNSPECIFIED_MEDIUM || medium < scn->next_medium_idx);
+ ASSERT(medium == SENC3D_UNSPECIFIED_MEDIUM
+ || medium < darray_side_range_size_get(&scn->media_use) - 1);
ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
- == 1 + scn->next_medium_idx);
+ == darray_side_range_size_get(&scn->media_use));
enc_ids_array_by_medium =
- darray_enc_ids_array_data_get(&scn->analyze.enc_ids_array_by_medium) + m_idx;
+ darray_enc_ids_array_data_get(&scn->analyze.enc_ids_array_by_medium)
+ + m_idx;
#pragma omp critical
{
tmp_res = darray_enc_id_push_back(enc_ids_array_by_medium, &e);
@@ -1364,7 +1369,7 @@ scene_analyze
connex_components_initialized = 1;
/* Just a hint; to limit contention */
OK2(darray_ptr_component_descriptor_reserve(&connex_components,
- 2 + 2 * scn->next_medium_idx));
+ 2 * darray_side_range_size_get(&scn->media_use)));
darray_triangle_comp_init(scn->dev->allocator, &triangles_comp);
triangles_comp_initialized = 1;
OK2(darray_triangle_comp_resize(&triangles_comp, scn->ntris));
@@ -1384,7 +1389,7 @@ scene_analyze
tmp_res = darray_trg_id_reserve(&scn->analyze.overlapping_ids,
htable_overlap_size_get(&overlaps));
if(tmp_res != RES_OK) goto tmp_error2;
- while (!htable_overlap_iterator_eq(&it, &end)) {
+ while(!htable_overlap_iterator_eq(&it, &end)) {
tmp_res = darray_trg_id_push_back(&scn->analyze.overlapping_ids,
htable_overlap_iterator_key_get(&it));
if(tmp_res != RES_OK) goto tmp_error2;
diff --git a/src/senc3d_scene_c.h b/src/senc3d_scene_c.h
@@ -300,7 +300,6 @@ struct senc3d_scene {
/* Keep sizes */
trg_id_t ntris; /* Trg count */
vrtx_id_t nverts; /* Vrtx count */
- medium_id_t next_medium_idx;
/* media_use 0 is for SENC3D_UNSPECIFIED_MEDIUM, n+1 is for n */
struct darray_side_range media_use;
diff --git a/src/test_senc3d_scene.c b/src/test_senc3d_scene.c
@@ -290,6 +290,9 @@ main(int argc, char** argv)
CHK(count == 0); /* Medium 2 unused */
OK(senc3d_scene_get_enclosure_count_by_medium(scn, 3, &count));
CHK(count == 1); /* Medium 3 used */
+ OK(senc3d_scene_get_enclosure_count_by_medium(scn, SENC3D_UNSPECIFIED_MEDIUM,
+ &count));
+ CHK(count == 0);
OK(senc3d_scene_ref_put(scn));
@@ -308,6 +311,19 @@ main(int argc, char** argv)
FOR_EACH(i, 0, 2) CHK(medback[i] == medfront[i]);
OK(senc3d_scene_ref_put(scn));
+
+ /* Geometry with no media information */
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ ntriangles, get_indices, NULL,
+ nvertices, get_position, &ctx, &scn));
+ OK(senc3d_scene_get_max_medium(scn, &maxm));
+ CHK(maxm == SENC3D_UNSPECIFIED_MEDIUM);
+ OK(senc3d_scene_get_enclosure_count_by_medium(scn, SENC3D_UNSPECIFIED_MEDIUM,
+ &count));
+ CHK(count == 2);
+
+ OK(senc3d_scene_ref_put(scn));
OK(senc3d_device_ref_put(dev));
check_memory_allocator(&allocator);