commit 29812324a77e30c230a35f68b3ab7221d487affa
parent 9de9cb0db670dbf069ca5111b9859ae95c184d6a
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Tue, 22 Jan 2019 09:57:48 +0100
Merge branch 'release_0.2.2'
Diffstat:
5 files changed, 76 insertions(+), 26 deletions(-)
diff --git a/README.md b/README.md
@@ -39,6 +39,13 @@ variable the install directories of its dependencies.
Release notes
-------------
+### Version 0.2.2
+
+- BugFix when grouping components into enclosures.
+- Add a warning message in log when triangles that could surround a
+ hole are found (triangles with at least one unshared edge and
+ different media on its sides).
+
### Version 0.2.1
- BugFix: needed data cleaning on computation canceling.
@@ -52,7 +59,8 @@ Release notes
License
-------
-StarEnclosures is Copyright (C) |Meso|Star> 2018
-(<contact@meso-star.com>). It is free software released under the GPLv3+
-license. You are welcome to redistribute it under certain conditions;
-refer to the COPYING files for details.
+StarEnclosures is Copyright (C) \\\|Meso\\\|Star> 2018
+(<a href="mailto:contact@meso-star.com" class="email">contact@meso-star.com</a>).
+It is free software released under the GPLv3+ license. You are welcome
+to redistribute it under certain conditions; refer to the COPYING files
+for details.
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -48,7 +48,7 @@ endif()
################################################################################
set(VERSION_MAJOR 0)
set(VERSION_MINOR 2)
-set(VERSION_PATCH 1)
+set(VERSION_PATCH 2)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SENC_FILES_SRC
diff --git a/src/senc_scene_analyze.c b/src/senc_scene_analyze.c
@@ -208,7 +208,8 @@ extract_connex_components
const struct side_range* media_use =
darray_side_range_cdata_get(&scn->media_use) + m;
side_id_t first_side_not_in_component = media_use->first;
- double max_z_nz;
+ double max_nz;
+ side_id_t max_nz_side_id = SIDE_NULL__;
const side_id_t last_side = media_use->last;
int component_canceled = 0;
res_T tmp_res = RES_OK;
@@ -370,16 +371,20 @@ extract_connex_components
ASSERT(IS_ALIGNED(triangles_comp->component, sizeof(cc->cc_id)));
FOR_EACH(ii, 0, sz) {
const side_id_t s = darray_side_id_cdata_get(¤t_component)[ii];
- triangles_comp[TRGSIDE_2_TRG(s)].component[TRGSIDE_2_SIDE(s)] = cc->cc_id;
+ ASSERT(triangles_comp[TRGSIDE_2_TRG(s)].component[TRGSIDE_2_SIDE(s)]
+ == COMPONENT_NULL__);
+ triangles_comp[TRGSIDE_2_TRG(s)].component[TRGSIDE_2_SIDE(s)]
+ = cc->cc_id;
}
/* Compute the normal at the max_z vertex. */
- max_z_nz = 0;
+ max_nz = 0;
sz = darray_side_id_size_get(&ids_of_sides_around_max_z_vertex);
FOR_EACH(ii, 0, sz) {
const side_id_t side_id =
darray_side_id_cdata_get(&ids_of_sides_around_max_z_vertex)[ii];
const trg_id_t trg_id = TRGSIDE_2_TRG(side_id);
+ enum side_id s = TRGSIDE_2_SIDE(side_id);
const struct triangle_in* trg_in =
darray_triangle_in_cdata_get(&scn->triangles_in) + trg_id;
const struct triangle_comp* trg_comp = triangles_comp + trg_id;
@@ -389,9 +394,8 @@ extract_connex_components
/* To garanty that triangles with 2 sides in the component total to 0
* regardless of numeric accuracy, we need to prevent them to
- * contribute (remember than x + y - y == 0 can be false). */
- ASSERT(trg_comp->component[SIDE_FRONT] == cc->cc_id
- || trg_comp->component[SIDE_BACK] == cc->cc_id);
+ * contribute (remember than x + y - y == x can be false). */
+ ASSERT(trg_comp->component[s] == cc->cc_id);
if(trg_comp->component[SIDE_FRONT] == trg_comp->component[SIDE_BACK])
continue;
@@ -403,15 +407,22 @@ extract_connex_components
norm = d3_normalize(normal, normal);
ASSERT(norm); (void)norm;
- /* Orient the geometrical normal according to the convention */
- if(TRGSIDE_IS_FRONT(side_id)
+ if(fabs(max_nz) < fabs(normal[2])) {
+ max_nz_side_id = side_id;
+ max_nz = normal[2];
+ }
+ }
+ if(max_nz == 0) cc->is_outer_border = 0;
+ else {
+ if(TRGSIDE_IS_FRONT(max_nz_side_id)
== ((scn->convention & SENC_CONVENTION_NORMAL_FRONT) != 0)) {
- max_z_nz += normal[2];
+ /* Geom normal points towards the component */
+ cc->is_outer_border = (max_nz < 0);
} else {
- max_z_nz -= normal[2];
+ /* Geom normal points away from the component */
+ cc->is_outer_border = (max_nz > 0);
}
}
- cc->is_outer_border = (max_z_nz < 0);
/* Need to synchronize connex_components growth as this global structure
* is accessed by multipe threads */
@@ -581,8 +592,13 @@ group_connex_components
const trg_id_t hit_trg_id = (trg_id_t)hit.prim.prim_id;
const struct triangle_comp* hit_trg_comp =
darray_triangle_comp_cdata_get(triangles_comp) + hit_trg_id;
- enum side_id hit_side = (hit.normal[2] > 0) ? SIDE_FRONT : SIDE_BACK;
-
+ enum side_id hit_side =
+ ((hit.normal[2] < 0) /* Facing geometrical normal of hit */
+ == ((desc->scene->convention & SENC_CONVENTION_NORMAL_FRONT) != 0))
+ /* Warning: Embree 2 convention for geometrical normals is
+ * left-handed and star-enclosure uses right-handed convention */
+ ? SIDE_BACK : SIDE_FRONT;
+ ASSERT(hit.normal[2] != 0);
ASSERT(hit_trg_id < desc->scene->nutris);
/* Not really the root until following links */
@@ -746,7 +762,7 @@ collect_and_link_neighbours
ASSERT(sz <= EDGE_MAX__);
edge_count = (edge_id_t)sz;
FOR_EACH(e, 0, edge_count) {
- double edge[3], common_edge[3], basis[9], norm, max_z, maxz_edge;
+ double edge[3], common_edge[3], basis[9], norm, max_z, maxz_edge, a;
vrtx_id_t v0, v1, v2;
struct edge_neighbourhood* neighbourhood
= darray_neighbourhood_data_get(&neighbourhood_by_edge) + e;
@@ -811,6 +827,7 @@ collect_and_link_neighbours
sizeof(struct neighbour_info), neighbour_cmp);
/* Link sides.
* Create cycles of sides by neighbourhood around common edge. */
+ a = -DBL_MAX;
FOR_EACH(i, 0, neighbour_count) {
/* Neighbourhood info for current pair of triangles */
const struct neighbour_info* current
@@ -839,15 +856,40 @@ collect_and_link_neighbours
/* Side ptrs */
struct trgside* const p_crt_side = trgsides + crt_side_idx;
struct trgside* const p_ccw_side = trgsides + ccw_side_idx;
+ /* Check that angle is a discriminant property */
+ ASSERT(a <= current->angle); /* Is sorted */
+ if(a == current->angle) {
+ /* Two consecutive triangles with same angle! */
+ const struct neighbour_info* previous;
+ trg_id_t prev_id;
+ ASSERT(i > 0);
+ previous = darray_neighbour_cdata_get(neighbour_list) + i - 1;
+ prev_id = previous->trg_id;
+ log_err(scn->dev,
+ "%s: found 2 overlying triangles (%u & %u).\n",
+ FUNC_NAME, prev_id, crt_id);
+ tmp_res = RES_BAD_OP;
+ goto tmp_error;
+ }
+ a = current->angle;
/* Link sides */
p_crt_side->facing_side_id[crt_edge] = ccw_side_idx;
p_ccw_side->facing_side_id[ccw_edge] = crt_side_idx;
-
/* Record media */
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);
+ /* Detect triangles that could surround a hole:
+ * - single triangle on (one of) its edge
+ * - different media on its sides */
+ if(neighbour_count == 1
+ && p_crt_side->medium != p_ccw_side->medium)
+ {
+ log_warn(scn->dev,
+ "%s: found possible hole involving triangle %u.\n",
+ FUNC_NAME, crt_id);
+ }
}
}
tmp_error:
diff --git a/src/test_senc_enclosure.c b/src/test_senc_enclosure.c
@@ -213,7 +213,7 @@ test(enum senc_convention convention)
ctx.scale = 1;
d3(ctx.offset, 0, 0, 0);
ctx.front_media = medium0;
- ctx.back_media = medium0;
+ ctx.back_media = medium1;
CHK(senc_scene_add_geometry(scn, ntriangles - 1, get_indices, get_media,
NULL, nvertices, get_position, &ctx) == RES_OK);
@@ -233,7 +233,7 @@ test(enum senc_convention convention)
CHK(senc_enclosure_get_header(enclosure, &header) == RES_OK);
CHK(header.enclosure_id == 0);
- CHK(header.enclosed_media_count == 1);
+ CHK(header.enclosed_media_count == 2);
CHK(header.triangle_count == 2 * header.unique_triangle_count);
CHK(header.unique_triangle_count == ntriangles - 1);
CHK(header.vertices_count == nvertices);
diff --git a/src/test_senc_utils.h b/src/test_senc_utils.h
@@ -270,19 +270,19 @@ cmp_trg
}
FOR_EACH(i, 0, 3) {
FOR_EACH(j, 0, 3) {
- if (d3_eq(t1[i], t2[j])) {
+ if(d3_eq(t1[i], t2[j])) {
trg1_eq[i] = j;
- if (i == 0) fst_vrtx = j;
+ if(i == 0) fst_vrtx = j;
break;
}
}
}
FOR_EACH(i, 0, 3) {
- if (trg1_eq[i] == 3) {
+ if(trg1_eq[i] == 3) {
*trg_eq = 0;
return;
}
- if (trg1_eq[i] == trg1_eq[(i + 1) % 3]
+ if(trg1_eq[i] == trg1_eq[(i + 1) % 3]
|| trg1_eq[i] == trg1_eq[(i + 2) % 3]) {
*trg_eq = 0;
return;