schiff

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

commit f2f579aa001224a42e8f2c5c442fd7855e536c8d
parent 5a91dc71a08d1b4f6d6eb01fe451edebd0877241
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Sun, 20 Mar 2016 10:53:33 +0100

Internally add the ellipsoid distribution

Add the support of the ellipsoid schiff geometry (not debugged yet).
This distribution is not handled by the schiff-geometry YAML file
format.

Diffstat:
Msrc/schiff_geometry.c | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/schiff_geometry.h | 14+++++++++++++-
2 files changed, 106 insertions(+), 1 deletion(-)

diff --git a/src/schiff_geometry.c b/src/schiff_geometry.c @@ -37,6 +37,20 @@ #include <star/ssp.h> #include <star/sschiff.h> +/* 3D Context of an ellipsoid */ +struct ellipsoid_context { + /* Precomputed values used to define the radius of the ellipsoid for a + * {theta, phi} position : + * r = (a*b*c) + * / sqrt(b^2*c^2*cos(theta)^2*cos(phi)^2 + * + a^2*c^2*sin(theta)^2*cos(phi)^2 + * + a^2*b^2*sin(phi)^2) */ + double abc; /* a*b*c */ + double b2c2; /* b^2*c^2 */ + double a2c2; /* a^2*c^2 */ + double a2b2; /* a^2*b^2 */ +}; + /* 3D Context of the sphere geometry */ struct sphere_context { float radius; /* Sphere radius */ @@ -66,6 +80,7 @@ struct mesh_context { const struct schiff_geometry* geometry; enum schiff_geometry_type type; union { + struct ellipsoid_context ellipsoid; struct cylinder_context cylinder; struct sphere_context sphere; struct super_shape_context super_shape; @@ -172,6 +187,35 @@ geometry_get_indices(const unsigned itri, unsigned ids[3], void* ctx) } static void +ellipsoid_get_position(const unsigned ivert, float vertex[3], void* ctx) +{ + struct mesh_context* mesh_ctx = ctx; + struct sin_cos angles[2]; + double sqr_cos_theta; + double sqr_cos_phi; + double sqr_sin_theta; + double sqr_sin_phi; + double radius; + double tmp; + ASSERT(mesh_ctx && mesh_ctx->type == SCHIFF_ELLIPSOID); + + schiff_mesh_get_polar_position(mesh_ctx->mesh, ivert, angles); + sqr_cos_theta = angles[0].cosine * angles[0].cosine; + sqr_sin_theta = angles[0].sinus * angles[0].sinus; + sqr_cos_phi = angles[1].cosine * angles[1].cosine; + sqr_sin_phi = angles[1].sinus * angles[1].sinus; + + tmp = mesh_ctx->data.ellipsoid.b2c2 * sqr_cos_theta * sqr_cos_phi + + mesh_ctx->data.ellipsoid.a2c2 * sqr_sin_theta * sqr_cos_phi + + mesh_ctx->data.ellipsoid.a2b2 * sqr_sin_phi; + radius = mesh_ctx->data.ellipsoid.abc / sqrt(tmp); + + vertex[0] = (float)(angles[0].cosine * angles[1].cosine * radius); + vertex[1] = (float)(angles[0].sinus * angles[1].cosine * radius); + vertex[2] = (float)(angles[1].sinus * radius); +} + +static void cylinder_get_position(const unsigned ivert, float vertex[3], void* ctx) { struct mesh_context* mesh_ctx = ctx; @@ -222,6 +266,48 @@ super_shape_get_position(const unsigned ivert, float vertex[3], void* ctx) } static res_T +geometry_sample_ellipsoid + (struct ssp_rng* rng, + const struct schiff_geometry* geom, + const struct schiff_mesh* mesh, + struct s3d_shape* shape) +{ + const struct schiff_ellipsoid* ellipsoid; + struct mesh_context mesh_ctx; + struct s3d_vertex_data attrib; + double a, b, c, a2, b2, c2; + size_t nverts, nprims; + ASSERT(rng && geom && mesh && shape); + ASSERT(geom->type == SCHIFF_ELLIPSOID); + + ellipsoid = &geom->data.ellipsoid; + + a = eval_param(&ellipsoid->a, rng); + b = eval_param(&ellipsoid->b, rng); + c = eval_param(&ellipsoid->c, rng); + a2 = a*a; + b2 = b*b; + c2 = c*c; + + mesh_ctx.mesh = mesh; + mesh_ctx.type = SCHIFF_ELLIPSOID; + mesh_ctx.data.ellipsoid.abc = a*b*c; + mesh_ctx.data.ellipsoid.b2c2 = b2*c2; + mesh_ctx.data.ellipsoid.a2c2 = a2*c2; + mesh_ctx.data.ellipsoid.a2b2 = a2*b2; + + attrib.usage = S3D_POSITION; + attrib.type = S3D_FLOAT3; + attrib.get = ellipsoid_get_position; + + nverts = darray_uint_size_get(&mesh->vertices.polar) / 2/*#theta/phi*/; + nprims = darray_uint_size_get(&mesh->indices) / 3/*#indices*/; + + return s3d_mesh_setup_indexed_vertices(shape, (unsigned)nprims, + geometry_get_indices, (unsigned)nverts, &attrib, 1, &mesh_ctx); +} + +static res_T geometry_sample_cylinder (struct ssp_rng* rng, const struct schiff_geometry* geom, @@ -348,6 +434,9 @@ geometry_sample mesh = distrib->meshes + isamp; switch(geom->type) { + case SCHIFF_ELLIPSOID: + res = geometry_sample_ellipsoid(rng, geom, mesh, shape); + break; case SCHIFF_CYLINDER: case SCHIFF_CYLINDER_AS_SPHERE: res = geometry_sample_cylinder(rng, geom, mesh, shape); @@ -430,6 +519,10 @@ schiff_geometry_distribution_init /* Generate the mesh template and setup its distribution context */ switch(geoms[i].type) { + case SCHIFF_ELLIPSOID: + res = schiff_mesh_init_sphere_polar(&mem_default_allocator, + &ctx->meshes[i], geoms[i].data.ellipsoid.nslices); + break; case SCHIFF_CYLINDER: case SCHIFF_CYLINDER_AS_SPHERE: res = schiff_mesh_init_cylinder(&mem_default_allocator, &ctx->meshes[i], diff --git a/src/schiff_geometry.h b/src/schiff_geometry.h @@ -50,6 +50,7 @@ struct schiff_param { #define SCHIFF_PARAM_DEFAULT__ {SCHIFF_PARAM_CONSTANT, {1.0}} enum schiff_geometry_type { + SCHIFF_ELLIPSOID, SCHIFF_CYLINDER, SCHIFF_CYLINDER_AS_SPHERE, /* The cylinder volume is control by a sphere */ SCHIFF_SPHERE, @@ -57,6 +58,16 @@ enum schiff_geometry_type { SCHIFF_NONE }; +struct schiff_ellipsoid { + struct schiff_param a; + struct schiff_param b; + struct schiff_param c; + unsigned nslices; +}; + +#define SCHIFF_ELLIPSOID_DEFAULT__ \ + {SCHIFF_PARAM_DEFAULT__, SCHIFF_PARAM_DEFAULT__, SCHIFF_PARAM_DEFAULT__, 64} + struct schiff_sphere { struct schiff_param radius; unsigned nslices; @@ -104,13 +115,14 @@ static const struct schiff_super_shape SCHIFF_SUPER_SHAPE_DEFAULT = struct schiff_geometry { enum schiff_geometry_type type; union { + struct schiff_ellipsoid ellipsoid; struct schiff_cylinder cylinder; struct schiff_sphere sphere; struct schiff_super_shape super_shape; } data; }; -#define SCHIFF_GEOMETRY_NULL__ { SCHIFF_NONE, { SCHIFF_CYLINDER_DEFAULT__ } } +#define SCHIFF_GEOMETRY_NULL__ { SCHIFF_NONE, { SCHIFF_ELLIPSOID_DEFAULT__ } } static const struct schiff_geometry SCHIFF_GEOMETRY_NULL = SCHIFF_GEOMETRY_NULL__;