star-line

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

commit aebdade527ef087332bafcc6e328c63d7a30444c
parent af80b87f0dffb12f0429229c64f8725f65c0b49e
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 23 May 2022 16:36:59 +0200

[De]serialize the tree

Add the functions sln_tree_write and sln_tree_create_from_stream

Diffstat:
Msrc/sln.h | 8++++++++
Msrc/sln_tree.c | 164+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 156 insertions(+), 16 deletions(-)

diff --git a/src/sln.h b/src/sln.h @@ -224,6 +224,14 @@ sln_tree_create const struct sln_tree_create_args* args, struct sln_tree** tree); +/* Load a tree serialized with the "sln_tree_write" function */ +SLN_API res_T +sln_tree_create_from_stream + (struct sln_device* sln, + struct shtr* shtr, + FILE* stream, + struct sln_tree** tree); + SLN_API res_T sln_tree_ref_get (struct sln_tree* tree); diff --git a/src/sln_tree.c b/src/sln_tree.c @@ -23,6 +23,7 @@ #include "sln_tree_c.h" #include <star/shtr.h> +#include <rsys/cstr.h> /******************************************************************************* * Helper functions @@ -38,7 +39,7 @@ check_sln_tree_create_args /* Currently only 1 line per leaf is accepted */ if(args->max_nlines_per_leaf != 1) { - log_err(sln, + log_err(sln, "%s: invalid maximum number of lines per leaf %lu. " "Currently it must be set to 1.\n", caller, (unsigned long)args->max_nlines_per_leaf); @@ -67,6 +68,35 @@ check_sln_tree_create_args return RES_OK; } +static res_T +create_tree + (struct sln_device* sln, + const char* caller, + struct sln_tree** out_tree) +{ + struct sln_tree* tree = NULL; + res_T res = RES_OK; + ASSERT(sln && caller && out_tree); + + tree = MEM_CALLOC(sln->allocator, 1, sizeof(struct sln_tree)); + if(!tree) { + log_err(sln, "%s: could not allocate the tree data structure.\n", + caller); + res = RES_MEM_ERR; + goto error; + } + ref_init(&tree->ref); + darray_node_init(sln->allocator, &tree->nodes); + darray_vertex_init(sln->allocator, &tree->vertices); + +exit: + *out_tree = tree; + return res; +error: + if(tree) { SLN(tree_ref_put(tree)); tree = NULL; } + goto exit; +} + static INLINE res_T store_input_args (struct sln_tree* tree, @@ -108,23 +138,92 @@ sln_tree_create res = check_sln_tree_create_args(mixture->sln, FUNC_NAME, args); if(res != RES_OK) goto error; - tree = MEM_CALLOC(mixture->sln->allocator, 1, sizeof(struct sln_tree)); - if(!tree) { - log_err(mixture->sln, "%s: could not allocate the tree data structure.\n", - FUNC_NAME); - res = RES_MEM_ERR; - goto error; - } - ref_init(&tree->ref); + res = create_tree(mixture->sln, FUNC_NAME, &tree); + if(res != RES_OK) goto error; SLN(mixture_ref_get(mixture)); tree->mixture = mixture; - darray_node_init(mixture->sln->allocator, &tree->nodes); - darray_vertex_init(mixture->sln->allocator, &tree->vertices); - #define CALL(Func) { if(RES_OK != (res = Func)) goto error; } (void)0 - CALL(store_input_args(tree, args)); - CALL(tree_build(tree, args)); - #undef CALL + res = store_input_args(tree, args); + if(res != RES_OK) goto error; + res = tree_build(tree, args); + if(res != RES_OK) goto error; + +exit: + if(out_tree) *out_tree = tree; + return res; +error: + if(tree) { SLN(tree_ref_put(tree)); tree = NULL; } + goto exit; +} + +res_T +sln_tree_create_from_stream + (struct sln_device* sln, + struct shtr* shtr, + FILE* stream, + struct sln_tree** out_tree) +{ + struct sln_tree* tree = NULL; + size_t n = 0; + int version = 0; + res_T res = RES_OK; + + if(!sln || !shtr || !stream || !out_tree) { + res = RES_BAD_ARG; + goto error; + } + + res = create_tree(sln, FUNC_NAME, &tree); + if(res != RES_OK) goto error; + + #define READ(Var, Nb) { \ + if(fread((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \ + if(feof(stream)) { \ + res = RES_BAD_ARG; \ + } else if(ferror(stream)) { \ + res = RES_IO_ERR; \ + } else { \ + res = RES_UNKNOWN_ERR; \ + } \ + log_err(sln, "%s: error reading tree data -- %s.\n", \ + FUNC_NAME, res_to_cstr(res)); \ + goto error; \ + } \ + } (void)0 + READ(&version, 1); + if(version != SLN_TREE_VERSION) { + log_err(sln, + "%s: unexpected tree version %d. Expecting a tree in version %d.\n", + FUNC_NAME, version, SLN_TREE_VERSION); + res = RES_BAD_ARG; + goto error; + } + + READ(&n, 1); + res = darray_node_resize(&tree->nodes, n); + if(res != RES_OK) { + log_err(sln, "%s: error allocating the tree nodes -- %s.\n", + FUNC_NAME, res_to_cstr(res)); + goto error; + } + READ(darray_node_data_get(&tree->nodes), n); + + READ(&n, 1); + res = darray_vertex_resize(&tree->vertices, n); + if(res != RES_OK) { + log_err(sln, "%s: error allocatiing the tree vertices -- %s.\n", + FUNC_NAME, res_to_cstr(res)); + goto error; + } + READ(darray_vertex_data_get(&tree->vertices), n); + + READ(&tree->max_nlines_per_leaf, 1); + READ(&tree->mesh_decimation_err, 1); + READ(&tree->line_profile, 1); + #undef READ + + res = sln_mixture_create_from_stream(sln, shtr, stream, &tree->mixture); + if(res != RES_OK) goto error; exit: if(out_tree) *out_tree = tree; @@ -221,5 +320,38 @@ sln_node_get_mesh res_T sln_tree_write(const struct sln_tree* tree, FILE* stream) { -} + size_t n; + res_T res = RES_OK; + + if(!tree || !stream) { res = RES_BAD_ARG; goto error; } + + #define WRITE(Var, Nb) { \ + if(fwrite((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \ + log_err(tree->mixture->sln, "%s: error writing the tree.\n", FUNC_NAME); \ + res = RES_IO_ERR; \ + goto error; \ + } \ + } (void)0 + WRITE(&SLN_TREE_VERSION, 1); + + n = darray_node_size_get(&tree->nodes); + WRITE(&n, 1); + WRITE(darray_node_cdata_get(&tree->nodes), n); + n = darray_vertex_size_get(&tree->vertices); + WRITE(&n, 1); + WRITE(darray_vertex_cdata_get(&tree->vertices), n); + + WRITE(&tree->max_nlines_per_leaf, 1); + WRITE(&tree->mesh_decimation_err, 1); + WRITE(&tree->line_profile, 1); + #undef WRITE + + res = sln_mixture_write(tree->mixture, stream); + if(res != RES_OK) goto error; + +exit: + return res; +error: + goto exit; +}