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 7e386804f5ab15dc7b725d8b39fe0947b4191b54
parent 9de058ca4f29cba57ee9415c0c27590bce8bec66
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Thu, 15 Feb 2018 10:24:28 +0100

Change enclosure triangles order when both sides are in.

All back-faces of doubly in triangles are put at the end.

Diffstat:
Msrc/senc_scene.c | 2+-
Msrc/senc_scene_analyze.c | 42++++++++++++++++++++++++++++++------------
Msrc/senc_scene_analyze_c.h | 10+++++-----
Msrc/test_senc_enclosure.c | 29++++++++++++++++-------------
Msrc/test_senc_sample_enclosure.c | 28++++++++++++++--------------
Msrc/test_senc_utils.h | 2+-
6 files changed, 67 insertions(+), 46 deletions(-)

diff --git a/src/senc_scene.c b/src/senc_scene.c @@ -137,7 +137,7 @@ senc_scene_add_geometry /* New vertex */ unique_v = scn->nuverts + actual_nuverts; res = darray_position_push_back(&scn->vertices, &tmp); - if (res != RES_OK) goto error; + if(res != RES_OK) goto error; ASSERT(unique_v == htable_vrtx_size_get(&scn->unique_vertices)); OK(htable_vrtx_set(&scn->unique_vertices, &tmp, &unique_v)); ++actual_nuverts; diff --git a/src/senc_scene_analyze.c b/src/senc_scene_analyze.c @@ -356,7 +356,7 @@ extract_connex_components ASSERT(trgsides[crt_side_id].medium == m); /* Record crt_side both as component and triangle level */ - current_cc.triangle_count++; + current_cc.side_count++; trgsides[crt_side_id].list_id = FLAG_LIST_COMPONENT; if(TRGSIDE_IS_FRONT(crt_side_id)) { ASSERT(trg_comp->component[SIDE_FRONT] == USHRT_MAX); @@ -889,7 +889,7 @@ build_result size_t tmp; component_id_t cc_count, c; enclosure_id_t e; - trg_id_t* approx_trg_counts; + side_id_t* side_counts; ASSERT(desc && connex_components); @@ -903,9 +903,8 @@ build_result triangles_in = darray_triangle_in_cdata_get(&desc->scene->triangles_in); positions = darray_position_cdata_get(&desc->scene->vertices); /* Set some enclosure data */ - approx_trg_counts - = MEM_CALLOC(alloc, desc->enclosures_count, sizeof(trg_id_t)); - if(!approx_trg_counts) { + side_counts = MEM_CALLOC(alloc, desc->enclosures_count, sizeof(side_id_t)); + if(!side_counts) { res = RES_MEM_ERR; goto error; } @@ -924,7 +923,7 @@ build_result || enc->header.enclosed_medium == cc->medium); /* Same medium */ ASSERT(enc->header.enclosed_medium < UINT_MAX); enc->header.enclosed_medium = (unsigned)cc->medium; /* Back to API type */ - approx_trg_counts[e_id] += cc->triangle_count; + side_counts[e_id] += cc->side_count; } side_membership = MEM_ALLOC(alloc, desc->scene->nutris * sizeof(*side_membership)); @@ -933,7 +932,7 @@ build_result goto error; } res = darray_triangle_enc_resize(&desc->triangles_enc, desc->scene->nutris); - if (res != RES_OK) goto error; + if(res != RES_OK) goto error; triangles_enc = darray_triangle_enc_data_get(&desc->triangles_enc); htable_vrtx_id_init(alloc, &vtable); FOR_EACH(e, 0, desc->enclosures_count) { @@ -949,12 +948,14 @@ build_result FOR_EACH(t, 0, desc->scene->nutris) side_membership[t] |= cc_membership[t]; } /* Translate membership into a side and vertex lists. */ - OK(darray_triangle_in_reserve(&enc->sides, approx_trg_counts[e])); - OK(darray_position_reserve(&enc->vertices, approx_trg_counts[e] / 2)); + OK(darray_triangle_in_reserve(&enc->sides, side_counts[e])); + OK(darray_position_reserve(&enc->vertices, side_counts[e] / 2)); /* New vertex numbering scheme local to the enclosure */ htable_vrtx_id_clear(&vtable); ASSERT(desc->scene->nutris == darray_triangle_in_size_get(&desc->scene->triangles_in)); + /* Proceed in 2 steps; the second step puts at the end the back-faces + * of triangles that also have front-face in the list. */ FOR_EACH(t, 0, desc->scene->nutris) { const struct triangle_in* trg_in = triangles_in + t; struct triangle_in trg; @@ -984,8 +985,7 @@ build_result OK(darray_triangle_in_push_back(&enc->sides, &trg)); ASSERT(triangles_enc[t].enclosure[SIDE_FRONT] == ENCLOSURE_NULL__); triangles_enc[t].enclosure[SIDE_FRONT] = e; - } - if(side_membership[t] & FLAG_BACK) { + } else if(side_membership[t] & FLAG_BACK) { ++enc->header.triangle_count; triangle_in_flip(&trg); OK(darray_triangle_in_push_back(&enc->sides, &trg)); @@ -993,12 +993,30 @@ build_result triangles_enc[t].enclosure[SIDE_BACK] = e; } } + FOR_EACH(t, 0, desc->scene->nutris) { + const struct triangle_in* trg_in = triangles_in + t; + struct triangle_in trg; + int i; + if(!((side_membership[t] & FLAG_FRONT) && (side_membership[t] & FLAG_BACK))) + continue; + ++enc->header.triangle_count; + FOR_EACH(i, 0, 3) { + vrtx_id_t* id = htable_vrtx_id_find(&vtable, trg_in->vertice_id + i); + ASSERT(id); + trg.vertice_id[2-i] = *id; /* Known vertex */ + } + FOR_EACH(i, 0, 2) trg.medium[1-i] = trg_in->medium[i]; + OK(darray_triangle_in_push_back(&enc->sides, &trg)); + ASSERT(triangles_enc[t].enclosure[SIDE_BACK] == ENCLOSURE_NULL__); + triangles_enc[t].enclosure[SIDE_BACK] = e; + } + ASSERT(darray_triangle_in_size_get(&enc->sides) == side_counts[e]); } exit: htable_vrtx_id_release(&vtable); if(side_membership) MEM_RM(alloc, side_membership); - if(approx_trg_counts) MEM_RM(alloc, approx_trg_counts); + if(side_counts) MEM_RM(alloc, side_counts); return res; error: goto exit; diff --git a/src/senc_scene_analyze_c.h b/src/senc_scene_analyze_c.h @@ -145,7 +145,7 @@ struct cc_descriptor { double max_z_nz; side_id_t max_z_side_id; vrtx_id_t max_z_vrtx_id; - trg_id_t triangle_count; + side_id_t side_count; medium_id_t medium; component_id_t cc_id; component_id_t cc_group_root; @@ -177,7 +177,7 @@ cc_descriptor_clear(struct cc_descriptor* data) data->max_z_nz = CC_DESCRIPTOR_NULL.max_z_nz; data->max_z_side_id = CC_DESCRIPTOR_NULL.max_z_side_id; data->max_z_vrtx_id = CC_DESCRIPTOR_NULL.max_z_vrtx_id; - data->triangle_count = CC_DESCRIPTOR_NULL.triangle_count; + data->side_count = CC_DESCRIPTOR_NULL.side_count; data->medium = CC_DESCRIPTOR_NULL.medium; data->cc_id = CC_DESCRIPTOR_NULL.cc_id; data->cc_group_root = CC_DESCRIPTOR_NULL.cc_group_root; @@ -192,7 +192,7 @@ cc_descriptor_purge(struct cc_descriptor* data) data->max_z_nz = CC_DESCRIPTOR_NULL.max_z_nz; data->max_z_side_id = CC_DESCRIPTOR_NULL.max_z_side_id; data->max_z_vrtx_id = CC_DESCRIPTOR_NULL.max_z_vrtx_id; - data->triangle_count = CC_DESCRIPTOR_NULL.triangle_count; + data->side_count = CC_DESCRIPTOR_NULL.side_count; data->medium = CC_DESCRIPTOR_NULL.medium; data->cc_id = CC_DESCRIPTOR_NULL.cc_id; data->cc_group_root = CC_DESCRIPTOR_NULL.cc_group_root; @@ -208,7 +208,7 @@ cc_descriptor_copy(struct cc_descriptor* dst, const struct cc_descriptor* src) dst->max_z_nz = src->max_z_nz; dst->max_z_side_id = src->max_z_side_id; dst->max_z_vrtx_id = src->max_z_vrtx_id; - dst->triangle_count = src->triangle_count; + dst->side_count = src->side_count; dst->medium = src->medium; dst->cc_id = src->cc_id; dst->cc_group_root = src->cc_group_root; @@ -224,7 +224,7 @@ cc_descriptor_copy_and_release(struct cc_descriptor* dst, struct cc_descriptor* dst->max_z_nz = src->max_z_nz; dst->max_z_side_id = src->max_z_side_id; dst->max_z_vrtx_id = src->max_z_vrtx_id; - dst->triangle_count = src->triangle_count; + dst->side_count = src->side_count; dst->medium = src->medium; dst->cc_id = src->cc_id; dst->cc_group_root = src->cc_group_root; diff --git a/src/test_senc_enclosure.c b/src/test_senc_enclosure.c @@ -72,7 +72,7 @@ main(int argc, char** argv) CHK(senc_descriptor_get_enclosure_count(desc, &count) == RES_OK); CHK(count == 2); - + FOR_EACH(i, 0, count) { CHK(senc_descriptor_get_enclosure(desc, i, &enclosure) == RES_OK); @@ -129,6 +129,8 @@ main(int argc, char** argv) CHK(senc_descriptor_get_enclosure_count(desc, &count) == RES_OK); CHK(count == 1); + dump_enclosure(desc, 0, "test_enclosure_hole.obj"); + CHK(senc_descriptor_get_enclosure(desc, 0, &enclosure) == RES_OK); CHK(senc_enclosure_get_header(NULL, &header) == RES_BAD_ARG); @@ -146,12 +148,13 @@ main(int argc, char** argv) FOR_EACH(n, 0, header->unique_triangle_count) { unsigned indices[2][3]; /* Read 2 consecutive triangles in the enclosure */ - FOR_EACH(i, 0, 2) - senc_enclosure_get_triangle(enclosure, 2 * n + i, indices[i]); + FOR_EACH(i, 0, 2) /* Triangle n VS 2n */ + CHK(senc_enclosure_get_triangle(enclosure, + n + i * header->unique_triangle_count, indices[i]) == RES_OK); /* Same triangles, opposite sides */ - CHK(indices[0][0] == indices[1][0]); - CHK(indices[0][1] == indices[1][2]); - CHK(indices[0][2] == indices[1][1]); + CHK(indices[0][0] == indices[1][2]); + CHK(indices[0][1] == indices[1][1]); + CHK(indices[0][2] == indices[1][0]); /* Put geometry in a 3D view */ CHK(s3d_shape_create_mesh(s3d, &s3d_shp) == RES_OK); @@ -162,16 +165,16 @@ main(int argc, char** argv) == RES_OK); CHK(s3d_scene_attach_shape(s3d_scn, s3d_shp) == RES_OK); - CHK(s3d_shape_ref_put(s3d_shp) == RES_OK); + S3D(shape_ref_put(s3d_shp)); } - CHK(s3d_device_ref_put(s3d) == RES_OK); - CHK(s3d_scene_ref_put(s3d_scn) == RES_OK); + S3D(device_ref_put(s3d)); + S3D(scene_ref_put(s3d_scn)); - CHK(senc_scene_ref_put(scn) == RES_OK); - CHK(senc_device_ref_put(dev) == RES_OK); - CHK(senc_descriptor_ref_put(desc) == RES_OK); - CHK(senc_enclosure_ref_put(enclosure) == RES_OK); + SENC(scene_ref_put(scn)); + SENC(device_ref_put(dev)); + SENC(descriptor_ref_put(desc)); + SENC(enclosure_ref_put(enclosure)); check_memory_allocator(&allocator); mem_shutdown_proxy_allocator(&allocator); diff --git a/src/test_senc_sample_enclosure.c b/src/test_senc_sample_enclosure.c @@ -89,23 +89,23 @@ main(int argc, char** argv) CHK(s3d_scene_view_create(s3d_scn, S3D_SAMPLE, &s3d_view) == RES_OK); /* ... and sample it. */ - ssp_rng_create(&allocator, &ssp_rng_threefry, &rng); + CHK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng) == RES_OK); FOR_EACH(i, 0, 10000) { struct s3d_attrib attrib; int n, c; - CHK(s3d_scene_view_sample(s3d_view, + S3D(scene_view_sample(s3d_view, ssp_rng_canonical_float(rng), ssp_rng_canonical_float(rng), ssp_rng_canonical_float(rng), - &prim, st) == RES_OK); - s3d_primitive_get_attrib(&prim, S3D_POSITION, st, &attrib); + &prim, st)); + S3D(primitive_get_attrib(&prim, S3D_POSITION, st, &attrib)); c = 0; FOR_EACH(n, 0, 3) if(eq_eps(attrib.value[n], 0, FLT_EPSILON) || eq_eps(attrib.value[n], 1, FLT_EPSILON)) c++; ASSERT(c == 1); - s3d_primitive_get_attrib(&prim, S3D_GEOMETRY_NORMAL, st, &attrib); + S3D(primitive_get_attrib(&prim, S3D_GEOMETRY_NORMAL, st, &attrib)); c = 0; FOR_EACH(n, 0, 3) if(eq_eps(attrib.value[n], -1, FLT_EPSILON) @@ -119,17 +119,17 @@ main(int argc, char** argv) ASSERT(c == 2); } - CHK(senc_enclosure_ref_put(enclosure) == RES_OK); - CHK(senc_scene_ref_put(scn) == RES_OK); - CHK(senc_device_ref_put(dev) == RES_OK); - CHK(senc_descriptor_ref_put(desc) == RES_OK); + SENC(enclosure_ref_put(enclosure)); + SENC(scene_ref_put(scn)); + SENC(device_ref_put(dev)); + SENC(descriptor_ref_put(desc)); - CHK(ssp_rng_ref_put(rng) == RES_OK); + SSP(rng_ref_put(rng)); - CHK(s3d_shape_ref_put(s3d_shp) == RES_OK); - CHK(s3d_scene_view_ref_put(s3d_view) == RES_OK); - CHK(s3d_device_ref_put(s3d) == RES_OK); - CHK(s3d_scene_ref_put(s3d_scn) == RES_OK); + S3D(shape_ref_put(s3d_shp)); + S3D(scene_view_ref_put(s3d_view)); + S3D(device_ref_put(s3d)); + S3D(scene_ref_put(s3d_scn)); check_memory_allocator(&allocator); mem_shutdown_proxy_allocator(&allocator); diff --git a/src/test_senc_utils.h b/src/test_senc_utils.h @@ -152,7 +152,7 @@ dump_enclosure CHK(senc_enclosure_get_vertex(enclosure, i, tmp) == RES_OK); fprintf(stream, "v %g %g %g\n", SPLIT3(tmp)); } - FOR_EACH(i, 0, header->unique_triangle_count) { + FOR_EACH(i, 0, header->triangle_count) { unsigned indices[3]; CHK(senc_enclosure_get_triangle(enclosure, i, indices) == RES_OK); fprintf(stream, "f %lu %lu %lu\n",