schiff

Estimate the radiative properties of soft particless
git clone git://git.meso-star.com/schiff.git
Log | Files | Refs | README | LICENSE

commit 92ff34973acb72b330352ed3db364ee1ac12f2e6
parent bc5f9d5ede084192f79a4cceb38ceb06ecbad4ec
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 19 May 2016 12:33:54 +0200

Fix a critical issue in the helical pipe distribution

Due to thread concurrency, the sampled helical pipe shape were totally
wrong. From now, the helical pipe mesh contains the shape indices only.
The buffer of the shape vertices is no more defined in the mesh. It is
locally created at runtime in the "geometry_sample" routine in order to
ensure that each thread write to its own vertex buffer.

Diffstat:
Msrc/schiff.c | 1-
Msrc/schiff_geometry.c | 95++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Msrc/schiff_geometry.h | 2+-
Msrc/schiff_mesh.c | 54++++++++++++++++++++++++++++++++++++++++--------------
Msrc/schiff_mesh.h | 15+++++++++++----
5 files changed, 117 insertions(+), 50 deletions(-)

diff --git a/src/schiff.c b/src/schiff.c @@ -419,7 +419,6 @@ error: /******************************************************************************* * Entry point ******************************************************************************/ -#include "schiff_mesh.h" int main(int argc, char** argv) { diff --git a/src/schiff_geometry.c b/src/schiff_geometry.c @@ -49,14 +49,6 @@ struct cylinder_context { float height; }; -/* 3D Context of an helical pipe */ -struct helical_pipe_context { - double radius_helicoid; - double radius_circle; - double pitch; - double height; -}; - /* 3D Context of the supershape geometry */ struct supershape_context { double formulas[2][6]; @@ -77,12 +69,18 @@ struct mesh_context { union { struct ellipsoid_context ellipsoid; struct cylinder_context cylinder; - struct helical_pipe_context helical_pipe; struct sphere_context sphere; struct supershape_context supershape; } data; }; +/* Specific mesh context for the helical pipe */ +struct helical_pipe_mesh_context { + const unsigned* indices; + const float* vertices; +}; + + struct shape { const struct schiff_geometry* geometry; /* Pointer onto the geometry */ struct s3d_shape* shape; /* May be NULL => No volume distribution */ @@ -199,7 +197,7 @@ get_material_property schiff_optical_properties_fetch(properties, wavelength, props); } -static void +static INLINE void geometry_get_indices(const unsigned itri, unsigned ids[3], void* ctx) { struct mesh_context* mesh_ctx = ctx; @@ -207,7 +205,7 @@ geometry_get_indices(const unsigned itri, unsigned ids[3], void* ctx) schiff_mesh_get_indices(mesh_ctx->mesh, itri, ids); } -static void +static INLINE void geometry_get_position(const unsigned ivert, float vertex[3], void* ctx) { struct mesh_context* mesh_ctx = ctx; @@ -256,6 +254,28 @@ cylinder_get_position(const unsigned ivert, float vertex[3], void* ctx) } static void +helical_pipe_get_indices(const unsigned itri, unsigned ids[3], void* ctx) +{ + size_t i = itri * 3/*#indices per triangle*/; + const struct helical_pipe_mesh_context* mesh_ctx = ctx; + ASSERT(mesh_ctx); + ids[0] = mesh_ctx->indices[i + 0]; + ids[1] = mesh_ctx->indices[i + 1]; + ids[2] = mesh_ctx->indices[i + 2]; +} + +static void +helical_pipe_get_position(const unsigned ivert, float vertex[3], void* ctx) +{ + const size_t i = ivert * 3/*#coords*/; + const struct helical_pipe_mesh_context* mesh_ctx = ctx; + ASSERT(mesh_ctx); + vertex[0] = mesh_ctx->vertices[i + 0]; + vertex[1] = mesh_ctx->vertices[i + 1]; + vertex[2] = mesh_ctx->vertices[i + 2]; +} + +static void sphere_get_position(const unsigned ivert, float vertex[3], void* ctx) { struct mesh_context* mesh_ctx = ctx; @@ -583,7 +603,8 @@ shape_helical_pipe_init const struct schiff_geometry* geometry) { const struct schiff_helical_pipe* helical_pipe; - struct mesh_context ctx; + float* vertices = NULL; + struct helical_pipe_mesh_context ctx; struct s3d_vertex_data attrib; size_t nprims, nverts; double pitch, height, hradius, cradius; @@ -619,22 +640,22 @@ shape_helical_pipe_init height = helical_pipe->height.data.constant; /* Setup the mesh vertices */ - res = schiff_mesh_setup_helical_pipe(&shape->mesh, pitch, height, hradius, - cradius, helical_pipe->nslices_helicoid, helical_pipe->nslices_circle); + res = schiff_mesh_helical_pipe_create_vertices(&shape->mesh, pitch, height, + hradius, cradius, helical_pipe->nslices_helicoid, + helical_pipe->nslices_circle, &nverts, &vertices); if(res != RES_OK) return res; - ctx.type = SCHIFF_HELICAL_PIPE; - ctx.mesh = &shape->mesh; + ctx.vertices = vertices; + ctx.indices = darray_uint_cdata_get(&shape->mesh.indices); attrib.usage = S3D_POSITION; attrib.type = S3D_FLOAT3; - attrib.get = geometry_get_position; + attrib.get = helical_pipe_get_position; - nverts = darray_float_size_get(&shape->mesh.vertices.cartesian) / 3/*#coords*/; nprims = darray_uint_size_get(&shape->mesh.indices) / 3/*#indices per prim*/; res = s3d_mesh_setup_indexed_vertices(shape->shape, (unsigned)nprims, - geometry_get_indices, (unsigned)nverts, &attrib, 1, &ctx); + helical_pipe_get_indices, (unsigned)nverts, &attrib, 1, &ctx); if(res != RES_OK) goto error; res = compute_s3d_shape_volume(s3d, shape->shape, &shape->volume); @@ -643,6 +664,9 @@ shape_helical_pipe_init schiff_mesh_release(&shape->mesh); exit: + if(vertices) { + schiff_mesh_helical_pipe_destroy_vertices(&shape->mesh, vertices); + } return res; error: shape_release(shape); @@ -657,7 +681,8 @@ shape_helical_pipe_generate_s3d_shape struct s3d_shape* s3d_shape) { const struct schiff_helical_pipe* helical_pipe; - struct mesh_context ctx; + float* vertices = NULL; + struct helical_pipe_mesh_context ctx; struct s3d_vertex_data attrib; size_t nprims, nverts; double pitch, height, hradius, cradius; @@ -675,23 +700,33 @@ shape_helical_pipe_generate_s3d_shape height = eval_param(&helical_pipe->height, rng); /* Setup the mesh vertices */ - res = schiff_mesh_setup_helical_pipe(&shape->mesh, pitch, height, hradius, - cradius, helical_pipe->nslices_helicoid, helical_pipe->nslices_circle); - if(res != RES_OK) return res; + res = schiff_mesh_helical_pipe_create_vertices(&shape->mesh, pitch, height, + hradius, cradius, helical_pipe->nslices_helicoid, + helical_pipe->nslices_circle, &nverts, &vertices); + if(res != RES_OK) goto error; - ctx.mesh = &shape->mesh; - ctx.type = SCHIFF_HELICAL_PIPE; + ctx.vertices = vertices; + ctx.indices = darray_uint_cdata_get(&shape->mesh.indices); attrib.usage = S3D_POSITION; attrib.type = S3D_FLOAT3; - attrib.get = geometry_get_position; + attrib.get = helical_pipe_get_position; - nverts = darray_float_size_get(&shape->mesh.vertices.cartesian) / 3/*#coords*/; nprims = darray_uint_size_get(&shape->mesh.indices) / 3/*#indices per prim*/; + res = s3d_mesh_setup_indexed_vertices(s3d_shape, (unsigned)nprims, + helical_pipe_get_indices, (unsigned)nverts, &attrib, 1, &ctx); + if(res != RES_OK) goto error; + *volume_scaling = 1.0; - return s3d_mesh_setup_indexed_vertices(s3d_shape, (unsigned)nprims, - geometry_get_indices, (unsigned)nverts, &attrib, 1, &ctx); + +exit: + if(vertices) { + schiff_mesh_helical_pipe_destroy_vertices(&shape->mesh, vertices); + } + return res; +error: + goto exit; } static res_T @@ -1012,7 +1047,7 @@ schiff_geometry_distribution_init res = RES_MEM_ERR; goto error; } - /* Directly setyp the distribution context to avoid memory leaks on error */ + /* Directly setup the distribution context to avoid memory leaks on error */ distrib->context = ctx; if(!sa_add(ctx->shapes, ngeoms)) { diff --git a/src/schiff_geometry.h b/src/schiff_geometry.h @@ -167,7 +167,7 @@ struct sschiff_geometry_distribution; extern LOCAL_SYM res_T schiff_geometry_distribution_init - (struct sschiff_geometry_distribution* distrib, + (struct sschiff_geometry_distribution* distrib, /* The distribution to init */ struct s3d_device* s3d, const struct schiff_geometry* geometry, const size_t ngeoms, diff --git a/src/schiff_mesh.c b/src/schiff_mesh.c @@ -140,6 +140,7 @@ schiff_mesh_init_sphere /* Define the indices of the sphere */ setup_sphere_indices(&sphere->indices, nthetas, nphis); + sphere->is_init = 1; exit: darray_sincos_release(&sphere->thetas); darray_sincos_release(&sphere->phis); @@ -223,6 +224,7 @@ schiff_mesh_init_sphere_polar /* Define the indices of the sphere */ setup_sphere_indices(&sphere->indices, nthetas, nphis); + sphere->is_init = 1; exit: return res; error: @@ -299,6 +301,8 @@ schiff_mesh_init_cylinder iprim[1] = (id + 3) % (nsteps*2); iprim[2] = (id + 1); } + + cylinder->is_init = 1; exit: return res; error: @@ -325,15 +329,12 @@ schiff_mesh_init_helical_pipe res_T res; ASSERT(allocator && helical_pipe && nsteps_helicoid>=2 && nsteps_circle>=4); - helical_pipe->coordinates = SCHIFF_CARTESIAN; - darray_float_init(allocator, &helical_pipe->vertices.cartesian); + helical_pipe->coordinates = SCHIFF_NO_COORDINATE; darray_uint_init(allocator, &helical_pipe->indices); nverts = (nsteps_helicoid+1)*nsteps_circle/*#contour*/ + 2/*#cap*/; ntris = (nsteps_helicoid)*nsteps_circle*2/*#contour*/ + 2*nsteps_circle/*#cap*/; - res = darray_float_resize(&helical_pipe->vertices.cartesian, nverts*3/*#coords*/); - if(res != RES_OK) goto error; res = darray_uint_resize(&helical_pipe->indices, ntris*3/*#indices per tri*/); if(res != RES_OK) goto error; @@ -396,6 +397,7 @@ schiff_mesh_init_helical_pipe top_cap[id + 2] = (unsigned)(icircle + ilast_meridian_vertex); } + helical_pipe->is_init = 1; exit: return res; error: @@ -404,32 +406,40 @@ error: } res_T -schiff_mesh_setup_helical_pipe - (struct schiff_mesh* mesh, +schiff_mesh_helical_pipe_create_vertices + (const struct schiff_mesh* mesh, const double pitch, const double height, const double hradius, /* Helicoid radius */ const double cradius, /* Circle radius */ const unsigned nsteps_helicoid, - const unsigned nsteps_circle) + const unsigned nsteps_circle, + size_t* nvertices, + float** out_vertices) { double* meridian = NULL; - float* vertices; + float* vertices = NULL; double c; double phi_max; double step_helicoid, step_circle; double rcp_sqrt_hradius2_add_c2; /* Precomputed value */ size_t ihelicoid, icircle; size_t icoord, icoord_top, icoord_bottom; + size_t nverts; res_T res = RES_OK; ASSERT(mesh && pitch > 0 && height > 0 && hradius > 0 && cradius > 0); - ASSERT(mesh->coordinates == SCHIFF_CARTESIAN); + ASSERT(nvertices && out_vertices); + ASSERT(mesh->coordinates == SCHIFF_NO_COORDINATE); ASSERT(nsteps_helicoid * nsteps_circle * 2 * 3 + nsteps_circle*3*2/*cap*/ == darray_uint_size_get(&mesh->indices)); - ASSERT((nsteps_helicoid+1) * nsteps_circle * 3 + 2*3/*cap*/ - == darray_float_size_get(&mesh->vertices.cartesian)); + (void)mesh; + nverts = (nsteps_helicoid+1) * nsteps_circle/*#contour*/ + 2/*#cap*/; + if(!sa_add(vertices, nverts * 3/*#coords per vertex*/)) { + res = RES_MEM_ERR; + goto error; + } if(!sa_add(meridian, nsteps_circle * 3/*#coords per vertex*/)) { res = RES_MEM_ERR; goto error; @@ -453,7 +463,6 @@ schiff_mesh_setup_helical_pipe meridian[id + 2] = cradius*hradius * rcp_sqrt_hradius2_add_c2 * sin_theta; } - vertices = darray_float_data_get(&mesh->vertices.cartesian); icoord = 0; icoord_bottom = (nsteps_helicoid + 1) @@ -490,17 +499,33 @@ schiff_mesh_setup_helical_pipe exit: if(meridian) sa_release(meridian); + *nvertices = nverts; + *out_vertices = vertices; return res; error: + if(vertices) { + sa_release(vertices); + vertices = NULL; + nverts = 0; + } goto exit; } void +schiff_mesh_helical_pipe_destroy_vertices + (const struct schiff_mesh* mesh, float* out_vertices) +{ + ASSERT(mesh && out_vertices); + (void)mesh; + sa_release(out_vertices); +} + +void schiff_mesh_release(struct schiff_mesh* mesh) { ASSERT(mesh); - if(mesh->coordinates == SCHIFF_NO_COORDINATE) - return; /* No coordinate is setuped */ + if(!mesh->is_init) + return; /* The mesh is not initialised */ switch(mesh->coordinates) { case SCHIFF_CARTESIAN: @@ -511,6 +536,7 @@ schiff_mesh_release(struct schiff_mesh* mesh) darray_sincos_release(&mesh->thetas); darray_sincos_release(&mesh->phis); break; + case SCHIFF_NO_COORDINATE: /* Do nothing */ break; default: FATAL("Unreachable code\n"); break; } darray_uint_release(&mesh->indices); diff --git a/src/schiff_mesh.h b/src/schiff_mesh.h @@ -74,16 +74,23 @@ schiff_mesh_init_helical_pipe const unsigned nsteps_circle); extern LOCAL_SYM res_T -schiff_mesh_setup_helical_pipe - (struct schiff_mesh* mesh, +schiff_mesh_helical_pipe_create_vertices + (const struct schiff_mesh* mesh, const double pitch, const double height, const double radius_helicoid, const double radius_circle, - /* The following attribs are assumed to be equal to attributes used by the + /* The 2 following attribs are assumed to be equal to attributes used by the * init function */ const unsigned nsteps_helicoid, - const unsigned nsteps_circle); + const unsigned nsteps_circle, + size_t* out_nvertices, + float** out_vertices); + +extern LOCAL_SYM void +schiff_mesh_helical_pipe_destroy_vertices + (const struct schiff_mesh* mesh, + float* vertices); extern LOCAL_SYM void schiff_mesh_release