commit a2af89ce3227132aa08cdcde019b657593cbad53
parent 8938737e7fccbaa3fda6f5261a674c99cc887576
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 20 Aug 2020 15:31:34 +0200
BugFix: grouping of nested components in contact at a single vertex
Diffstat:
2 files changed, 251 insertions(+), 27 deletions(-)
diff --git a/src/senc3d_scene_analyze.c b/src/senc3d_scene_analyze.c
@@ -68,6 +68,7 @@ struct filter_ctx1 {
struct darray_triangle_comp* triangles_comp;
struct darray_ptr_component_descriptor* components;
/* Result of hit */
+ double current_6volume;
component_id_t hit_component;
};
@@ -184,7 +185,9 @@ self_hit_filter
hit_comp = components[hit->prim.prim_id].component;
if(hit_comp[SENC3D_FRONT] == ctx2->component
|| hit_comp[SENC3D_BACK] == ctx2->component)
- ctx2->cpt++;
+ {
+ ctx2->cpt++;
+ }
return 1; /* Reject to continue counting */
}
@@ -293,8 +296,14 @@ self_hit_filter
/* origin_component is linked_to an outer component if cpt is odd,
* linked_to an inner component if cpt is even */
if(descriptors[c]->is_outer_border == (fctx2.c.ctx2.cpt % 2)) {
+ double v = fabs(descriptors[c]->_6volume);
+ /* If origin_component is inside several components, the one we are
+ * looking for is the smallest one */
+ if(v >= fctx->current_6volume) continue;
fctx->hit_component = fctx2.c.ctx2.component;
- return 0 /* origin_component is linked to c: keep */;
+ fctx->current_6volume = v;
+ /* Continue searching for a smaller component that includes
+ * origin_component */
}
}
return 1; /* Reject */
@@ -938,8 +947,10 @@ group_connex_components
f3_set_d3(origin, max_vrtx);
/* Self-hit data: self hit if hit this component "on the other side" */
fctx.c.ctx1.origin_component = cc->cc_id;
+ fctx.c.ctx1.current_6volume = DBL_MAX;
+ fctx.c.ctx1.hit_component = COMPONENT_NULL__;
/* Limit search radius. Only upwards moves (+Z) will be considered.
- * Ue a radius allowing to reach the closest top vertex of scene's AABB */
+ * Use a radius allowing to reach the closest top vertex of scene's AABB */
FOR_EACH(i, 0, 2) {
ASSERT(lower[i] <= origin[i] && origin[i] <= upper[i]);
rrr[i] = MMIN(origin[i] - lower[i], upper[i] - origin[i]);
@@ -952,9 +963,8 @@ group_connex_components
*res = tmp_res;
continue;
}
- ASSERT(fctx.c.ctx1.hit_component != COMPONENT_NULL__);
/* If no hit, the component is facing an infinite medium */
- if(S3D_HIT_NONE(&hit)) {
+ if(fctx.c.ctx1.hit_component == COMPONENT_NULL__) {
cc->cc_group_root = CC_GROUP_ROOT_INFINITE;
cc->enclosure_id = 0;
} else {
diff --git a/src/test_senc3d_zero_distance.c b/src/test_senc3d_zero_distance.c
@@ -25,7 +25,12 @@
#include <stdio.h>
-/* Test created using -c option of stardis */
+/* Tests created using -c option of stardis */
+
+/* zero_1 geometry is made of a big distorded cube, that as a single highest
+ * vertex V, and two internal shapes (highly distorded cubes) that joint at the
+ * same V vertex. Distance between the 6 components (inside and outside of each
+ * shape) is zero. */
#define zero_1_UNSPECIFIED_PROPERTY 4294967295
static const unsigned
@@ -140,11 +145,201 @@ zero_1_properties[36][3] = {
{ 1, 0, zero_1_UNSPECIFIED_PROPERTY }
};
-int
+/* zero_2 geometry is made of 5 nested distorded cubes of decreasing sizes, that
+ * all join at a single vertex V (the highest vertex in the model). Distance between
+ * the 10 components (inside and outside of each shape) is zero. */
+#define zero_2_UNSPECIFIED_PROPERTY 4294967295
+
+static const unsigned
+zero_2_vertices_count = 36;
+
+static const unsigned
+zero_2_triangles_count = 60;
+
+static const double
+zero_2_vertices[36][3] = {
+ { 0, 10, 0 },
+ { 0, 0, 0 },
+ { 0, 10, 10 },
+ { 0, 0, 10 },
+ { 10, 0, 10 },
+ { 10, 0, 0 },
+ { 9, 9, 11 },
+ { 10, 10, 0 },
+ { 1, 9, 1 },
+ { 1, 1, 1 },
+ { 1, 9, 9 },
+ { 1, 1, 9 },
+ { 9, 1, 9 },
+ { 9, 1, 1 },
+ { 9, 9, 1 },
+ { 2, 8, 2 },
+ { 2, 2, 2 },
+ { 2, 8, 8 },
+ { 2, 2, 8 },
+ { 8, 2, 8 },
+ { 8, 2, 2 },
+ { 8, 8, 2 },
+ { 3, 7, 3 },
+ { 3, 3, 3 },
+ { 3, 7, 7 },
+ { 3, 3, 7 },
+ { 7, 3, 7 },
+ { 7, 3, 3 },
+ { 7, 7, 3 },
+ { 4, 6, 4 },
+ { 4, 4, 4 },
+ { 4, 6, 6 },
+ { 4, 4, 6 },
+ { 6, 4, 6 },
+ { 6, 4, 4 },
+ { 6, 6, 4 }
+};
+
+static const unsigned
+zero_2_triangles[60][3] = {
+ { 0, 1, 2 },
+ { 1, 3, 2 },
+ { 4, 5, 6 },
+ { 5, 7, 6 },
+ { 2, 3, 4 },
+ { 6, 2, 4 },
+ { 5, 1, 0 },
+ { 7, 5, 0 },
+ { 3, 1, 5 },
+ { 4, 3, 5 },
+ { 7, 0, 2 },
+ { 6, 7, 2 },
+ { 8, 9, 10 },
+ { 9, 11, 10 },
+ { 12, 13, 6 },
+ { 13, 14, 6 },
+ { 10, 11, 12 },
+ { 6, 10, 12 },
+ { 13, 9, 8 },
+ { 14, 13, 8 },
+ { 11, 9, 13 },
+ { 12, 11, 13 },
+ { 14, 8, 10 },
+ { 6, 14, 10 },
+ { 15, 16, 17 },
+ { 16, 18, 17 },
+ { 19, 20, 6 },
+ { 20, 21, 6 },
+ { 17, 18, 19 },
+ { 6, 17, 19 },
+ { 20, 16, 15 },
+ { 21, 20, 15 },
+ { 18, 16, 20 },
+ { 19, 18, 20 },
+ { 21, 15, 17 },
+ { 6, 21, 17 },
+ { 22, 23, 24 },
+ { 23, 25, 24 },
+ { 26, 27, 6 },
+ { 27, 28, 6 },
+ { 24, 25, 26 },
+ { 6, 24, 26 },
+ { 27, 23, 22 },
+ { 28, 27, 22 },
+ { 25, 23, 27 },
+ { 26, 25, 27 },
+ { 28, 22, 24 },
+ { 6, 28, 24 },
+ { 29, 30, 31 },
+ { 30, 32, 31 },
+ { 33, 34, 6 },
+ { 34, 35, 6 },
+ { 31, 32, 33 },
+ { 6, 31, 33 },
+ { 34, 30, 29 },
+ { 35, 34, 29 },
+ { 32, 30, 34 },
+ { 33, 32, 34 },
+ { 35, 29, 31 },
+ { 6, 35, 31 }
+};
+
+static const unsigned
+zero_2_properties[60][3] = {
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY }
+};
+
+/* Enclosures' order is consistent accross runs as they are sorted by triangle
+ * sides, thus allowing to expect a given order */
+struct expected {
+ unsigned enclosure_count; /* max 16 */
+ double volume[16]; /* the volume of the expected enclosures */
+ unsigned medium[16]; /* the single medium of the expected enclosures */
+};
+
+static int
test
(const double* positions,
const unsigned* indices,
- const unsigned* properties)
+ const unsigned* properties,
+ const unsigned triangles_count,
+ const unsigned vertices_count,
+ const struct expected* expected)
{
struct mem_allocator allocator;
struct senc3d_device* dev = NULL;
@@ -153,7 +348,7 @@ test
unsigned count, e, n;
OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
- OK(senc3d_device_create(NULL, &allocator, 1, 1, &dev));
+ OK(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
FOR_EACH(n, 0, 2) {
/* Create a scene with 4 enclosures joining at a single vertex. */
@@ -170,20 +365,18 @@ test
OK(senc3d_scene_create(dev,
SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_OUTSIDE,
- zero_1_triangles_count, get_indices, get_media_from_properties,
- zero_1_vertices_count, get_position, &ctx, &scn));
-
- OK(senc3d_scene_get_enclosure_count(scn, &count));
- CHK(count == 4);
+ triangles_count, get_indices, get_media_from_properties,
+ vertices_count, get_position, &ctx, &scn));
OK(senc3d_scene_get_vertices_count(scn, &count));
- CHK(count == zero_1_vertices_count);
+ CHK(count == vertices_count);
OK(senc3d_scene_get_triangles_count(scn, &count));
- CHK(count == zero_1_triangles_count);
+ CHK(count == triangles_count);
OK(senc3d_scene_get_enclosure_count(scn, &count));
- CHK(count == 4);
+ CHK(count == expected->enclosure_count);
+
FOR_EACH(e, 0, count) {
struct senc3d_enclosure* enclosure;
struct senc3d_enclosure_header header;
@@ -193,15 +386,8 @@ test
OK(senc3d_enclosure_get_header(enclosure, &header));
CHK(header.enclosed_media_count == 1);
OK(senc3d_enclosure_get_medium(enclosure, 0, &m));
- if (header.is_infinite) {
- CHK(m == zero_1_UNSPECIFIED_PROPERTY); /* External */
- }
- else if (header.primitives_count == 12) {
- CHK(m == 1); /* Internal */
- }
- else {
- CHK(m == 0); /* In between */
- }
+ CHK(m == expected->medium[e]);
+ CHK(eq_eps(header.volume, expected->volume[e], 0.01));
OK(senc3d_enclosure_ref_put(enclosure));
#ifdef DUMP_ENCLOSURES
snprintf(name, sizeof(name), "test_cube_on_cube_%u.obj", e);
@@ -223,10 +409,38 @@ test
int
main(int argc, char** argv)
{
+ struct expected expected;
(void)argc, (void)argv;
+ expected.enclosure_count = 4;
+ expected.medium[0] = SENC3D_UNSPECIFIED_MEDIUM;
+ expected.volume[0] = -966.67;
+ expected.medium[1] = 0;
+ expected.volume[1] = 647.33;
+ expected.medium[2] = 1;
+ expected.volume[2] = 150;
+ expected.medium[3] = 1;
+ expected.volume[3] = 169.33;
test((double *)zero_1_vertices, (unsigned*)zero_1_triangles,
- (unsigned *)zero_1_properties);
+ (unsigned *)zero_1_properties, zero_1_triangles_count,
+ zero_1_vertices_count, &expected);
+
+ expected.enclosure_count = 6;
+ expected.medium[0] = SENC3D_UNSPECIFIED_MEDIUM;
+ expected.volume[0] = -966.67;
+ expected.medium[1] = 0;
+ expected.volume[1] = 433.33;
+ expected.medium[2] = 1;
+ expected.volume[2] = 281.33;
+ expected.medium[3] = 2;
+ expected.volume[3] = 161.33;
+ expected.medium[4] = 3;
+ expected.volume[4] = 73.33;
+ expected.medium[5] = 4;
+ expected.volume[5] = 17.33;
+ test((double*)zero_2_vertices, (unsigned*)zero_2_triangles,
+ (unsigned*)zero_2_properties, zero_2_triangles_count,
+ zero_2_vertices_count, &expected);
return 0;
}
\ No newline at end of file