Frame: guard sliver-producing refinement splits

This commit is contained in:
wyj committed 2026-08-29 02:06:06 -04:00
1 parent b95c6579bd
commit 451b700b32
5 files changed
+161 -9

No files matched your search

+86
View File
@@ -193,6 +193,92 @@ int main(void) {
goto done;
}
frame_lens_mesh_destroy(&adaptive_mesh);
/* A shared fold edge can be shorter than either triangle's longest edge.
* Splitting it alone would produce low-quality children, so the quality
* guard must promote both leaves to conforming red refinement. */
LensVertex *quality_vertices = calloc(4, sizeof *quality_vertices);
LensTriangle *quality_triangles = calloc(2, sizeof *quality_triangles);
if (quality_vertices == NULL || quality_triangles == NULL) {
free(quality_vertices);
free(quality_triangles);
goto done;
}
quality_vertices[0].image_x = 0.0;
quality_vertices[0].image_y = 0.0;
quality_vertices[1].image_x = 1.0;
quality_vertices[1].image_y = 0.0;
quality_vertices[2].image_x = 0.5;
quality_vertices[2].image_y = 1.0;
quality_vertices[3].image_x = 0.5;
quality_vertices[3].image_y = -1.0;
const double quality_source_directions[4][3] = {
{1.0, 0.0, 0.0}, {1.0, 0.1, 0.0},
{1.0, 0.0, 0.1}, {1.0, 0.0, 0.1}};
for (size_t i = 0; i < 4; ++i) {
quality_vertices[i].traced = 1;
quality_vertices[i].status = RAY_ENDPOINT_ESCAPED;
quality_vertices[i].camera_direction[0] = 1.0;
quality_vertices[i].camera_direction[1] = 0.01 * quality_vertices[i].image_x;
quality_vertices[i].camera_direction[2] = 0.01 * quality_vertices[i].image_y;
double length = sqrt(quality_vertices[i].camera_direction[0] *
quality_vertices[i].camera_direction[0] +
quality_vertices[i].camera_direction[1] *
quality_vertices[i].camera_direction[1] +
quality_vertices[i].camera_direction[2] *
quality_vertices[i].camera_direction[2]);
for (size_t axis = 0; axis < 3; ++axis)
quality_vertices[i].camera_direction[axis] /= length;
memcpy(quality_vertices[i].n_infinity, quality_source_directions[i],
sizeof quality_source_directions[i]);
length = sqrt(quality_vertices[i].n_infinity[0] *
quality_vertices[i].n_infinity[0] +
quality_vertices[i].n_infinity[1] *
quality_vertices[i].n_infinity[1] +
quality_vertices[i].n_infinity[2] *
quality_vertices[i].n_infinity[2]);
for (size_t axis = 0; axis < 3; ++axis)
quality_vertices[i].n_infinity[axis] /= length;
}
quality_triangles[0] = (LensTriangle){{0, 1, 2}, 0, 0};
quality_triangles[1] = (LensTriangle){{1, 0, 3}, 0, 0};
adaptive_mesh = (FrameLensMesh){.vertices = quality_vertices,
.triangles = quality_triangles,
.vertex_count = 4,
.vertex_capacity = 4,
.triangle_count = 2,
.triangle_capacity = 2};
refine.angle_absolute_rad = 3.14159265358979323846;
refine.angle_relative = 1e6;
refine.jacobian_minimum = 1000.0;
refine.min_edge_pixels = 0.1;
refine.min_area_pixels2 = 0.01;
refine.min_triangle_quality = 0.8;
const RayEndpoint quality_probe = {.n_infinity = {1.0, 0.0, 0.0},
.frequency_ratio = 1.0,
.status = RAY_ENDPOINT_ESCAPED};
const int quality_prepared =
frame_lens_mesh_prepare_generation(&adaptive_mesh, &refine);
if (quality_prepared != 2) {
fprintf(stderr, "adaptive quality probe setup regression failed (%d)\n",
quality_prepared);
goto done;
}
for (size_t i = 0; i < adaptive_mesh.sample_count; ++i)
if (frame_lens_mesh_install_sample(&adaptive_mesh, i, &quality_probe))
goto done;
const int quality_midpoints =
frame_lens_mesh_finish_generation(&adaptive_mesh, &refine);
if (quality_midpoints != 5 ||
adaptive_mesh.vertex_count != 9 || adaptive_mesh.triangle_count != 8) {
fprintf(stderr,
"adaptive quality red-refinement regression failed (%d midpoints, "
"%zu vertices, %zu triangles)\n",
quality_midpoints, adaptive_mesh.vertex_count,
adaptive_mesh.triangle_count);
frame_lens_mesh_destroy(&adaptive_mesh);
goto done;
}
frame_lens_mesh_destroy(&adaptive_mesh);
const RayEndpoint flat_probe = {.n_infinity = {1.0, 0.0, 0.0},
.frequency_ratio = 1.0,
.status = RAY_ENDPOINT_ESCAPED};