commit 43cd6f1031dab4b70b806a42d1e0d3f2b163a7ef
parent fc91c9efee867a2b670ee4a2070bcfe87217e38c
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 11 Oct 2019 14:51:55 +0200
Allow to analyze scenes including sides with undefined medium
Diffstat:
9 files changed, 203 insertions(+), 68 deletions(-)
diff --git a/src/senc.h b/src/senc.h
@@ -69,7 +69,8 @@ struct senc_enclosure_header {
unsigned unique_triangle_count;
/* Number of vertices */
unsigned vertices_count;
- /* The number of media inside the enclosure */
+ /* The number of media inside the enclosure,
+ * SENC_UNDEFINED_MEDIUM included */
unsigned enclosed_media_count;
/* Is the enclosure open/infinite?
* Only the outermost enclosure is infinite. */
@@ -165,7 +166,8 @@ senc_scene_reserve
/* Add a new set of vertices and triangles to the scene.
* Vertices can be duplicates and are deduplicated on the fly.
* Triangles can be duplicates as long as they constantly define the same
- * medium on both sides (or an error will be reported) and are deduplicated.
+ * medium on both sides (or an error will be reported, with the exception
+ * of SENC_UNDEFINED_MEDIUM that causes no error) and are deduplicated.
* The special value SENC_UNDEFINED_MEDIUM denotes an undefined medium.
* It can be used to define the 2 sides of a triangle at different times.
* When deduplicating triangles, the first occurence is kept (with its original
@@ -176,15 +178,15 @@ senc_scene_add_geometry
(struct senc_scene* scene,
const unsigned triangles_count,
void(*indices)(const unsigned itri, unsigned ids[3], void* context),
- void(*media)(const unsigned itri, unsigned med[2], void* context),
- void(*global_id) /* May be NULL <=> use triangle rank */
- (const unsigned itri, unsigned* gid, void* context),
+ void(*media) /* Can be NULL <=> SENC_UNDEFINED_MEDIUM medium used */
+ (const unsigned itri, unsigned med[2], void* context),
+ void(*global_id) /* Can be NULL <=> use triangle rank */
+ (const unsigned itri, unsigned* gid, void* context),
const unsigned vertices_count,
void(*position)(const unsigned ivert, double pos[3], void* context),
void* context);
-/* Returns a descriptor of the scene that holds the analysis' result.
- * Its an error that some triangle side still has undefined medium. */
+/* Returns a descriptor of the scene that holds the analysis' result. */
SENC_API res_T
senc_scene_analyze
(struct senc_scene* scene,
@@ -209,6 +211,12 @@ senc_scene_get_unique_triangles_count
(const struct senc_scene* scene,
unsigned* count);
+/* Returns the number of unique sides with SENC_UNDEFINED_MEDIUM medium. */
+SENC_API res_T
+senc_scene_get_unique_sides_without_medium_count
+ (const struct senc_scene* scene,
+ unsigned* count);
+
/* Returns the itri_th unique triangles; the returned indices are
* unique vertex indices.
* Can be called anytime, before or after a call to analyze. */
diff --git a/src/senc_descriptor.c b/src/senc_descriptor.c
@@ -61,7 +61,8 @@ descriptor_create(struct senc_scene* scn)
darray_enclosure_init(scn->dev->allocator, &desc->enclosures);
darray_enc_ids_array_init(scn->dev->allocator,
&desc->enc_ids_array_by_medium);
- OK(darray_enc_ids_array_resize(&desc->enc_ids_array_by_medium, scn->nmeds));
+ OK(darray_enc_ids_array_resize(&desc->enc_ids_array_by_medium,
+ 1 + scn->next_medium_idx)); /* +1 is for undef */
darray_frontier_edge_init(scn->dev->allocator, &desc->frontiers);
/* Enclosure 0 is always defined for infinite */
OK(darray_enclosure_resize(&desc->enclosures, 1));
@@ -91,8 +92,8 @@ senc_descriptor_get_max_medium
(const struct senc_descriptor* desc, unsigned* max_medium_id)
{
if(!desc || !max_medium_id) return RES_BAD_ARG;
- ASSERT(desc->scene->nmeds < UINT_MAX); /* API type */
- *max_medium_id = (unsigned)desc->scene->nmeds - 1;
+ ASSERT(desc->scene->next_medium_idx < UINT_MAX); /* API type */
+ *max_medium_id = (unsigned)desc->scene->next_medium_idx - 1;
return RES_OK;
}
@@ -115,13 +116,16 @@ senc_descriptor_get_enclosure_count_by_medium
const unsigned imed,
unsigned* count)
{
- size_t tmp;
+ size_t tmp, m_idx;
const struct darray_enc_id* enc_ids;
- if(!desc || !count || imed >= desc->scene->nmeds)
+ if(!desc || !count
+ || (imed != SENC_UNDEFINED_MEDIUM && imed >= desc->scene->next_medium_idx))
return RES_BAD_ARG;
ASSERT(darray_enc_ids_array_size_get(&desc->enc_ids_array_by_medium)
- == desc->scene->nmeds);
- enc_ids = darray_enc_ids_array_cdata_get(&desc->enc_ids_array_by_medium) + imed;
+ == 1 + desc->scene->next_medium_idx);
+ m_idx = (imed == SENC_UNDEFINED_MEDIUM) ? desc->scene->next_medium_idx : imed;
+ enc_ids = darray_enc_ids_array_cdata_get(&desc->enc_ids_array_by_medium)
+ + m_idx;
tmp = darray_enc_id_size_get(enc_ids);
ASSERT(tmp < UINT_MAX); /* API type */
*count = (unsigned)tmp;
@@ -150,11 +154,17 @@ senc_descriptor_get_enclosure_by_medium
const unsigned idx,
struct senc_enclosure** out_enc)
{
+ size_t m_idx;
const struct darray_enc_id* enc_ids;
unsigned index;
- if(!desc || imed >= desc->scene->nmeds || !out_enc) return RES_BAD_ARG;
+ if(!desc || !out_enc
+ || (imed != SENC_UNDEFINED_MEDIUM && imed >= desc->scene->next_medium_idx))
+ return RES_BAD_ARG;
+ ASSERT(darray_enc_ids_array_size_get(&desc->enc_ids_array_by_medium)
+ == 1 + desc->scene->next_medium_idx);
+ m_idx = (imed == SENC_UNDEFINED_MEDIUM) ? desc->scene->next_medium_idx : imed;
enc_ids =
- darray_enc_ids_array_cdata_get(&desc->enc_ids_array_by_medium) + imed;
+ darray_enc_ids_array_cdata_get(&desc->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 senc_descriptor_get_enclosure(desc, index, out_enc);
diff --git a/src/senc_enclosure_data.h b/src/senc_enclosure_data.h
@@ -83,23 +83,24 @@ error:
static FINLINE res_T
bool_array_of_media_to_darray_media
(struct darray_media* dst,
- struct darray_uchar* src)
+ const struct darray_uchar* src,
+ const medium_id_t undef_idx)
{
res_T res = RES_OK;
medium_id_t i;
- size_t sz;
const unsigned char* data;
ASSERT(src && dst);
data = darray_uchar_cdata_get(src);
- sz = darray_uchar_size_get(src);
- ASSERT(sz <= MEDIUM_MAX__);
+ ASSERT(undef_idx + 1 == darray_uchar_size_get(src));
+ ASSERT(undef_idx < MEDIUM_MAX__);
darray_media_clear(dst);
if(res != RES_OK) goto error;
- FOR_EACH(i, 0, (medium_id_t)sz) {
+ FOR_EACH(i, 0, undef_idx + 1) {
+ medium_id_t v = (i == undef_idx) ? SENC_UNDEFINED_MEDIUM : i;
if(!data[i]) continue;
- res = darray_media_push_back(dst, &i);
+ res = darray_media_push_back(dst, &v);
if(res != RES_OK) goto error;
}
end:
diff --git a/src/senc_scene.c b/src/senc_scene.c
@@ -83,7 +83,7 @@ senc_scene_create
scn->ngeoms = 0;
scn->ntris = 0;
scn->nutris = 0;
- scn->nmeds = 0;
+ scn->next_medium_idx = 0;
scn->nverts = 0;
scn->nuverts = 0;
scn->sides_with_defined_medium_count = 0;
@@ -147,7 +147,7 @@ senc_scene_add_geometry
res_T res = RES_OK;
if(!scn
- || !indices || !media || !position
+ || !indices || !position
|| !nverts || ((size_t)scn->nverts + (size_t)nverts) > VRTX_MAX__
|| !ntris || ((size_t)scn->ntris + (size_t)ntris) > TRG_MAX__)
return RES_BAD_ARG;
@@ -193,7 +193,7 @@ senc_scene_add_geometry
FOR_EACH(i, 0, ntris) {
int j;
- unsigned med[2];
+ unsigned med[2] = { SENC_UNDEFINED_MEDIUM, SENC_UNDEFINED_MEDIUM };
unsigned ind[3];
union vrtx_id3 trg_key;
struct triangle_in tmp, *range_adjust_ptr = NULL;
@@ -229,12 +229,12 @@ senc_scene_add_geometry
goto error;
}
/* Get media */
- media(i, med, ctx); /* API: media needs an unsigned */
+ if(media) media(i, med, ctx); /* API: media needs an unsigned */
FOR_EACH(j, 0, 2) {
- if(med[j] != SENC_UNDEFINED_MEDIUM && med[j] >= scn->nmeds) {
+ if(med[j] != SENC_UNDEFINED_MEDIUM && med[j] >= scn->next_medium_idx) {
ASSERT(med[j] < MEDIUM_MAX__);
- scn->nmeds = med[j] + 1;
- darray_side_range_resize(&scn->media_use, scn->nmeds);
+ scn->next_medium_idx = med[j] + 1;
+ darray_side_range_resize(&scn->media_use, scn->next_medium_idx);
}
tmp.medium[j] = (medium_id_t)med[j];
}
@@ -307,7 +307,7 @@ senc_scene_add_geometry
FOR_EACH(j, 0, 2) {
struct side_range* media_use;
if(tmp.medium[j] == SENC_UNDEFINED_MEDIUM) continue;
- ASSERT(tmp.medium[j] < scn->nmeds);
+ ASSERT(tmp.medium[j] < scn->next_medium_idx);
media_use = darray_side_range_data_get(&scn->media_use) + tmp.medium[j];
media_use->first =
MMIN(media_use->first, TRGIDxSIDE_2_TRGSIDE((trg_id_t)u, j));
@@ -368,6 +368,17 @@ senc_scene_get_unique_triangles_count
}
res_T
+senc_scene_get_unique_sides_without_medium_count
+ (const struct senc_scene* scn,
+ unsigned* count)
+{
+ if(!scn || !count) return RES_BAD_ARG;
+ ASSERT(2 * scn->nutris >= scn->sides_with_defined_medium_count);
+ *count = 2 * scn->nutris - scn->sides_with_defined_medium_count;
+ return RES_OK;
+}
+
+res_T
senc_scene_get_unique_triangle
(const struct senc_scene* scn,
const unsigned itri,
diff --git a/src/senc_scene_analyze.c b/src/senc_scene_analyze.c
@@ -150,7 +150,7 @@ extract_connex_components
* concurrently. */
struct senc_scene* scn;
struct mem_allocator* alloc;
- int64_t mm;
+ int64_t mm, undefs;
struct darray_side_id stack;
struct darray_side_id ids_of_sides_around_max_z_vertex;
const union double3* positions;
@@ -180,6 +180,19 @@ extract_connex_components
return;
}
+ /* If there are sides with undefined medium, its like another medium */
+ undefs = (scn->sides_with_defined_medium_count < 2 * scn->nutris) ? 1 : 0;
+#pragma omp single
+ {
+ if(undefs) {
+ /* Range is unknown, process each side */
+ struct side_range und;
+ und.first = 0;
+ und.last = 2 * scn->nutris - 1;
+ darray_side_range_push_back(&scn->media_use, &und);
+ }
+ } /* Implicit barrier here */
+
#ifndef NDEBUG
#pragma omp single
{
@@ -192,7 +205,8 @@ extract_connex_components
= darray_side_range_cdata_get(&scn->media_use);
FOR_EACH(mm, 0, 2) {
const side_id_t side = TRGIDxSIDE_2_TRGSIDE(t_, mm);
- const medium_id_t medium = trg_in->medium[mm];
+ medium_id_t medium = trg_in->medium[mm];
+ if(medium == SENC_UNDEFINED_MEDIUM) medium = scn->next_medium_idx;
ASSERT(media_use[medium].first <= side && side
<= media_use[medium].last);
}
@@ -202,11 +216,14 @@ extract_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;
+ /* Process all media, including undef */
+ for(mm = 0; mm < undefs + (int64_t)scn->next_medium_idx; mm++) {
+ const medium_id_t m_idx = (medium_id_t)mm;
+ const medium_id_t m = (mm == scn->next_medium_idx)
+ ? SENC_UNDEFINED_MEDIUM : (medium_id_t)mm;
/* 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;
+ darray_side_range_cdata_get(&scn->media_use) + m_idx;
side_id_t first_side_not_in_component = media_use->first;
double max_nz;
side_id_t max_nz_side_id = SIDE_NULL__;
@@ -249,15 +266,15 @@ extract_connex_components
/* Reuse array if possible, or create a new one */
if(current_media) {
- memset(current_media, 0, scn->nmeds);
+ memset(current_media, 0, 1 + scn->next_medium_idx); /* +1 for possible undef */
} else {
- current_media = MEM_CALLOC(alloc, scn->nmeds, sizeof(unsigned char));
+ current_media = MEM_CALLOC(alloc, 1 + scn->next_medium_idx, sizeof(unsigned char));
if(!current_media) {
*p_res = RES_MEM_ERR;
continue;
}
}
- current_media[m] = 1;
+ current_media[m_idx] = 1;
for(;;) { /* Process all sides of this component */
int i;
enum side_flag crt_side_flag = TRGSIDE_2_SIDEFLAG(crt_side_id);
@@ -318,6 +335,8 @@ extract_connex_components
enum side_flag nbour_side_id = TRGSIDE_2_SIDEFLAG(neighbour_id);
unsigned char* nbour_used = processed + nbour_trg_id;
const struct trgside* neighbour = trgsides + neighbour_id;
+ medium_id_t nbour_med_idx = (neighbour->medium == SENC_UNDEFINED_MEDIUM)
+ ? scn->next_medium_idx : neighbour->medium;
if(neighbour->medium < m
|| (*nbour_used & (unsigned char)SIDE_CANCELED_FLAG(nbour_side_id)))
{
@@ -354,7 +373,7 @@ extract_connex_components
*nbour_used |= (unsigned char)nbour_side_id;
OK2(darray_side_id_push_back(&stack, &neighbour_id));
OK2(darray_side_id_push_back(¤t_component, &neighbour_id));
- current_media[neighbour->medium] = 1;
+ current_media[nbour_med_idx] = 1;
}
sz = darray_side_id_size_get(&stack);
if(sz == 0) break; /* Empty stack => component is done! */
@@ -669,7 +688,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,
- desc->scene->nmeds);
+ desc->scene->next_medium_idx + 1);
if(tmp_res != RES_OK) {
*res = tmp_res;
break;
@@ -912,8 +931,10 @@ collect_and_link_neighbours
|| p_ccw_side->medium == triangles_in[ccw_id].medium[ccw_side]);
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 < scn->nmeds);
- ASSERT(p_ccw_side->medium < scn->nmeds);
+ ASSERT(p_crt_side->medium == SENC_UNDEFINED_MEDIUM
+ || p_crt_side->medium < scn->next_medium_idx);
+ ASSERT(p_ccw_side->medium == SENC_UNDEFINED_MEDIUM
+ || p_ccw_side->medium < scn->next_medium_idx);
/* Detect triangles that could surround a hole:
* - single triangle on (one of) its edge
* - different media on its sides */
@@ -1032,9 +1053,9 @@ build_result
enc->header.is_infinite = (e == 0);
ASSERT(darray_uchar_size_get(&enc->tmp_enclosed_media) <= UINT_MAX);
- ASSERT(enc->header.enclosed_media_count <= scn->nmeds);
+ 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));
+ (&enc->enclosed_media, &enc->tmp_enclosed_media, scn->next_medium_idx));
enc->header.enclosed_media_count
= (unsigned)darray_media_size_get(&enc->enclosed_media);
darray_uchar_purge(&enc->tmp_enclosed_media);
@@ -1042,8 +1063,14 @@ build_result
/* Add this enclosure in relevant by-medium lists */
FOR_EACH(m, 0, enc->header.enclosed_media_count) {
medium_id_t medium = darray_media_data_get(&enc->enclosed_media)[m];
- struct darray_enc_id* enc_ids_by_medium =
- darray_enc_ids_array_data_get(&desc->enc_ids_array_by_medium) + medium;
+ size_t m_idx = (medium == SENC_UNDEFINED_MEDIUM)
+ ? scn->next_medium_idx : medium;
+ struct darray_enc_id* enc_ids_by_medium;
+ ASSERT(medium == SENC_UNDEFINED_MEDIUM || medium < scn->next_medium_idx);
+ ASSERT(darray_enc_ids_array_size_get(&desc->enc_ids_array_by_medium)
+ == 1 + scn->next_medium_idx);
+ enc_ids_by_medium =
+ darray_enc_ids_array_data_get(&desc->enc_ids_array_by_medium) + m_idx;
#pragma omp critical
{
tmp_res = darray_enc_id_push_back(enc_ids_by_medium, &e);
@@ -1179,12 +1206,6 @@ senc_scene_analyze
if(!scn || !out_desc) return RES_BAD_ARG;
- if(scn->sides_with_defined_medium_count < 2 * scn->nutris) {
- log_err(scn->dev,
- "%s: not all triangles have defined media on both sides.\n", FUNC_NAME);
- return RES_BAD_ARG;
- }
-
desc = descriptor_create(scn);
if(!desc) {
res = RES_MEM_ERR;
@@ -1240,7 +1261,7 @@ senc_scene_analyze
connex_components_initialized = 1;
/* Just a hint; to limit contention */
OK2(darray_ptr_component_descriptor_reserve(&connex_components,
- 2 * scn->nmeds));
+ 2 + 2 * scn->next_medium_idx));
darray_triangle_comp_init(scn->dev->allocator, &triangles_comp);
triangles_comp_initialized = 1;
OK2(darray_triangle_comp_resize(&triangles_comp, scn->nutris));
diff --git a/src/senc_scene_c.h b/src/senc_scene_c.h
@@ -217,7 +217,7 @@ struct senc_scene {
unsigned ngeoms; /* Not used yet (just counted). */
trg_id_t ntris, nutris; /* Trg count, unique trg count */
vrtx_id_t nverts, nuverts; /* Vrtx count, unique vrtx count */
- medium_id_t nmeds;
+ medium_id_t next_medium_idx;
struct darray_side_range media_use;
side_id_t sides_with_defined_medium_count;
diff --git a/src/test_senc_scene.c b/src/test_senc_scene.c
@@ -85,6 +85,16 @@ main(int argc, char** argv)
CHK(senc_scene_get_unique_vertices_count(scn, &count) == RES_OK);
CHK(count == 0);
+ CHK(senc_scene_get_unique_sides_without_medium_count(NULL, &count)
+ == RES_BAD_ARG);
+ CHK(senc_scene_get_unique_sides_without_medium_count(scn, NULL)
+ == RES_BAD_ARG);
+ CHK(senc_scene_get_unique_sides_without_medium_count(NULL, NULL)
+ == RES_BAD_ARG);
+ CHK(senc_scene_get_unique_sides_without_medium_count(scn, &count)
+ == RES_OK);
+ CHK(count == 0);
+
/* A 3D cube.
* With this geometry front is inside with NORMAL_BACK convention,
* outside with NORMAL_FRONT convention */
@@ -104,8 +114,6 @@ main(int argc, char** argv)
nvertices, get_position, &ctx) == RES_BAD_ARG);
CHK(senc_scene_add_geometry(scn, ntriangles, NULL, get_media,
get_global_id, nvertices, get_position, &ctx) == RES_BAD_ARG);
- CHK(senc_scene_add_geometry(scn, ntriangles, get_indices, NULL,
- get_global_id, nvertices, get_position, &ctx) == RES_BAD_ARG);
CHK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media,
get_global_id, 0, get_position, &ctx) == RES_BAD_ARG);
CHK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media,
diff --git a/src/test_senc_undefined_medium.c b/src/test_senc_undefined_medium.c
@@ -30,13 +30,17 @@ test(enum senc_convention convention)
struct senc_scene* scn = NULL;
struct senc_enclosure* enclosure;
struct senc_enclosure_header header;
- unsigned medium;
+ unsigned medium, expected_external_medium, expected_internal_medium;
unsigned gid;
struct context ctx;
- unsigned i, t, ecount, vcount, tcount;
+ unsigned i, t, ecount, vcount, tcount, scount;
int is_front, is_in;
unsigned media[12];
unsigned rev_box_indices[sizeof(box_indices) / sizeof(*box_indices)];
+ int conv_front, conv_in;
+
+ conv_front = (convention & SENC_CONVENTION_NORMAL_FRONT) != 0;
+ conv_in = (convention & SENC_CONVENTION_NORMAL_INSIDE) != 0;
/* Create the box with reversed triangles */
FOR_EACH(i, 0, sizeof(rev_box_indices) / sizeof(*rev_box_indices)) {
@@ -67,23 +71,77 @@ test(enum senc_convention convention)
/* Can add the same triangles again defined/undefined media in any order */
- /* Add geometry with no media information */
+ /* Add geometry with no media information on both sides */
for (i = 0; i < sizeof(media) / sizeof(*media); i++)
media[i] = SENC_UNDEFINED_MEDIUM;
+ OK(senc_scene_add_geometry(scn, ntriangles, get_indices, NULL,
+ NULL, nvertices, get_position, &ctx));
+ OK(senc_scene_get_unique_sides_without_medium_count(scn, &scount));
+ CHK(scount == 2 * ntriangles);
+
+ /* Add geometry with no media information on the front sides */
OK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media,
NULL, nvertices, get_position, &ctx));
+ OK(senc_scene_get_unique_sides_without_medium_count(scn, &scount));
+ CHK(scount == ntriangles);
+
+ /* Analyze with undefined media on the front sides */
+ OK(senc_scene_analyze(scn, &desc));
+ OK(senc_descriptor_get_enclosure_count(desc, &ecount));
+ CHK(ecount == 2);
- /* Cannot run analyze with undefined media */
- BA(senc_scene_analyze(scn, &desc));
+ FOR_EACH(i, 0, ecount) {
+ struct senc_enclosure* ee;
+ struct senc_enclosure_header hh;
+ unsigned cc;
+ OK(senc_descriptor_get_enclosure(desc, i, &enclosure));
+ OK(senc_enclosure_get_header(enclosure, &header));
+
+ CHK(header.enclosure_id == i);
+ CHK(header.enclosed_media_count == 1);
+
+ OK(senc_enclosure_get_medium(enclosure, 0, &medium));
+ /* Geometrical normals point outside the cube in input triangles:
+ * if convention is front, front medium (undef) is outside,
+ * that is medium 0's enclosure is infinite */
+ expected_external_medium = conv_front ? SENC_UNDEFINED_MEDIUM : 1;
+ expected_internal_medium = conv_front ? 1 :SENC_UNDEFINED_MEDIUM;
+
+ CHK(medium == (header.is_infinite
+ ? expected_external_medium : expected_internal_medium));
+ CHK(header.triangle_count == ntriangles);
+ CHK(header.unique_triangle_count == ntriangles);
+ CHK(header.vertices_count == nvertices);
+ CHK(header.is_infinite == (i == 0));
+
+ OK(senc_descriptor_get_enclosure_count_by_medium(desc, medium, &cc));
+ CHK(cc == 1);
+ OK(senc_descriptor_get_enclosure_by_medium(desc, medium, 0, &ee));
+ OK(senc_enclosure_get_header(ee, &hh));
+ CHK(header.enclosure_id == hh.enclosure_id);
+ OK(senc_enclosure_ref_put(ee));
+
+ FOR_EACH(t, 0, header.triangle_count) {
+ unsigned ind[3];
+ OK(senc_enclosure_get_triangle_global_id(enclosure, t, &gid));
+ CHK(gid == t);
+ OK(senc_enclosure_get_triangle(enclosure, t, ind));
+ }
+ OK(senc_enclosure_ref_put(enclosure));
+ }
+ OK(senc_descriptor_ref_put(desc));
/* Same geometry, front media are defined for odd triangles */
for (i = 0; i < sizeof(media) / sizeof(*media); i++)
media[i] = (i % 2) ? 0 : SENC_UNDEFINED_MEDIUM;
OK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media,
NULL, nvertices, get_position, &ctx));
+ OK(senc_scene_get_unique_sides_without_medium_count(scn, &scount));
+ CHK(scount == ntriangles / 2);
- /* Cannot run analyze with undefined media */
- BA(senc_scene_analyze(scn, &desc));
+ /* Analyze with undefined media */
+ OK(senc_scene_analyze(scn, &desc));
+ OK(senc_descriptor_ref_put(desc));
/* Get the deduplicated geometry without (successful) analyze */
OK(senc_scene_get_unique_vertices_count(scn, &vcount));
@@ -108,15 +166,20 @@ test(enum senc_convention convention)
SWAP(const unsigned*, ctx.front_media, ctx.back_media);
OK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media,
NULL, nvertices, get_position, &ctx));
+ OK(senc_scene_get_unique_sides_without_medium_count(scn, &scount));
+ CHK(scount == ntriangles / 2);
- /* Cannot run analyze with undefined media */
- BA(senc_scene_analyze(scn, &desc));
+ /* Analyze with undefined media */
+ OK(senc_scene_analyze(scn, &desc));
+ OK(senc_descriptor_ref_put(desc));
/* Define media for remaining triangles, using reversed box */
for (i = 0; i < sizeof(media) / sizeof(*media); i++)
media[i] = (i % 2) ? SENC_UNDEFINED_MEDIUM : 0;
OK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media,
NULL, nvertices, get_position, &ctx));
+ OK(senc_scene_get_unique_sides_without_medium_count(scn, &scount));
+ CHK(scount == 0);
/* Get the deduplicated geometry without (successful) analyze */
OK(senc_scene_get_unique_vertices_count(scn, &vcount));
@@ -136,7 +199,7 @@ test(enum senc_convention convention)
}
}
- /* Can run analyze */
+ /* Analyze with all media defined */
OK(senc_scene_analyze(scn, &desc));
OK(senc_descriptor_ref_put(desc));
@@ -145,17 +208,20 @@ test(enum senc_convention convention)
media[i] = 0;
OK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media,
NULL, nvertices, get_position, &ctx));
+ OK(senc_scene_get_unique_sides_without_medium_count(scn, &scount));
+ CHK(scount == 0);
/* Define incoherent media for some triangles */
for (i = 0; i < sizeof(media) / sizeof(*media); i++)
media[i] = (i % 2);
BA(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media,
NULL, nvertices, get_position, &ctx));
+ OK(senc_scene_get_unique_sides_without_medium_count(scn, &scount));
+ CHK(scount == 0);
/* Scene is still OK and can be analyzed */
OK(senc_scene_analyze(scn, &desc));
-
OK(senc_descriptor_get_global_triangles_count(desc, &tcount));
CHK(tcount == sizeof(media) / sizeof(*media));
@@ -163,6 +229,9 @@ test(enum senc_convention convention)
CHK(ecount == 2);
FOR_EACH(i, 0, ecount) {
+ struct senc_enclosure* ee;
+ struct senc_enclosure_header hh;
+ unsigned cc;
OK(senc_descriptor_get_enclosure(desc, i, &enclosure));
OK(senc_enclosure_get_header(enclosure, &header));
@@ -178,6 +247,13 @@ test(enum senc_convention convention)
CHK(header.vertices_count == nvertices);
CHK(header.is_infinite == (i == 0));
+ OK(senc_descriptor_get_enclosure_count_by_medium(desc, medium, &cc));
+ CHK(cc == 1);
+ OK(senc_descriptor_get_enclosure_by_medium(desc, medium, 0, &ee));
+ OK(senc_enclosure_get_header(ee, &hh));
+ CHK(header.enclosure_id == hh.enclosure_id);
+ OK(senc_enclosure_ref_put(ee));
+
FOR_EACH(t, 0, header.triangle_count) {
OK(senc_enclosure_get_triangle_global_id(enclosure, t, &gid));
CHK(gid == t);
diff --git a/src/test_senc_utils.h b/src/test_senc_utils.h
@@ -204,7 +204,7 @@ static INLINE void
check_memory_allocator(struct mem_allocator* allocator)
{
if(MEM_ALLOCATED_SIZE(allocator)) {
- char dump[128];
+ char dump[1024];
MEM_DUMP(allocator, dump, sizeof(dump));
fprintf(stderr, "%s\n", dump);
FATAL("Memory leaks.\n");