solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

commit 0adf9cbf36058cd40f74ce3307a9f089273f766c
parent 6b9694436ac338c095077be3e97511ad5fb95465
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 22 Feb 2017 10:34:59 +0100

Add the ssol_scene_for_each_instance function

Diffstat:
Msrc/ssol.h | 6++++++
Msrc/ssol_scene.c | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Msrc/ssol_scene_c.h | 2+-
3 files changed, 62 insertions(+), 15 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -476,6 +476,12 @@ ssol_scene_detach_atmosphere (struct ssol_scene* scn, struct ssol_atmosphere* atm); +SSOL_API res_T +ssol_scene_for_each_instance + (struct ssol_scene* scn, + res_T (*func)(struct ssol_instance* instance, void* ctx), + void* ctx); + /******************************************************************************* * Shape API - Define a geometry that can be generated from a quadric equation * or from a triangular mesh. diff --git a/src/ssol_scene.c b/src/ssol_scene.c @@ -115,15 +115,18 @@ res_T ssol_scene_attach_instance (struct ssol_scene* scene, struct ssol_instance* instance) { + enum { ATTACH_S3D, SET_INSTANCE_RT }; unsigned id; struct ssol_instance** pinst; + int mask = 0; res_T res; if(!scene || !instance) return RES_BAD_ARG; /* Attach the instantiated s3d shape to ray-trace to the RT scene */ res = s3d_scene_attach_shape(scene->scn_rt, instance->shape_rt); - if(res != RES_OK) return res; + if(res != RES_OK) goto error; + mask |= BIT(ATTACH_S3D); /* Register the instance against the scene */ S3D(shape_get_id(instance->shape_rt, &id)); @@ -131,15 +134,26 @@ ssol_scene_attach_instance if(pinst) { /* already attached */ ASSERT(*pinst == instance); /* cannot be attached to another instance! */ - return RES_OK; + goto exit; } + res = htable_instance_set(&scene->instances_rt, &id, &instance); - if(res != RES_OK) { + if(res != RES_OK) goto error; + mask |= BIT(SET_INSTANCE_RT); + + SSOL(instance_ref_get(instance)); + +exit: + return res; +error: + if(mask & BIT(ATTACH_S3D)) { S3D(scene_detach_shape(scene->scn_rt, instance->shape_rt)); - return res; } - SSOL(instance_ref_get(instance)); - return RES_OK; + if(mask & BIT(SET_INSTANCE_RT)) { + const size_t n = htable_instance_erase(&scene->instances_rt, &id); + ASSERT(n == 1); (void)n; + } + goto exit; } res_T @@ -192,9 +206,8 @@ ssol_scene_clear(struct ssol_scene* scene) htable_instance_clear(&scene->instances_samp); S3D(scene_clear(scene->scn_rt)); S3D(scene_clear(scene->scn_samp)); - if (scene->sun) ssol_scene_detach_sun(scene, scene->sun); - if (scene->atmosphere) - ssol_scene_detach_atmosphere(scene, scene->atmosphere); + if(scene->sun) SSOL(scene_detach_sun(scene, scene->sun)); + if(scene->atmosphere) SSOL(scene_detach_atmosphere(scene, scene->atmosphere)); return RES_OK; } @@ -204,13 +217,11 @@ ssol_scene_attach_sun(struct ssol_scene* scene, struct ssol_sun* sun) if(!scene || ! sun) return RES_BAD_ARG; if(sun->scene_attachment || scene->sun) { - /* already attached: must be linked together */ + /* Already attached: must be linked together */ if(sun->scene_attachment != scene || scene->sun != sun) { - /* if not detach first! */ - return RES_BAD_ARG; + return RES_BAD_ARG; /* If not detach first! */ } else { - /* nothing to change */ - return RES_OK; + return RES_OK; /* Nothing to change */ } } /* no previous attachment */ @@ -269,6 +280,36 @@ ssol_scene_detach_atmosphere(struct ssol_scene* scene, struct ssol_atmosphere* a return RES_OK; } +res_T +ssol_scene_for_each_instance + (struct ssol_scene* scn, + res_T (*func)(struct ssol_instance* instance, void* ctx), + void* ctx) +{ + struct htable_instance_iterator it, end; + res_T res = RES_OK; + + if(!scn || !func) { + res = RES_BAD_ARG; + goto error; + } + + htable_instance_begin(&scn->instances_rt, &it); + htable_instance_end(&scn->instances_rt, &end); + while(!htable_instance_iterator_eq(&it, &end)) { + struct ssol_instance* inst = *htable_instance_iterator_data_get(&it); + htable_instance_iterator_next(&it); + + res = func(inst, ctx); + if(res != RES_OK) goto error; + } + +exit: + return res; +error: + goto exit; +} + /******************************************************************************* * Local functions ******************************************************************************/ diff --git a/src/ssol_scene_c.h b/src/ssol_scene_c.h @@ -22,7 +22,7 @@ struct ssol_instance; - /* Define the htable_instance data structure */ +/* Define the htable_instance data structure */ #define HTABLE_NAME instance #define HTABLE_KEY unsigned /* S3D object instance identifier */ #define HTABLE_DATA struct ssol_instance*