commit 7f866ca1f88fc69afd8c762464f89b3165359e81
parent 6d755b60eb576f85d9bf0a84d2527b74c60fa209
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 8 Nov 2019 14:59:43 +0100
Fix global id of triangles; reintroduce dedicated API
Diffstat:
8 files changed, 76 insertions(+), 14 deletions(-)
diff --git a/src/senc.h b/src/senc.h
@@ -178,7 +178,8 @@ senc_scene_reserve
* 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 remains.
+ * When deduplicating triangles, the first occurence remains (with its
+ * original index in user world, regardless of deduplication).
* The add_triangle and merge_triangle callbacks can be used for attributes
* management including triangle IDs; they allow the client app to store
* its own data. They can also fail and stop the add_geometry call. */
@@ -374,6 +375,14 @@ senc_descriptor_get_global_triangle_enclosures
const unsigned itri,
unsigned enclosures[2]);
+/* Returns the global id of the itri_th global unique triangle, that is the
+ * triangle index in user world regardless of deduplication. */
+SENC_API res_T
+senc_descriptor_get_global_triangle_global_id
+ (const struct senc_descriptor* descriptor,
+ const unsigned itri,
+ unsigned* gid);
+
/* Returns the number of segments that are frontier segments:
* - that have arity 1 (single triangle using the segment)
* - that connect 2 different media */
diff --git a/src/senc_descriptor.c b/src/senc_descriptor.c
@@ -272,6 +272,21 @@ senc_descriptor_get_global_triangle_enclosures
}
res_T
+senc_descriptor_get_global_triangle_global_id
+ (const struct senc_descriptor* desc,
+ const unsigned itri,
+ unsigned* gid)
+{
+ const struct triangle_in* trg;
+ if(!gid || !desc
+ || itri >= darray_triangle_in_size_get(&desc->scene->triangles_in))
+ return RES_BAD_ARG;
+ trg = darray_triangle_in_cdata_get(&desc->scene->triangles_in) + itri;
+ *gid = trg->global_id;
+ return RES_OK;
+}
+
+res_T
senc_descriptor_get_frontier_segments_count
(const struct senc_descriptor* desc,
unsigned* count)
diff --git a/src/senc_scene.c b/src/senc_scene.c
@@ -200,6 +200,8 @@ senc_scene_add_geometry
struct triangle_in tmp, *range_adjust_ptr = NULL;
trg_id_t* p_trg;
char reversed;
+ /* Triangle index in user world regardless of deduplication. */
+ tmp.global_id = (unsigned)(scn->ntris + i);
indices(i, ind, ctx); /* API: indices need unsigneds */
FOR_EACH(j, 0, 3) {
if(ind[j] >= nverts) {
@@ -216,7 +218,7 @@ senc_scene_add_geometry
const union double3* positions
= darray_position_cdata_get(&scn->vertices);
log_err(scn->dev, "%s: triangle %lu is degenerate.\n",
- FUNC_NAME, (unsigned long)(scn->ntris + i));
+ FUNC_NAME, (unsigned long)tmp.global_id);
log_err(scn->dev, " (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n",
SPLIT3(positions[trg[i].vertice_id[0]].vec),
SPLIT3(positions[trg[i].vertice_id[1]].vec),
@@ -254,10 +256,11 @@ senc_scene_add_geometry
= darray_position_cdata_get(&scn->vertices);
log_err(scn->dev, "%s: triangle %lu is a duplicate"
" of triangle %lu with incoherent media.\n",
- FUNC_NAME, (unsigned long)(scn->ntris + i), (unsigned long)*p_trg);
+ FUNC_NAME, (unsigned long)tmp.global_id,
+ (unsigned long)trg[*p_trg].global_id);
log_err(scn->dev,
"Triangle %lu:\n (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n",
- (unsigned long)*p_trg,
+ (unsigned long)trg[*p_trg].global_id,
SPLIT3(positions[trg[*p_trg].vertice_id[0]].vec),
SPLIT3(positions[trg[*p_trg].vertice_id[1]].vec),
SPLIT3(positions[trg[*p_trg].vertice_id[2]].vec));
@@ -280,11 +283,12 @@ senc_scene_add_geometry
}
}
if(merge_triangle) {
- OK(merge_triangle((unsigned)*p_trg, i, same, ctx));
+ OK(merge_triangle(trg[*p_trg].global_id, i, same, ctx));
} else {
log_warn(scn->dev,
"%s: triangle %lu is a duplicate of triangle %lu.\n",
- FUNC_NAME, (unsigned long)(scn->ntris + i), (unsigned long)*p_trg);
+ FUNC_NAME, (unsigned long)tmp.global_id,
+ (unsigned long)trg[*p_trg].global_id);
}
}
} else {
@@ -299,7 +303,7 @@ senc_scene_add_geometry
scn->sides_with_defined_medium_count++;
}
if(add_triangle) {
- OK(add_triangle((unsigned)u, i, ctx));
+ OK(add_triangle(tmp.global_id, i, ctx));
}
++actual_nutris;
}
diff --git a/src/senc_scene_analyze.c b/src/senc_scene_analyze.c
@@ -913,7 +913,8 @@ collect_and_link_neighbours
prev_id = previous->trg_id;
log_err(scn->dev,
"%s: found 2 overlying triangles (%lu & %lu).\n", FUNC_NAME,
- (unsigned long)crt_id, (unsigned long)prev_id);
+ (unsigned long)triangles_in[crt_id].global_id,
+ (unsigned long)triangles_in[prev_id].global_id);
tmp_res = RES_BAD_OP;
goto tmp_error;
}
@@ -944,7 +945,7 @@ collect_and_link_neighbours
struct trg_edge disc;
log_warn(scn->dev,
"%s: found frontier involving triangle %lu.\n",
- FUNC_NAME, (unsigned long)crt_id);
+ FUNC_NAME, (unsigned long)triangles_in[crt_id].global_id);
disc.vrtx0 = v0;
disc.vrtx1 = v1;
darray_frontier_edge_push_back(frontiers, &disc);
@@ -1132,7 +1133,7 @@ build_result
int ii = revert_triangle ? 2 - i : i;
side_enc->vertice_id[i] = vertice_id[ii];
}
- side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(t, SENC_FRONT);
+ side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(trg_in->global_id, SENC_FRONT);
}
if(triangles_enc[t].enclosure[SENC_BACK] == e) {
/* Back side of the original triangle is member of the enclosure */
@@ -1146,7 +1147,7 @@ build_result
int ii = revert_triangle ? 2 - i : i;
side_enc->vertice_id[i] = vertice_id[ii];
}
- side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(t, SENC_BACK);
+ side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(trg_in->global_id, SENC_BACK);
}
if(fst_idx == sgd_idx) break;
}
diff --git a/src/senc_scene_c.h b/src/senc_scene_c.h
@@ -48,6 +48,8 @@ struct triangle_in {
vrtx_id_t vertice_id[3];
/* Ids of this triangle's media */
medium_id_t medium[2];
+ /* Triangle index in user world regardless of deduplication. */
+ unsigned global_id;
};
static FINLINE void
@@ -57,6 +59,7 @@ triangle_in_init(struct mem_allocator* alloc, struct triangle_in* trg) {
ASSERT(trg);
FOR_EACH(i, 0, 3) trg->vertice_id[i] = VRTX_NULL__;
FOR_EACH(i, 0, 2) trg->medium[i] = SENC_UNDEFINED_MEDIUM;
+ trg->global_id = 0;
}
#define DARRAY_NAME triangle_in
diff --git a/src/test_senc_descriptor.c b/src/test_senc_descriptor.c
@@ -161,8 +161,18 @@ main(int argc, char** argv)
== RES_BAD_ARG);
CHK(senc_descriptor_get_global_triangle_enclosures(desc, 0, enclosures)
== RES_OK);
- CHK(enclosures[0] == 0
- && enclosures[1] == 1);
+ CHK(enclosures[0] == 0 && enclosures[1] == 1);
+
+ CHK(senc_descriptor_get_global_triangle_global_id(NULL, 0, indices)
+ == RES_BAD_ARG);
+ CHK(senc_descriptor_get_global_triangle_global_id(NULL, nvertices, indices)
+ == RES_BAD_ARG);
+ CHK(senc_descriptor_get_global_triangle_global_id(desc, 0, NULL)
+ == RES_BAD_ARG);
+ CHK(senc_descriptor_get_global_triangle_global_id(desc, 0, indices)
+ == RES_OK);
+ /* No duplicates: user id is unique vertex id */
+ CHK(indices[0] == 0);
/* Add valid duplicate geometry */
CHK(senc_descriptor_ref_put(desc) == RES_OK);
diff --git a/src/test_senc_enclosure.c b/src/test_senc_enclosure.c
@@ -249,7 +249,7 @@ test(const int convention)
CHK(senc_enclosure_get_triangle_global_id(enclosure, t, &gid, &side) == RES_OK);
/* The first unique_triangle_count triangles of an enclosure
* are unique triangles */
- if (t < header.unique_triangle_count) CHK(gid == t);
+ if(t < header.unique_triangle_count) CHK(gid == t);
CHK(side == (t < header.unique_triangle_count) ? SENC_FRONT : SENC_BACK);
}
diff --git a/src/test_senc_scene.c b/src/test_senc_scene.c
@@ -173,6 +173,9 @@ main(int argc, char** argv)
SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK);
CHK(senc_scene_get_convention(scn, &convention) == RES_OK);
CHK(convention == (SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_INSIDE));
+ /* Add the first triangle twice to create a shift in numbering */
+ CHK(senc_scene_add_geometry(scn, 1, get_indices, get_media,
+ nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
CHK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media,
nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
CHK(senc_scene_analyze(scn, &desc) == RES_OK);
@@ -182,6 +185,13 @@ main(int argc, char** argv)
CHK(!header.is_infinite);
CHK(senc_enclosure_ref_put(enc) == RES_OK);
+ FOR_EACH(i, 0, ntriangles) {
+ unsigned gid;
+ CHK(senc_descriptor_get_global_triangle_global_id(desc, i, &gid) == RES_OK);
+ /* Check numbering shift */
+ CHK(gid == (i ? i + 1 : 0));
+ }
+
CHK(senc_descriptor_get_global_triangle_media(desc, 0, medback) == RES_OK);
ctx.front_media = medium1_3;
CHK(senc_scene_ref_put(scn) == RES_OK);
@@ -210,6 +220,9 @@ main(int argc, char** argv)
CHK(senc_descriptor_ref_put(desc) == RES_OK);
CHK(senc_scene_create(dev,
SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK);
+ /* Add the first triangle twice to create a shift in numbering */
+ CHK(senc_scene_add_geometry(scn, 1, get_indices, get_media,
+ nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
CHK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media,
nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
CHK(senc_scene_analyze(scn, &desc) == RES_OK);
@@ -219,6 +232,13 @@ main(int argc, char** argv)
CHK(header.is_infinite);
CHK(senc_enclosure_ref_put(enc) == RES_OK);
+ FOR_EACH(i, 0, ntriangles) {
+ unsigned gid;
+ CHK(senc_descriptor_get_global_triangle_global_id(desc, i, &gid) == RES_OK);
+ /* Check numbering shift */
+ CHK(gid == (i ? i + 1 : 0));
+ }
+
CHK(senc_descriptor_get_global_triangle_media(desc, 0, medfront) == RES_OK);
FOR_EACH(i, 0, 2) CHK(medback[i] == medfront[i]);