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 e7648f0d886adef0dafc92f6cdd47f785cf3dfcb
parent 5d0dc00b94833aac4669978fdcd9ce6361bd3d17
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 25 Jan 2023 17:02:11 +0100

Simplification et réécriture des sources C

Nous supprimons ici de nombreuses fonctionnalités et lignes de code qui
venaient alourdir les sources C eu égard l'objectif énoncé dans les
sources noweb. Cette phase de réécriture prépare le remplacements des
sources C du calcul de sensiblité en translation par leur version
noweb.

Le plus gros changement concerne la géométrie de la scène qui,
désormais, ne peut être qu'une boîte alignée aux axes ; l'escalier et la
pente ont été supprimés. La face supérieure de la boîte peut désormais
se déplacer le long de sa normale suivant le nouveau paramètre "pi"
entré sur la ligne de commande via l'option décrivant la boîte (option
-b).

Plus secondaires sont la suppression de l'option contrôlant le niveau de
verbosité (le programme affiche désormais tous les messages) et le
changement de nom des constantes de l'énumération sgs_surface_type, un
changement de nom déjà anticipé dans les sources noweb.

Diffstat:
MMakefile | 3---
Msrc/sgs.c | 22++--------------------
Msrc/sgs_args.c | 207+++++++------------------------------------------------------------------------
Msrc/sgs_args.h | 22++--------------------
Msrc/sgs_c.h | 5-----
Dsrc/sgs_compute_4v_s.c | 176-------------------------------------------------------------------------------
Msrc/sgs_compute_sensitivity_translation.c | 17+++--------------
Msrc/sgs_geometry.c | 20+-------------------
Msrc/sgs_geometry.h | 141++++++++++++++-----------------------------------------------------------------
Msrc/sgs_geometry_box.c | 66++++++++++++++++++++++++++++++++++++++----------------------------
Msrc/sgs_geometry_c.h | 2--
Dsrc/sgs_geometry_slope.c | 159-------------------------------------------------------------------------------
Dsrc/sgs_geometry_step.c | 207-------------------------------------------------------------------------------
Msrc/sgs_log.c | 4+---
14 files changed, 89 insertions(+), 962 deletions(-)

