star-line

Structure for accelerating line importance sampling
git clone git://git.meso-star.fr/star-line.git
Log | Files | Refs | README | LICENSE

commit e0669f09d99f5866e16b662a05f13310fff6b0db
parent a18b7b206480fc086260e1be30364f7c6efca030
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 30 Apr 2026 12:22:45 +0200

Fix for tree whose root contains all lines

This is a borderline case that highlights several specific issues in the
construction process, which this commit resolves.

A new test has been added to detect construction bugs, and it now
verifies that everything works as expected.

Diffstat:
Msrc/sln_tree_build.c | 10+++++++---
Msrc/test_sln_tree.c | 10+++++++++-
2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/sln_tree_build.c b/src/sln_tree_build.c @@ -1091,7 +1091,7 @@ partition_lines_breadth_first node_range[0] = NODE(inode)->range[0]; node_range[1] = NODE(inode)->range[1]; nlines_node = node_range[1] - node_range[0] + 1/*inclusive bound*/; - ASSERT(nlines_node > tree->args.leaf_nlines); + ASSERT(nlines_node >= tree->args.leaf_nlines); if(nlines_node <= tree->args.leaf_nlines) { /* Make a leaf */ @@ -1187,6 +1187,7 @@ build_subtrees ASSERT(nsubtrees < INT_MAX); #define NODE(Id) (darray_node_data_get(&tree->nodes) + (Id)) + #define IS_LEAF(Buf, Id) (darray_node_cdata_get(Buf)[Id].offset == 0) allocator = tree->sln->allocator; @@ -1254,8 +1255,11 @@ build_subtrees nnodes_t = darray_node_size_get(&tree->nodes); res2 = darray_node_resize(&tree->nodes, nnodes_t + nnodes_s - 1/*root*/); if(res2 == RES_OK) { - /* Set the offset to the first child of the root node of the subtree */ - NODE(subtrees[i])->offset = ui64_to_ui32(nnodes_t - subtrees[i]); + + if(!IS_LEAF(&scratch->nodes, 0)) { + /* Set the offset to the first child of the root node of the subtree */ + NODE(subtrees[i])->offset = ui64_to_ui32(nnodes_t - subtrees[i]); + } /* Copy the subtree nodes in the main node buffer */ src = darray_node_cdata_get(&scratch->nodes) + 1/*discard root*/; diff --git a/src/test_sln_tree.c b/src/test_sln_tree.c @@ -344,7 +344,7 @@ test_tree CHK(sln_node_get_desc(tree, node, &node_desc) == RES_OK); CHK(node_desc.ilines[0] == 0); CHK(node_desc.ilines[1] == desc.nlines - 1); - CHK(node_desc.nvertices >= 1 && node_desc.nvertices < desc.nvertices); + CHK(node_desc.nvertices >= 1 && node_desc.nvertices <= desc.nvertices); CHK(node_desc.nchildren <= desc.arity); while(!sln_node_is_leaf(node)) { @@ -590,6 +590,14 @@ main(int argc, char** argv) test_tree(sln, &tree_args, line_list); test_tree_serialization(sln, &tree_args); + /* Test building a tree forcing all lines beeing in the root of the tree */ + CHK(g_nlines < SLN_LEAF_NLINES_MAX); + tree_args.arity = 2; + tree_args.leaf_nlines = (unsigned)g_nlines; + tree_args.collapse_polylines = 0; + test_tree(sln, &tree_args, line_list); + test_tree_serialization(sln, &tree_args); + CHK(sln_device_ref_put(sln) == RES_OK); CHK(shtr_ref_put(shtr) == RES_OK); CHK(shtr_line_list_ref_put(line_list) == RES_OK);