star-enclosures-3d

Extract enclosures from 3D geometry
git clone git://git.meso-star.fr/star-enclosures-3d.git
Log | Files | Refs | README | LICENSE

commit e3c0df09d923326dd728cdb3a87164bf2db0ac3e
parent 09d0ba46ffda95f4de759daf0b146479e5fba93d
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Thu, 15 Feb 2018 12:28:12 +0100

Add a self-hit filter.

Diffstat:
Msrc/senc_scene_analyze.c | 54++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 46 insertions(+), 8 deletions(-)

diff --git a/src/senc_scene_analyze.c b/src/senc_scene_analyze.c @@ -174,8 +174,6 @@ find_component_Zmax side = SIDE_BACK; } - /* TODO: keep the list of triangle sharing the selected vertex - * to improve self-hit filter. */ if(cc->max_vrtx[2] < trg_tmp->max_z) { change = 1; /* Try first to improve z */ } @@ -469,6 +467,40 @@ get_scn_position(const unsigned ivert, float pos[3], void* ctx) { f3_set_d3(pos, pt->vec); } +struct ray_ctx { + component_id_t origin_component; + const struct darray_triangle_comp* triangles_comp; +}; + +static int +self_hit_filter +(const struct s3d_hit* hit, + const float ray_org[3], + const float ray_dir[3], + void* ray_data, + void* filter_data) +{ + const struct senc_descriptor* desc = filter_data; + const struct ray_ctx* ctx = ray_data; + const struct triangle_comp* hit_trg_comp; + enum side_id hit_side; + component_id_t hit_component; + + (void)ray_org; (void)ray_dir; + ASSERT(hit && ray_org && ctx && ray_data && desc); + ASSERT(hit->prim.prim_id < darray_triangle_comp_size_get(ctx->triangles_comp)); + hit_trg_comp + = darray_triangle_comp_cdata_get(ctx->triangles_comp) + hit->prim.prim_id; + hit_side = (hit->normal[2] > 0) ? SIDE_FRONT : SIDE_BACK; + hit_component = hit_trg_comp->component[hit_side]; + + if(hit_component == ctx->origin_component) { + /* self hit */ + ASSERT(hit->distance < 1e-6); + } + return (hit_component == ctx->origin_component); +} + static res_T group_connex_components (struct senc_descriptor* desc, @@ -484,6 +516,7 @@ group_connex_components struct s3d_shape* s3d_shp = NULL; struct s3d_scene_view* s3d_view = NULL; struct s3d_vertex_data attribs; + struct ray_ctx ray_context; size_t tmp; component_id_t cc_count, c; medium_id_t infinite_medium = MEDIUM_NULL__; @@ -513,6 +546,8 @@ group_connex_components ASSERT(desc->scene->nuverts < UINT_MAX); OK(s3d_mesh_setup_indexed_vertices(s3d_shp, (unsigned)desc->scene->nutris, get_scn_indices, (unsigned)desc->scene->nuverts, &attribs, 1, desc->scene)); + s3d_mesh_set_hit_filter_function(s3d_shp, self_hit_filter, desc); + ray_context.triangles_comp = triangles_comp; OK(s3d_scene_attach_shape(s3d_scn, s3d_shp)); OK(s3d_scene_view_create(s3d_scn, S3D_TRACE, &s3d_view)); @@ -523,6 +558,8 @@ group_connex_components const float dir[3] = { 0, 0, 1 }; const float range[2] = { 0, FLT_MAX }; struct cc_descriptor* const cc = descriptors + c; + const struct triangle_comp* origin_trg = + darray_triangle_comp_cdata_get(triangles_comp) + cc->max_z_vrtx_id; ASSERT(cc->cc_group_root == CC_GROUP_ID_NONE); @@ -545,7 +582,10 @@ group_connex_components || trgsides[cc->max_z_side_id].facing_side_id[2] == TRGSIDE_OPPOSITE(cc->max_z_side_id)))); f3_set_d3(origin, cc->max_vrtx); - OK(s3d_scene_view_trace_ray(s3d_view, origin, dir, range, NULL, &hit)); + /* Self-hit data: self hit if hit this component "on the other side" */ + ray_context.origin_component + = origin_trg->component[1- TRGSIDE_2_SIDE(cc->max_z_side_id)]; + OK(s3d_scene_view_trace_ray(s3d_view, origin, dir, range, &ray_context, &hit)); /* If no hit, the component is facing an infinite medium */ if(S3D_HIT_NONE(&hit)) { cc->cc_group_root = CC_GROUP_ROOT_INFINITE; @@ -556,9 +596,8 @@ group_connex_components infinite_medium_first_side = cc->max_z_side_id; continue; } - if(infinite_medium != cc->medium) { - /* Medium mismatch! - * Model topology is broken. */ + if(infinite_medium == cc->medium) { + /* Medium mismatch! Model topology is broken. */ const trg_id_t t1 = TRGSIDE_2_TRG(infinite_medium_first_side); const trg_id_t t2 = TRGSIDE_2_TRG(cc->max_z_side_id); const struct triangle_in* triangles_in @@ -601,7 +640,7 @@ group_connex_components enum side_id hit_side = (hit.normal[2] > 0) ? SIDE_FRONT : SIDE_BACK; const side_id_t hit_side_id = TRGIDxSIDE_2_TRGSIDE(hit_trg_id, hit_side); - ASSERT(hit.prim.prim_id < desc->scene->nutris); + ASSERT(hit_trg_id < desc->scene->nutris); /* Not really the root until following links */ cc->cc_group_root = hit_trg_comp->component[hit_side]; @@ -821,7 +860,6 @@ link_neighbours /* Compute rotation angle around common edge */ d3_sub(edge, vertices[v2].vec, vertices[v0].vec); d33_muld3(edge, basis, edge); - /* TODO: where are invalid triangles detected? */ ASSERT(d3_len(edge) && (edge[0] || edge[1])); neighbour_info->angle = atan2(edge[1], edge[0]); if(neighbour_info->angle < 0) neighbour_info->angle += 2 * PI;