diff --git a/Makefile b/Makefile @@ -27,12 +27,9 @@ include config.mk SRC =\ src/sgs_args.c\ src/sgs.c\ - src/sgs_compute_4v_s.c\ src/sgs_compute_sensitivity_translation.c\ src/sgs_geometry_box.c\ src/sgs_geometry.c\ - src/sgs_geometry_slope.c\ - src/sgs_geometry_step.c\ src/sgs_log.c\ src/sgs_main.c diff --git a/src/sgs.c b/src/sgs.c @@ -54,7 +54,6 @@ sgs_create sgs->allocator = allocator; sgs->nrealisations = (size_t)args->nrealisations; sgs->nthreads = args->nthreads; - sgs->verbose = args->verbose; sgs->dump_geometry = args->dump_geometry; setup_logger(sgs); @@ -66,21 +65,8 @@ sgs_create goto error; } - switch(args->geom.type) { - case SGS_GEOMETRY_BOX: - res = sgs_geometry_box_create(sgs, &args->geom.args.box, &sgs->geom); - if(res != RES_OK) goto error; - break; - case SGS_GEOMETRY_SLOPE: - res = sgs_geometry_slope_create(sgs, &args->geom.args.slope, &sgs->geom); - if(res != RES_OK) goto error; - break; - case SGS_GEOMETRY_STEP: - 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; - } + res = sgs_geometry_box_create(sgs, &args->geom, &sgs->geom); + if(res != RES_OK) goto error; exit: *out_sgs = sgs; @@ -152,11 +138,7 @@ sgs_run(struct sgs* sgs) res = sgs_geometry_dump_vtk(sgs->geom, stdout); if(res != RES_OK) goto error; } else { -#if 1 res = compute_sensitivity_translation(sgs); -#else - res = compute_4v_s(sgs); -#endif if(res != RES_OK) goto error; } diff --git a/src/sgs_args.c b/src/sgs_args.c @@ -36,13 +36,13 @@ static void print_help(void) { - printf("Usage: sgs [<options>]\n"); - printf("Test geometric sensitivities on predefined 3D scenes.\n"); + printf("Usage: sgs [option] ...\n"); + printf("Calculate geometric sensitivity.\n"); printf("\n"); printf( " -b <box-params:...>\n" -" define an axis aligned bounding box (default)\n" +" define an axis aligned bounding box\n" " Available box parameters are:\n"); printf( " default\n" @@ -61,8 +61,15 @@ print_help(void) SGS_GEOMETRY_BOX_ARGS_DEFAULT.upper[0], SGS_GEOMETRY_BOX_ARGS_DEFAULT.upper[1], SGS_GEOMETRY_BOX_ARGS_DEFAULT.upper[2]); + + printf( +" pi=t\n" +" translation of the top face\n" +" (default: %g).\n", + SGS_GEOMETRY_BOX_ARGS_DEFAULT.pi); printf( -" -d dump geometry following the VTK file format.\n"); +" -d write geometry to stdout\n" +" (VTK file format).\n"); printf( " -h display this help and exit.\n"); printf( @@ -70,66 +77,8 @@ print_help(void) " number of realisations (default: %li).\n", SGS_ARGS_DEFAULT.nrealisations); printf( -" -p <step-params:...>\n" -" define an axis aligned box whose +Z face is replaced\n" -" by a step along the X axis. Available step parameters\n" -" are:\n"); - printf( -" default\n" -" use default settings.\n"); - printf( -" low=x,y,z\n" -" define the lower bound (default: %g,%g,%g).\n", - SGS_GEOMETRY_STEP_ARGS_DEFAULT.lower[0], - SGS_GEOMETRY_STEP_ARGS_DEFAULT.lower[1], - SGS_GEOMETRY_STEP_ARGS_DEFAULT.lower[2]); - printf( -" upp=x,y\n" -" define the upper bound in the XY plane\n" -" (default: %g,%g).\n", - SGS_GEOMETRY_STEP_ARGS_DEFAULT.upper[0], - SGS_GEOMETRY_STEP_ARGS_DEFAULT.upper[1]); - printf( -" heights=h0,h1\n" -" define the heights of the first and second\n" -" levels of the step (default: %g,%g).\n", - SGS_GEOMETRY_STEP_ARGS_DEFAULT.heights[0], - SGS_GEOMETRY_STEP_ARGS_DEFAULT.heights[1]); - printf( -" step=x\n" -" coordinates of the step along the X axis\n" -" (default: %g).\n", - SGS_GEOMETRY_STEP_ARGS_DEFAULT.step); - printf( -" -s <slope-params:...>\n" -" define an axis aligned box whose +Z face is tilted\n" -" along the X axis. Available slope parameters are:\n"); - printf( -" default\n" -" use default settings.\n"); - printf( -" low=x,y,z\n" -" define the lower bound (default: %g,%g,%g).\n", - SGS_GEOMETRY_SLOPE_ARGS_DEFAULT.lower[0], - SGS_GEOMETRY_SLOPE_ARGS_DEFAULT.lower[1], - SGS_GEOMETRY_SLOPE_ARGS_DEFAULT.lower[2]); - printf( -" upp=x,y\n" -" define the upper bound in the XY plane\n" -" (default: %g,%g).\n", - SGS_GEOMETRY_SLOPE_ARGS_DEFAULT.upper[0], - SGS_GEOMETRY_SLOPE_ARGS_DEFAULT.upper[1]); - printf( -" heights=h0,h1\n" -" define the start and end heights of the slope\n" -" (default: %g,%g).\n", - SGS_GEOMETRY_SLOPE_ARGS_DEFAULT.heights[0], - SGS_GEOMETRY_SLOPE_ARGS_DEFAULT.heights[1]); - printf( -" -t nthreads hint on the number of threads to use. By default use\n" -" as many threads as CPU cores.\n"); - printf( -" -v make the command verbose.\n"); +" -t nthreads hint on the number of threads to use.\n" +" Default assumes as many threads as CPU cores.\n"); printf("\n"); sgs_fprint_license(stdout); @@ -166,6 +115,8 @@ parse_box_parameters(const char* str, void* ptr) } else if(!strcmp(key, "upp")) { res = cstr_to_list_double(val, ',', box->upper, &len, 3); if(res == RES_OK && len != 3) res = RES_BAD_ARG; + } else if(!strcmp(key, "pi")) { + res = cstr_to_double(val, &box->pi); } else { fprintf(stderr, SGS_LOG_ERROR_PREFIX "Invalid box parameter `%s'.\n", key); @@ -185,114 +136,6 @@ error: goto exit; } -static res_T -parse_slope_parameters(const char* str, void* ptr) -{ - char buf[128]; - struct sgs_geometry_slope_args* slope = ptr; - char* key; - char* val; - char* ctx; - size_t len; - res_T res = RES_OK; - ASSERT(ptr && str); - - if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { - fprintf(stderr, SGS_LOG_ERROR_PREFIX - "Could not duplicate the slope option string `%s'.\n", str); - res = RES_MEM_ERR; - goto error; - } - strncpy(buf, str, sizeof(buf)); - - key = strtok_r(buf, "=", &ctx); - val = strtok_r(NULL, "", &ctx); - - if(!strcmp(key, "default")) { - *slope = SGS_GEOMETRY_SLOPE_ARGS_DEFAULT; - } else if(!strcmp(key, "low")) { - res = cstr_to_list_double(val, ',', slope->lower, &len, 3); - if(res == RES_OK && len != 3) res = RES_BAD_ARG; - } else if(!strcmp(key, "upp")) { - res = cstr_to_list_double(val, ',', slope->upper, &len, 2); - if(res == RES_OK && len != 2) res = RES_BAD_ARG; - } else if(!strcmp(key, "heights")) { - res = cstr_to_list_double(val, ',', slope->heights, &len, 2); - if(res == RES_OK && len != 2) res = RES_BAD_ARG; - } else { - fprintf(stderr, SGS_LOG_ERROR_PREFIX - "Invalid slope parameter `%s'.\n", key); - res = RES_BAD_ARG; - goto error; - } - if(res != RES_OK) { - fprintf(stderr, SGS_LOG_ERROR_PREFIX - "Error parsing the value of the `%s' slope parameter: %s -- %s.\n", - key, val, res_to_cstr(res)); - goto error; - } - -exit: - return res; -error: - goto exit; -} - -static res_T -parse_step_parameters(const char* str, void* ptr) -{ - char buf[128]; - struct sgs_geometry_step_args* step = ptr; - char* key; - char* val; - char* ctx; - size_t len; - res_T res = RES_OK; - ASSERT(ptr && str); - - if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { - fprintf(stderr, SGS_LOG_ERROR_PREFIX - "Could not duplicate the step option string `%s'.\n", str); - res = RES_MEM_ERR; - goto error; - } - strncpy(buf, str, sizeof(buf)); - - key = strtok_r(buf, "=", &ctx); - val = strtok_r(NULL, "", &ctx); - - if(!strcmp(key, "default")) { - *step = SGS_GEOMETRY_STEP_ARGS_DEFAULT; - } else if(!strcmp(key, "low")) { - res = cstr_to_list_double(val, ',', step->lower, &len, 3); - if(res == RES_OK && len != 3) res = RES_BAD_ARG; - } else if(!strcmp(key, "upp")) { - res = cstr_to_list_double(val, ',', step->upper, &len, 2); - if(res == RES_OK && len != 2) res = RES_BAD_ARG; - } else if(!strcmp(key, "heights")) { - res = cstr_to_list_double(val, ',', step->heights, &len, 2); - if(res == RES_OK && len != 2) res = RES_BAD_ARG; - } else if(!strcmp(key, "step")) { - res = cstr_to_double(val, &step->step); - } else { - fprintf(stderr, SGS_LOG_ERROR_PREFIX - "Invalid step parameter `%s'.\n", key); - res = RES_BAD_ARG; - goto error; - } - if(res != RES_OK) { - fprintf(stderr, SGS_LOG_ERROR_PREFIX - "Error parsing the value of the `%s' step parameter: %s -- %s.\n", - key, val, res_to_cstr(res)); - goto error; - } - -exit: - return res; -error: - goto exit; -} - /******************************************************************************* * sgs_args API ******************************************************************************/ @@ -305,13 +148,12 @@ sgs_args_init(struct sgs_args* args, int argc, char** argv) *args = SGS_ARGS_DEFAULT; - while((opt = getopt(argc, argv, "b:dhn:p:s:t:v")) != -1) { + while((opt = getopt(argc, argv, "b:dhn:t:")) != -1) { switch(opt) { case 'b': - args->geom.type = SGS_GEOMETRY_BOX; - args->geom.args.box = SGS_GEOMETRY_BOX_ARGS_DEFAULT; + args->geom = SGS_GEOMETRY_BOX_ARGS_DEFAULT; res = cstr_parse_list - (optarg, ':', parse_box_parameters, &args->geom.args.box); + (optarg, ':', parse_box_parameters, &args->geom); break; case 'd': args->dump_geometry = 1; break; case 'h': @@ -323,23 +165,10 @@ sgs_args_init(struct sgs_args* args, int argc, char** argv) res = cstr_to_long(optarg, &args->nrealisations); if(res == RES_OK && args->nrealisations <= 0) res = RES_BAD_ARG; break; - case 'p': - args->geom.type = SGS_GEOMETRY_STEP; - args->geom.args.step = SGS_GEOMETRY_STEP_ARGS_DEFAULT; - res = cstr_parse_list - (optarg, ':', parse_step_parameters, &args->geom.args.step); - break; - case 's': - args->geom.type = SGS_GEOMETRY_SLOPE; - args->geom.args.slope = SGS_GEOMETRY_SLOPE_ARGS_DEFAULT; - res = cstr_parse_list - (optarg, ':', parse_slope_parameters, &args->geom.args.slope); - break; case 't': res = cstr_to_uint(optarg, &args->nthreads); if(res == RES_OK && !args->nthreads) res = RES_BAD_ARG; break; - case 'v': args->verbose = 1; break; default: res = RES_BAD_ARG; break; } if(res != RES_OK) { diff --git a/src/sgs_args.h b/src/sgs_args.h @@ -25,40 +25,22 @@ #include "sgs_geometry.h" #include <limits.h> -struct sgs_args_geometry { - enum sgs_geometry_type type; - union { - struct sgs_geometry_box_args box; - struct sgs_geometry_slope_args slope; - struct sgs_geometry_step_args step; - } args; -}; - -#define SGS_ARGS_GEOMETRY_DEFAULT__ { \ - SGS_GEOMETRY_BOX, \ - {SGS_GEOMETRY_BOX_ARGS_DEFAULT__} \ -} -static const struct sgs_args_geometry SGS_ARGS_GEOMETRY_DEFAULT = - SGS_ARGS_GEOMETRY_DEFAULT__; - struct sgs_args { - struct sgs_args_geometry geom; /* The scene geometry */ + struct sgs_geometry_box_args geom; /* The scene geometry */ long nrealisations; /* Miscellaneous parameters */ unsigned nthreads; int dump_geometry; - int verbose; /* Verbosity level */ int quit; /* Stop the command */ }; #define SGS_ARGS_DEFAULT__ { \ - SGS_ARGS_GEOMETRY_DEFAULT__, /* Scene geometry */ \ + SGS_GEOMETRY_BOX_ARGS_DEFAULT, /* Scene geometry */ \ 10000, /* #realisations */ \ \ UINT_MAX, /* #threads */ \ 0, /* Dump geometry */ \ - 0, /* Verbose flag */ \ 0 /* Stop the command */ \ } static const struct sgs_args SGS_ARGS_DEFAULT = SGS_ARGS_DEFAULT__; diff --git a/src/sgs_c.h b/src/sgs_c.h @@ -33,7 +33,6 @@ struct sgs { unsigned int nthreads; /* #threads */ - int verbose; int dump_geometry; struct logger logger; @@ -60,10 +59,6 @@ setup_logger (struct sgs* sgs); extern LOCAL_SYM res_T -compute_4v_s - (struct sgs* sgs); - -extern LOCAL_SYM res_T compute_sensitivity_translation (struct sgs* sgs); diff --git a/src/sgs_compute_4v_s.c b/src/sgs_compute_4v_s.c @@ -1,176 +0,0 @@ -/* Copyright (C) 2021, 2022 Centre National de la Recherche Scientifique - * Copyright (C) 2021, 2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2021, 2022 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2021, 2022 Université Clermont Auvergne - * Copyright (C) 2021, 2022 Université de Lorraine - * Copyright (C) 2021, 2022 Université de Lyon - * Copyright (C) 2021, 2022 Université de Toulouse - * - * 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_c.h" -#include "sgs_geometry.h" -#include "sgs_log.h" - -#include <star/smc.h> -#include <star/ssp.h> - -#include <rsys/double2.h> -#include <rsys/double3.h> -#include <rsys/cstr.h> - -/******************************************************************************* - * Helper function - ******************************************************************************/ -static res_T -realisation(void* weight, struct ssp_rng* rng, const unsigned ithread, void* ctx) -{ - struct sgs_fragment frag = SGS_FRAGMENT_NULL; - struct sgs_hit hit = SGS_HIT_NULL; - - double vec[3] = {0, 0, 0}; - double pos[3] = {0, 0, 0}; - double dir[3] = {0, 0, 0}; - double range[2] = {0, DBL_MAX}; - - enum sgs_surface_type surface_from = SGS_SURFACE_NONE; - struct sgs* sgs = ctx; - - double len = 0; - - int emissive_surfaces = 0; - res_T res = RES_OK; - - ASSERT(weight && rng && ctx); - (void)ithread; - - /* Retrieve the mask of the emissive surfaces */ - emissive_surfaces = sgs_geometry_get_sampling_mask(sgs->geom); - - /* Sample the emissive surface */ - sgs_geometry_sample(sgs->geom, rng, &frag); - surface_from = frag.surface; - - /* Cosine weighted sampling of the hemisphere around the sampled normal */ - ssp_ran_hemisphere_cos(rng, frag.normal, dir, NULL); - - pos[0] = frag.position[0]; - pos[1] = frag.position[1]; - pos[2] = frag.position[2]; - - range[0] = 0; - range[1] = INF; - - for(;;) { - sgs_geometry_trace_ray(sgs->geom, pos, dir, range, surface_from, &hit); - if(SGS_HIT_NONE(&hit)) { /* Unexpected error */ - res = RES_BAD_OP; - goto error; - } - - /* Update the path length */ - len += hit.distance; - - if(((int)hit.surface & emissive_surfaces) != 0) - break; /* Stop random walk */ - - /* Move to the intersection */ - d3_muld(vec, dir, hit.distance); - d3_add(pos, pos, vec); - - /* Reflect the direction with respect to the intersection normal */ - d3_minus(dir, dir); /* Ensure reflect convention */ - reflect(dir, dir, hit.normal); - - surface_from = hit.surface; - } -exit: - SMC_DOUBLE(weight) = len; - return res; -error: - len = NaN; - goto exit; -} - - -/******************************************************************************* - * Local function - ******************************************************************************/ -res_T -compute_4v_s(struct sgs* sgs) -{ - struct smc_device_create_args args = SMC_DEVICE_CREATE_ARGS_DEFAULT; - struct smc_estimator_status status = SMC_ESTIMATOR_STATUS_NULL; - struct smc_integrator integrator = SMC_INTEGRATOR_NULL; - struct smc_device* smc = NULL; - struct smc_estimator* estimator = NULL; - double V; - double S; - res_T res = RES_OK; - ASSERT(sgs); - - /* Create the Star-MonteCarlo device */ - args.logger = &sgs->logger; - args.allocator = sgs->allocator; - args.nthreads_hint = sgs->nthreads; - args.rng_type = SSP_RNG_MT19937_64; - res = smc_device_create(&args, &smc); - if(res != RES_OK) { - sgs_log_err(sgs, "Could not create the Star-MonteCarlo device -- %s.\n", - res_to_cstr(res)); - goto error; - } - - /* Setup the integrator */ - integrator.integrand = realisation; - integrator.type = &smc_double; - integrator.max_realisations = sgs->nrealisations; - integrator.max_failures = (size_t)((double)sgs->nrealisations*0.01); - - /* Run Monte-Carlo integration */ - res = smc_solve(smc, &integrator, sgs, &estimator); - if(res != RES_OK) { - sgs_log_err(sgs, "Error while solving 4V/S -- %s.\n", - res_to_cstr(res)); - goto error; - } - - /* Retrieve the estimated value */ - SMC(estimator_get_status(estimator, &status)); - if(status.NF >= integrator.max_failures) { - sgs_log_err(sgs, "Too many failures: %lu\n", (unsigned long)status.NF); - res = RES_BAD_OP; - goto error; - } - - /* Fetch the reference values */ - V = sgs_geometry_compute_volume(sgs->geom); - S = sgs_geometry_compute_sampling_area(sgs->geom); - sgs_log(sgs, "V = %g; S = %g\n", V, S); - - /* Print the result */ - sgs_log(sgs, "4V/S = %g ~ %g +/- %g; #failures = %lu/%lu\n", - 4*V/S, - SMC_DOUBLE(status.E), - SMC_DOUBLE(status.SE), - (unsigned long)status.NF, - (unsigned long)sgs->nrealisations); - -exit: - if(smc) SMC(device_ref_put(smc)); - if(estimator) SMC(estimator_ref_put(estimator)); - return res; -error: - goto exit; -} diff --git a/src/sgs_compute_sensitivity_translation.c b/src/sgs_compute_sensitivity_translation.c @@ -120,7 +120,7 @@ hit_receiver pos_recv[Y] = ray_org[Y] + hit->distance*ray_dir[Y]; pos_recv[Z] = ray_org[Z] + hit->distance*ray_dir[Z]; - if(hit->surface != SGS_SURFACE_Z_NEG + if(hit->surface != SGS_SURFACE_Z_MIN || pos_recv[X] < scn->recv_min[X] || scn->recv_max[X] < pos_recv[X] || pos_recv[Y] < scn->recv_min[Y] || scn->recv_max[Y] < pos_recv[Y]) { return 0; /* The ray does not intersect the receiver */ @@ -142,7 +142,7 @@ hit_source pos_emit_e[Y] = ray_org[Y] + hit->distance*ray_dir[Y]; pos_emit_e[Z] = ray_org[Z] + hit->distance*ray_dir[Z]; - if(hit->surface != SGS_SURFACE_X_POS + if(hit->surface != SGS_SURFACE_X_MAX || pos_emit_e[Z] > scn->emit_e_threshold) { return 0; /* The ray does not intersect the emitter */ } else { @@ -351,21 +351,10 @@ compute_sensitivity_translation(struct sgs* sgs) struct smc_device* smc = NULL; struct smc_estimator* estimator = NULL; struct smc_doubleN_context ctx; - enum sgs_geometry_type type; res_T res = RES_OK; ASSERT(sgs); - type = sgs_geometry_get_type(sgs->geom); - if(type != SGS_GEOMETRY_BOX) { - sgs_log_err(sgs, - "Invalid `%s' geometry. The box geometry is the only one that is " - "currently supported by the translation sensitivity computation.\n", - sgs_geometry_type_to_cstr(type)); - res = RES_BAD_ARG; - goto error; - } - - if(sgs_geometry_get_sampling_mask(sgs->geom) != SGS_SURFACE_Z_POS) { + if(sgs_geometry_get_sampling_mask(sgs->geom) != SGS_SURFACE_Z_MAX) { sgs_log_err(sgs, "Invalid sensitivity emissive surface. Only positive Z face of the box " "geometry can be a sensitivity source.\n"); diff --git a/src/sgs_geometry.c b/src/sgs_geometry.c @@ -184,13 +184,6 @@ sgs_geometry_ref_put(struct sgs_geometry* geom) ref_put(&geom->ref, release_geometry); } -enum sgs_geometry_type -sgs_geometry_get_type(const struct sgs_geometry* geom) -{ - ASSERT(geom); - return geom->type; -} - void sgs_geometry_get_aabb (const struct sgs_geometry* geom, @@ -210,15 +203,6 @@ sgs_geometry_get_sampling_mask(const struct sgs_geometry* geom) } double -sgs_geometry_compute_volume(const struct sgs_geometry* geom) -{ - float volume; - ASSERT(geom); - S3D(scene_view_compute_volume(geom->view_rt, &volume)); - return volume; -} - -double sgs_geometry_compute_sampling_area(const struct sgs_geometry* geom) { float area; @@ -380,14 +364,13 @@ error: res_T geometry_create (struct sgs* sgs, - const enum sgs_geometry_type type, const int sampling_mask, struct sgs_geometry** out_geom) { struct sgs_geometry* geom = NULL; struct mem_allocator* allocator = NULL; res_T res = RES_OK; - ASSERT(sgs && (unsigned)type < SGS_GEOMETRY_TYPES_COUNT__ && out_geom); + ASSERT(sgs && out_geom); ASSERT(sampling_mask != 0); allocator = sgs_get_allocator(sgs); @@ -403,7 +386,6 @@ geometry_create darray_size_t_init(allocator, &geom->tris); darray_int_init(allocator, &geom->tris_rt_type); darray_int_init(allocator, &geom->tris_sp_type); - geom->type = type; geom->sampling_mask = sampling_mask; exit: diff --git a/src/sgs_geometry.h b/src/sgs_geometry.h @@ -25,99 +25,40 @@ #include <star/s3d.h> #include <rsys/rsys.h> -enum sgs_geometry_type { - SGS_GEOMETRY_BOX, - SGS_GEOMETRY_SLOPE, - SGS_GEOMETRY_STEP, - SGS_GEOMETRY_NONE, - SGS_GEOMETRY_TYPES_COUNT__ = SGS_GEOMETRY_NONE -}; - enum sgs_surface_type { - SGS_SURFACE_X_NEG = BIT(0), /* -X face */ - SGS_SURFACE_X_POS = BIT(1), /* +X face */ - SGS_SURFACE_Y_NEG = BIT(2), /* -Y face */ - SGS_SURFACE_Y_POS = BIT(3), /* +Y face */ - SGS_SURFACE_Z_NEG = BIT(4), /* -Z face */ - SGS_SURFACE_Z_POS = BIT(5), /* +Z face */ - SGS_SURFACE_Z_SLOPE = BIT(6), /* +Z face representing a slope */ - SGS_SURFACE_Z_LVL0 = BIT(7), /* +Z face representing the 1st level along X */ - SGS_SURFACE_Z_LVL1 = BIT(8), /* +Z face representing the 2nd level along X */ - SGS_SURFACE_Z_STEP = BIT(9), /* +Z face representing the step between the 2 levels */ + SGS_SURFACE_X_MIN = BIT(0), /* -X face */ + SGS_SURFACE_X_MAX = BIT(1), /* +X face */ + SGS_SURFACE_Y_MIN = BIT(2), /* -Y face */ + SGS_SURFACE_Y_MAX = BIT(3), /* +Y face */ + SGS_SURFACE_Z_MIN = BIT(4), /* -Z face */ + SGS_SURFACE_Z_MAX = BIT(5), /* +Z face */ SGS_SURFACE_NONE = 0 }; -/* A simple axis aligned bounding box - * Z o--------u upper - * ^ Y /' /| - * |/ o--------o | - * o--> X | ' | | - * | o......|.o - * |. |/ - * lower l--------o */ +/* A simple axis-aligned bounding box whose top face is translated by pi + * + * o--------o + * / / + * . . .o--------o + * ^ + * Z pi o--------u upper + * ^ Y | /| /| + * |/ . . .o--------o | + * o--> X | ' | | + * | o......|.o + * |. |/ + * lower l--------o + */ struct sgs_geometry_box_args { double lower[3]; /* Lower bound */ double upper[3]; /* Upper bound */ - int sampling_mask; /* Combination of enum sgs_surface_type */ + double pi; + int sampling_mask; /* Surface that can be uniformly sampled */ }; -#define SGS_GEOMETRY_BOX_ARGS_DEFAULT__ {{0,0,0}, {1,1,1}, SGS_SURFACE_Z_POS} +#define SGS_GEOMETRY_BOX_ARGS_DEFAULT__ {{0,0,0}, {1,1,1}, 0, SGS_SURFACE_Z_MAX} static const struct sgs_geometry_box_args SGS_GEOMETRY_BOX_ARGS_DEFAULT = SGS_GEOMETRY_BOX_ARGS_DEFAULT__; -/* A "box" whose +Z face forms a slope along the X axis - * ,o - * ,'/| - * ,',o.| . . . . . - * Z ,',' | | ^ - * ^ Y o',' | | | - * |/ /,' | | heights[1] - * o--> X . . . . o'' | | | - * ^ | ' | | | - * heighst[0] | o......|.u upper | - * | |. |/ | - * . . . . l--------o . . . . . . - * lower */ -struct sgs_geometry_slope_args { - double lower[3]; /* 3D lower bound */ - double upper[2]; /* 2D upper bound in the XY plane */ - double heights[2]; /* The slope heights in Z along the X axis */ - int sampling_mask; /* Combination of enum sgs_surface_type */ -}; -#define SGS_GEOMETRY_SLOPE_ARGS_DEFAULT__ \ - {{0,0,0}, {1,1}, {0.5,1}, SGS_SURFACE_Z_SLOPE} -static const struct sgs_geometry_slope_args SGS_GEOMETRY_SLOPE_ARGS_DEFAULT = - SGS_GEOMETRY_SLOPE_ARGS_DEFAULT__; - -/* A "box" whose +Z face forms a step along the X axis - * o---o - * /' /| - * o---o.| . . . . . - * Z | ' | | ^ - * ^ Y o--|.o | | | - * |/ / | | | heights[1] - * o--> X . . . . o----o | | | - * ^ | ' ' | | | - * heights[0] | o....s.|.u upper | - * | |, , |/ | - * . . . . l----s---o . . . . . . - * lower step */ -struct sgs_geometry_step_args { - double lower[3]; /* 3D lower bound */ - double upper[2]; /* 2D upper bound in the XY plane */ - double heights[2]; /* The slope heights in Z along the X axis */ - double step; /* X coordinate of the step */ - int sampling_mask; /* Combination of enum sgs_surface_type */ -}; -#define SGS_GEOMETRY_STEP_ARGS_DEFAULT__ { \ - {0,0,0}, \ - {1,1}, \ - {0.5,1}, \ - 0.5, \ - SGS_SURFACE_Z_LVL0 | SGS_SURFACE_Z_LVL1 | SGS_SURFACE_Z_STEP \ -} -static const struct sgs_geometry_step_args SGS_GEOMETRY_STEP_ARGS_DEFAULT = - SGS_GEOMETRY_STEP_ARGS_DEFAULT__; - /* Position onto a geometry surface */ struct sgs_fragment { double normal[3]; /* Normalized */ @@ -140,25 +81,11 @@ static const struct sgs_hit SGS_HIT_NULL = SGS_HIT_NULL__; /* Helper macro */ #define SGS_HIT_NONE(Hit) ((Hit)->distance >= FLT_MAX) -/* Forward declaration */ +/* Forward declarations */ struct sgs; struct sgs_geometry; struct ssp_rng; -static INLINE const char* -sgs_geometry_type_to_cstr(const enum sgs_geometry_type type) -{ - const char* str = "unknown"; - switch(type) { - case SGS_GEOMETRY_BOX: str = "box"; break; - case SGS_GEOMETRY_SLOPE: str = "slope"; break; - case SGS_GEOMETRY_STEP: str = "step"; break; - case SGS_GEOMETRY_NONE: str = "none"; break; - default: FATAL("Unreachable code.\n"); break; - } - return str; -} - /******************************************************************************* * Geometry API ******************************************************************************/ @@ -168,18 +95,6 @@ sgs_geometry_box_create const struct sgs_geometry_box_args* args, struct sgs_geometry** geom); -extern LOCAL_SYM res_T -sgs_geometry_slope_create - (struct sgs* sgs, - const struct sgs_geometry_slope_args* args, - struct sgs_geometry** geom); - -extern LOCAL_SYM res_T -sgs_geometry_step_create - (struct sgs* sgs, - const struct sgs_geometry_step_args* args, - struct sgs_geometry** geom); - extern LOCAL_SYM void sgs_geometry_ref_get (struct sgs_geometry* geom); @@ -188,10 +103,6 @@ extern LOCAL_SYM void sgs_geometry_ref_put (struct sgs_geometry* geom); -extern LOCAL_SYM enum sgs_geometry_type -sgs_geometry_get_type - (const struct sgs_geometry* geom); - extern LOCAL_SYM void sgs_geometry_get_aabb (const struct sgs_geometry* geom, @@ -203,10 +114,6 @@ sgs_geometry_get_sampling_mask (const struct sgs_geometry* geom); extern LOCAL_SYM double -sgs_geometry_compute_volume - (const struct sgs_geometry* geom); - -extern LOCAL_SYM double sgs_geometry_compute_sampling_area (const struct sgs_geometry* geom); diff --git a/src/sgs_geometry_box.c b/src/sgs_geometry_box.c @@ -26,7 +26,7 @@ /******************************************************************************* * Helper functions ******************************************************************************/ -static int +static res_T check_box_args(struct sgs* sgs, const struct sgs_geometry_box_args* args) { ASSERT(args); @@ -37,9 +37,16 @@ check_box_args(struct sgs* sgs, const struct sgs_geometry_box_args* args) "Invalid box definition (lower: %g,%g,%g; upper: %g,%g,%g)\n", SPLIT3(args->lower), SPLIT3(args->upper)); - return 0; + return RES_BAD_ARG; } - return 1; + + if(args->pi < 0) { + sgs_log_err(sgs, + "Invalid box opening (pi = %g)\n", args->pi); + return RES_BAD_ARG; + } + + return RES_OK; } static res_T @@ -56,7 +63,7 @@ setup_box_mesh ASSERT(geom && args); /* Allocate memory space */ - res = darray_double_resize(&geom->verts, 8/*#vertices*/*3/*#coords per vertex*/); + 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, 12/*#triangles*/*3/*#ids per triangle*/); if(res != RES_OK) goto error; @@ -77,32 +84,38 @@ setup_box_mesh 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] = upp[2]; vtx[5*3+0] = upp[0]; vtx[5*3+1] = low[1]; vtx[5*3+2] = upp[2]; vtx[6*3+0] = low[0]; vtx[6*3+1] = upp[1]; vtx[6*3+2] = upp[2]; vtx[7*3+0] = upp[0]; vtx[7*3+1] = upp[1]; vtx[7*3+2] = upp[2]; + vtx[8*3 +0] = low[0]; vtx[8*3+1] = low[1]; vtx[8*3+2] = upp[2]+args->pi; + vtx[9*3 +0] = upp[0]; vtx[9*3+1] = low[1]; vtx[9*3+2] = upp[2]+args->pi; + vtx[10*3+0] = low[0]; vtx[10*3+1] = upp[1]; vtx[10*3+2] = upp[2]+args->pi; + vtx[11*3+0] = upp[0]; vtx[11*3+1] = upp[1]; vtx[11*3+2] = upp[2]+args->pi; + /* 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 */ - ids[4*3+0] = 0; ids[4*3+1] = 1; ids[4*3+2] = 5; /* -Y */ - ids[5*3+0] = 5; ids[5*3+1] = 4; ids[5*3+2] = 0; /* -Y */ - ids[6*3+0] = 2; ids[6*3+1] = 6; ids[6*3+2] = 7; /* +Y */ - ids[7*3+0] = 7; ids[7*3+1] = 3; ids[7*3+2] = 2; /* +Y */ - ids[8*3+0] = 0; ids[8*3+1] = 2; ids[8*3+2] = 1; /* -Z */ - ids[9*3+0] = 1; ids[9*3+1] = 2; ids[9*3+2] = 3; /* -Z */ - ids[10*3+0] = 4; ids[10*3+1] = 5; ids[10*3+2] = 6; /* +Z */ - ids[11*3+0] = 6; ids[11*3+1] = 5; ids[11*3+2] = 7; /* +Z */ + ids[0*3+0] = 0; ids[0*3+1] = 4; ids[0*3+2] = 2; /* min X */ + ids[1*3+0] = 2; ids[1*3+1] = 4; ids[1*3+2] = 6; /* min X */ + ids[2*3+0] = 3; ids[2*3+1] = 7; ids[2*3+2] = 5; /* max X */ + ids[3*3+0] = 5; ids[3*3+1] = 1; ids[3*3+2] = 3; /* max X */ + ids[4*3+0] = 0; ids[4*3+1] = 1; ids[4*3+2] = 5; /* min Y */ + ids[5*3+0] = 5; ids[5*3+1] = 4; ids[5*3+2] = 0; /* min Y */ + ids[6*3+0] = 2; ids[6*3+1] = 6; ids[6*3+2] = 7; /* max Y */ + ids[7*3+0] = 7; ids[7*3+1] = 3; ids[7*3+2] = 2; /* max Y */ + ids[8*3+0] = 0; ids[8*3+1] = 2; ids[8*3+2] = 1; /* min Z */ + ids[9*3+0] = 1; ids[9*3+1] = 2; ids[9*3+2] = 3; /* min Z */ + ids[10*3+0] = 8; ids[10*3+1] = 9; ids[10*3+2] = 10; /* max Z */ + ids[11*3+0] = 10; ids[11*3+1] = 9; ids[11*3+2] = 11; /* max Z */ /* 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_POS; - types[8] = types[9] = SGS_SURFACE_Z_NEG; - types[10] = types[11] = SGS_SURFACE_Z_POS; + types[0] = types[1] = SGS_SURFACE_X_MIN; + types[2] = types[3] = SGS_SURFACE_X_MAX; + types[4] = types[5] = SGS_SURFACE_Y_MIN; + types[6] = types[7] = SGS_SURFACE_Y_MAX; + types[8] = types[9] = SGS_SURFACE_Z_MIN; + types[10] = types[11] = SGS_SURFACE_Z_MAX; exit: return res; @@ -126,12 +139,9 @@ sgs_geometry_box_create res_T res = RES_OK; ASSERT(sgs && args && out_geom); - if(!check_box_args(sgs, args)) { - res = RES_BAD_ARG; - goto error; - } - - res = geometry_create(sgs, SGS_GEOMETRY_BOX, args->sampling_mask, &geom); + res = check_box_args(sgs, args); + if(res != RES_OK) goto error; + res = geometry_create(sgs, args->sampling_mask, &geom); if(res != RES_OK) goto error; res = setup_box_mesh(geom, args); if(res != RES_OK) goto error; diff --git a/src/sgs_geometry_c.h b/src/sgs_geometry_c.h @@ -42,7 +42,6 @@ struct sgs_geometry { double low[3], upp[3]; /* Axis aligned bounding box */ - enum sgs_geometry_type type; int sampling_mask; /* Combination of enum sgs_surface_type */ struct sgs* sgs; @@ -52,7 +51,6 @@ struct sgs_geometry { extern LOCAL_SYM res_T geometry_create (struct sgs* sgs, - const enum sgs_geometry_type type, const int sampling_mask, struct sgs_geometry** out_geom); diff --git a/src/sgs_geometry_slope.c b/src/sgs_geometry_slope.c @@ -1,159 +0,0 @@ -/* Copyright (C) 2021, 2022 Centre National de la Recherche Scientifique - * Copyright (C) 2021, 2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2021, 2022 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2021, 2022 Université Clermont Auvergne - * Copyright (C) 2021, 2022 Université de Lorraine - * Copyright (C) 2021, 2022 Université de Lyon - * Copyright (C) 2021, 2022 Université de Toulouse - * - * 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_slope_args(struct sgs* sgs, const struct sgs_geometry_slope_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]) { - sgs_log_err(sgs, - "Invalid slope definition (lower: %g,%g,%g; upper: %g,%g; heights: %g,%g)\n", - SPLIT3(args->lower), - SPLIT2(args->upper), - SPLIT2(args->heights)); - return 0; - } - return 1; -} - -static res_T -setup_slope_mesh - (struct sgs_geometry* geom, - const struct sgs_geometry_slope_args* args) -{ - const double* low = NULL; - const double* upp = NULL; - const double* heights = NULL; - 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, 8/*#vertices*/*3/*#coords per vertex*/); - if(res != RES_OK) goto error; - res = darray_size_t_resize(&geom->tris, 12/*#triangles*/*3/*#ids per triangle*/); - if(res != RES_OK) goto error; - res = darray_int_resize(&geom->tris_rt_type, 12/*#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_rt_type); - - /* Fetch input args */ - low = args->lower; - upp = args->upper; - heights = args->heights; - - /* 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]; - - /* 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 */ - ids[4*3+0] = 0; ids[4*3+1] = 1; ids[4*3+2] = 5; /* -Y */ - ids[5*3+0] = 5; ids[5*3+1] = 4; ids[5*3+2] = 0; /* -Y */ - ids[6*3+0] = 2; ids[6*3+1] = 6; ids[6*3+2] = 7; /* +Y */ - ids[7*3+0] = 7; ids[7*3+1] = 3; ids[7*3+2] = 2; /* +Y */ - ids[8*3+0] = 0; ids[8*3+1] = 2; ids[8*3+2] = 1; /* -Z */ - ids[9*3+0] = 1; ids[9*3+1] = 2; ids[9*3+2] = 3; /* -Z */ - ids[10*3+0] = 4; ids[10*3+1] = 5; ids[10*3+2] = 6; /* +Z */ - ids[11*3+0] = 6; ids[11*3+1] = 5; ids[11*3+2] = 7; /* +Z */ - - /* 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_POS; - types[8] = types[9] = SGS_SURFACE_Z_NEG; - types[10] = types[11] = SGS_SURFACE_Z_SLOPE; - -exit: - return res; -error: - darray_double_clear(&geom->verts); - darray_size_t_clear(&geom->tris); - darray_int_clear(&geom->tris_rt_type); - goto exit; -} - -/******************************************************************************* - * API function - ******************************************************************************/ -res_T -sgs_geometry_slope_create - (struct sgs* sgs, - const struct sgs_geometry_slope_args* args, - struct sgs_geometry** out_geom) -{ - struct sgs_geometry* geom = NULL; - res_T res = RES_OK; - ASSERT(sgs && args && out_geom); - - if(!check_slope_args(sgs, args)) { - res = RES_BAD_ARG; - goto error; - } - - res = geometry_create(sgs, SGS_GEOMETRY_SLOPE, args->sampling_mask, &geom); - if(res != RES_OK) goto error; - res = setup_slope_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; - - geometry_compute_aabb(geom); - -exit: - *out_geom = geom; - return res; -error: - if(geom) { - sgs_geometry_ref_put(geom); - geom = NULL; - } - goto exit; -} - diff --git a/src/sgs_geometry_step.c b/src/sgs_geometry_step.c @@ -1,207 +0,0 @@ -/* Copyright (C) 2021, 2022 Centre National de la Recherche Scientifique - * Copyright (C) 2021, 2022 Institut Mines Télécom Albi-Carmaux - * Copyright (C) 2021, 2022 |Méso|Star> (contact@meso-star.com) - * Copyright (C) 2021, 2022 Université Clermont Auvergne - * Copyright (C) 2021, 2022 Université de Lorraine - * Copyright (C) 2021, 2022 Université de Lyon - * Copyright (C) 2021, 2022 Université de Toulouse - * - * 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_rt_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_rt_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_rt_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; - - geometry_compute_aabb(geom); - -exit: - *out_geom = geom; - return res; -error: - if(geom) { - sgs_geometry_ref_put(geom); - geom = NULL; - } - goto exit; -} diff --git a/src/sgs_log.c b/src/sgs_log.c @@ -59,9 +59,7 @@ log_msg va_list vargs) { ASSERT(sgs && msg); - if(sgs->verbose) { - CHK(logger_vprint(&sgs->logger, stream, msg, vargs) == RES_OK); - } + CHK(logger_vprint(&sgs->logger, stream, msg, vargs) == RES_OK); } /*******************************************************************************