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:
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;
+}