star-gf

Compute Gebhart factors
git clone git://git.meso-star.fr/star-gf.git
Log | Files | Refs | README | LICENSE

commit 10345c084a53917caa88af238cb8e3313a27fbcf
parent 174a238ae6151575f0590dc4fdf2320652112226
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 18 Oct 2016 15:23:03 +0200

Implement the SGF 3D shape

Diffstat:
Mcmake/CMakeLists.txt | 9+++++++--
Msrc/sgf.h | 77++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/sgf_device.c | 11++++++++++-
Msrc/sgf_device_c.h | 2++
Asrc/sgf_shape.c | 192+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 287 insertions(+), 4 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -47,9 +47,14 @@ set(VERSION_MINOR 1) set(VERSION_PATCH 0) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) -set(SGF_FILES_SRC sgf_device.c sgf_estimator.c) +set(SGF_FILES_SRC + sgf_device.c + sgf_estimator.c + sgf_shape.c) set(SGF_FILES_INC_API sgf.h) -set(SGF_FILES_INC sgf_device_c.h sgf_realisation.h) +set(SGF_FILES_INC + sgf_device_c.h + sgf_realisation.h) set(SGF_FILES_DOC COPYING README.md) # Prepend each file in the `SGF_FILES_<SRC|INC>' list by `SGF_SOURCE_DIR' diff --git a/src/sgf.h b/src/sgf.h @@ -80,6 +80,25 @@ static const struct sgf_scene_desc SGF_SCENE_DESC_NULL = { NULL, NULL, 0, 0, SGF_3D, { NULL } }; +struct sgf_shape3d_desc { + void (*get_indices)(const unsigned itri, unsigned ids[3], void* ctx); + void (*get_position)(const unsigned ivert, float pos[3], void* ctx); + + void (*get_emissivity) + (const unsigned itri, const unsigned iband, double* val, void* ctx); + void (*get_reflectivity) + (const unsigned itri, const unsigned iband, double* val, void* ctx); + void (*get_specularity) + (const unsigned itri, const unsigned iband, double* val, void* ctx); + void (*get_absorption) /* May be NULL <=> no medium */ + (const unsigned itri, const unsigned iband, double* val, void* ctx); + + void* context; /* User defined data */ + unsigned ntris; /* #triangles */ + unsigned nverts; /* #vertices */ + unsigned nbands; /* #spectral bands */ +}; + /* Estimated Gebart Factor between 2 faces */ struct sgf_status { double E; /* Expected value */ @@ -91,9 +110,11 @@ struct sgf_status { /* Opaque types */ struct sgf_device; struct sgf_estimator; +struct sgf_shape; +struct sgf_scene; /******************************************************************************* - * Star Gebhart Factor API + * Device API ******************************************************************************/ BEGIN_DECLS @@ -112,6 +133,60 @@ SGF_API res_T sgf_device_ref_put (struct sgf_device* dev); +/******************************************************************************* + * Shape API + ******************************************************************************/ +SGF_API res_T +sgf_shape3d_create + (struct sgf_device* device, + struct sgf_shape** shape); + +SGF_API res_T +sgf_shape_ref_get + (struct sgf_shape* shape); + +SGF_API res_T +sgf_shape_ref_put + (struct sgf_shape* shape); + +SGF_API res_T +sgf_shape3d_setup + (struct sgf_shape* shape, + const struct sgf_shape3d_desc* desc); + +/******************************************************************************* + * Scene API + ******************************************************************************/ +SGF_API res_T +sgf_scene3d_create + (struct sgf_device, + struct sgf_scene** scn); + +SGF_API res_T +sgf_scene_ref_get + (struct sgf_scene* scn); + +SGF_API res_T +sgf_scene_ref_put + (struct sgf_scene* scn); + +SGF_API res_T +sgf_scene_attach_shape + (struct sgf_scene* scn, + struct sgf_shape* shape); + +SGF_API res_T +sgf_scene_detach_shape + (struct sgf_scene* scn, + struct sgf_shape* shape); + +SGF_API res_T +sgf_scene_clear + (struct sgf_scene* scn); + +/******************************************************************************* + * Integration API + ******************************************************************************/ /* Numerical estimation of the Gebhart Factor between `primitive_id' and the * other scene primitives. An active S3D_TRACE/S3D_GET_PRIMITIVE session must * be active on `desc->scene'. This function is thread safe and can be invoked diff --git a/src/sgf_device.c b/src/sgf_device.c @@ -19,6 +19,8 @@ #include <rsys/logger.h> #include <rsys/mem_allocator.h> +#include <star/s3d.h> + /******************************************************************************* * Helper function ******************************************************************************/ @@ -28,6 +30,7 @@ device_release(ref_T* ref) struct sgf_device* dev; ASSERT(ref); dev = CONTAINER_OF(ref, struct sgf_device, ref); + if(dev->s3d) S3D(device_ref_put(dev->s3d)); MEM_RM(dev->allocator, dev); } @@ -58,7 +61,7 @@ sgf_device_create if(!dev) { if(verbose) { logger_print(logger, LOG_ERROR, - "Couldn't allocate the Star-Gebhart-Factor device.\n"); + "%s: couldn't allocate the Star-Gebhart-Factor device.\n", FUNC_NAME); } res = RES_MEM_ERR; goto error; @@ -68,6 +71,12 @@ sgf_device_create dev->logger = logger; dev->verbose = verbose; + res = s3d_device_create(NULL, dev->allocator, 0, &dev->s3d); + if(res != RES_OK) { + log_error(dev, "%s: couldn't create the Star-3D device.\n", FUNC_NAME); + goto error; + } + exit: if(out_dev) *out_dev = dev; return res; diff --git a/src/sgf_device_c.h b/src/sgf_device_c.h @@ -20,10 +20,12 @@ struct logger; struct mem_allocator; +struct s3d_device; struct sgf_device { int verbose; struct logger* logger; + struct s3d_device* s3d; struct mem_allocator* allocator; ref_T ref; diff --git a/src/sgf_shape.c b/src/sgf_shape.c @@ -0,0 +1,192 @@ +/* Copyright (C) 2015-2016 EDF S.A., France (syrthes-support@edf.fr) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "sgf.h" +#include "sgf_device_c.h" + +#include <rsys/dynamic_array_double.h> +#include <rsys/ref_count.h> + +#include <star/s3d.h> + +struct sgf_shape { + struct s3d_shape* s3d_shape; + struct darray_double abs; /* Per primitive absorption */ + struct darray_double emi; /* Per primitive emissivity */ + struct darray_double refl; /* Per primitive reflectivity */ + struct darray_double spec; /* Per primitive specularity */ + size_t nbands; /* #spectral bands */ + + ref_T ref; + struct sgf_device* dev; +}; + +/******************************************************************************* + * Local functions + ******************************************************************************/ +static FINLINE int +check_shape3d_desc(const struct sgf_shape3d_desc* desc) +{ + return desc + && desc->get_indices + && desc->get_emissivity + && desc->get_reflectivity + && desc->get_specularity + && desc->get_position + && desc->ntris + && desc->nverts; +} + +static void +shape_release(ref_T* ref) +{ + struct sgf_device* dev; + struct sgf_shape* shape; + ASSERT(ref); + shape = CONTAINER_OF(ref, struct sgf_shape, ref); + dev = shape->dev; + if(shape->s3d_shape) S3D(shape_ref_put(shape->s3d_shape)); + darray_double_release(&shape->abs); + darray_double_release(&shape->emi); + darray_double_release(&shape->refl); + darray_double_release(&shape->spec); + MEM_RM(dev->allocator, shape); + SGF(device_ref_put(dev)); +} + +/******************************************************************************* + * Exported functions + ******************************************************************************/ +res_T +sgf_shape3d_create(struct sgf_device* dev, struct sgf_shape** out_shape) +{ + struct sgf_shape* shape = NULL; + res_T res = RES_OK; + + if(!dev || !out_shape) { + res = RES_BAD_ARG; + goto error; + } + + shape = MEM_CALLOC(dev->allocator, 1, sizeof(struct sgf_shape)); + if(!shape) { + res = RES_MEM_ERR; + goto error; + } + ref_init(&shape->ref); + SGF(device_ref_get(dev)); + shape->dev = dev; + + res = s3d_shape_create_mesh(dev->s3d, &shape->s3d_shape); + if(res != RES_OK) goto error; + + darray_double_init(dev->allocator, &shape->abs); + darray_double_init(dev->allocator, &shape->emi); + darray_double_init(dev->allocator, &shape->refl); + darray_double_init(dev->allocator, &shape->spec); + +exit: + if(out_shape) *out_shape = shape; + return res; +error: + if(shape) { + SGF(shape_ref_put(shape)); + shape = NULL; + } + goto exit; +} + +res_T +sgf_shape_ref_get(struct sgf_shape* shape) +{ + if(!shape) return RES_BAD_ARG; + ref_get(&shape->ref); + return RES_OK; +} + +res_T +sgf_shape_ref_put(struct sgf_shape* shape) +{ + if(!shape) return RES_BAD_ARG; + ref_put(&shape->ref, shape_release); + return RES_OK; +} + +res_T +sgf_shape3d_setup + (struct sgf_shape* shape, const struct sgf_shape3d_desc* desc) +{ + struct s3d_vertex_data vdata; + unsigned iprim, iband, i; + double* abs, *emi, *refl, *spec; + res_T res = RES_OK; + + if(!shape || !check_shape3d_desc(desc)) { + res = RES_BAD_ARG; + goto error; + } + + /* Allocate the buffers of material attributes */ + #define RESIZE(V, Name) { \ + res = darray_double_resize(&(V), desc->ntris*desc->nbands); \ + if(res != RES_OK) { \ + log_error(shape->dev, \ + "%s: couldn't allocate the "Name" buffer.", FUNC_NAME); \ + goto error; \ + } \ + } (void)0 + RESIZE(shape->emi, "emissivity"); + RESIZE(shape->refl, "reflectivity"); + RESIZE(shape->spec, "specularity"); + if(desc->get_absorption) RESIZE(shape->abs, "absorption"); + #undef RESIZE + + /* Setup the material */ + abs = desc->get_absorption ? darray_double_data_get(&shape->abs) : NULL; + emi = darray_double_data_get(&shape->emi); + refl = darray_double_data_get(&shape->refl); + spec = darray_double_data_get(&shape->spec); + FOR_EACH(iband, 0, desc->nbands) { + FOR_EACH(iprim, 0, desc->ntris) { + if(abs) desc->get_absorption(iprim, iband, abs + i, desc->context); + desc->get_emissivity(iprim, iband, emi + i, desc->context); + desc->get_reflectivity(iprim, iband, refl + i, desc->context); + desc->get_specularity(iprim, iband, spec + i, desc->context); + ++i; + }} + + /* Setup the geometry */ + vdata.usage = S3D_POSITION; + vdata.type = S3D_FLOAT3; + vdata.get = desc->get_position; + res = s3d_mesh_setup_indexed_vertices(shape->s3d_shape, desc->ntris, + desc->get_indices, desc->nverts, &vdata, 1, desc->context); + if(res != RES_OK) { + log_error(shape->dev, "%s: couldn't setup the geometry.\n", FUNC_NAME); + goto error; + } + +exit: + return res; +error: + if(shape) { + darray_double_clear(&shape->abs); + darray_double_clear(&shape->emi); + darray_double_clear(&shape->refl); + darray_double_clear(&shape->spec); + } + goto exit; +} +