star-meshtool

Mesh transformation
git clone git://git.meso-star.fr/star-meshtool.git
Log | Files | Refs | README | LICENSE

mtool_args.c (4833B)


      1 /* Copyright (C) 2025 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #define _POSIX_C_SOURCE 200112L /* getopt support */
     17 
     18 #include "mtool_args.h"
     19 #include "mtool_version.h"
     20 
     21 #include <rsys/cstr.h>
     22 #include <rsys/double3.h>
     23 
     24 #include <unistd.h> /* getopt */
     25 
     26 /*******************************************************************************
     27  * Helper functions
     28  ******************************************************************************/
     29 static INLINE void
     30 usage(FILE* stream)
     31 {
     32   fprintf(stream,
     33 "usage: mesh-tool [-abdhrv] [-i input] [-o output] [-S sx,sy,sz] [-T tx,ty,tz]\n"
     34 "                 [-V verbosity]\n");
     35 }
     36 
     37 static INLINE void
     38 version(FILE* stream)
     39 {
     40   fprintf(stream,
     41     "mesh-tool version %i.%i.%i\n",
     42     MTOOL_VERSION_MAJOR,
     43     MTOOL_VERSION_MINOR,
     44     MTOOL_VERSION_PATCH);
     45 }
     46 
     47 static res_T
     48 apply_scale(struct mtool_args* args, const char* str)
     49 {
     50   double scale[3] = {0,0,0};
     51   size_t len = 0;
     52   res_T res = RES_OK;
     53 
     54   ASSERT(args && str);
     55 
     56   res = cstr_to_list_double(str, ',', scale, &len, 3);
     57   if(res == RES_OK && len != 3) res = RES_BAD_ARG;
     58   if(res != RES_OK) goto error;
     59 
     60   /*      | Sx  0  0  0 |   | A, D G J |    | A*Sx D*Sx G*Sx J*Sx |
     61    *  M = |  0 Sy  0  0 | * | B, E H K |  = | B*Sy E*Sy H*Sy K*Sy |
     62    *      |  0  0 Sz  0 |   | C, F I L |    | C*Sz F*Sz I*Sz L*Sz |
     63    *      |  0  0  0  1 |   | 0, 0 0 1 |    |    0    0    0    1 | */
     64   d3_mul(args->transform+0, args->transform+0, scale);
     65   d3_mul(args->transform+3, args->transform+3, scale);
     66   d3_mul(args->transform+6, args->transform+6, scale);
     67   d3_mul(args->transform+9, args->transform+9, scale);
     68 
     69 exit:
     70   return res;
     71 error:
     72   goto exit;
     73 }
     74 
     75 static res_T
     76 apply_translation(struct mtool_args* args, const char* str)
     77 {
     78   double translation[3] = {0,0,0};
     79   size_t len = 0;
     80   res_T res = RES_OK;
     81 
     82   ASSERT(args && str);
     83 
     84   res = cstr_to_list_double(str, ',', translation, &len, 3);
     85   if(res == RES_OK && len != 3) res = RES_BAD_ARG;
     86   if(res != RES_OK) goto error;
     87 
     88   /*      | 1 0 0 Tx |   | A D G J |   | A  D  G (Tx + J) |
     89    *  M = | 0 1 0 Ty | * | B E H K | = | B  E  H (Ty + K) |
     90    *      | 0 0 1 Tz |   | C F I L |   | C  F  I (Tz + L) |
     91    *      | 0 0 0  1 |   | 0 0 0 1 |   | 0  0  0        1 | */
     92   d3_add(args->transform+9, args->transform+9, translation);
     93 
     94 exit:
     95   return res;
     96 error:
     97   goto exit;
     98 }
     99 
    100 static res_T
    101 parse_verbosity(struct mtool_args* args, const char* str)
    102 {
    103   unsigned verbosity = 0;
    104   res_T res = RES_OK;
    105 
    106   ASSERT(args && str);
    107 
    108   res = cstr_to_uint(str, &verbosity);
    109   if(res == RES_OK && verbosity > 3) res = RES_BAD_ARG;
    110   if(res != RES_OK) goto error;
    111 
    112   args->verbose = (int)verbosity;
    113 
    114 exit:
    115   return res;
    116 error:
    117   goto exit;
    118 }
    119 
    120 /*******************************************************************************
    121  * Local functions
    122  ******************************************************************************/
    123 res_T
    124 mtool_args_init
    125   (struct mtool_args* args,
    126    int argc,
    127    char** argv)
    128 {
    129   const char option_list[] = "abdhi:o:rS:T:vV:";
    130   int opt = 0;
    131   res_T res = RES_OK;
    132 
    133   ASSERT(args && argc && argv);
    134 
    135   *args = MTOOL_ARGS_DEFAULT;
    136 
    137   while((opt = getopt(argc, argv, option_list)) != -1) {
    138     switch (opt) {
    139       case 'a': args->type = SSTL_ASCII; break;
    140       case 'b': args->type = SSTL_BINARY; break;
    141       case 'd': args->print_desc = 1; break;
    142       case 'h':
    143         usage(stdout);
    144         args->quit = 1;
    145         goto exit;
    146       case 'i': args->input = optarg; break;
    147       case 'o': args->output = optarg; break;
    148       case 'r': args->reverse_normals = 1; break;
    149       case 'S': res = apply_scale(args, optarg); break;
    150       case 'T': res = apply_translation(args, optarg); break;
    151       case 'v':
    152         version(stdout);
    153         args->quit = 1;
    154         goto exit;
    155       case 'V': res = parse_verbosity(args, optarg); break;
    156       default: res = RES_BAD_ARG; break;
    157     }
    158     if(res != RES_OK) {
    159       if(optarg) {
    160         fprintf(stderr, "mesh-tool: invalid option argument '%s' -- '%c'\n",
    161           optarg, opt);
    162       }
    163       goto error;
    164     }
    165   }
    166 
    167 exit:
    168   return res;
    169 error:
    170   mtool_args_release(args);
    171   usage(stderr);
    172   goto exit;
    173 }
    174 
    175 void
    176 mtool_args_release(struct mtool_args* args)
    177 {
    178   ASSERT(args);
    179   *args = MTOOL_ARGS_DEFAULT;
    180 }