commit bb7813ddc4ec7b5e5bc58e7a092db4921b4d2159
parent aab81bd201bbfe8ea80a86f384efb71e2647a575
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Wed, 19 Jun 2024 15:02:04 +0200
Merge branch 'release_0.7.1'
Diffstat:
3 files changed, 93 insertions(+), 62 deletions(-)
diff --git a/README.md b/README.md
@@ -37,6 +37,10 @@ Edit config.mk as needed, then run:
## Release notes
+### Version 0.7.1
+
+- Fixes a bug in the code that groups connex components to create enclosures.
+
### Version 0.7
- Replace CMake by Makefile as build system.
diff --git a/config.mk b/config.mk
@@ -1,4 +1,4 @@
-VERSION = 0.7.0
+VERSION = 0.7.1
PREFIX = /usr/local
LIB_TYPE = SHARED
diff --git a/src/senc3d_scene_analyze.c b/src/senc3d_scene_analyze.c
@@ -293,13 +293,12 @@ self_hit_filter
trg_comp = darray_triangle_comp_cdata_get(ctx->triangles_comp);
const component_id_t*
hit_comp = trg_comp[hit->prim.prim_id].component;
+ const component_id_t oc = ctx->origin_component;
ASSERT(hit->prim.prim_id
< darray_triangle_comp_size_get(ctx->triangles_comp));
- if(hit_comp[SENC3D_FRONT] == ctx->origin_component
- || hit_comp[SENC3D_BACK] == ctx->origin_component)
- {
+ if(hit_comp[SENC3D_FRONT] == oc || hit_comp[SENC3D_BACK] == oc) {
/* Self hit */
return 1; /* Reject */
}
@@ -332,48 +331,49 @@ self_hit_filter
* as a common vertex (they can also partially intersect, but this is invalid
* and remains undetected by star enclosures). */
struct filter_ctx1* ctx = &fctx_->c.ctx1;
- struct cc_descriptor* const*
- comp_descriptors = darray_ptr_component_descriptor_cdata_get(ctx->components);
+ struct cc_descriptor* const* comp_descriptors
+ = darray_ptr_component_descriptor_cdata_get(ctx->components);
const struct triangle_comp*
trg_comp = darray_triangle_comp_cdata_get(ctx->triangles_comp);
const component_id_t*
hit_comp = trg_comp[hit->prim.prim_id].component;
- const union double3* vertices = darray_position_cdata_get(&ctx->scn->vertices);
+ const union double3*
+ vertices = darray_position_cdata_get(&ctx->scn->vertices);
enum senc3d_side hit_side;
float s = 0, hit_normal[3], rdir[3];
const int log_components =
ctx->scn->convention & SENC3D_LOG_COMPONENTS_INFORMATION;
+ const component_id_t oc = ctx->origin_component;
+ /* Links must be upward to avoid creating loops
+ * Instead of comparing hit.z VS origin.z, compare max_Z of components
+ * Here we keep max_z of the origin component that will be used for these
+ * comparisons */
+ const double org_z = vertices[comp_descriptors[oc]->max_z_vrtx_id].pos.z;
+ vrtx_id_t other_id;
ASSERT(hit->prim.prim_id
< darray_triangle_comp_size_get(ctx->triangles_comp));
if(log_components) {
- printf("Component #%u: investigating hit (d=%g, n= %g %g %g).\n",
- ctx->origin_component, hit->distance, SPLIT3(hit->normal));
+ printf("Component #%u: investigating hit "
+ "(d=%g, n=%g,%g,%g, components: %u, %u)\n",
+ oc, hit->distance, SPLIT3(hit->normal),
+ hit_comp[SENC3D_FRONT], hit_comp[SENC3D_BACK]);
}
if(hit->distance > ctx->hit_dist) {
/* No improvement */
if(log_components) {
- printf("Component #%u: further away => reject.\n", ctx->origin_component);
+ printf("Component #%u: further away (%g): reject\n",
+ oc, ctx->hit_dist);
}
return 1;
}
- if(hit_comp[SENC3D_FRONT] == ctx->origin_component
- || hit_comp[SENC3D_BACK] == ctx->origin_component)
- {
+ if(hit_comp[SENC3D_FRONT] == oc || hit_comp[SENC3D_BACK] == oc) {
/* Self hit */
if(log_components) {
- printf("Component #%u: self hit => reject.\n", ctx->origin_component);
- }
- return 1;
- }
-
- if(hit->distance > 0 && ray_dir[2] <= 0) {
- /* Not upward */
- if(log_components) {
- printf("Component #%u: not upward => reject.\n", ctx->origin_component);
+ printf("Component #%u: self hit: reject\n", oc);
}
return 1;
}
@@ -392,7 +392,8 @@ self_hit_filter
/* Cannot change ctx->hit_component */
if(log_components) {
printf("Component #%u: hit component #%u and already linked to it:"
- " reject\n", ctx->origin_component, c);
+ " reject\n",
+ oc, c);
}
continue;
}
@@ -401,14 +402,13 @@ self_hit_filter
/* The inner component we are trying to link can only be linked to
* an outer component if it is inside */
if(log_components) {
- printf("Component #%u: hit outer component #%u\n",
- ctx->origin_component, c);
+ printf("Component #%u: hit outer component #%u\n", oc, c);
}
if(!is_component_inside(comp_descriptors[c],
- comp_descriptors[ctx->origin_component], ctx))
+ comp_descriptors[oc], ctx))
{
if(log_components) {
- printf("Component #%u: not inside: reject\n", ctx->origin_component);
+ printf("Component #%u: not inside: reject\n", oc);
}
continue;
}
@@ -427,36 +427,36 @@ self_hit_filter
ctx->hit_prim = hit->prim;
if(log_components) {
if(v < ctx->current_6volume) {
- printf("Component #%u: currently the smaller one: keep component"
- " #%u\n", ctx->origin_component, ctx->hit_component);
+ printf("Component #%u: currently the smaller one: "
+ "keep component #%u\n",
+ oc, ctx->hit_component);
} else {
- printf("Component #%u: change from inner to outer: keep component"
- " #%u\n", ctx->origin_component, ctx->hit_component);
+ printf("Component #%u: change from inner to outer: "
+ "keep component #%u\n",
+ oc, ctx->hit_component);
}
}
} else {
if(log_components) {
- printf("Component #%u: not the smaller one: reject\n",
- ctx->origin_component);
+ printf("Component #%u: not the smaller one: reject\n", oc);
}
continue;
}
} else {
/* c is an inner component */
vrtx_id_t c_z_id;
- double org_z, v;
+ double v;
/* If we've already found a valid outer component, inner components
* should not be considered anymore */
if(log_components) {
- printf("Component #%u: hit inner component #%u\n",
- ctx->origin_component, c);
+ printf("Component #%u: hit inner component #%u\n", oc, c);
}
if(ctx->hit_component != COMPONENT_NULL__
&& comp_descriptors[ctx->hit_component]->is_outer_border )
{
if(log_components) {
printf("Component #%u: already in an outer component: reject\n",
- ctx->origin_component);
+ oc);
}
continue;
}
@@ -464,22 +464,19 @@ self_hit_filter
* another inner component if (at least partly) above it and not
* inside */
c_z_id = comp_descriptors[c]->max_z_vrtx_id;
- org_z =
- vertices[comp_descriptors[ctx->origin_component]->max_z_vrtx_id].pos.z;
ASSERT(c_z_id < darray_position_size_get(&ctx->scn->vertices));
ASSERT(vertices[c_z_id].pos.z >= org_z);
if(vertices[c_z_id].pos.z == org_z) {
if(log_components) {
- printf("Component #%u: not (even in part) above: reject\n",
- ctx->origin_component);
+ printf("Component #%u: not (even in part) above: reject\n", oc);
}
continue; /* Not above */
}
if(is_component_inside(comp_descriptors[c],
- comp_descriptors[ctx->origin_component], ctx))
+ comp_descriptors[oc], ctx))
{
if(log_components) {
- printf("Component #%u: not outside: reject\n", ctx->origin_component);
+ printf("Component #%u: not outside: reject\n", oc);
}
continue; /* Inside */
}
@@ -493,13 +490,13 @@ self_hit_filter
ctx->hit_dist = 0;
ctx->hit_prim = hit->prim;
if(log_components) {
- printf("Component #%u: currently the bigger one: keep component"
- " #%u\n", ctx->origin_component, ctx->hit_component);
+ printf("Component #%u: currently the bigger one: "
+ "keep component #%u\n",
+ oc, ctx->hit_component);
}
} else {
if(log_components) {
- printf("Component #%u: not the bigger one: reject\n",
- ctx->origin_component);
+ printf("Component #%u: not the bigger one: reject\n", oc);
}
continue;
}
@@ -511,14 +508,24 @@ self_hit_filter
ASSERT(hit->distance > 0);
if(hit_comp[SENC3D_FRONT] == hit_comp[SENC3D_BACK]) {
/* Easy case and hit component is known */
+ other_id = comp_descriptors[hit_comp[SENC3D_FRONT]]->max_z_vrtx_id;
+ ASSERT(other_id < darray_position_size_get(&ctx->scn->vertices));
+ if(vertices[other_id].pos.z <= org_z) {
+ if(log_components) {
+ printf("Component #%u: 2 sides, not (even in part) above: reject\n",
+ oc);
+ }
+ return 1;
+ }
ctx->hit_component = hit_comp[SENC3D_FRONT];
ctx->s = 1;
f3_set(ctx->hit_dir, ray_dir);
ctx->hit_dist = hit->distance;
ctx->hit_prim = hit->prim;
if(log_components) {
- printf("Component #%u: 2 sides with same component: keep component"
- " #%u\n", ctx->origin_component, ctx->hit_component);
+ printf("Component #%u: 2 sides with same component: "
+ "keep component #%u\n",
+ oc, ctx->hit_component);
}
return 1;
}
@@ -535,7 +542,7 @@ self_hit_filter
s = f3_dot(rdir, hit_normal);
ASSERT(!isnan(s));
if(log_components) {
- printf("Component #%u: had to fix s (was NaN)\n", ctx->origin_component);
+ printf("Component #%u: had to fix s (was NaN)\n", oc);
}
}
@@ -543,21 +550,32 @@ self_hit_filter
/* Same distance with no s improvement: keep the previous hit */
if(log_components) {
printf("Component #%u: not improving s (%g VS %g): reject\n",
- ctx->origin_component, s, ctx->s);
+ oc, s, ctx->s);
}
return 1;
}
if(fabsf(s) < DOT_THRESHOLD) {
/* We cannot know for sure which side to consider */
+ vrtx_id_t i1 = comp_descriptors[hit_comp[SENC3D_FRONT]]->max_z_vrtx_id;
+ vrtx_id_t i2 = comp_descriptors[hit_comp[SENC3D_BACK]]->max_z_vrtx_id;
+ double possible_z = MMAX(vertices[i1].pos.z, vertices[i2].pos.z);
+ if(possible_z <= org_z) {
+ if(log_components) {
+ printf("Component #%u: tiny s, not (even in part) above: reject\n",
+ oc);
+ }
+ return 1;
+ }
ctx->hit_component = COMPONENT_NULL__;
ctx->s = s;
f3_set(ctx->hit_dir, ray_dir);
ctx->hit_dist = hit->distance;
ctx->hit_prim = hit->prim;
if(log_components) {
- printf("Component #%u: tiny s (%g): keep but don't know the component\n",
- ctx->origin_component, s);
+ printf("Component #%u: tiny s (%g): "
+ "keep but don't know the component\n",
+ oc, s);
}
return 1;
}
@@ -569,14 +587,23 @@ self_hit_filter
* the Star3D hit normal is left-handed while star-enclosures-3d uses
* right-handed convention */
? SENC3D_BACK : SENC3D_FRONT;
+ other_id = comp_descriptors[hit_comp[hit_side]]->max_z_vrtx_id;
+ ASSERT(other_id < darray_position_size_get(&ctx->scn->vertices));
+ if(vertices[other_id].pos.z <= org_z) {
+ if(log_components) {
+ printf("Component #%u: standard s, not (even in part) above: reject\n",
+ oc);
+ }
+ return 1;
+ }
ctx->hit_component = hit_comp[hit_side];
ctx->s = s;
f3_set(ctx->hit_dir, ray_dir);
ctx->hit_dist = hit->distance;
ctx->hit_prim = hit->prim;
if(log_components) {
- printf("Component #%u: standard s (%g): keep component #%u\n",
- ctx->origin_component, s, ctx->hit_component);
+ printf("Component #%u: standard s, (%g): keep component #%u\n",
+ oc, s, ctx->hit_component);
}
return 1;
}
@@ -1150,7 +1177,7 @@ group_connex_components
const int output_normal_in =
(scn->convention & SENC3D_CONVENTION_NORMAL_INSIDE) != 0;
str_init(scn->dev->allocator, &name);
- printf("Dumping components for scene #%u.\n", scene_cpt);
+ printf("Dumping components for scene #%u\n", scene_cpt);
for(ccc = 0; ccc < (int64_t)cc_count; ccc++) {
FILE* f;
trg_id_t t;
@@ -1187,7 +1214,7 @@ group_connex_components
fprintf(f, " endfacet\n");
}
}
- printf("Dumped component #%u in file %s.\n", c, str_cget(&name));
+ printf("Dumped component #%u in file %s\n", c, str_cget(&name));
fprintf(f, "endsolid %s\n", str_cget(&name));
fclose(f);
}
@@ -1294,7 +1321,7 @@ group_connex_components
* FRONT/BACK discrimination was not reliable enough and should be done
* differently. */
/* Could try something; now just report a failure */
- log_err(scn->dev, LIB_NAME": %s: %d: search failed.\n", FUNC_NAME,
+ log_err(scn->dev, LIB_NAME": %s: %d: search failed\n", FUNC_NAME,
__LINE__ );
*res = RES_BAD_OP;
continue;
@@ -2039,7 +2066,7 @@ scene_analyze
{
if(res != RES_OK) {
log_err(scn->dev,
- LIB_NAME":%s: could not build neighbourhoods from scene.\n",
+ LIB_NAME":%s: could not build neighbourhoods from scene\n",
FUNC_NAME);
} else {
res = res2;
@@ -2062,7 +2089,7 @@ scene_analyze
#pragma omp single nowait
{
log_err(scn->dev,
- LIB_NAME":%s: could not extract connex components from scene.\n",
+ LIB_NAME":%s: could not extract connex components from scene\n",
FUNC_NAME);
} /* No barrier here */
goto error_;
@@ -2086,7 +2113,7 @@ scene_analyze
#pragma omp single nowait
{
log_err(scn->dev,
- LIB_NAME":%s: could not group connex components from scene.\n",
+ LIB_NAME":%s: could not group connex components from scene\n",
FUNC_NAME);
}
goto error_;
@@ -2114,7 +2141,7 @@ scene_analyze
#pragma omp single nowait
{
log_err(scn->dev,
- LIB_NAME":%s: could not build result.\n", FUNC_NAME);
+ LIB_NAME":%s: could not build result\n", FUNC_NAME);
}
goto error_;
}