1 /***************************************************************************
2                           coarsen2.c  -  description
3                              -------------------
4     begin                : Fri Jun 18 2004
5     copyright            : (C) 2004 by jakub
6     email                : jakub@hurin
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "SUMA_suma.h"
19 #include "SUMA_GeomComp.h"
20 #include "SUMA_gts.h"
21 
22 #define SURFPATCH_MAX_SURF 1  /*!< Maximum number of input surfaces */
23 
usage_SUMA_coarsen(SUMA_GENERIC_ARGV_PARSE * ps)24 void usage_SUMA_coarsen (SUMA_GENERIC_ARGV_PARSE *ps)
25 {
26    static char FuncName[]={"usage_SUMA_coarsen"};
27    char * s = NULL, *sio=NULL;
28    s = SUMA_help_basics();
29    sio = SUMA_help_IO_Args (ps);
30    printf ( "\nUsage:\n"
31             "  SurfMesh <-i_TYPE SURFACE> <-o_TYPE OUTPUT> <-edges FRAC> \n"
32             "           [-sv SURF_VOL]\n"
33             " \n"
34             "  Example:\n"
35             "  SurfMesh -i_ply surf1.ply -o_ply surf1_half -edges 0.5\n"
36             "\n"
37             "  Mandatory parameters:\n"
38             "     -i_TYPE SURFACE: Input surface. See below for details. \n"
39             "              You can also use the -t* method or\n"
40             "              the -spec SPECFILE -surf SURFACE method.\n"
41             "     -o_TYPE OUTPUT: Output surface, see below.\n"
42             "     -edges FRAC: surface will be simplified to number of\n"
43             "              edges times FRAC (fraction). Default is .5\n"
44             "              refines surface if edges > 1\n"
45             "\n"
46             "%s"
47             "\n"
48             "%s"
49             "\n",sio,s); SUMA_free(sio); sio = NULL;SUMA_free(s); s = NULL;
50    s = SUMA_New_Additions(0, 1); printf("%s\n", s);SUMA_free(s); s = NULL;
51    printf(  " Originally written by Jakub Otwinowski.\n"
52             " Now maintained by Ziad S. Saad SSCC/NIMH/NIH saadz@mail.nih.gov     \n");
53    printf(  " This program uses the GTS library gts.sf.net\n"
54             " for fun read \"Fast and memory efficient polygonal simplification\" (1998) \n"
55             " and \"Evaluation of memoryless simplification\" (1999) by Lindstrom and Turk.\n");
56    exit (0);
57 }
58 
59 /*!
60    \brief parse the arguments for SurfSmooth program
61 
62    \param argv (char *)
63    \param argc (int)
64    \return Opt (SUMA_coarsen_OPTIONS *) options structure.
65                To free it, use
66                SUMA_free(Opt->out_prefix);
67                SUMA_free(Opt);
68 */
SUMA_coarsen_ParseInput(char * argv[],int argc,SUMA_GENERIC_ARGV_PARSE * ps)69 SUMA_GENERIC_PROG_OPTIONS_STRUCT *SUMA_coarsen_ParseInput (char *argv[], int argc, SUMA_GENERIC_ARGV_PARSE *ps)
70 {
71    static char FuncName[]={"SUMA_coarsen_ParseInput"};
72    SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt=NULL;
73    int kar, i, ind;
74    char *outprefix;
75    SUMA_Boolean brk = NOPE;
76    void *SO_name=NULL;
77    SUMA_Boolean exists = NOPE;
78    SUMA_Boolean LocalHead = NOPE;
79 
80    SUMA_ENTRY;
81 
82    Opt = SUMA_Alloc_Generic_Prog_Options_Struct();
83 
84    kar = 1;
85    Opt->out_prefix = NULL;
86    Opt->v0 = .5;
87    brk = NOPE;
88 
89    while (kar < argc)
90    { /* loop accross command ine options */
91       /*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/
92       if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0)
93       {
94          usage_SUMA_coarsen(ps);
95          exit (0);
96       }
97 
98       SUMA_SKIP_COMMON_OPTIONS(brk, kar);
99 
100 
101       if (!brk && (strcmp(argv[kar], "-edges") == 0))
102       {
103          if (kar+1 >= argc)
104          {
105             fprintf (SUMA_STDERR, "need a number after -edges \n");
106             exit (1);
107          }
108          Opt->v0 = atof(argv[++kar]);
109 
110          brk = YUP;
111       }
112 
113 
114       if (!brk && !ps->arg_checked[kar])
115       {
116          fprintf (SUMA_STDERR,"Error %s:\nOption %s not understood. Try -help for usage\n", FuncName, argv[kar]);
117          exit (1);
118       } else
119       {
120          brk = NOPE;
121          kar ++;
122       }
123 
124    }
125 
126    /* check for only one surface at input */
127    if (ps->s_N_surfnames + ps->i_N_surfnames + ps->t_N_surfnames != 1) {
128       SUMA_S_Err("Multiple surface specifications used. Only one surface allowed.");
129       exit(1);
130    }
131 
132    /* write out the surface */
133    if (ps->o_N_surfnames) {
134       Opt->out_prefix = SUMA_copy_string(ps->o_surfnames[0]);
135       Opt->SurfFileType = ps->o_FT[0];
136       Opt->SurfFileFormat = ps->o_FF[0];
137    } else {
138       Opt->out_prefix = SUMA_copy_string("SurfMesh_out");
139       Opt->SurfFileType = SUMA_PLY;
140       Opt->SurfFileFormat = SUMA_ASCII;
141    }
142    SO_name = SUMA_Prefix2SurfaceName(Opt->out_prefix, NULL, NULL, Opt->SurfFileType, &exists);
143    if (exists) {
144       fprintf(SUMA_STDERR,"Error %s:\nOutput file(s) %s* on disk.\nWill not overwrite.\n", FuncName, Opt->out_prefix);
145       exit(1);
146    }
147    /* free SO_name for now */
148    if (SO_name) SUMA_free(SO_name); SO_name = NULL;
149 
150 
151    SUMA_RETURN (Opt);
152 
153 }
154 
distance(SUMA_SurfaceObject * SO,int n,int m)155 double distance(SUMA_SurfaceObject *SO, int n, int m)
156 {
157    int i;
158    double result = 0;
159    for (i = 0; i<3; i++)
160       result += pow(SO->NodeList[n*3+i] - SO->NodeList[m*3+i], 2);
161    return sqrt(result);
162 }
163 
164 
main(int argc,char * argv[])165 int main (int argc,char *argv[])
166 {/* Main */
167    static char FuncName[]={"SurfMesh"};
168    SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt=NULL;
169    int SO_read = -1;
170    int i = 0;
171    SUMA_SurfaceObject *SO = NULL, *S2 = NULL;
172    void *SO_name = NULL;
173    SUMA_Boolean exists = NOPE;
174    FILE* out = NULL;
175    SUMA_GENERIC_ARGV_PARSE *ps=NULL;
176    SUMA_SurfSpecFile *Spec = NULL;
177    int N_Spec=0;
178    SUMA_Boolean LocalHead = NOPE;
179 
180    SUMA_STANDALONE_INIT;
181    SUMA_mainENTRY;
182 
183 
184 
185    ps = SUMA_Parse_IO_Args(argc, argv, "-i;-t;-spec;-s;-sv;-o;");
186 
187    /* Allocate space for DO structure */
188    SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS);
189 
190    if (argc < 4)
191    {
192       usage_SUMA_coarsen(ps);
193       exit (1);
194    }
195 
196    Opt = SUMA_coarsen_ParseInput (argv, argc, ps);
197 
198    Spec = SUMA_IO_args_2_spec(ps, &N_Spec);
199    if (N_Spec != 1) {
200       SUMA_S_Err("Multiple spec at input.");
201       exit(1);
202    }
203 
204    SO = SUMA_Load_Spec_Surf(Spec, 0, ps->sv[0], 0);
205    if (!SO) {
206          fprintf (SUMA_STDERR,"Error %s:\n"
207                               "Failed to find surface\n"
208                               "in spec file. \n",
209                               FuncName );
210          exit(1);
211 
212    }
213 
214    S2 = SUMA_Mesh_Resample (SO, Opt->v0);
215 
216    SO_name = SUMA_Prefix2SurfaceName(Opt->out_prefix, NULL, NULL, Opt->SurfFileType, &exists);
217    if (exists) {
218       fprintf(SUMA_STDERR,"Error %s:\nOutput file(s) %s* on disk.\nWill not overwrite.\n", FuncName, Opt->out_prefix);
219       exit(1);
220    }
221 
222    /* write the surfaces to disk */
223    fprintf (SUMA_STDERR,"%s: Writing surface  ...\n", FuncName);
224    if (!SUMA_Save_Surface_Object (SO_name, S2, Opt->SurfFileType, Opt->SurfFileFormat, NULL)) {
225       fprintf (SUMA_STDERR,"Error %s: Failed to write surface object.\n", FuncName);
226       exit (1);
227    }
228 
229 
230    SUMA_LH("clean up");
231 
232    if (N_Spec) {
233       int k=0;
234       for (k=0; k<N_Spec; ++k) {
235          if (!SUMA_FreeSpecFields(&(Spec[k]))) { SUMA_S_Err("Failed to free spec fields"); }
236       }
237       SUMA_free(Spec); Spec = NULL; N_Spec = 0;
238    }
239    if (SO_name) SUMA_free(SO_name); SO_name = NULL;
240    if (SO) SUMA_Free_Surface_Object(SO); SO = NULL;
241    if (S2) SUMA_Free_Surface_Object(S2); S2 = NULL;
242    if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL;
243    if (Spec) SUMA_free(Spec); Spec = NULL;
244    if (Opt) Opt = SUMA_Free_Generic_Prog_Options_Struct(Opt);
245    if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) {
246       SUMA_SL_Err("DO Cleanup Failed!");
247    }
248 
249    if (!SUMA_Free_CommonFields(SUMAg_CF)) {SUMA_SL_Err("SUMAg_CF Cleanup Failed!");}
250 
251    SUMA_RETURN(0);
252 }
253