commit 0ba350c43693e11d0512e5b667f6a1539b2a0ad9
parent af4c65de032591da950d4b5640153d0329578e7d
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 8 Nov 2019 15:18:53 +0100
Merge branch 'release_0.4.2'
Diffstat:
11 files changed, 98 insertions(+), 29 deletions(-)
diff --git a/README.md b/README.md
@@ -35,6 +35,13 @@ variable the install directories of its dependencies.
Release notes
-------------
+### Version 0.4.2
+
+- Fix global id of segments; releases 0.4.0 and 0.4.1 are broken
+
+- Reintroduce an API call to get the global id in user space of
+ a global unique segment after deduplication
+
### Version 0.4.1
- Fix an infinite loop related to a rare numerical accuracy problem.
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -47,7 +47,7 @@ endif()
################################################################################
set(VERSION_MAJOR 0)
set(VERSION_MINOR 4)
-set(VERSION_PATCH 1)
+set(VERSION_PATCH 2)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SENC2D_FILES_SRC
diff --git a/src/senc2d.h b/src/senc2d.h
@@ -177,7 +177,8 @@ senc2d_scene_reserve
* of SENC_UNDEFINED_MEDIUM that causes no error) and are deduplicated.
* The special value SENC2D_UNDEFINED_MEDIUM denotes an undefined medium.
* It can be used to define the 2 sides of a segment at different times.
- * When deduplicating segments, the first occurence remains.
+ * When deduplicating segments, the first occurence remains (with its
+ * original index in user world, regardless of deduplication).
* The add_segment and merge_segment callbacks can be used for attributes
* management including segment IDs; they allow the client app to store
* its own data. They can also fail and stop the add_geometry call. */
@@ -372,6 +373,14 @@ senc2d_descriptor_get_global_segment_enclosures
const unsigned iseg,
unsigned enclosures[2]);
+/* Returns the global id of the iseg_th global unique segment, that is the
+ * segment index in user world regardless of deduplication. */
+SENC2D_API res_T
+senc2d_descriptor_get_global_segment_global_id
+ (const struct senc2d_descriptor* descriptor,
+ const unsigned iseg,
+ unsigned* gid);
+
/* Returns the number of vertices that are frontier vertices:
* - that have arity 1 (single segment using the vertex)
* - that connect 2 different media */
diff --git a/src/senc2d_descriptor.c b/src/senc2d_descriptor.c
@@ -272,6 +272,21 @@ senc2d_descriptor_get_global_segment_enclosures
}
res_T
+senc2d_descriptor_get_global_segment_global_id
+ (const struct senc2d_descriptor* desc,
+ const unsigned iseg,
+ unsigned* gid)
+{
+ const struct segment_in* seg;
+ if(!gid || !desc
+ || iseg >= darray_segment_in_size_get(&desc->scene->segments_in))
+ return RES_BAD_ARG;
+ seg = darray_segment_in_cdata_get(&desc->scene->segments_in) + iseg;
+ *gid = seg->global_id;
+ return RES_OK;
+}
+
+res_T
senc2d_descriptor_get_frontier_vertices_count
(const struct senc2d_descriptor* desc,
unsigned* count)
diff --git a/src/senc2d_scene.c b/src/senc2d_scene.c
@@ -200,6 +200,8 @@ senc2d_scene_add_geometry
struct segment_in tmp, *range_adjust_ptr = NULL;
seg_id_t* p_seg;
char reversed;
+ /* Segment index in user world regardless of deduplication. */
+ tmp.global_id = (unsigned)(scn->nsegs + i);
indices(i, ind, ctx); /* API: indices needs an unsigned */
FOR_EACH(j, 0, 2) {
if(ind[j] >= nverts) {
@@ -214,7 +216,7 @@ senc2d_scene_add_geometry
const union double2* positions
= darray_position_cdata_get(&scn->vertices);
log_err(scn->dev, "%s: segment %lu is degenerate.\n",
- FUNC_NAME, (unsigned long)scn->nsegs + i);
+ FUNC_NAME, (unsigned long)tmp.global_id);
log_err(scn->dev, " (%g %g) (%g %g)\n",
SPLIT2(positions[seg[i].vertice_id[0]].vec),
SPLIT2(positions[seg[i].vertice_id[1]].vec));
@@ -251,10 +253,11 @@ senc2d_scene_add_geometry
= darray_position_cdata_get(&scn->vertices);
log_err(scn->dev, "%s: segment %lu is a duplicate"
" of segment %lu with incoherent media.\n",
- FUNC_NAME, (unsigned long)(scn->nsegs + i), (unsigned long)*p_seg);
+ FUNC_NAME, (unsigned long)tmp.global_id,
+ (unsigned long)seg[*p_seg].global_id);
log_err(scn->dev,
"Segment %lu:\n (%g %g ) (%g %g)\n",
- (unsigned long)*p_seg,
+ (unsigned long)seg[*p_seg].global_id,
SPLIT2(positions[seg[*p_seg].vertice_id[0]].vec),
SPLIT2(positions[seg[*p_seg].vertice_id[1]].vec));
log_err(scn->dev, "Media: (%lu, %lu) VS (%lu, %lu)\n",
@@ -275,13 +278,13 @@ senc2d_scene_add_geometry
scn->sides_with_defined_medium_count++;
}
}
- if (merge_segment) {
- OK(merge_segment((unsigned)*p_seg, i, same, ctx));
- }
- else {
+ if(merge_segment) {
+ OK(merge_segment(seg[*p_seg].global_id, i, same, ctx));
+ } else {
log_warn(scn->dev,
"%s: segment %lu is a duplicate of segment %lu.\n",
- FUNC_NAME, (unsigned long)(scn->nsegs + i), (unsigned long)*p_seg);
+ FUNC_NAME, (unsigned long)tmp.global_id,
+ (unsigned long)seg[*p_seg].global_id);
}
}
} else {
@@ -295,8 +298,8 @@ senc2d_scene_add_geometry
if(tmp.medium[j] != SENC2D_UNDEFINED_MEDIUM)
scn->sides_with_defined_medium_count++;
}
- if (add_segment) {
- OK(add_segment((unsigned)u, i, ctx));
+ if(add_segment) {
+ OK(add_segment(tmp.global_id, i, ctx));
}
++actual_nusegs;
}
diff --git a/src/senc2d_scene_analyze.c b/src/senc2d_scene_analyze.c
@@ -875,8 +875,8 @@ collect_and_link_neighbours
prev_id = previous->seg_id;
log_err(scn->dev,
"%s: found 2 overlying segments (%lu & %lu).\n", FUNC_NAME,
- (unsigned long)crt_id, (unsigned long)prev_id);
-
+ (unsigned long)segments_in[crt_id].global_id,
+ (unsigned long)segments_in[prev_id].global_id);
*res = RES_BAD_OP;
return;
}
@@ -906,7 +906,7 @@ collect_and_link_neighbours
{
log_warn(scn->dev,
"%s: found possible frontier involving segment %lu.\n",
- FUNC_NAME, (unsigned long)crt_id);
+ FUNC_NAME, (unsigned long)segments_in[crt_id].global_id);
darray_vrtx_id_push_back(frontiers, &v);
}
}
@@ -1086,7 +1086,7 @@ build_result
int ii = revert_segment ? 1 - i : i;
side_enc->vertice_id[i] = vertice_id[ii];
}
- side_enc->side_id = SEGIDxSIDE_2_SEGSIDE(s, SENC2D_FRONT);
+ side_enc->side_id = SEGIDxSIDE_2_SEGSIDE(seg_in->global_id, SENC2D_FRONT);
}
if(segments_enc[s].enclosure[SENC2D_BACK] == e) {
/* Back side of the original segment is member of the enclosure */
@@ -1100,7 +1100,7 @@ build_result
int ii = revert_segment ? 1 - i : i;
side_enc->vertice_id[i] = vertice_id[ii];
}
- side_enc->side_id = SEGIDxSIDE_2_SEGSIDE(s, SENC2D_BACK);
+ side_enc->side_id = SEGIDxSIDE_2_SEGSIDE(seg_in->global_id, SENC2D_BACK);
}
if(fst_idx == sgd_idx) break;
}
diff --git a/src/senc2d_scene_c.h b/src/senc2d_scene_c.h
@@ -48,6 +48,8 @@ struct segment_in {
vrtx_id_t vertice_id[2];
/* Ids of this segment's media */
medium_id_t medium[2];
+ /* Segment index in user world regardless of deduplication. */
+ unsigned global_id;
};
static FINLINE void
@@ -57,6 +59,7 @@ segment_in_init(struct mem_allocator* alloc, struct segment_in* seg) {
ASSERT(seg);
FOR_EACH(i, 0, 2) seg->vertice_id[i] = VRTX_NULL__;
FOR_EACH(i, 0, 2) seg->medium[i] = SENC2D_UNDEFINED_MEDIUM;
+ seg->global_id = 0;
}
#define DARRAY_NAME segment_in
diff --git a/src/test_senc2d_descriptor.c b/src/test_senc2d_descriptor.c
@@ -167,6 +167,17 @@ main(int argc, char** argv)
== RES_OK);
CHK(enclosures[0] == 0 && enclosures[1] == 1);
+ CHK(senc2d_descriptor_get_global_segment_global_id(NULL, 0, indices)
+ == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_global_segment_global_id(NULL, nvertices, indices)
+ == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_global_segment_global_id(desc, 0, NULL)
+ == RES_BAD_ARG);
+ CHK(senc2d_descriptor_get_global_segment_global_id(desc, 0, indices)
+ == RES_OK);
+ /* No duplicates and no custom id: user id is unique vertex id */
+ CHK(indices[0] == 0);
+
/* Add valid duplicate geometry */
CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
desc = NULL;
diff --git a/src/test_senc2d_enclosure.c b/src/test_senc2d_enclosure.c
@@ -248,7 +248,7 @@ test(const int convention)
CHK(senc2d_enclosure_get_segment_global_id(enclosure, s, &gid, &side) == RES_OK);
/* The first unique_segment_count segments of an enclosure
* are unique segments */
- if (s < header.unique_segment_count) CHK(gid == s);
+ if(s < header.unique_segment_count) CHK(gid == s);
CHK(side == (s < header.unique_segment_count) ? SENC2D_FRONT : SENC2D_BACK);
}
diff --git a/src/test_senc2d_scene.c b/src/test_senc2d_scene.c
@@ -180,6 +180,9 @@ main(int argc, char** argv)
CHK(senc2d_scene_get_convention(scn, &convention) == RES_OK);
CHK(convention ==
(SENC2D_CONVENTION_NORMAL_BACK | SENC2D_CONVENTION_NORMAL_INSIDE));
+ /* Add the first segment twice to create a shift in numbering */
+ CHK(senc2d_scene_add_geometry(scn, 1, get_indices, get_media,
+ nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
@@ -188,8 +191,15 @@ main(int argc, char** argv)
CHK(senc2d_enclosure_get_header(enc, &header) == RES_OK);
CHK(!header.is_infinite);
CHK(senc2d_enclosure_ref_put(enc) == RES_OK);
- CHK(senc2d_descriptor_get_global_segment_media(desc, 0, medback) == RES_OK);
+ FOR_EACH(i, 0, nsegments) {
+ unsigned gid;
+ CHK(senc2d_descriptor_get_global_segment_global_id(desc, i, &gid) == RES_OK);
+ /* Check numbering shift */
+ CHK(gid == (i ? i + 1 : 0));
+ }
+
+ CHK(senc2d_descriptor_get_global_segment_media(desc, 0, medback) == RES_OK);
ctx.front_media = medium1_3;
CHK(senc2d_scene_ref_put(scn) == RES_OK);
CHK(senc2d_descriptor_ref_put(desc) == RES_OK);
@@ -219,6 +229,9 @@ main(int argc, char** argv)
CHK(senc2d_scene_create(dev,
SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn)
== RES_OK);
+ /* Add the first segment twice to create a shift in numbering */
+ CHK(senc2d_scene_add_geometry(scn, 1, get_indices, get_media,
+ nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
CHK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
nvertices, get_position, NULL, NULL, &ctx) == RES_OK);
CHK(senc2d_scene_analyze(scn, &desc) == RES_OK);
@@ -227,6 +240,14 @@ main(int argc, char** argv)
CHK(senc2d_enclosure_get_header(enc, &header) == RES_OK);
CHK(header.is_infinite);
CHK(senc2d_enclosure_ref_put(enc) == RES_OK);
+
+ FOR_EACH(i, 0, nsegments) {
+ unsigned gid;
+ CHK(senc2d_descriptor_get_global_segment_global_id(desc, i, &gid) == RES_OK);
+ /* Check numbering shift */
+ CHK(gid == (i ? i + 1 : 0));
+ }
+
CHK(senc2d_descriptor_get_global_segment_media(desc, 0, medfront) == RES_OK);
FOR_EACH(i, 0, 2) CHK(medback[i] == medfront[i]);
diff --git a/src/test_senc2d_undefined_medium_attr.c b/src/test_senc2d_undefined_medium_attr.c
@@ -58,7 +58,7 @@ add_seg
interf = merge_ctx->current_add_interf_data[iseg];
/* Keep data */
res = darray_intface_id_resize(&merge_ctx->global_interf_data, global_id + 1);
- if (res != RES_OK) return res;
+ if(res != RES_OK) return res;
darray_intface_id_data_get(&merge_ctx->global_interf_data)[global_id] = interf;
return res;
}
@@ -79,18 +79,18 @@ merge_seg
ASSERT(ctx); (void)reversed_segment;
merge_ctx = ctx->custom;
res = darray_intface_id_resize(&merge_ctx->global_interf_data, global_id + 1);
- if (res != RES_OK) return res;
+ if(res != RES_OK) return res;
/* Get interface information from ctx */
interf = merge_ctx->current_add_interf_data[iseg];
interf_data = darray_intface_id_data_get(&merge_ctx->global_interf_data);
need_merge = (interf_data[global_id] != INVALID_INTFACE_ID);
- if (need_merge) {
- if (interf_data[global_id] != interf)
+ if(need_merge) {
+ if(interf_data[global_id] != interf)
/* Previous interface id is different: no possible merge */
return RES_BAD_ARG;
} else {
- /* Triangle is known, but without interface information: create */
+ /* Segment is known, but without interface information: create */
interf_data[global_id] = interf;
}
/* Same data: no merge needed */
@@ -147,7 +147,7 @@ test(const int convention)
/* Can add the same segments again defined/undefined media in any order */
/* Add geometry with no media information on both sides */
- for (i = 0; i < sizeof(media) / sizeof(*media); i++)
+ for(i = 0; i < sizeof(media) / sizeof(*media); i++)
media[i] = SENC2D_UNDEFINED_MEDIUM;
OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, NULL,
nvertices, get_position, add_seg, merge_seg, &ctx));
@@ -214,7 +214,7 @@ test(const int convention)
OK(senc2d_descriptor_ref_put(desc));
/* Same geometry, front media are defined for odd segments */
- for (i = 0; i < sizeof(media) / sizeof(*media); i++)
+ for(i = 0; i < sizeof(media) / sizeof(*media); i++)
media[i] = (i % 2) ? 0 : SENC2D_UNDEFINED_MEDIUM;
OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
nvertices, get_position, add_seg, merge_seg, &ctx));
@@ -256,7 +256,7 @@ test(const int convention)
OK(senc2d_descriptor_ref_put(desc));
/* Define media for remaining segments, using reversed box */
- for (i = 0; i < sizeof(media) / sizeof(*media); i++)
+ for(i = 0; i < sizeof(media) / sizeof(*media); i++)
media[i] = (i % 2) ? SENC2D_UNDEFINED_MEDIUM : 0;
OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
nvertices, get_position, add_seg, merge_seg, &ctx));
@@ -286,7 +286,7 @@ test(const int convention)
OK(senc2d_descriptor_ref_put(desc));
/* Define media for all segments, nothing new here */
- for (i = 0; i < sizeof(media) / sizeof(*media); i++)
+ for(i = 0; i < sizeof(media) / sizeof(*media); i++)
media[i] = 0;
OK(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
nvertices, get_position, add_seg, merge_seg, &ctx));
@@ -294,7 +294,7 @@ test(const int convention)
CHK(scount == 0);
/* Define incoherent media for some segments */
- for (i = 0; i < sizeof(media) / sizeof(*media); i++)
+ for(i = 0; i < sizeof(media) / sizeof(*media); i++)
media[i] = (i % 2);
BA(senc2d_scene_add_geometry(scn, nsegments, get_indices, get_media,
nvertices, get_position, add_seg, merge_seg, &ctx));