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 90edf161d38fa7bb9e1a0e2e8aba9996bcba5bf9
parent bf92ade10d11e306b21aedaca255d37f7a3ae8b3
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri,  5 Apr 2024 15:12:40 +0200

Continue bugfixes on connec components grouping

Fixes include:
- first inner component volume test was wrong
- outer prevalence over inner not inforced
- unexpected NaN occurences on side computation

Diffstat:
Msrc/senc3d_scene_analyze.c | 57+++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 45 insertions(+), 12 deletions(-)

diff --git a/src/senc3d_scene_analyze.c b/src/senc3d_scene_analyze.c @@ -218,7 +218,11 @@ get_side_not_in_connex_component /* Here unsigned are required by s3d API */ static void -get_scn_indices(const unsigned itri, unsigned ids[3], void* ctx) { +get_scn_indices + (const unsigned itri, + unsigned ids[3], + void* ctx) +{ int i; const struct senc3d_scene* scene = ctx; const struct triangle_in* trg = @@ -232,7 +236,11 @@ get_scn_indices(const unsigned itri, unsigned ids[3], void* ctx) { /* Here unsigned are required by s3d API */ static void -get_scn_position(const unsigned ivert, float pos[3], void* ctx) { +get_scn_position + (const unsigned ivert, + float pos[3], + void* ctx) +{ const struct senc3d_scene* scene = ctx; const union double3* pt = darray_position_cdata_get(&scene->vertices) + ivert; @@ -337,6 +345,11 @@ self_hit_filter ASSERT(hit->prim.prim_id < darray_triangle_comp_size_get(ctx->triangles_comp)); + if(hit->distance > ctx->hit_dist) { + /* No improvement */ + return 1; + } + if(hit_comp[SENC3D_FRONT] == ctx->origin_component || hit_comp[SENC3D_BACK] == ctx->origin_component) { @@ -359,6 +372,10 @@ self_hit_filter const enum senc3d_side sides[2] = { SENC3D_FRONT, SENC3D_BACK }; component_id_t c = hit_comp[sides[n]]; ASSERT(c < darray_ptr_component_descriptor_size_get(ctx->components)); + if(c == ctx->hit_component) { + /* Cannot change ctx->hit_component */ + continue; + } if(comp_descriptors[c]->is_outer_border) { double v; /* The inner component we are trying to link can only be linked to @@ -369,14 +386,20 @@ self_hit_filter continue; } v = fabs(comp_descriptors[c]->_6volume); - /* If origin_component is inside several outer components, the one + /* If already linked to an inner component, prefer an outer one + * regardless of their respective volumes. + * If origin_component is inside several outer components, the one * we are looking for is the smallest one (to manage outer component - * inside another outer component) */ - if(v < ctx->current_6volume) { + * inside another outer component). */ + if((ctx->hit_component != COMPONENT_NULL__ + && !comp_descriptors[ctx->hit_component]->is_outer_border ) + || v < ctx->current_6volume) { ctx->hit_component = c; ctx->current_6volume = v; ctx->hit_dist = 0; ctx->hit_prim = hit->prim; + } else { + continue; } } else { /* c is an inner component */ @@ -409,11 +432,13 @@ self_hit_filter /* If origin_component is facing several inner components, the one * we are looking for is the largest one (to manage inner component * inside another inner component) */ - if(v > ctx->current_6volume) { + if(ctx->current_6volume == DBL_MAX || v > ctx->current_6volume) { ctx->hit_component = c; ctx->current_6volume = v; ctx->hit_dist = 0; ctx->hit_prim = hit->prim; + } else { + continue; } } } @@ -435,14 +460,22 @@ self_hit_filter /* For s to be comparable, vectors must be normailzed */ f3_normalize(hit_normal, hit->normal); f3_normalize(rdir, ray_dir); - s = f3_dot(rdir, hit_normal); + s = f3_dot(rdir, hit_normal); /* Can be NaN for tiny distances */ + if(isnan(s)) { + /* Try to fix it */ + f3_divf(rdir, ray_dir, hit->distance); + f3_normalize(rdir, rdir); + s = f3_dot(rdir, hit_normal); + ASSERT(!isnan(s)); + } + + if(ctx->hit_dist == hit->distance && fabsf(ctx->s) >= fabsf(s)) { + /* Same distance with no s improvement: keep the previous hit */ + return 1; + } if(fabsf(s) < DOT_THRESHOLD) { /* We cannot know for sure which side to consider */ - if(ctx->hit_dist == hit->distance && fabsf(ctx->s) > fabsf(s)) { - /* Same distance with worse s: keep the previous hit */ - return 1; - } ctx->hit_component = COMPONENT_NULL__; ctx->s = s; f3_set(ctx->hit_dir, ray_dir); @@ -1014,12 +1047,12 @@ group_connex_components } if(*res != RES_OK) return; #endif - descriptors = darray_ptr_component_descriptor_data_get(connex_components); tmp = darray_ptr_component_descriptor_size_get(connex_components); ASSERT(tmp <= COMPONENT_MAX__); cc_count = (component_id_t)tmp; positions = darray_position_cdata_get(&scn->vertices); + ctx0.type = FCTX0; ctx0.c.ctx0.triangles_comp = triangles_comp; ctx1.type = FCTX1;