commit f8c4d647553d256c9438efaa308ee735f8b3c1c7
parent 1bbb54155cad8f2e302a444f3049c95f8231b553
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Tue, 21 Jul 2020 17:06:09 +0200
BugFix: broken enclosure whith multiple media inside
Diffstat:
3 files changed, 144 insertions(+), 11 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -155,6 +155,7 @@ if(NOT NO_TEST)
new_test(test_senc3d_enclosure)
new_test(test_senc3d_inconsistant_cube)
new_test(test_senc3d_invalid_scenes)
+ new_test(test_senc3d_multi_media)
new_test(test_senc3d_sample_enclosure)
new_test(test_senc3d_scene)
new_test(test_senc3d_some_enclosures)
diff --git a/src/senc3d_scene_analyze.c b/src/senc3d_scene_analyze.c
@@ -286,6 +286,8 @@ extract_connex_components
side_id_t max_nz_side_id;
const side_id_t last_side = media_use->last;
int component_canceled = 0, max_z_is_2sided = 0, fst_nz = 1;
+ side_id_t cc_start_side_id = SIDE_NULL__;
+ side_id_t cc_last_side_id = SIDE_NULL__;
res_T tmp_res = RES_OK;
ATOMIC id;
@@ -296,25 +298,30 @@ extract_connex_components
ASSERT(darray_side_id_size_get(&stack) == 0);
ASSERT(darray_side_id_size_get(¤t_component) == 0);
for(;;) { /* Process all components for this medium */
- const side_id_t start_side_id = get_side_not_in_connex_component
+ side_id_t crt_side_id = get_side_not_in_connex_component
(last_side, trgsides, processed, &first_side_not_in_component, medium);
- side_id_t crt_side_id = start_side_id;
- side_id_t last_side_id = start_side_id;
vrtx_id_t max_z_vrtx_id = VRTX_NULL__;
struct cc_descriptor *cc;
double max_z = -DBL_MAX;
component_canceled = 0;
- ASSERT(start_side_id == SIDE_NULL__ || start_side_id < 2 * scn->ntris);
+ ASSERT(crt_side_id == SIDE_NULL__ || crt_side_id < 2 * scn->ntris);
darray_side_id_clear(¤t_component);
if(*p_res != RES_OK) break;
- if(start_side_id == SIDE_NULL__)
+ if(crt_side_id == SIDE_NULL__)
break; /* start_side_id=SIDE_NULL__ => component done! */
+ if(cc_start_side_id == SIDE_NULL__) {
+ cc_start_side_id = cc_last_side_id = crt_side_id;
+ } else {
+ cc_start_side_id = MMIN(cc_start_side_id, crt_side_id);
+ cc_last_side_id = MMAX(cc_last_side_id, crt_side_id);
+ }
+
#ifndef NDEBUG
{
- trg_id_t tid = TRGSIDE_2_TRG(start_side_id);
- enum senc3d_side s = TRGSIDE_2_SIDE(start_side_id);
+ trg_id_t tid = TRGSIDE_2_TRG(crt_side_id);
+ enum senc3d_side s = TRGSIDE_2_SIDE(crt_side_id);
medium_id_t side_med
= darray_triangle_in_data_get(&scn->triangles_in)[tid].medium[s];
ASSERT(side_med == medium);
@@ -421,7 +428,8 @@ extract_connex_components
if(sz == 0) break; /* Empty stack => component is done! */
crt_side_id = darray_side_id_cdata_get(&stack)[sz - 1];
darray_side_id_pop_back(&stack);
- last_side_id = MMAX(last_side_id, crt_side_id);
+ cc_start_side_id = MMIN(cc_start_side_id, crt_side_id);
+ cc_last_side_id = MMAX(cc_last_side_id, crt_side_id);
}
canceled:
if(component_canceled) continue;
@@ -431,7 +439,6 @@ extract_connex_components
if(!cc) *p_res = RES_MEM_ERR;
if(*p_res != RES_OK) break;
- ASSERT(medium == trgsides[start_side_id].medium);
ASSERT(max_z_vrtx_id != VRTX_NULL__);
cc_descriptor_init(alloc, cc);
id = ATOMIC_INCR(component_count) - 1;
@@ -440,14 +447,18 @@ extract_connex_components
sz = darray_side_id_size_get(¤t_component);
ASSERT(sz > 0 && sz <= SIDE_MAX__);
cc->side_count = (side_id_t)sz;
- cc->side_range.first = start_side_id;
- cc->side_range.last = last_side_id;
+ cc->side_range.first = cc_start_side_id;
+ cc->side_range.last = cc_last_side_id;
cc->max_z_vrtx_id = max_z_vrtx_id;
/* Tranfer ownership of the array to component */
ASSERT(!cc->media && current_media);
cc->media = current_media;
current_media = NULL;
+ /* Reset for next component */
+ cc_start_side_id = SIDE_NULL__;
+ cc_last_side_id = SIDE_NULL__;
+
/* Write component membership in the global structure
* No need for sync here as an unique thread writes a given side */
{STATIC_ASSERT(sizeof(cc->cc_id) >= 4, Cannot_write_IDs_sync_free);}
diff --git a/src/test_senc3d_multi_media.c b/src/test_senc3d_multi_media.c
@@ -0,0 +1,121 @@
+/* Copyright (C) |Meso|Star> 2016-2020 (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* This test has been created using the sg3_geometry_dump_as_C_code feature
+ * of star-geometry. It uses output from test_sg3_cube_on_cube. */
+
+#define _POSIX_C_SOURCE 200112L /* snprintf */
+
+#include "senc3d.h"
+#include "test_senc3d_utils.h"
+
+#include <rsys/double3.h>
+
+#include <stdio.h>
+
+ /* Dump of star-geometry-3d 'multi_media'. */
+static const unsigned multi_media_vertices_count = 8;
+static const double multi_media_vertices[24] =
+{
+ 0, 0, 0,
+ 1, 0, 0,
+ 0, 1, 0,
+ 1, 1, 0,
+ 0, 0, 1,
+ 1, 0, 1,
+ 0, 1, 1,
+ 1, 1, 1
+};
+static const unsigned multi_media_triangles_count = 12;
+static const unsigned multi_media_triangles[36] =
+{
+ 0, 2, 1,
+ 1, 2, 3,
+ 0, 4, 2,
+ 2, 4, 6,
+ 4, 5, 6,
+ 6, 5, 7,
+ 3, 7, 1,
+ 1, 7, 5,
+ 2, 6, 3,
+ 3, 6, 7,
+ 0, 1, 4,
+ 4, 1, 5
+};
+static const unsigned multi_media_properties[36] =
+{
+ 0, 4, 4,
+ 0, 4, 4,
+ 0, 3, 3,
+ 0, 3, 3,
+ 0, 3, 3,
+ 0, 3, 3,
+ 0, 2, 2,
+ 0, 2, 2,
+ 0, 2, 2,
+ 0, 1, 1,
+ 0, 1, 1,
+ 0, 1, 1
+};
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct senc3d_device* dev = NULL;
+ struct senc3d_scene* scn = NULL;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned ecount, tcount, t, e;
+ struct senc3d_enclosure* enc;
+ (void)argc, (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* Degenerated triangle: duplicated vertex */
+ ctx.positions = multi_media_vertices;
+ ctx.indices = multi_media_triangles;
+ ctx.properties = multi_media_properties;
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ multi_media_triangles_count, get_indices, get_media_from_properties,
+ multi_media_vertices_count, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_triangles_count(scn, &tcount));
+ CHK(tcount == multi_media_triangles_count);
+ FOR_EACH(t, 0, tcount) {
+ unsigned ids[2];
+ OK(senc3d_scene_get_triangle_enclosures(scn, t, ids));
+ CHK(ids[0] == 0 && ids[1] == 1);
+ }
+ OK(senc3d_scene_get_enclosure_count(scn, &ecount));
+ CHK(ecount == 2);
+ FOR_EACH(e, 0, ecount) {
+ struct senc3d_enclosure_header header;
+ OK(senc3d_scene_get_enclosure(scn, e, &enc));
+ OK(senc3d_enclosure_get_header(enc, &header));
+ CHK(header.primitives_count == multi_media_triangles_count);
+ CHK(header.enclosed_media_count == (header.is_infinite ? 1u : 4u));
+ OK(senc3d_enclosure_ref_put(enc));
+ }
+
+ OK(senc3d_scene_ref_put(scn));
+ OK(senc3d_device_ref_put(dev));
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}