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