stardis-solver

Solve coupled heat transfers
git clone git://git.meso-star.fr/stardis-solver.git
Log | Files | Refs | README | LICENSE

commit 09c5f0f4326effabccaf1332c55acab314e9b489
parent 6d0a24a5da6828e45561ee176507ef9ad5c10dc7
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 11 Apr 2018 13:33:28 +0200

First draft of Stardis using Star-Enc to analyse the submitted data

Currently, only 3D scenes are handled.

Diffstat:
Mcmake/CMakeLists.txt | 5+++--
Msrc/sdis_medium_c.h | 7+++++++
Msrc/sdis_scene.c | 428+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Msrc/sdis_scene_c.h | 108++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
4 files changed, 466 insertions(+), 82 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -27,6 +27,7 @@ find_package(RCMake 0.3 REQUIRED) find_package(Star2D 0.1 REQUIRED) find_package(Star3D 0.4 REQUIRED) find_package(StarSP 0.7 REQUIRED) +find_package(StarEnc 0.1 REQUIRED) find_package(RSys 0.6 REQUIRED) find_package(OpenMP 1.2 REQUIRED) @@ -34,7 +35,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR}) include(rcmake) include(rcmake_runtime) -rcmake_append_runtime_dirs(_runtime_dirs RSys Star3D StarSP) +rcmake_append_runtime_dirs(_runtime_dirs RSys Star3D StarSP StarEnc) ################################################################################ # Configure and define targets @@ -79,7 +80,7 @@ add_library(sdis SHARED ${SDIS_FILES_SRC} ${SDIS_FILES_INC} ${SDIS_FILES_INC_API}) -target_link_libraries(sdis RSys Star2D Star3D StarSP m) +target_link_libraries(sdis RSys Star2D Star3D StarEnc StarSP m) if(CMAKE_COMPILER_IS_GNUCC) target_link_libraries(sdis m) endif() diff --git a/src/sdis_medium_c.h b/src/sdis_medium_c.h @@ -32,6 +32,13 @@ struct sdis_medium { struct sdis_device* dev; }; +static FINLINE unsigned +medium_get_id(const struct sdis_medium* mdm) +{ + ASSERT(mdm); + return mdm->id.index; +} + /******************************************************************************* * Fluid local functions ******************************************************************************/ diff --git a/src/sdis_scene.c b/src/sdis_scene.c @@ -16,6 +16,7 @@ #include "sdis.h" #include "sdis_device_c.h" #include "sdis_interface_c.h" +#include "sdis_medium_c.h" #include "sdis_scene_c.h" #include <rsys/float2.h> @@ -24,14 +25,16 @@ #include <rsys/double3.h> #include <rsys/mem_allocator.h> +#include <senc.h> #include <star/s2d.h> #include <star/s3d.h> #include <limits.h> -/* Context used to wrap the user geometry to Star-XD. */ -struct geometry_context { +/* Context used to wrap the user geometry and interfaces to Star-Enc */ +struct geometry { void (*indices)(const size_t iprim, size_t ids[], void*); + void (*interf)(const size_t iprim, struct sdis_interface**, void*); void (*position)(const size_t ivert, double pos[], void*); void* data; }; @@ -122,53 +125,106 @@ hit_filter_function_2d } static void -get_indices_2d(const unsigned iseg, unsigned out_ids[2], void* data) +geometry_indices_3d(const unsigned itri, unsigned out_ids[3], void* data) { - struct geometry_context* ctx = data; - size_t ids[2]; - ASSERT(ctx); - ctx->indices(iseg, ids, ctx->data); + struct geometry* ctx = data; + size_t ids[3]; + ASSERT(ctx && out_ids); + ctx->indices(itri, ids, ctx->data); out_ids[0] = (unsigned)ids[0]; out_ids[1] = (unsigned)ids[1]; + out_ids[2] = (unsigned)ids[2]; } static void -get_indices_3d(const unsigned itri, unsigned out_ids[3], void* data) +geometry_media(const unsigned itri, unsigned media[2], void* data) { - struct geometry_context* ctx = data; - size_t ids[3]; - ASSERT(ctx); - ctx->indices(itri, ids, ctx->data); - out_ids[0] = (unsigned)ids[0]; - out_ids[1] = (unsigned)ids[1]; - out_ids[2] = (unsigned)ids[2]; + struct geometry* ctx = data; + struct sdis_interface* interf; + ASSERT(ctx && media); + ctx->interf(itri, &interf, ctx->data); + /* FIXME check that the order in which media are returned is right */ + media[0] = medium_get_id(interf->medium_back); + media[1] = medium_get_id(interf->medium_front); } static void -get_position_2d(const unsigned ivert, float out_pos[2], void* data) +geometry_position_3d(const unsigned ivert, double out_pos[3], void* data) { - struct geometry_context* ctx = data; - double pos[2]; - ASSERT(ctx); + struct geometry* ctx = data; + double pos[3]; + ASSERT(ctx && out_pos); ctx->position(ivert, pos, ctx->data); + out_pos[0] = pos[0]; + out_pos[1] = pos[1]; + out_pos[2] = pos[2]; +} + +static void +descriptor_indices_3d(const unsigned itri, unsigned ids[3], void* data) +{ + struct senc_descriptor* desc = data; + SENC(descriptor_get_global_triangle(desc, itri, ids)); +} + + +static void +descriptor_position_3d(const unsigned ivert, float out_pos[3], void* data) +{ + struct senc_descriptor* desc = data; + double pos[3]; + SENC(descriptor_get_global_vertex(desc, ivert, pos)); out_pos[0] = (float)pos[0]; out_pos[1] = (float)pos[1]; + out_pos[2] = (float)pos[2]; } static void -get_position_3d(const unsigned ivert, float out_pos[3], void* data) +enclosure_indices_3d(const unsigned itri, unsigned ids[3], void* data) { - struct geometry_context* ctx = data; + struct senc_enclosure* enc = data; + SENC(enclosure_get_triangle(enc, itri, ids)); +} + +static void +enclosure_position_3d(const unsigned ivert, float out_pos[3], void* data) +{ + struct senc_enclosure* enc = data; double pos[3]; + ASSERT(out_pos); + SENC(enclosure_get_vertex(enc, ivert, pos)); + out_pos[0] = (float)pos[0]; + out_pos[1] = (float)pos[1]; + out_pos[2] = (float)pos[2]; +} + +#if 0 +static void +get_indices_2d(const unsigned iseg, unsigned out_ids[2], void* data) +{ + struct geometry_context* ctx = data; + size_t ids[2]; + ASSERT(ctx); + ctx->indices(iseg, ids, ctx->data); + out_ids[0] = (unsigned)ids[0]; + out_ids[1] = (unsigned)ids[1]; +} + +static void +get_position_2d(const unsigned ivert, float out_pos[2], void* data) +{ + struct geometry_context* ctx = data; + double pos[2]; ASSERT(ctx); ctx->position(ivert, pos, ctx->data); out_pos[0] = (float)pos[0]; out_pos[1] = (float)pos[1]; - out_pos[2] = (float)pos[2]; } +#endif + static void -clear_interfaces(struct sdis_scene* scn) +clear_properties(struct sdis_scene* scn) { size_t i; ASSERT(scn); @@ -178,32 +234,136 @@ clear_interfaces(struct sdis_scene* scn) } } darray_interf_clear(&scn->interfaces); - darray_interf_clear(&scn->prim_interfaces); + darray_medium_clear(&scn->media); + darray_prim_prop_clear(&scn->prim_props); } static res_T -setup_interfaces +run_analyze_3d (struct sdis_scene* scn, const size_t ntris, /* #triangles */ + void (*indices)(const size_t itri, size_t ids[3], void*), void (*interf)(const size_t itri, struct sdis_interface**, void*), - void* ctx) + const size_t nverts, /* #vertices */ + void (*position)(const size_t ivert, double pos[3], void* ctx), + void* ctx, + struct senc_descriptor** out_desc) { + struct geometry geom; + struct senc_device* senc = NULL; + struct senc_scene* senc_scn = NULL; + struct senc_descriptor* desc = NULL; + size_t nmedia; size_t itri; res_T res = RES_OK; - ASSERT(ntris && interf); + ASSERT(scn && ntris && indices && interf && nverts && position && out_desc); - clear_interfaces(scn); + res = senc_device_create(scn->dev->logger, scn->dev->allocator, + scn->dev->nthreads, scn->dev->verbose, &senc); + if(res != RES_OK) goto error; + /* Conservatively define the number of media. + * + * FIXME The number of media is going to be remove from senc_scene_create + * profile and thus the following code should be unecessary soon. */ + nmedia = 0; FOR_EACH(itri, 0, ntris) { struct sdis_interface* itface; - size_t ninterfaces; + interf(itri, &itface, ctx); + nmedia = MMAX(nmedia, medium_get_id(itface->medium_front)); + nmedia = MMAX(nmedia, medium_get_id(itface->medium_back)); + } + nmedia += 1; /* +1 to define the "number of" media and not the max id */ + + res = senc_scene_create(senc, (unsigned)nmedia, &senc_scn); + if(res != RES_OK) goto error; + + /* Setup the geometry data */ + geom.indices = indices; + geom.interf = interf; + geom.position = position; + geom.data = ctx; + res = senc_scene_add_geometry + (senc_scn, (unsigned)ntris, geometry_indices_3d, geometry_media, NULL, + (unsigned)nverts, geometry_position_3d, &geom); + if(res != RES_OK) goto error; + + /* Launch the scene analyze */ + res = senc_scene_analyze(senc_scn, &desc); + if(res != RES_OK) goto error; + +exit: + if(senc) SENC(device_ref_put(senc)); + if(senc_scn) SENC(scene_ref_put(senc_scn)); + if(out_desc) *out_desc = desc; + return res; +error: + if(desc) { + SENC(descriptor_ref_put(desc)); + desc = NULL; + } + goto exit; +} + +static res_T +register_medium(struct sdis_scene* scn, struct sdis_medium* mdm) +{ + unsigned id; + size_t nmedia; + res_T res = RES_OK; + ASSERT(scn && mdm); + + /* Check that the front medium is already registered against the scene */ + id = medium_get_id(mdm); + nmedia = darray_medium_size_get(&scn->media); + if(id >= nmedia) { + res = darray_medium_resize(&scn->media, id + 1); + if(res != RES_OK) return res; + } + if(darray_medium_cdata_get(&scn->media)[id]) { + ASSERT(darray_medium_cdata_get(&scn->media)[id] == mdm); + } else { + /* Do not take a reference onto the medium since we already take a + * reference onto at least one interface that uses it, and thus that has a + * reference onto it */ + darray_medium_data_get(&scn->media)[id] = mdm; + } + return RES_OK; +} + +static res_T +setup_properties + (struct sdis_scene* scn, + struct senc_descriptor* desc, + void (*interf)(const size_t itri, struct sdis_interface**, void*), + void* ctx) +{ + unsigned itri, ntris; + res_T res = RES_OK; + ASSERT(scn && interf); + + clear_properties(scn); + + SENC(descriptor_get_global_triangles_count(desc, &ntris)); + FOR_EACH(itri, 0, ntris) { + struct prim_prop* prim_prop; + struct sdis_interface* itface; + unsigned enclosures[2]; + unsigned itri_adjusted; /* Triangle id in user space */ unsigned id; + size_t ninterfaces; + + /* Retrieve the triangle id in user space */ + SENC(descriptor_get_global_triangle_global_id(desc, itri, &itri_adjusted)); + + /* Fetch the enclosures that the triangle splits */ + SENC(descriptor_get_global_triangle_enclosures(desc, itri, enclosures)); - /* Retrieve the interface of the primitive */ + /* Fetch the interface of the primitive */ interf(itri, &itface, ctx); - id = interface_get_id(itface); /* Check that the interface is already registered against the scene */ + id = interface_get_id(itface); ninterfaces = darray_interf_size_get(&scn->interfaces); if(id >= ninterfaces) { res = darray_interf_resize(&scn->interfaces, id + 1); @@ -216,18 +376,35 @@ setup_interfaces darray_interf_data_get(&scn->interfaces)[id] = itface; } - /* Register the primitive interface */ - res = darray_interf_push_back(&scn->prim_interfaces, &itface); + /* Register the interface media against the scene */ + res = register_medium(scn, itface->medium_front); + if(res != RES_OK) goto error; + res = register_medium(scn, itface->medium_back); if(res != RES_OK) goto error; + + /* Allocate primitive properties */ + res = darray_prim_prop_resize(&scn->prim_props, itri+1); + if(res != RES_OK) goto error; + + + /* Setup primitive properties */ + prim_prop = darray_prim_prop_data_get(&scn->prim_props) + itri; + prim_prop->interf = itface; + /* FIXME Ensure that the enclosure order is right one. Actually, it seems + * that Star-Enc front facing convention is reversed wrt Stardis. Faces are + * front facing when their vertex are CCW ordered */ + prim_prop->back_enclosure = enclosures[0]; + prim_prop->front_enclosure = enclosures[1]; } exit: return res; error: - clear_interfaces(scn); + clear_properties(scn); goto exit; } +#if 0 static res_T setup_geometry_2d (struct sdis_scene* scn, @@ -279,55 +456,144 @@ error: if(scn->s2d_view) S2D(scene_view_ref_put(scn->s2d_view)); goto exit; } +#endif static res_T -setup_geometry_3d - (struct sdis_scene* scn, - const size_t ntris, /* #triangles */ - void (*indices)(const size_t itri, size_t ids[3], void*), - const size_t nverts, /* #vertices */ - void (*position)(const size_t ivert, double pos[3], void* ctx), - void* ctx) +setup_scene_geometry_3d(struct sdis_scene* scn, struct senc_descriptor* desc) { - struct geometry_context context; struct s3d_shape* s3d_msh = NULL; struct s3d_scene* s3d_scn = NULL; struct s3d_vertex_data vdata = S3D_VERTEX_DATA_NULL; + unsigned ntris, nverts; res_T res = RES_OK; - ASSERT(scn && ntris && indices && nverts && position); + ASSERT(scn && desc); - /* Setup the intermediary geometry context */ - context.indices = indices; - context.position = position; - context.data = ctx; + SENC(descriptor_get_global_triangles_count(desc, &ntris)); + SENC(descriptor_get_global_vertices_count(desc, &nverts)); /* Setup the vertex data */ vdata.usage = S3D_POSITION; vdata.type = S3D_FLOAT3; - vdata.get = get_position_3d; + vdata.get = descriptor_position_3d; + + /* Create the Star-3D geometry of the whole scene */ + #define CALL(Func) { if(RES_OK != (res = Func)) goto error; } (void)0 + CALL(s3d_scene_create(scn->dev->s3d, &s3d_scn)); + CALL(s3d_shape_create_mesh(scn->dev->s3d, &s3d_msh)); + CALL(s3d_mesh_set_hit_filter_function(s3d_msh, hit_filter_function_3d, NULL)); + CALL(s3d_scene_attach_shape(s3d_scn, s3d_msh)); + CALL(s3d_mesh_setup_indexed_vertices(s3d_msh, ntris, descriptor_indices_3d, + nverts, &vdata, 1, desc)); + CALL(s3d_scene_view_create(s3d_scn, S3D_TRACE|S3D_GET_PRIMITIVE, + &scn->s3d_view)); + #undef CALL - /* Create the Star-3D geometry */ - res = s3d_scene_create(scn->dev->s3d, &s3d_scn); - if(res != RES_OK) goto error; - res = s3d_shape_create_mesh(scn->dev->s3d, &s3d_msh); - if(res != RES_OK) goto error; - res = s3d_mesh_set_hit_filter_function(s3d_msh, hit_filter_function_3d, NULL); - if(res != RES_OK) goto error; - res = s3d_scene_attach_shape(s3d_scn, s3d_msh); - if(res != RES_OK) goto error; - res = s3d_mesh_setup_indexed_vertices(s3d_msh, (unsigned)ntris, - get_indices_3d, (unsigned)nverts, &vdata, 1, &context); +exit: + if(s3d_msh) S3D(shape_ref_put(s3d_msh)); + if(s3d_scn) S3D(scene_ref_put(s3d_scn)); + return res; +error: + if(scn->s3d_view) S3D(scene_view_ref_put(scn->s3d_view)); + goto exit; +} + +static res_T +setup_enclosure_geometry_3d(struct sdis_scene* scn, struct senc_enclosure* enc) +{ + struct s3d_scene* s3d_scn = NULL; + struct s3d_shape* s3d_msh = NULL; + struct s3d_vertex_data vdata = S3D_VERTEX_DATA_NULL; + const struct enclosure_header* header; + struct enclosure enc_dummy; + struct enclosure* enc_data; + unsigned itri, ntris, nverts; + res_T res = RES_OK; + ASSERT(scn && enc); + + enclosure_init(scn->dev->allocator, &enc_dummy); + + SENC(enclosure_get_header(enc, &header)); + ntris = header->triangle_count; + nverts = header->vertices_count; + + /* Register the enclosure into the scene. Use a dummy data on their + * registration. We are going to setup the data after their registration into + * the hash table in order to avoid a costly copy. In other words, the + * following hash table registration can be seen as an allocation of the + * enclosure data that are then setup. */ + res = htable_enclosure_set(&scn->enclosures, &header->enclosure_id, &enc_dummy); if(res != RES_OK) goto error; - res = s3d_scene_view_create(s3d_scn, S3D_SAMPLE|S3D_TRACE|S3D_GET_PRIMITIVE, - &scn->s3d_view); + + /* Fetch the data of the registered enclosure */ + enc_data = htable_enclosure_find(&scn->enclosures, &header->enclosure_id); + ASSERT(enc_data != NULL); + + /* Setup the vertex data */ + vdata.usage = S3D_POSITION; + vdata.type = S3D_FLOAT3; + vdata.get = enclosure_position_3d; + + /* Create the Star-3D geometry */ + #define CALL(Func) { if(RES_OK != (res = Func)) goto error; } (void)0 + CALL(s3d_scene_create(scn->dev->s3d, &s3d_scn)); + CALL(s3d_shape_create_mesh(scn->dev->s3d, &s3d_msh)); + CALL(s3d_scene_attach_shape(s3d_scn, s3d_msh)); + CALL(s3d_mesh_setup_indexed_vertices(s3d_msh, ntris, enclosure_indices_3d, + nverts, &vdata, 1, enc)); + CALL(s3d_scene_view_create(s3d_scn, S3D_SAMPLE, &enc_data->s3d_view)); + #undef CALL + + /* Define the identifier of the enclosure primitives in the whole scene */ + res = darray_uint_resize(&enc_data->local2global, ntris); if(res != RES_OK) goto error; + FOR_EACH(itri, 0, ntris) { + SENC(enclosure_get_triangle_global_id + (enc, itri, darray_uint_data_get(&enc_data->local2global)+itri)); + } exit: + enclosure_release(&enc_dummy); if(s3d_msh) S3D(shape_ref_put(s3d_msh)); if(s3d_scn) S3D(scene_ref_put(s3d_scn)); return res; error: - if(scn->s3d_view) S3D(scene_view_ref_put(scn->s3d_view)); + htable_enclosure_erase(&scn->enclosures, &header->enclosure_id); + goto exit; +} + +static res_T +setup_enclosures_3d(struct sdis_scene* scn, struct senc_descriptor* desc) +{ + struct senc_enclosure* enc = NULL; + unsigned ienc, nencs; + res_T res = RES_OK; + ASSERT(scn && desc); + + SENC(descriptor_get_enclosure_count(desc, &nencs)); + FOR_EACH(ienc, 0, nencs) { + const struct enclosure_header* header; + const struct sdis_medium* mdm; + + SENC(descriptor_get_enclosure(desc, ienc, &enc)); + SENC(enclosure_get_header(enc, &header)); + + ASSERT(header->enclosed_medium < darray_medium_size_get(&scn->media)); + mdm = darray_medium_cdata_get(&scn->media)[header->enclosed_medium]; + ASSERT(mdm); + + /* Silently discard the solid enclosures */ + if(mdm->type == SDIS_MEDIUM_FLUID) { + res = setup_enclosure_geometry_3d(scn, enc); + if(res != RES_OK) goto error; + } + SENC(enclosure_ref_put(enc)); + enc = NULL; + } + +exit: + if(enc) SENC(enclosure_ref_put(enc)); + return res; +error: goto exit; } @@ -343,6 +609,7 @@ scene_create void* ctx, struct sdis_scene** out_scn) { + struct senc_descriptor* desc = NULL; struct sdis_scene* scn = NULL; res_T res = RES_OK; @@ -363,26 +630,37 @@ scene_create scn->dev = dev; scn->ambient_radiative_temperature = -1; darray_interf_init(dev->allocator, &scn->interfaces); - darray_interf_init(dev->allocator, &scn->prim_interfaces); + darray_medium_init(dev->allocator, &scn->media); + darray_prim_prop_init(dev->allocator, &scn->prim_props); + htable_enclosure_init(dev->allocator, &scn->enclosures); - res = setup_interfaces(scn, nprims, interf, ctx); + if(is_2d) FATAL("2D is not supported yet.\n"); + + res = run_analyze_3d(scn, nprims, indices, interf, nverts, position, ctx, &desc); if(res != RES_OK) { - log_err(dev, "%s: could not setup the scene interfaces.\n", FUNC_NAME); + log_err(dev, "%s: error during the scene analysis.\n", FUNC_NAME); goto error; } - - if(is_2d) { - res = setup_geometry_2d(scn, nprims, indices, nverts, position, ctx); - } else { - res = setup_geometry_3d(scn, nprims, indices, nverts, position, ctx); + res = setup_properties(scn, desc, interf, ctx); + if(res != RES_OK) { + log_err(dev, "%s: could not setup the scene interfaces and their media.\n", + FUNC_NAME); + goto error; } + res = setup_scene_geometry_3d(scn, desc); if(res != RES_OK) { log_err(dev, "%s: could not setup the scene geometry.\n", FUNC_NAME); goto error; } + res = setup_enclosures_3d(scn, desc); + if(res != RES_OK) { + log_err(dev, "%s: could not setup the enclosures.\n", FUNC_NAME); + goto error; + } exit: if(out_scn) *out_scn = scn; + if(desc) SENC(descriptor_ref_put(desc)); return res; error: if(scn) { @@ -528,9 +806,11 @@ scene_release(ref_T * ref) ASSERT(ref); scn = CONTAINER_OF(ref, struct sdis_scene, ref); dev = scn->dev; - clear_interfaces(scn); + clear_properties(scn); darray_interf_release(&scn->interfaces); - darray_interf_release(&scn->prim_interfaces); + darray_medium_release(&scn->media); + darray_prim_prop_release(&scn->prim_props); + htable_enclosure_release(&scn->enclosures); if(scn->s2d_view) S2D(scene_view_ref_put(scn->s2d_view)); if(scn->s3d_view) S3D(scene_view_ref_put(scn->s3d_view)); MEM_RM(dev->allocator, scn); @@ -645,8 +925,8 @@ sdis_scene_get_boundary_position const struct sdis_interface* scene_get_interface(const struct sdis_scene* scn, const unsigned iprim) { - ASSERT(scn && iprim < darray_interf_size_get(&scn->prim_interfaces)); - return darray_interf_cdata_get(&scn->prim_interfaces)[iprim]; + ASSERT(scn && iprim < darray_prim_prop_size_get(&scn->prim_props)); + return darray_prim_prop_cdata_get(&scn->prim_props)[iprim].interf; } res_T diff --git a/src/sdis_scene_c.h b/src/sdis_scene_c.h @@ -16,30 +16,126 @@ #ifndef SDIS_SCENE_C_H #define SDIS_SCENE_C_H -#include <rsys/dynamic_array.h> +#include <star/s3d.h> + +#include <rsys/dynamic_array_uint.h> +#include <rsys/hash_table.h> #include <rsys/ref_count.h> +#include <limits.h> + +struct prim_prop { + struct sdis_interface* interf; + unsigned front_enclosure; /* Id of the front facing enclosure */ + unsigned back_enclosure; /* Id of the back facing enclosure */ +}; + +static INLINE void +prim_prop_init(struct mem_allocator* allocator, struct prim_prop* prim) +{ + (void)allocator; + prim->interf = NULL; + prim->front_enclosure = UINT_MAX; + prim->back_enclosure = UINT_MAX; +} + static INLINE void -interface_init - (struct mem_allocator* allocator, - struct sdis_interface** interf) +interface_init(struct mem_allocator* allocator, struct sdis_interface** interf) { (void)allocator; *interf = NULL; } +static INLINE void +medium_init(struct mem_allocator* allocator, struct sdis_medium** medium) +{ + (void)allocator; + *medium = NULL; +} + +struct enclosure { + struct s3d_scene_view* s3d_view; + /* Map the id of the enclosure primitives to their primitive id into the + * whole scene */ + struct darray_uint local2global; +}; + +static INLINE void +enclosure_init(struct mem_allocator* allocator, struct enclosure* enc) +{ + ASSERT(allocator && enc); + enc->s3d_view = NULL; + darray_uint_init(allocator, &enc->local2global); +} + +static INLINE void +enclosure_release(struct enclosure* enc) +{ + if(enc->s3d_view) S3D(scene_view_ref_put(enc->s3d_view)); + darray_uint_release(&enc->local2global); +} + +static INLINE res_T +enclosure_copy(struct enclosure* dst, const struct enclosure* src) +{ + if(src->s3d_view) { + S3D(scene_view_ref_get(src->s3d_view)); + dst->s3d_view = src->s3d_view; + } + return darray_uint_copy(&dst->local2global, &src->local2global); +} + +static INLINE res_T +enclosure_copy_and_release(struct enclosure* dst, struct enclosure* src) +{ + res_T res = RES_OK; + res = darray_uint_copy_and_release(&dst->local2global, &src->local2global); + if(res != RES_OK) return res; + if(src->s3d_view) { + /* Only transfer ownership */ + dst->s3d_view = src->s3d_view; + src->s3d_view = NULL; + } + return RES_OK; +} + /* Declare the array of interfaces */ #define DARRAY_NAME interf #define DARRAY_DATA struct sdis_interface* #define DARRAY_FUNCTOR_INIT interface_init #include <rsys/dynamic_array.h> +/* Declare the array of medium */ +#define DARRAY_NAME medium +#define DARRAY_DATA struct sdis_medium* +#define DARRAY_FUNCTOR_INIT medium_init +#include <rsys/dynamic_array.h> + +/* Declare the array of primitive */ +#define DARRAY_NAME prim_prop +#define DARRAY_DATA struct prim_prop +#define DARRAY_FUNCTOR_INIT prim_prop_init +#include <rsys/dynamic_array.h> + +/* Declare the hash table that maps an enclosure id to its data */ +#define HTABLE_NAME enclosure +#define HTABLE_KEY unsigned +#define HTABLE_DATA struct enclosure +#define HTABLE_DATA_FUNCTOR_INIT enclosure_init +#define HTABLE_DATA_FUNCTOR_RELEASE enclosure_release +#define HTABLE_DATA_FUNCTOR_COPY enclosure_copy +#define HTABLE_DATA_FUNCTOR_COPY_AND_RELEASE enclosure_copy_and_release +#include <rsys/hash_table.h> + struct sdis_scene { struct darray_interf interfaces; /* List of interfaces own by the scene */ - struct darray_interf prim_interfaces; /* Per primitive interface */ + struct darray_medium media; /* List of media own by the scene */ + struct darray_prim_prop prim_props; /* Per primitive properties */ struct s2d_scene_view* s2d_view; struct s3d_scene_view* s3d_view; + struct htable_enclosure enclosures; /* Map an enclosure id to its data */ + double ambient_radiative_temperature; /* In Kelvin */ ref_T ref; @@ -50,7 +146,7 @@ static FINLINE size_t scene_get_primitives_count(const struct sdis_scene* scn) { ASSERT(scn); - return darray_interf_size_get(&scn->prim_interfaces); + return darray_prim_prop_size_get(&scn->prim_props); } extern LOCAL_SYM const struct sdis_interface*