solstice-solver

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

commit 49160bcfd6e6247d1941043c5753c3655f1a8175
parent b9dd0b8492c6c7b13b773972ef09f00b764e1d3a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri,  2 Sep 2016 15:13:00 +0200

Finalise the implementation of the ssol_punched_surface function

Diffstat:
Msrc/ssol_shape.c | 119++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/test_ssol_geometries.h | 28++++++++++++++++------------
Msrc/test_ssol_shape.c | 10++++++----
3 files changed, 134 insertions(+), 23 deletions(-)

diff --git a/src/ssol_shape.c b/src/ssol_shape.c @@ -27,11 +27,19 @@ #include <star/scpr.h> +#include <limits.h> /* UINT_MAX constant */ + struct mesh_context { const double* coords; const size_t* ids; }; +struct quadric_mesh_context { + const double* coords; + const size_t* ids; + double focal; /* Use by parabol and parabolic cylinder quadrics */ +}; + /******************************************************************************* * Helper functions ******************************************************************************/ @@ -119,7 +127,7 @@ ssol_to_scpr_clip_op(const enum ssol_clipping_op clip_op) switch(clip_op) { case SSOL_AND: op = SCPR_AND; break; case SSOL_SUB: op = SCPR_SUB; break; - default: FATAL("Unreachable code \n"); break; + default: FATAL("Unreachable code.\n"); break; } return op; } @@ -145,11 +153,62 @@ mesh_get_pos(const size_t ivert, double pos[2], void* ctx) pos[1] = msh->coords[i+1]; } +static void +quadric_mesh_get_ids(const unsigned itri, unsigned ids[3], void* ctx) +{ + const size_t i = itri*3/*#ids per triangle*/; + const struct quadric_mesh_context* msh = ctx; + ASSERT(ids && ctx); + ids[0] = (unsigned)msh->ids[i+0]; + ids[1] = (unsigned)msh->ids[i+1]; + ids[2] = (unsigned)msh->ids[i+2]; +} + +static void +quadric_mesh_plane_get_pos(const unsigned ivert, float pos[3], void* ctx) +{ + const size_t i = ivert*2/*#coords per vertex*/; + const struct quadric_mesh_context* msh = ctx; + ASSERT(pos && ctx); + pos[0] = (float)msh->coords[i+0]; + pos[1] = (float)msh->coords[i+1]; + pos[2] = 0.f; +} + +static void +quadric_mesh_parabol_get_pos(const unsigned ivert, float pos[3], void* ctx) +{ + const size_t i = ivert*2/*#coords per vertex*/; + const struct quadric_mesh_context* msh = ctx; + double x, y; + ASSERT(pos && ctx); + x = msh->coords[i+0]; + y = msh->coords[i+1]; + pos[0] = (float)x; + pos[1] = (float)y; + pos[2] = (float)((x*x + y*y) / (4.0*msh->focal)); +} + +static void +quadric_mesh_parabolic_cylinder_get_pos + (const unsigned ivert, float pos[3], void* ctx) +{ + const size_t i = ivert*2/*#coords per vertex*/; + const struct quadric_mesh_context* msh = ctx; + double x, y; + ASSERT(pos && ctx); + x = msh->coords[i+0]; + y = msh->coords[i+1]; + pos[0] = (float)x; + pos[1] = (float)y; + pos[2] = (float)((y*y) / (4.0*msh->focal)); +} + static FINLINE int aabb_is_degenerated(const double lower[2], const double upper[2]) { ASSERT(lower && upper); - return lower[0] > upper[0] || lower[1] > upper[1]; + return lower[0] >= upper[0] || lower[1] >= upper[1]; } static void @@ -203,7 +262,10 @@ build_triangulated_plane d2_sub(size, upper, lower); size_max = MMAX(size[0], size[1]); - if(eq_eps(size_max, 0, 1.e-6)) goto exit; + if(eq_eps(size_max, 0, 1.e-6)) { + res = RES_BAD_ARG; + goto error; + } delta = size_max / (double)nsteps; nsteps2[0] = (size_t)ceil(size[0] / delta); @@ -335,6 +397,48 @@ error: goto exit; } +static res_T +quadric_setup_s3d_shape + (const struct ssol_quadric* quadric, + const struct darray_double* coords, + const struct darray_size_t* ids, + struct s3d_shape* shape) +{ + struct quadric_mesh_context ctx; + struct s3d_vertex_data vdata; + unsigned nverts; + unsigned ntris; + ASSERT(quadric && coords && ids && shape); + ASSERT(darray_double_size_get(coords)%2 == 0); + ASSERT(darray_size_t_size_get(ids)%3 == 0); + ASSERT(darray_double_size_get(coords)/2 <= UINT_MAX); + ASSERT(darray_size_t_size_get(ids)/3 <= UINT_MAX); + + nverts = (unsigned)darray_double_size_get(coords) / 2/*#coords per vertex*/; + ntris = (unsigned)darray_size_t_size_get(ids) / 3/*#ids per triangle*/; + ctx.coords = darray_double_cdata_get(coords); + ctx.ids = darray_size_t_cdata_get(ids); + + vdata.usage = S3D_POSITION; + vdata.type = S3D_FLOAT3; + switch(quadric->type) { + case SSOL_QUADRIC_PARABOL: + ctx.focal = quadric->data.parabol.focal; + vdata.get = quadric_mesh_parabol_get_pos; + break; + case SSOL_QUADRIC_PARABOLIC_CYLINDER: + ctx.focal = quadric->data.parabolic_cylinder.focal; + vdata.get = quadric_mesh_parabolic_cylinder_get_pos; + break; + case SSOL_QUADRIC_PLANE: + vdata.get = quadric_mesh_plane_get_pos; + break; + default: FATAL("Unreachable code.\n"); break; + } + + return s3d_mesh_setup_indexed_vertices + (shape, ntris, quadric_mesh_get_ids, nverts, &vdata, 1, &ctx); +} static res_T shape_create @@ -454,7 +558,7 @@ ssol_punched_surface_setup carvings_compute_aabb(psurf->carvings, psurf->nb_carvings, lower, upper); if(aabb_is_degenerated(lower, upper)) { log_error(shape->dev, - "%s: infinite punched surface; no `and' carving polygon is defined.\n", + "%s: infinite or null punched surface.\n", FUNC_NAME); res = RES_BAD_ARG; goto error; @@ -470,8 +574,9 @@ ssol_punched_surface_setup (&coords, &ids, shape->dev->scpr_mesh, psurf->carvings, psurf->nb_carvings); if(res != RES_OK) goto error; - /* TODO displace the triangulated plane vertices */ - /* TODO register the displaced triangulated plane in the s3d_shape */ + res = quadric_setup_s3d_shape + (psurf->quadric, &coords, &ids, shape->s3d_shape); + if(res != RES_OK) goto error; exit: darray_double_release(&coords); @@ -528,7 +633,7 @@ ssol_mesh_setup attrs[i].usage = SSOL_TO_S3D_TEXCOORD; attrs[i].type = S3D_FLOAT2; break; - default: FATAL("Unreachable code \n"); break; + default: FATAL("Unreachable code.\n"); break; } } res = s3d_mesh_setup_indexed_vertices diff --git a/src/test_ssol_geometries.h b/src/test_ssol_geometries.h @@ -25,16 +25,14 @@ struct desc { * Plane ******************************************************************************/ static const float square_walls [] = { - -1, -1, 0, - 1, -1, 0, - 1, 1, 0, - -1, 1, 0 + -1.f, -1.f, 0.f, + 1.f, -1.f, 0.f, + 1.f, 1.f, 0.f, + -1.f, 1.f, 0.f }; const unsigned square_walls_nverts = sizeof(square_walls) / sizeof(float[3]); -const unsigned square_walls_ids [] = { - 0, 2, 1, 2, 0, 3 -}; +const unsigned square_walls_ids [] = { 0, 2, 1, 2, 0, 3 }; const unsigned square_walls_ntris = sizeof(square_walls_ids) / sizeof(unsigned[3]); static const struct desc square_walls_desc = { square_walls, square_walls_ids }; @@ -74,6 +72,7 @@ get_ids(const unsigned itri, unsigned ids[3], void* data) const unsigned id = itri * 3; struct desc* desc = data; NCHECK(desc, NULL); + NCHECK(ids, NULL); ids[0] = desc->indices[id + 0]; ids[1] = desc->indices[id + 1]; ids[2] = desc->indices[id + 2]; @@ -84,6 +83,7 @@ get_position(const unsigned ivert, float position[3], void* data) { struct desc* desc = data; NCHECK(desc, NULL); + NCHECK(position, NULL); position[0] = desc->vertices[ivert * 3 + 0]; position[1] = desc->vertices[ivert * 3 + 1]; position[2] = desc->vertices[ivert * 3 + 2]; @@ -92,7 +92,8 @@ get_position(const unsigned ivert, float position[3], void* data) static INLINE void get_normal(const unsigned ivert, float normal[3], void* data) { - (void) ivert, (void) data; + (void)ivert, (void)data; + NCHECK(normal, NULL); normal[0] = 1.f; normal[1] = 0.f; normal[2] = 0.f; @@ -101,7 +102,8 @@ get_normal(const unsigned ivert, float normal[3], void* data) static INLINE void get_uv(const unsigned ivert, float uv[2], void* data) { - (void) ivert, (void) data; + (void)ivert, (void)data; + NCHECK(uv, NULL); uv[0] = -1.f; uv[1] = 1.f; } @@ -109,9 +111,11 @@ get_uv(const unsigned ivert, float uv[2], void* data) static INLINE void get_polygon_vertices(const size_t ivert, double position[2], void* ctx) { - (void) ivert, (void) ctx; - position[0] = -1.f; - position[1] = 1.f; + const double* verts = ctx; + NCHECK(position, NULL); + NCHECK(ctx, NULL); + position[0] = verts[ivert*2+0]; + position[1] = verts[ivert*2+1]; } #endif /* TEST_SSOL_GEOMETRIES_H */ diff --git a/src/test_ssol_shape.c b/src/test_ssol_shape.c @@ -33,6 +33,8 @@ main(int argc, char** argv) struct ssol_punched_surface punched_surface; struct ssol_carving carving; struct ssol_quadric quadric; + const double polygon[] = { -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0 }; + const size_t npolygon_verts = sizeof(polygon)/sizeof(double[2]); (void) argc, (void) argv; mem_init_proxy_allocator(&allocator, &mem_default_allocator); @@ -43,7 +45,7 @@ main(int argc, char** argv) logger_set_stream(&logger, LOG_WARNING, log_stream, NULL); CHECK(ssol_device_create - (&logger, &allocator, SSOL_NTHREADS_DEFAULT, 0, &dev), RES_OK); + (&logger, &allocator, SSOL_NTHREADS_DEFAULT, 1, &dev), RES_OK); CHECK(ssol_shape_create_mesh(NULL, NULL), RES_BAD_ARG); CHECK(ssol_shape_create_mesh(dev, NULL), RES_BAD_ARG); @@ -93,8 +95,8 @@ main(int argc, char** argv) carving.get = get_polygon_vertices; carving.operation = SSOL_AND; - carving.nb_vertices = 1; - carving.context = NULL; + carving.nb_vertices = npolygon_verts; + carving.context = &polygon; quadric.type = SSOL_QUADRIC_PLANE; punched_surface.nb_carvings = 1; punched_surface.quadric = &quadric; @@ -119,7 +121,7 @@ main(int argc, char** argv) carving.nb_vertices = 0; CHECK(ssol_punched_surface_setup(shape, &punched_surface), RES_BAD_ARG); - carving.nb_vertices = 1; + carving.nb_vertices = npolygon_verts; carving.get = NULL; CHECK(ssol_punched_surface_setup(shape, &punched_surface), RES_BAD_ARG);