star-gs

Literate program for a geometric sensitivity calculation
git clone git://git.meso-star.fr/star-gs.git
Log | Files | Refs | README | LICENSE

commit bd205874d685ee877768ab632590db114e9b38c5
parent fe5afc09c9736c1d061036f975d1e6909f8c3697
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Sun, 25 Apr 2021 22:04:59 +0200

Add the support of the step geometry

Diffstat:
Mcmake/CMakeLists.txt | 1+
Msrc/sgs.c | 5++---
Asrc/sgs_geometry_step.c | 203+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 206 insertions(+), 3 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -53,6 +53,7 @@ set(SGS_FILES_SRC sgs_geometry.c sgs_geometry_box.c sgs_geometry_slope.c + sgs_geometry_step.c sgs_log.c sgs_main.c) diff --git a/src/sgs.c b/src/sgs.c @@ -73,9 +73,8 @@ sgs_create if(res != RES_OK) goto error; break; case SGS_GEOMETRY_STEP: - sgs_log_warn(sgs, "Step geometry is not supported yet.\n"); - res = RES_BAD_OP; - goto error; + res = sgs_geometry_step_create(sgs, &args->geom.args.step, &sgs->geom); + if(res != RES_OK) goto error; break; default: FATAL(SGS_LOG_ERROR_PREFIX"Unreachable code.\n"); break; } diff --git a/src/sgs_geometry_step.c b/src/sgs_geometry_step.c @@ -0,0 +1,203 @@ +/* Copyright (C) 2021 + * CNRS/RAPSODEE, + * CNRS/LMAP, + * |Meso|Star> (contact@meso-star.com), + * UPS/Laplace. + * + * 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 "sgs_geometry.h" +#include "sgs_geometry_c.h" +#include "sgs_log.h" + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static int +check_step_args(struct sgs* sgs, const struct sgs_geometry_step_args* args) +{ + ASSERT(args); + if(args->lower[0] >= args->upper[0] + || args->lower[1] >= args->upper[1] + || args->lower[2] >= args->heights[0] + || args->lower[2] >= args->heights[1] + || args->lower[0] >= args->step + || args->upper[0] <= args->step) { + sgs_log_err(sgs, + "Invalid step definition " + "(lower: %g,%g,%g; upper: %g,%g; heights: %g,%g; step: %g)\n", + SPLIT3(args->lower), + SPLIT2(args->upper), + SPLIT2(args->heights), + args->step); + return 0; + } + return 1; +} + +static res_T +setup_step_mesh + (struct sgs_geometry* geom, + const struct sgs_geometry_step_args* args) +{ + const double* low = NULL; + const double* upp = NULL; + const double* heights = NULL; + double step = 0; + double* vtx = NULL; + size_t* ids = NULL; + int* types = NULL; + res_T res = RES_OK; + ASSERT(geom && args); + + /* Allocate memory space */ + res = darray_double_resize(&geom->verts, 12/*#vertices*/*3/*#coords per vertex*/); + if(res != RES_OK) goto error; + res = darray_size_t_resize(&geom->tris, 20/*#triangles*/*3/*#ids per triangle*/); + if(res != RES_OK) goto error; + res = darray_int_resize(&geom->tris_type, 20/*#triangles*/); + if(res != RES_OK) goto error; + + /* Fetch allocated memory space */ + vtx = darray_double_data_get(&geom->verts); + ids = darray_size_t_data_get(&geom->tris); + types = darray_int_data_get(&geom->tris_type); + + /* Fetch input args */ + low = args->lower; + upp = args->upper; + heights = args->heights; + step = args->step; + + /* 11 +------+ 7 + * /' 5 /| + * 9 +------+ | + * Z 6 +----|.+ 10 | | + * ^ Y /' |/ | | + * |/ 4 +------+ 8 | | + * o--> X | ' 2 | | 3 + * | +...........|.+ + * |/ |/ + * 0 +-------------+ 1 */ + + /* Setup the vertices */ + vtx[0*3+0] = low[0]; vtx[0*3+1] = low[1]; vtx[0*3+2] = low[2]; + vtx[1*3+0] = upp[0]; vtx[1*3+1] = low[1]; vtx[1*3+2] = low[2]; + vtx[2*3+0] = low[0]; vtx[2*3+1] = upp[1]; vtx[2*3+2] = low[2]; + vtx[3*3+0] = upp[0]; vtx[3*3+1] = upp[1]; vtx[3*3+2] = low[2]; + vtx[4*3+0] = low[0]; vtx[4*3+1] = low[1]; vtx[4*3+2] = heights[0]; + vtx[5*3+0] = upp[0]; vtx[5*3+1] = low[1]; vtx[5*3+2] = heights[1]; + vtx[6*3+0] = low[0]; vtx[6*3+1] = upp[1]; vtx[6*3+2] = heights[0]; + vtx[7*3+0] = upp[0]; vtx[7*3+1] = upp[1]; vtx[7*3+2] = heights[1]; + vtx[8*3+0] = step; vtx[8*3+1] = low[1]; vtx[8*3+2] = heights[0]; + vtx[9*3+0] = step; vtx[9*3+1] = low[1]; vtx[9*3+2] = heights[1]; + vtx[10*3+0]= step; vtx[10*3+1]= upp[1]; vtx[10*3+2]= heights[0]; + vtx[11*3+0]= step; vtx[11*3+1]= upp[1]; vtx[11*3+2]= heights[1]; + + /* Setup the triangles */ + ids[0*3+0] = 0; ids[0*3+1] = 4; ids[0*3+2] = 2; /* -X */ + ids[1*3+0] = 2; ids[1*3+1] = 4; ids[1*3+2] = 6; /* -X */ + ids[2*3+0] = 3; ids[2*3+1] = 7; ids[2*3+2] = 5; /* +X */ + ids[3*3+0] = 5; ids[3*3+1] = 1; ids[3*3+2] = 3; /* +X */ + + if(heights[0] < heights[1]) { + ids[4*3+0] = 0; ids[4*3+1] = 1; ids[4*3+2] = 4; /* -Y */ + ids[5*3+0] = 4; ids[5*3+1] = 1; ids[5*3+2] = 8; /* -Y */ + ids[6*3+0] = 8; ids[6*3+1] = 1; ids[6*3+2] = 9; /* -Y */ + ids[7*3+0] = 9; ids[7*3+1] = 1; ids[7*3+2] = 5; /* -Y */ + + ids[8*3+0] = 6; ids[8*3+1] = 3; ids[8*3+2] = 2; /* +Y */ + ids[9*3+0] =10; ids[9*3+1] = 3; ids[9*3+2] = 6; /* +Y */ + ids[10*3+0]=11; ids[10*3+1]= 3; ids[10*3+2]=10; /* +Y */ + ids[11*3+0]= 7; ids[11*3+1]= 3; ids[11*3+2]=11; /* +Y */ + } else { + ids[4*3+0] = 5; ids[4*3+1] = 0; ids[4*3+2] = 1; /* -Y */ + ids[5*3+0] = 9; ids[5*3+1] = 0; ids[5*3+2] = 5; /* -Y */ + ids[6*3+0] = 8; ids[6*3+1] = 0; ids[6*3+2] = 9; /* -Y */ + ids[7*3+0] = 4; ids[7*3+1] = 0; ids[7*3+2] = 8; /* -Y */ + + ids[8*3+0] = 3; ids[8*3+1] = 2; ids[8*3+2] = 7; /* +Y */ + ids[9*3+0] = 7; ids[9*3+1] = 2; ids[9*3+2] =11; /* +Y */ + ids[10*3+0]=11; ids[10*3+1]= 2; ids[10*3+2]=10; /* +Y */ + ids[11*3+0]=10; ids[11*3+1]= 2; ids[11*3+2]= 6; /* +Y */ + } + + ids[12*3+0] = 0; ids[12*3+1] = 2; ids[12*3+2] = 1; /* -Z */ + ids[13*3+0] = 1; ids[13*3+1] = 2; ids[13*3+2] = 3; /* -Z */ + + ids[14*3+0] = 4; ids[14*3+1] = 8; ids[14*3+2] = 6; /* lvl0 */ + ids[15*3+0] = 6; ids[15*3+1] = 8; ids[15*3+2] =10; /* lvl0 */ + ids[16*3+0] = 9; ids[16*3+1] = 5; ids[16*3+2] =11; /* lvl1 */ + ids[17*3+0] =11; ids[17*3+1] = 5; ids[17*3+2] = 7; /* lvl1 */ + ids[18*3+0] = 8; ids[18*3+1] = 9; ids[18*3+2] =10; /* step */ + ids[19*3+0] =10; ids[19*3+1] = 9; ids[19*3+2] =11; /* step */ + + /* Setup the type of the triangles */ + types[0] = types[1] = SGS_SURFACE_X_NEG; + types[2] = types[3] = SGS_SURFACE_X_POS; + types[4] = types[5] = SGS_SURFACE_Y_NEG; + types[6] = types[7] = SGS_SURFACE_Y_NEG; + types[8] = types[9] = SGS_SURFACE_Y_POS; + types[10]= types[11]= SGS_SURFACE_Y_POS; + types[12]= types[13]= SGS_SURFACE_Z_NEG; + types[14]= types[15]= SGS_SURFACE_Z_LVL0; + types[16]= types[17]= SGS_SURFACE_Z_LVL1; + types[18]= types[19]= SGS_SURFACE_Z_STEP; + +exit: + return res; +error: + darray_double_clear(&geom->verts); + darray_size_t_clear(&geom->tris); + darray_int_clear(&geom->tris_type); + goto exit; +} + +/******************************************************************************* + * API function + ******************************************************************************/ +res_T +sgs_geometry_step_create + (struct sgs* sgs, + const struct sgs_geometry_step_args* args, + struct sgs_geometry** out_geom) +{ + struct sgs_geometry* geom = NULL; + res_T res = RES_OK; + ASSERT(sgs && args && out_geom); + + if(!check_step_args(sgs, args)) { + res = RES_BAD_ARG; + goto error; + } + + res = geometry_create(sgs, SGS_GEOMETRY_STEP, args->sampling_mask, &geom); + if(res != RES_OK) goto error; + res = setup_step_mesh(geom, args); + if(res != RES_OK) goto error; + res = geometry_setup_view_rt(geom); + if(res != RES_OK) goto error; + res = geometry_setup_view_sp(geom, args->sampling_mask); + if(res != RES_OK) goto error; + +exit: + *out_geom = geom; + return res; +error: + if(geom) { + sgs_geometry_ref_put(geom); + geom = NULL; + } + goto exit; +}