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 906ed56bcfc2e8c105602b7b73dd6d9b3f68c57f
parent 051843e1a9032660bf2a7ff35030e39bbaa9d5c3
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Wed,  6 May 2020 07:29:32 +0200

Fix misleading comments and small changes to the code

The modified code, that is supposed to give the same results, is
clearer.

Diffstat:
Msrc/senc3d_scene_analyze.c | 43+++++++++++++++++++++++++------------------
1 file changed, 25 insertions(+), 18 deletions(-)

diff --git a/src/senc3d_scene_analyze.c b/src/senc3d_scene_analyze.c @@ -163,7 +163,7 @@ self_hit_filter ((s < 0) /* Facing geometrical normal of hit */ == ((filter_ctx->scn->convention & SENC3D_CONVENTION_NORMAL_FRONT) != 0)) /* Warning: following Embree 2 convention for geometrical normals, - * the Star3D hit normal is left-handed while star-enclosure uses + * the Star3D hit normal is left-handed while star-enclosures-3d uses * right-handed convention */ ? SENC3D_BACK : SENC3D_FRONT; filter_ctx->hit_component = hit_trg_comp->component[hit_side]; @@ -248,9 +248,9 @@ extract_connex_components /* Any not-already-used side is used as a starting point */ side_id_t first_side_not_in_component = media_use->first; double max_nz; - side_id_t max_nz_side_id = SIDE_NULL__; + side_id_t max_nz_side_id; const side_id_t last_side = media_use->last; - int component_canceled = 0; + int component_canceled = 0, max_z_is_2sided = 0; res_T tmp_res = RES_OK; ATOMIC id; @@ -444,8 +444,12 @@ extract_connex_components cmp[sid] = cc->cc_id; } - /* Compute the normal at the max_z vertex. */ + /* Determine if this component can be an inner part inside another + * component (creating a hole) as only these components will need + * to search for their possible outer component when grouping + * components to create encosures */ max_nz = 0; + max_nz_side_id = SIDE_NULL__; sz = darray_side_id_size_get(&ids_of_sides_around_max_z_vertex); ASSERT(sz > 0); FOR_EACH(ii, 0, sz) { @@ -460,13 +464,7 @@ extract_connex_components darray_position_cdata_get(&scn->vertices); double edge0[3], edge1[3], normal[3], norm; - /* To ensure 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 == x can be false). */ ASSERT(trg_comp->component[s] == cc->cc_id); (void)s; - if(trg_comp->component[SENC3D_FRONT] == trg_comp->component[SENC3D_BACK]) - continue; - d3_sub(edge0, vertices[trg_in->vertice_id[1]].vec, vertices[trg_in->vertice_id[0]].vec); d3_sub(edge1, vertices[trg_in->vertice_id[2]].vec, @@ -478,10 +476,18 @@ extract_connex_components if(fabs(max_nz) < fabs(normal[2])) { max_nz_side_id = side_id; max_nz = normal[2]; + max_z_is_2sided = (trg_comp->component[SENC3D_FRONT] + == trg_comp->component[SENC3D_BACK]); } } - if(max_nz == 0) cc->is_outer_border = 0; + /* The inner/outer property comes from the normal orientation of the + * triangle on top of the component, this triangle being the one whose + * |Nz| is maximal. If this triangle has its 2 sides in the component, + * the component is inner */ + if(max_nz == 0) ASSERT(max_z_is_2sided); + if(max_z_is_2sided) cc->is_outer_border = 0; else { + ASSERT(max_nz_side_id != SIDE_NULL__); if(TRGSIDE_IS_FRONT(max_nz_side_id) == ((scn->convention & SENC3D_CONVENTION_NORMAL_FRONT) != 0)) { /* Geom normal points towards the component */ @@ -634,7 +640,7 @@ group_connex_components max_vrtx = positions[cc->max_z_vrtx_id].vec; if(cc->is_outer_border) { ATOMIC id; - /* Don't need to cast a ray */ + /* No need to query closest point */ cc->cc_group_root = cc->cc_id; /* New group with self as root */ id = ATOMIC_INCR(next_enclosure_id) - 1; ASSERT(id <= ENCLOSURE_MAX__); @@ -1012,6 +1018,7 @@ build_result const struct triangle_comp* triangles_comp; struct htable_vrtx_id vtable; int output_normal_in, normals_front, normals_back; + size_t cc_count; int64_t tt; int64_t ee; @@ -1024,8 +1031,8 @@ build_result ASSERT(normals_back != normals_front); ASSERT(output_normal_in != ((scn->convention & SENC3D_CONVENTION_NORMAL_OUTSIDE) != 0)); - ASSERT(darray_ptr_component_descriptor_size_get(connex_components) - <= COMPONENT_MAX__); + cc_count = darray_ptr_component_descriptor_size_get(connex_components); + ASSERT(cc_count <= COMPONENT_MAX__); cc_descriptors = darray_ptr_component_descriptor_cdata_get(connex_components); enclosures = darray_enclosure_data_get(&scn->analyze.enclosures); triangles_in = darray_triangle_in_cdata_get(&scn->triangles_in); @@ -1054,9 +1061,10 @@ build_result ordered_ids[rank] = e; } /* Rewrite cc_descriptors */ - FOR_EACH(d, 0, darray_ptr_component_descriptor_size_get(connex_components)) + FOR_EACH(d, 0, cc_count) { cc_descriptors[d]->enclosure_id = - ordered_ids[cc_descriptors[d]->enclosure_id]; + ordered_ids[cc_descriptors[d]->enclosure_id]; + } single_err: (void)0; }/* Implicit barrier here. */ if(*res != RES_OK) goto exit; @@ -1093,8 +1101,7 @@ build_result trg_id_t t; medium_id_t m; res_T tmp_res = RES_OK; - ASSERT(enc->first_component - < darray_ptr_component_descriptor_size_get(connex_components)); + ASSERT(enc->first_component < cc_count); ASSERT(cc_descriptors[enc->first_component]->cc_id == enc->first_component);