solstice-solver

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

commit 6559593a00cf159aa3551f3860cff332a9d1b981
parent 203f80de0cf0bb98275cc2599740a72e0c33bc22
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 17 Mar 2017 10:01:22 +0100

Merge remote-tracking branch 'origin/develop' into feature_outputs

Diffstat:
Msrc/ssol.h | 9+++++++--
Msrc/ssol_mc_receiver.c | 9+++++++++
Msrc/ssol_shape.c | 179+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/ssol_shape_c.h | 13+++++--------
Msrc/test_ssol_scene.c | 2+-
5 files changed, 143 insertions(+), 69 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -159,9 +159,9 @@ static const struct ssol_quadric_parabol SSOL_QUADRIC_PARABOL_NULL = SSOL_QUADRIC_PARABOL_NULL__; struct ssol_quadric_hyperbol { - double img_focal, real_focal; /* Define (x^2 + y^2) / a^2 - (z - 1/2)^2 / b^2 + 1 = 0 * with a^2 = f - f^2; b = f -1/2; f = real_focal / (img_focal + real_focal) */ + double img_focal, real_focal; }; #define SSOL_QUADRIC_HYPERBOL_NULL__ { -1.0 , -1.0 } static const struct ssol_quadric_hyperbol SSOL_QUADRIC_HYPERBOL_NULL = @@ -185,13 +185,18 @@ struct ssol_quadric { /* 3x4 column major transformation of the quadric in object space */ double transform[12]; + + /* Hint on the how to discretised */ + size_t slices_count_hint; }; #define SSOL_QUADRIC_DEFAULT__ { \ SSOL_QUADRIC_PLANE, \ {SSOL_QUADRIC_PLANE_DEFAULT__}, \ - {1,0,0, 0,1,0, 0,0,1, 0,0,0} \ + {1,0,0, 0,1,0, 0,0,1, 0,0,0}, \ + SIZE_MAX /* <=> Use default discretisation */ \ } + static const struct ssol_quadric SSOL_QUADRIC_DEFAULT = SSOL_QUADRIC_DEFAULT__; /* Define the contour of a 2D polygon as well as the clipping operation to diff --git a/src/ssol_mc_receiver.c b/src/ssol_mc_receiver.c @@ -17,6 +17,11 @@ #include "ssol_estimator_c.h" #include "ssol_object_c.h" +#ifdef COMPILER_CL + #pragma warning(push) + #pragma warning(disable:4706) /* Assignment within a condition */ +#endif + /******************************************************************************* * Exported functions ******************************************************************************/ @@ -122,3 +127,7 @@ ssol_mc_shape_get_mc_primitive return RES_OK; } +#ifdef COMPILER_CL + #pragma warning(pop) +#endif + diff --git a/src/ssol_shape.c b/src/ssol_shape.c @@ -44,7 +44,7 @@ struct mesh_context { struct quadric_mesh_context { const double* coords; const size_t* ids; - const struct priv_quadric_data* quadric; + const union priv_quadric_data* quadric; const double* transform; /* 3x4 column major matrix */ }; @@ -228,7 +228,7 @@ quadric_mesh_parabol_get_pos(const unsigned ivert, float pos[3], void* ctx) ASSERT(pos && ctx); p[0] = msh->coords[i+0]; p[1] = msh->coords[i+1]; - p[2] = parabol_z(p, &msh->quadric->data.parabol); + p[2] = parabol_z(p, &msh->quadric->parabol); /* Transform the position in object space */ d33_muld3(p, msh->transform, p); @@ -246,7 +246,7 @@ quadric_mesh_hyperbol_get_pos(const unsigned ivert, float pos[3], void* ctx) ASSERT(pos && ctx); p[0] = msh->coords[i+0]; p[1] = msh->coords[i+1]; - p[2] = hyperbol_z(p, &msh->quadric->data.hyperbol); + p[2] = hyperbol_z(p, &msh->quadric->hyperbol); /* Transform the position in object space */ d33_muld3(p, msh->transform, p); @@ -265,7 +265,7 @@ quadric_mesh_parabolic_cylinder_get_pos ASSERT(pos && ctx); p[0] = msh->coords[i+0]; p[1] = msh->coords[i+1]; - p[2] = parabolic_cylinder_z(p, &msh->quadric->data.pcylinder); + p[2] = parabolic_cylinder_z(p, &msh->quadric->pcylinder); /* Transform the position in object space */ d33_muld3(p, msh->transform, p); @@ -843,13 +843,13 @@ punched_shape_set_z_local(const struct ssol_shape* shape, double pt[3]) pt[2] = 0; break; case SSOL_QUADRIC_PARABOLIC_CYLINDER: - pt[2] = parabolic_cylinder_z(pt, &shape->priv_quadric.data.pcylinder); + pt[2] = parabolic_cylinder_z(pt, &shape->priv_quadric.pcylinder); break; case SSOL_QUADRIC_PARABOL: - pt[2] = parabol_z(pt, &shape->priv_quadric.data.parabol); + pt[2] = parabol_z(pt, &shape->priv_quadric.parabol); break; case SSOL_QUADRIC_HYPERBOL: - pt[2] = hyperbol_z(pt, &shape->priv_quadric.data.hyperbol); + pt[2] = hyperbol_z(pt, &shape->priv_quadric.hyperbol); break; default: FATAL("Unreachable code\n"); break; } @@ -869,15 +869,15 @@ punched_shape_set_normal_local break; case SSOL_QUADRIC_PARABOLIC_CYLINDER: quadric_parabolic_cylinder_gradient_local - (&shape->priv_quadric.data.pcylinder, pt, normal); + (&shape->priv_quadric.pcylinder, pt, normal); break; case SSOL_QUADRIC_PARABOL: { quadric_parabol_gradient_local - (&shape->priv_quadric.data.parabol, pt, normal); + (&shape->priv_quadric.parabol, pt, normal); break; case SSOL_QUADRIC_HYPERBOL: quadric_hyperbol_gradient_local - (&shape->priv_quadric.data.hyperbol, pt, normal); + (&shape->priv_quadric.hyperbol, pt, normal); break; } default: FATAL("Unreachable code\n"); break; @@ -906,15 +906,15 @@ punched_shape_intersect_local break; case SSOL_QUADRIC_PARABOLIC_CYLINDER: hit = quadric_parabolic_cylinder_intersect_local - (&shape->priv_quadric.data.pcylinder, org, dir, hint, pt, N, dist); + (&shape->priv_quadric.pcylinder, org, dir, hint, pt, N, dist); break; case SSOL_QUADRIC_PARABOL: hit = quadric_parabol_intersect_local - (&shape->priv_quadric.data.parabol, org, dir, hint, pt, N, dist); + (&shape->priv_quadric.parabol, org, dir, hint, pt, N, dist); break; case SSOL_QUADRIC_HYPERBOL: hit = quadric_hyperbol_intersect_local - (&shape->priv_quadric.data.hyperbol, org, dir, hint, pt, N, dist); + (&shape->priv_quadric.hyperbol, org, dir, hint, pt, N, dist); break; default: FATAL("Unreachable code\n"); break; } @@ -935,6 +935,106 @@ shape_release(ref_T* ref) SSOL(device_ref_put(dev)); } +/* Return the parabol discretisation parameter */ +static FINLINE void +priv_parabol_data_setup + (struct priv_parabol_data* data, + const struct ssol_quadric_parabol* parabol) +{ + ASSERT(data && parabol); + data->focal = parabol->focal; + data->one_over_4focal = 1 / (4.0 * parabol->focal); +} + +static FINLINE void +priv_hyperbol_data_setup + (struct priv_hyperbol_data* data, + const struct ssol_quadric_hyperbol* hyperbol) +{ + double g, f, a2; + ASSERT(data && hyperbol); + + /* Re-dimensionalize */ + g = hyperbol->real_focal + hyperbol->img_focal; + f = hyperbol->real_focal / g; + a2 = g * g * (f - f * f); + + data->g_square = g * 0.5; + data->abs_b = g * fabs(f - 0.5); + data->a_square_over_b_square = a2 / (data->abs_b * data->abs_b); + data->one_over_a_square = 1 / a2; +} + +static FINLINE void +priv_parabolic_cylinder_data_setup + (struct priv_pcylinder_data* data, + const struct ssol_quadric_parabolic_cylinder* parabolic_cylinder) +{ + ASSERT(data && parabolic_cylinder); + data->focal = parabolic_cylinder->focal; + data->one_over_4focal = 1 / (4.0 * parabolic_cylinder->focal); +} + +static INLINE void +priv_quadric_data_setup + (union priv_quadric_data* priv_data, + const struct ssol_quadric* quadric) +{ + ASSERT(priv_data && quadric); + switch(quadric->type) { + case SSOL_QUADRIC_PLANE: /* Do nothing */ break; + case SSOL_QUADRIC_PARABOL: + priv_parabol_data_setup + (&priv_data->parabol, &quadric->data.parabol); + break; + case SSOL_QUADRIC_HYPERBOL: + priv_hyperbol_data_setup + (&priv_data->hyperbol, &quadric->data.hyperbol); + break; + case SSOL_QUADRIC_PARABOLIC_CYLINDER: + priv_parabolic_cylinder_data_setup + (&priv_data->pcylinder, &quadric->data.parabolic_cylinder); + break; + default: FATAL("Unreachable code\n"); break; + } +} + +static INLINE size_t +priv_quadric_data_compute_slices_count + (const enum ssol_quadric_type type, + const union priv_quadric_data* priv_data, + const double lower[3], + const double upper[3]) +{ + size_t nslices; + double max_z; + ASSERT(priv_data && lower && upper); + + switch(type) { + case SSOL_QUADRIC_PLANE: nslices = 1; break; + case SSOL_QUADRIC_PARABOL: + max_z = MMAX + (parabol_z(lower, &priv_data->parabol), + parabol_z(upper, &priv_data->parabol)); + nslices = MMIN(50, (size_t)(3 + sqrt(max_z) * 6)); + break; + case SSOL_QUADRIC_HYPERBOL: + max_z = MMAX + (hyperbol_z(lower, &priv_data->hyperbol), + hyperbol_z(upper, &priv_data->hyperbol)); + nslices = MMIN(50, (size_t)(3 + sqrt(max_z) * 6)); + break; + case SSOL_QUADRIC_PARABOLIC_CYLINDER: + max_z = MMAX + (parabolic_cylinder_z(lower, &priv_data->pcylinder), + parabolic_cylinder_z(upper, &priv_data->pcylinder)); + nslices = MMIN(50, (size_t)(3 + sqrt(max_z) * 6)); + break; + default: FATAL("Unreachable code\n"); break; + } + return nslices; +} + /******************************************************************************* * Local functions ******************************************************************************/ @@ -1175,52 +1275,15 @@ ssol_punched_surface_setup goto error; } + /* Setup internal data */ + priv_quadric_data_setup(&shape->priv_quadric, psurf->quadric); + /* Define the #slices of the discretized quadric */ - switch (psurf->quadric->type) { - case SSOL_QUADRIC_PLANE: - nslices = 1; - break; - case SSOL_QUADRIC_PARABOL: { - const struct ssol_quadric_parabol* parabol - = &psurf->quadric->data.parabol; - struct priv_parabol_data* data = &shape->priv_quadric.data.parabol; - double max_z; - data->focal = parabol->focal; - data->one_over_4focal = 1 / (4.0 * parabol->focal); - max_z = MMAX(parabol_z(lower, data), parabol_z(upper, data)); - nslices = MMIN(50, (size_t) (3 + sqrt(max_z) * 6)); - break; - } - case SSOL_QUADRIC_HYPERBOL: { - const struct ssol_quadric_hyperbol* hyperbol = - &psurf->quadric->data.hyperbol; - struct priv_hyperbol_data* data = &shape->priv_quadric.data.hyperbol; - /* re-dimensionalize */ - const double g = hyperbol->real_focal + hyperbol->img_focal; - const double f = hyperbol->real_focal / g; - const double a2 = g * g * (f - f * f); - double max_z; - data->g_square = g * 0.5; - data->abs_b = g * fabs(f - 0.5); - data->a_square_over_b_square = a2 / (data->abs_b * data->abs_b); - data->one_over_a_square = 1 / a2; - max_z = MMAX(hyperbol_z(lower, data), hyperbol_z(upper, data)); - nslices = MMIN(50, (size_t) (3 + sqrt(max_z) * 6)); - break; - } - case SSOL_QUADRIC_PARABOLIC_CYLINDER: { - const struct ssol_quadric_parabolic_cylinder* parabolic_cylinder - = &psurf->quadric->data.parabolic_cylinder; - struct priv_pcylinder_data* data = &shape->priv_quadric.data.pcylinder; - double max_z; - data->focal = psurf->quadric->data.parabolic_cylinder.focal; - data->one_over_4focal = 1 / (4.0 * parabolic_cylinder->focal); - max_z = MMAX(parabolic_cylinder_z(lower, data), - parabolic_cylinder_z(upper, data)); - nslices = MMIN(50, (size_t) (3 + sqrt(max_z) * 6)); - break; - } - default: FATAL("Unreachable code\n"); break; + if(psurf->quadric->slices_count_hint != SIZE_MAX) { + nslices = psurf->quadric->slices_count_hint; + } else { + nslices = priv_quadric_data_compute_slices_count + (shape->quadric.type, &shape->priv_quadric, lower, upper); } res = build_triangulated_plane(&coords, &ids, lower, upper, nslices); diff --git a/src/ssol_shape_c.h b/src/ssol_shape_c.h @@ -43,13 +43,10 @@ struct priv_pcylinder_data { double one_over_4focal; }; -struct priv_quadric_data { - enum ssol_quadric_type type; - union { - struct priv_hyperbol_data hyperbol; - struct priv_parabol_data parabol; - struct priv_pcylinder_data pcylinder; - } data; +union priv_quadric_data { + struct priv_hyperbol_data hyperbol; + struct priv_parabol_data parabol; + struct priv_pcylinder_data pcylinder; }; struct ssol_shape { @@ -57,7 +54,7 @@ struct ssol_shape { struct s3d_shape* shape_rt; /* Star-3D shape to ray-trace */ struct s3d_shape* shape_samp; /* Star-3D shape to sample */ - struct priv_quadric_data priv_quadric; + union priv_quadric_data priv_quadric; struct ssol_quadric quadric; double shape_rt_area, shape_samp_area; double n[3]; /* sum of normals */ diff --git a/src/test_ssol_scene.c b/src/test_ssol_scene.c @@ -40,7 +40,7 @@ instance_func(struct ssol_instance* inst, void* context) CHECK(ctx->instance2_found, 0); ctx->instance2_found = 1; } else { - CHECK(0, 1); /* Unreachable code */ + FATAL("Unreachable code.\n"); } return RES_OK; }