commit 3bc3487ebd717b1bddd90babeae5de74adc18b85
parent 1a8529bb096a8c9f3e833caadb2c6ebb77dbf7d6
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Sun, 18 Apr 2021 19:33:02 +0200
First draft of the sgs command
Diffstat:
| A | cmake/CMakeLists.txt | | | 86 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/sgs.c | | | 147 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/sgs.h | | | 62 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/sgs_args.c | | | 175 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/sgs_args.h | | | 72 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/sgs_c.h | | | 43 | +++++++++++++++++++++++++++++++++++++++++++ |
| A | src/sgs_geometry.c | | | 353 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/sgs_geometry.h | | | 146 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/sgs_log.c | | | 108 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/sgs_log.h | | | 62 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/sgs_main.c | | | 60 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
11 files changed, 1314 insertions(+), 0 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -0,0 +1,86 @@
+# 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/>.
+
+cmake_minimum_required(VERSION 3.1)
+project(atrstm C)
+enable_testing()
+
+set(SGS_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
+option(NO_TEST "Do not build tests" OFF)
+
+################################################################################
+# Check dependencies
+################################################################################
+find_package(RCMake 0.4 REQUIRED)
+find_package(RSys 0.12 REQUIRED)
+find_package(Star3D 0.7 REQUIRED)
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR})
+include(rcmake)
+include(rcmake_runtime)
+
+include_directories(
+ ${RSys_INCLUDE_DIR}
+ ${Star3D_INCLUDE_DIR})
+
+################################################################################
+# Configure and define targets
+################################################################################
+set(VERSION_MAJOR 0)
+set(VERSION_MINOR 0)
+set(VERSION_PATCH 0)
+set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
+
+set(SGS_FILES_SRC
+ sgs_args.c
+ sgs.c
+ sgs_geometry.c
+ sgs_log.c
+ sgs_main.c)
+
+set(SGS_FILES_INC
+ sgs_args.h
+ sgs_c.h
+ sgs_geometry.h
+ sgs.h
+ sgs_log.h)
+
+set(SGS_FILES_DOC COPYING README.md)
+
+# Prepend each file in the `SGS_FILES_<SRC|INC>' list by `SGS_SOURCE_DIR'
+rcmake_prepend_path(SGS_FILES_SRC ${SGS_SOURCE_DIR})
+rcmake_prepend_path(SGS_FILES_INC ${SGS_SOURCE_DIR})
+rcmake_prepend_path(SGS_FILES_DOC ${PROJECT_SOURCE_DIR}/../)
+
+add_executable(sgs ${SGS_FILES_SRC} ${SGS_FILES_INC})
+target_link_libraries(sgs RSys Star3D m)
+
+set_target_properties(sgs PROPERTIES
+ VERSION ${VERSION}
+ SOVERSION ${VERSION_MAJOR})
+
+################################################################################
+# Define output & install directories
+################################################################################
+install(TARGETS sgs
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+install(FILES ${SGS_FILES_DOC} DESTINATION share/doc/sgs)
+
diff --git a/src/sgs.c b/src/sgs.c
@@ -0,0 +1,147 @@
+/* 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.h"
+#include "sgs_args.h"
+#include "sgs_c.h"
+#include "sgs_log.h"
+
+#include <star/s3d.h>
+
+#include <rsys/cstr.h>
+#include <rsys/mem_allocator.h>
+
+/*******************************************************************************
+ * sgs API
+ ******************************************************************************/
+res_T
+sgs_create
+ (struct mem_allocator* mem_allocator,
+ const struct sgs_args* args,
+ struct sgs** out_sgs)
+{
+ struct sgs* sgs = NULL;
+ struct mem_allocator* allocator = NULL;
+ res_T res = RES_OK;
+ ASSERT(args && out_sgs);
+
+ allocator = mem_allocator ? mem_allocator : &mem_default_allocator;
+ sgs = MEM_CALLOC(allocator, 1, sizeof(struct sgs));
+ if(!sgs) {
+ fprintf(stderr, SGS_LOG_ERROR_PREFIX
+ "Could not allocate the sgs data structure.\n");
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ sgs->allocator = allocator;
+ sgs->nthreads = args->nthreads;
+ sgs->verbose = args->verbose;
+ sgs->dump_geometry = args->dump_geometry;
+
+ setup_logger(sgs);
+
+ res = s3d_device_create(&sgs->logger, sgs->allocator, 0, &sgs->s3d);
+ if(res != RES_OK) {
+ sgs_log_err(sgs, "Error creating the Star-3D device -- %s.\n",
+ res_to_cstr(res));
+ 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:
+ sgs_log_warn(sgs, "Slope geometry is not supported yet.\n");
+ res = RES_BAD_OP;
+ goto error;
+ break;
+ case SGS_GEOMETRY_STEP:
+ sgs_log_warn(sgs, "Step geometry is not supported yet.\n");
+ res = RES_BAD_OP;
+ goto error;
+ break;
+ default: FATAL(SGS_LOG_ERROR_PREFIX"Unreachable code.\n"); break;
+ }
+
+exit:
+ *out_sgs = sgs;
+ return res;
+error:
+ if(sgs) {
+ sgs_release(sgs);
+ sgs = NULL;
+ }
+ goto exit;
+}
+
+void
+sgs_release(struct sgs* sgs)
+{
+ ASSERT(sgs);
+
+ if(sgs->s3d) S3D(device_ref_put(sgs->s3d));
+ if(sgs->geom) sgs_geometry_ref_put(sgs->geom);
+ logger_release(&sgs->logger);
+ MEM_RM(sgs->allocator, sgs);
+}
+
+struct mem_allocator*
+sgs_get_allocator(struct sgs* sgs)
+{
+ ASSERT(sgs);
+ return sgs->allocator;
+}
+
+void
+sgs_fprint_copyright(FILE* stream)
+{
+ ASSERT(stream);
+ fprintf(stream,
+"Copyright (C) 2021 CNRS/RAPSODEE, CNRS/LMAP, |Meso|Star>, UPS/Laplace.\n");
+}
+
+void
+sgs_fprint_license(FILE* stream)
+{
+ ASSERT(stream);
+ fprintf(stream,
+"Star Geometric Sensitivity is free software released under the GNU GPL\n"
+"license, version 3 or later. You are free to change or redistribute it\n"
+"under certain conditions <http://gnu.org/licenses/gpl.html>.\n");
+}
+
+res_T
+sgs_run(struct sgs* sgs)
+{
+ res_T res = RES_OK;
+ ASSERT(sgs);
+
+ if(sgs->dump_geometry) {
+ res = sgs_geometry_dump_vtk(sgs->geom, stdout);
+ if(res != RES_OK) goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
diff --git a/src/sgs.h b/src/sgs.h
@@ -0,0 +1,62 @@
+/* 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/>. */
+
+#ifndef SGS_H
+#define SGS_H
+
+#include <rsys/rsys.h>
+
+/* Forward declarations */
+struct mem_allocator;
+struct sgs;
+struct sgs_args;
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+extern LOCAL_SYM void
+sgs_fprint_copyright
+ (FILE* stream);
+
+extern LOCAL_SYM void
+sgs_fprint_license
+ (FILE* stream);
+
+/*******************************************************************************
+ * sgs API
+ ******************************************************************************/
+extern LOCAL_SYM res_T
+sgs_create
+ (struct mem_allocator* allocator, /* NULL <=> Use default allocator */
+ const struct sgs_args* args,
+ struct sgs** sgs);
+
+extern LOCAL_SYM void
+sgs_release
+ (struct sgs* sgs);
+
+extern LOCAL_SYM res_T
+sgs_run
+ (struct sgs* sgs);
+
+extern LOCAL_SYM struct mem_allocator*
+sgs_get_allocator
+ (struct sgs* sgs);
+
+#endif /* SGS_H */
diff --git a/src/sgs_args.c b/src/sgs_args.c
@@ -0,0 +1,175 @@
+/* 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/>. */
+
+#define _POSIX_C_SOURCE 200112L /* strtok_r support */
+
+#include "sgs.h"
+#include "sgs_args.h"
+#include "sgs_log.h"
+
+#include <rsys/cstr.h>
+
+#include <getopt.h>
+#include <string.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+print_help(void)
+{
+ printf("Usage: sgs [<options>]\n");
+ printf("Test geometric sensitivities on predefined 3D scenes.\n");
+ printf("\n");
+
+ printf(
+" -b <box-parameters:...>\n"
+" define an axis aligned bounding box. Available box\n"
+" parameters are:\n");
+ printf(
+" low=x,y,z\n"
+" defines the lower bound of the box\n"
+" (default: %g,%g,%g).\n",
+ SGS_GEOMETRY_BOX_ARGS_DEFAULT.lower[0],
+ SGS_GEOMETRY_BOX_ARGS_DEFAULT.lower[1],
+ SGS_GEOMETRY_BOX_ARGS_DEFAULT.lower[2]);
+ printf(
+" upp=x,y,z\n"
+" defines the upper bound of the box\n"
+" (default: %g,%g,%g).\n",
+ SGS_GEOMETRY_BOX_ARGS_DEFAULT.upper[0],
+ SGS_GEOMETRY_BOX_ARGS_DEFAULT.upper[1],
+ SGS_GEOMETRY_BOX_ARGS_DEFAULT.upper[2]);
+ printf(
+" -d dump geometry following the VTK file format.\n");
+ printf(
+" -h display this help and exit.\n");
+ 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");
+ printf("\n");
+
+ sgs_fprint_copyright(stdout);
+ sgs_fprint_license(stdout);
+}
+
+static res_T
+parse_box_parameters(const char* str, void* ptr)
+{
+ char buf[128];
+ struct sgs_args_geometry* geom = 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 box 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);
+
+ geom->type = SGS_GEOMETRY_BOX;
+
+ if(!strcmp(key, "low")) {
+ res = cstr_to_list_double(val, ',', geom->args.box.lower, &len, 3);
+ if(res == RES_OK && len != 3) res = RES_BAD_ARG;
+ } else if(!strcmp(key, "upp")) {
+ res = cstr_to_list_double(val, ',', geom->args.box.upper, &len, 3);
+ if(res == RES_OK && len != 3) res = RES_BAD_ARG;
+ } else {
+ fprintf(stderr, SGS_LOG_ERROR_PREFIX
+ "Invalid box 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' box parameter: %s -- %s.\n",
+ key, val, res_to_cstr(res));
+ goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+/*******************************************************************************
+ * sgs_args API
+ ******************************************************************************/
+res_T
+sgs_args_init(struct sgs_args* args, int argc, char** argv)
+{
+ int opt;
+ res_T res = RES_OK;
+ ASSERT(args && argc && argv);
+
+ *args = SGS_ARGS_DEFAULT;
+
+ while((opt = getopt(argc, argv, "b:dht:v")) != -1) {
+ switch(opt) {
+ case 'b':
+ res = cstr_parse_list(optarg, ':', parse_box_parameters, &args->geom);
+ break;
+ case 'd': args->dump_geometry = 1; break;
+ case 'h':
+ print_help();
+ sgs_args_release(args);
+ args->quit = 1;
+ 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) {
+ if(optarg) {
+ fprintf(stderr, SGS_LOG_ERROR_PREFIX
+ "%s: invalid option argument '%s' -- '%c'\n",
+ argv[0], optarg, opt);
+ }
+ goto error;
+ }
+ }
+exit:
+ return res;
+error:
+ sgs_args_release(args);
+ goto exit;
+}
+
+void
+sgs_args_release(struct sgs_args* args)
+{
+ ASSERT(args);
+ *args = SGS_ARGS_DEFAULT;
+}
diff --git a/src/sgs_args.h b/src/sgs_args.h
@@ -0,0 +1,72 @@
+/* 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/>. */
+
+#ifndef SGS_ARGS_H
+#define SGS_ARGS_H
+
+#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 */
+
+ /* 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 */ \
+ \
+ UINT_MAX, /* #threads */ \
+ 0, /* Dump geometry */ \
+ 0, /* Verbose flag */ \
+ 0 /* Stop the command */ \
+}
+static const struct sgs_args SGS_ARGS_DEFAULT = SGS_ARGS_DEFAULT__;
+
+extern LOCAL_SYM res_T
+sgs_args_init
+ (struct sgs_args* args,
+ int argc,
+ char** argv);
+
+extern LOCAL_SYM void
+sgs_args_release
+ (struct sgs_args* args);
+
+#endif /* SGS_ARGS_H */
diff --git a/src/sgs_c.h b/src/sgs_c.h
@@ -0,0 +1,43 @@
+/* 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/>. */
+
+#ifndef SGS_C_H
+#define SGS_C_H
+
+#include <rsys/logger.h>
+#include <rsys/rsys.h>
+
+struct sgs {
+ struct s3d_device* s3d;
+ struct sgs_geometry* geom;
+
+ unsigned int nthreads; /* #threads */
+
+ int verbose;
+ int dump_geometry;
+
+ struct logger logger;
+ struct mem_allocator* allocator;
+};
+
+extern LOCAL_SYM void
+setup_logger
+ (struct sgs* sgs);
+
+#endif /* SGS_C_H */
diff --git a/src/sgs_geometry.c b/src/sgs_geometry.c
@@ -0,0 +1,353 @@
+/* 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.h"
+#include "sgs_c.h"
+#include "sgs_geometry.h"
+#include "sgs_log.h"
+
+#include <star/s3d.h>
+
+#include <rsys/dynamic_array_double.h>
+#include <rsys/dynamic_array_int.h>
+#include <rsys/dynamic_array_size_t.h>
+#include <rsys/ref_count.h>
+
+struct sgs_geometry {
+ struct darray_double verts;
+ struct darray_size_t tris;
+ struct darray_int tris_type; /* List of enum sgs_surface_type */
+
+ struct s3d_scene_view* view_sp;
+ struct s3d_scene_view* view_rt;
+
+ enum sgs_geometry_type type;
+
+ struct sgs* sgs;
+ ref_T ref;
+};
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static res_T
+geometry_create
+ (struct sgs* sgs,
+ struct sgs_geometry** out_geom)
+{
+ struct sgs_geometry* geom = NULL;
+ struct mem_allocator* allocator = NULL;
+ res_T res = RES_OK;
+ ASSERT(sgs && out_geom);
+
+ allocator = sgs_get_allocator(sgs);
+ geom = MEM_CALLOC(allocator, 1, sizeof(struct sgs_geometry));
+ if(!geom) {
+ sgs_log_err(sgs, "Could not allocate the geometry.\n");
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&geom->ref);
+ geom->sgs = sgs;
+ darray_double_init(allocator, &geom->verts);
+ darray_size_t_init(allocator, &geom->tris);
+ darray_int_init(allocator, &geom->tris_type);
+ geom->type = SGS_GEOMETRY_NONE;
+
+exit:
+ *out_geom = geom;
+ return res;
+error:
+ if(geom) {
+ sgs_geometry_ref_put(geom);
+ geom = NULL;
+ }
+ goto exit;
+}
+
+/* Return the number of vertices */
+static FINLINE size_t
+geometry_get_nvertices(const struct sgs_geometry* geom)
+{
+ ASSERT(geom);
+ return darray_double_size_get(&geom->verts) / 3/*#coords per vertex*/;
+}
+
+/* Return the number of triangles */
+static FINLINE size_t
+geometry_get_ntriangles(const struct sgs_geometry* geom)
+{
+ ASSERT(geom);
+ return darray_size_t_size_get(&geom->tris) / 3/*#ids per triangles*/;
+}
+
+static void
+geometry_get_vertex(const unsigned ivert, float pos[3], void* ctx)
+{
+ struct sgs_geometry* geom = ctx;
+ ASSERT(pos && ctx && ivert < geometry_get_nvertices(geom));
+ pos[0] = (float)darray_double_cdata_get(&geom->verts)[ivert*3+0];
+ pos[1] = (float)darray_double_cdata_get(&geom->verts)[ivert*3+1];
+ pos[2] = (float)darray_double_cdata_get(&geom->verts)[ivert*3+2];
+}
+static void
+geometry_get_triangle(const unsigned itri, unsigned ids[3], void* ctx)
+{
+ struct sgs_geometry* geom = ctx;
+ ASSERT(ids && ctx && itri < geometry_get_ntriangles(geom));
+ ids[0] = (unsigned)darray_size_t_cdata_get(&geom->tris)[itri*3+0];
+ ids[1] = (unsigned)darray_size_t_cdata_get(&geom->tris)[itri*3+1];
+ ids[2] = (unsigned)darray_size_t_cdata_get(&geom->tris)[itri*3+2];
+}
+
+static res_T
+setup_view_rt(struct sgs_geometry* geom)
+{
+ struct s3d_vertex_data vdata = S3D_VERTEX_DATA_NULL;
+ struct s3d_shape* shape = NULL;
+ struct s3d_scene* scene = NULL;
+ unsigned ntris = 0;
+ unsigned nverts = 0;
+ res_T res = RES_OK;
+ ASSERT(geom);
+
+ nverts = (unsigned)geometry_get_nvertices(geom);
+ ntris = (unsigned)geometry_get_ntriangles(geom);
+
+ /* Setup the Star-3D vertex data */
+ vdata.usage = S3D_POSITION;
+ vdata.type = S3D_FLOAT3;
+ vdata.get = geometry_get_vertex;
+
+ /* Setup the Star-3D ray-tracing scene */
+ res = s3d_shape_create_mesh(geom->sgs->s3d, &shape);
+ if(res != RES_OK) goto error;
+ res = s3d_mesh_setup_indexed_vertices
+ (shape, ntris, geometry_get_triangle, nverts, &vdata, 1, geom);
+ if(res != RES_OK) goto error;
+ res = s3d_scene_create(geom->sgs->s3d, &scene);
+ if(res != RES_OK) goto error;
+ res = s3d_scene_attach_shape(scene, shape);
+ if(res != RES_OK) goto error;
+
+ /* Create the scene view */
+ res = s3d_scene_view_create(scene, S3D_TRACE, &geom->view_rt);
+ if(res != RES_OK) goto error;
+
+exit:
+ if(shape) S3D(shape_ref_put(shape));
+ if(scene) S3D(scene_ref_put(scene));
+ return res;
+error:
+ goto exit;
+}
+
+
+static res_T
+setup_box_mesh
+ (struct sgs_geometry* geom,
+ const struct sgs_geometry_box_args* args)
+{
+ const double* low = NULL;
+ const double* upp = 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_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_type);
+
+ /* Fetch input args */
+ low = args->lower;
+ upp = args->upper;
+
+ /* 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] = 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];
+
+ /* 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_POS;
+
+exit:
+ return res;
+error:
+ darray_double_clear(&geom->verts);
+ darray_size_t_clear(&geom->tris);
+ darray_int_clear(&geom->tris_type);
+ goto exit;
+}
+
+static void
+release_geometry(ref_T* ref)
+{
+ struct sgs_geometry* geom = CONTAINER_OF(ref, struct sgs_geometry, ref);
+ struct sgs* sgs = NULL;
+ ASSERT(ref);
+
+ if(geom->view_sp) S3D(scene_view_ref_put(geom->view_sp));
+ if(geom->view_rt) S3D(scene_view_ref_put(geom->view_rt));
+ darray_double_release(&geom->verts);
+ darray_size_t_release(&geom->tris);
+ darray_int_release(&geom->tris_type);
+
+ sgs = geom->sgs;
+ MEM_RM(sgs_get_allocator(sgs), geom);
+}
+
+/*******************************************************************************
+ * API functions
+ ******************************************************************************/
+res_T
+sgs_geometry_box_create
+ (struct sgs* sgs,
+ const struct sgs_geometry_box_args* args,
+ struct sgs_geometry** out_geom)
+{
+ struct sgs_geometry* geom = NULL;
+ res_T res = RES_OK;
+ ASSERT(sgs && args && out_geom);
+
+ res = geometry_create(sgs, &geom);
+ if(res != RES_OK) goto error;
+ res = setup_box_mesh(geom, args);
+ if(res != RES_OK) goto error;
+ res = setup_view_rt(geom);
+ if(res != RES_OK) goto error;
+
+exit:
+ *out_geom = geom;
+ return res;
+error:
+ if(geom) {
+ sgs_geometry_ref_put(geom);
+ geom = NULL;
+ }
+ goto exit;
+}
+
+void
+sgs_geometry_ref_get(struct sgs_geometry* geom)
+{
+ ASSERT(geom);
+ ref_get(&geom->ref);
+}
+
+void
+sgs_geometry_ref_put(struct sgs_geometry* geom)
+{
+ ASSERT(geom);
+ ref_put(&geom->ref, release_geometry);
+}
+
+res_T
+sgs_geometry_dump_vtk(const struct sgs_geometry* geom, FILE* stream)
+{
+ size_t i = 0;
+ size_t nverts = 0;
+ size_t ntris = 0;
+ res_T res = RES_OK;
+ int err = 0;
+ ASSERT(geom);
+
+ nverts = geometry_get_nvertices(geom);
+ ntris = geometry_get_ntriangles(geom);
+
+ #define FPRINTF(Fmt, Args) { \
+ err = fprintf(stream, Fmt COMMA_##Args LIST_##Args); \
+ if(err < 0) { \
+ sgs_log_err(geom->sgs, "Error writing data.\n"); \
+ res = RES_IO_ERR; \
+ goto error; \
+ } \
+ } (void)0
+
+ /* Write header */
+ FPRINTF("# vtk DataFile Version 2.0\n", ARG0());
+ FPRINTF("Geometry\n", ARG0());
+ FPRINTF("ASCII\n", ARG0());
+ FPRINTF("DATASET POLYDATA\n", ARG0());
+
+ /* Write the vertices */
+ FPRINTF("POINTS %lu float\n", ARG1((unsigned long)nverts));
+ FOR_EACH(i, 0, nverts) {
+ const double* pos = darray_double_cdata_get(&geom->verts) + i*3;
+ FPRINTF("%g %g %g\n", ARG3(pos[0], pos[1], pos[2]));
+ }
+
+ /* Write the triangles */
+ FPRINTF("POLYGONS %lu %lu\n",
+ ARG2((unsigned long)ntris, (unsigned long)ntris*4));
+ FOR_EACH(i, 0, ntris) {
+ const size_t* ids = darray_size_t_cdata_get(&geom->tris) + i*3;
+ FPRINTF("3 %lu %lu %lu\n", ARG3(ids[0], ids[1], ids[2]));
+ }
+
+ /* Write the triangle type */
+ FPRINTF("CELL_DATA %lu\n", ARG1((unsigned long)ntris));
+ FPRINTF("SCALARS Triangle_Type integer 1\n", ARG0());
+ FPRINTF("LOOKUP_TABLE default\n", ARG0());
+ FOR_EACH(i, 0, ntris) {
+ const enum sgs_surface_type type = darray_int_cdata_get(&geom->tris_type)[i];
+ FPRINTF("%i\n", ARG1(type));
+ }
+
+ #undef FPRINTF
+
+exit:
+ return res;
+error:
+ goto exit;
+}
diff --git a/src/sgs_geometry.h b/src/sgs_geometry.h
@@ -0,0 +1,146 @@
+/* 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/>. */
+
+#ifndef SGS_GEOMETRY_H
+#define SGS_GEOMETRY_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, /* -X face */
+ SGS_SURFACE_X_POS, /* +X face */
+ SGS_SURFACE_Y_NEG, /* -Y face */
+ SGS_SURFACE_Y_POS, /* +Y face */
+ SGS_SURFACE_Z_NEG, /* -Z face */
+ SGS_SURFACE_Z_POS, /* +Z face */
+ SGS_SURFACE_Z_SLOPE, /* +Z face representing a slope */
+ SGS_SURFACE_Z_LVL0, /* +Z face representing the 1st level along X */
+ SGS_SURFACE_Z_LVL1, /* +Z face representing the 2nd level along X */
+ SGS_SURFACE_Z_STEP /* +Z face representing the step between the 2 levels */
+};
+
+/* A simple axis aligned bounding box
+ * Z 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 */
+};
+#define SGS_GEOMETRY_BOX_ARGS_DEFAULT__ {{0,0,0}, {1,1,1}}
+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',' | | |
+ * |/ /,' | | elevation[1]
+ * o--> X . . . . o'' | | |
+ * ^ | ' | | |
+ * elevation[0] | o......|.u upper |
+ * | |. |/ |
+ * . . . . l--------o . . . . . .
+ * lower */
+struct sgs_geometry_slope_args {
+ double lower[2]; /* 2D lower bound in the XY plane */
+ double upper[2]; /* 2D upper bound in the XY plane */
+ double elevation[2]; /* The slope elevations in Z along the X axis */
+};
+#define SGS_GEOMETRY_SLOPE_ARGS_DEFAULT__ {{0,0}, {1,1}, {0.5,1}}
+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 | | |
+ * |/ / | | | elevation[1]
+ * o--> X . . . . o----o | | |
+ * ^ | ' ' | | |
+ * elevation[0] | o....s.|.u upper |
+ * | |, , |/ |
+ * . . . . l----s---o . . . . . .
+ * lower step */
+struct sgs_geometry_step_args {
+ double lower[2]; /* 2D lower bound in the XY plane */
+ double upper[2]; /* 2D upper bound in the XY plane */
+ double elevation[2]; /* The slope elevations in Z along the X axis */
+ double step; /* X coordinate of the step */
+};
+#define SGS_GEOMETRY_STEP_ARGS_DEFAULT__ {{0,0}, {1,1}, {0.5,1}, 0.5}
+static const struct sgs_geometry_step_args SGS_GEOMETRY_STEP_ARGS_DEFAULT =
+ SGS_GEOMETRY_STEP_ARGS_DEFAULT__;
+
+/* Forward declaration */
+struct sgs;
+struct sgs_geometry;
+
+/*******************************************************************************
+ * Geometry API
+ ******************************************************************************/
+extern LOCAL_SYM res_T
+sgs_geometry_box_create
+ (struct sgs* sgs,
+ 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);
+
+extern LOCAL_SYM void
+sgs_geometry_ref_put
+ (struct sgs_geometry* geom);
+
+extern LOCAL_SYM res_T
+sgs_geometry_dump_vtk
+ (const struct sgs_geometry* geom,
+ FILE* stream);
+
+#endif /* SGS_GEOMETRY_H */
diff --git a/src/sgs_log.c b/src/sgs_log.c
@@ -0,0 +1,108 @@
+/* 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_c.h"
+#include "sgs_log.h"
+
+#include <rsys/logger.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+print_out(const char* msg, void* ctx)
+{
+ ASSERT(msg);
+ (void)ctx;
+ fprintf(stderr, SGS_LOG_INFO_PREFIX"%s", msg);
+}
+
+static void
+print_err(const char* msg, void* ctx)
+{
+ ASSERT(msg);
+ (void)ctx;
+ fprintf(stderr, SGS_LOG_ERROR_PREFIX"%s", msg);
+}
+
+static void
+print_warn(const char* msg, void* ctx)
+{
+ ASSERT(msg);
+ (void)ctx;
+ fprintf(stderr, SGS_LOG_WARNING_PREFIX"%s", msg);
+}
+
+static void
+log_msg
+ (struct sgs* sgs,
+ const enum log_type stream,
+ const char* msg,
+ va_list vargs)
+{
+ ASSERT(sgs && msg);
+ if(sgs->verbose) {
+ CHK(logger_vprint(&sgs->logger, stream, msg, vargs) == RES_OK);
+ }
+}
+
+/*******************************************************************************
+ * sgs log API
+ ******************************************************************************/
+void
+sgs_log(struct sgs* sgs, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(sgs && msg);
+ va_start(vargs_list, msg);
+ log_msg(sgs, LOG_OUTPUT, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+void
+sgs_log_err(struct sgs* sgs, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(sgs && msg);
+ va_start(vargs_list, msg);
+ log_msg(sgs, LOG_ERROR, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+void
+sgs_log_warn(struct sgs* sgs, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(sgs && msg);
+ va_start(vargs_list, msg);
+ log_msg(sgs, LOG_WARNING, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+/*******************************************************************************
+ * Local function
+ ******************************************************************************/
+void
+setup_logger(struct sgs* sgs)
+{
+ logger_init(sgs->allocator, &sgs->logger);
+ logger_set_stream(&sgs->logger, LOG_OUTPUT, print_out, NULL);
+ logger_set_stream(&sgs->logger, LOG_ERROR, print_err, NULL);
+ logger_set_stream(&sgs->logger, LOG_WARNING, print_warn, NULL);
+}
diff --git a/src/sgs_log.h b/src/sgs_log.h
@@ -0,0 +1,62 @@
+/* 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/>. */
+
+#ifndef SGS_LOG_H
+#define SGS_LOG_H
+
+#include <rsys/rsys.h>
+
+#define SGS_LOG_INFO_PREFIX "\x1b[1m\x1b[32m>\x1b[0m "
+#define SGS_LOG_ERROR_PREFIX "\x1b[31merror:\x1b[0m "
+#define SGS_LOG_WARNING_PREFIX "\x1b[33mwarning:\x1b[0m "
+
+/* Forward declaration */
+struct sgs;
+
+extern LOCAL_SYM void
+sgs_log
+ (struct sgs* sgs,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+ ;
+
+extern LOCAL_SYM void
+sgs_log_err
+ (struct sgs* sgs,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+ ;
+
+extern LOCAL_SYM void
+sgs_log_warn
+ (struct sgs* sgs,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+ ;
+
+#endif /* SGS_LOG_H */
diff --git a/src/sgs_main.c b/src/sgs_main.c
@@ -0,0 +1,60 @@
+/* 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.h"
+#include "sgs_args.h"
+#include "sgs_log.h"
+
+#include <rsys/mem_allocator.h>
+
+int
+main(int argc, char** argv)
+{
+ struct sgs_args args = SGS_ARGS_DEFAULT;
+ struct sgs* sgs = NULL;
+ size_t memsz = 0;
+ int err = 0;
+ res_T res = RES_OK;
+
+ res = sgs_args_init(&args, argc, argv);
+ if(res != RES_OK) goto error;
+ if(args.quit) goto exit;
+
+ res = sgs_create(NULL, &args, &sgs);
+ if(res != RES_OK) goto error;
+
+ res = sgs_run(sgs);
+ if(res != RES_OK) goto error;
+
+exit:
+ sgs_args_release(&args);
+ if(sgs) sgs_release(sgs);
+
+ /* Check memory leaks */
+ memsz = mem_allocated_size();
+ if(memsz) {
+ fprintf(stderr, SGS_LOG_WARNING_PREFIX"Memory leaks: %lu Bytes\n",
+ (unsigned long)memsz);
+ err = -1;
+ }
+ return err;
+error:
+ err = -1;
+ goto exit;
+}