1 /* GTS - Library for the manipulation of triangulated surfaces
2  * Copyright (C) 1999 St�phane Popinet
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 
20 #include <stdlib.h>
21 #include "config.h"
22 #ifdef HAVE_GETOPT_H
23 #  include <getopt.h>
24 #endif /* HAVE_GETOPT_H */
25 #ifdef HAVE_UNISTD_H
26 #  include <unistd.h>
27 #endif /* HAVE_UNISTD_H */
28 #include "gts.h"
29 
30 /* volume - compute the volume of a given surface if it is a closed and
31    orientable manifold */
main(int argc,char * argv[])32 int main (int argc, char * argv[])
33 {
34   GtsSurface * s;
35   gboolean verbose = FALSE;
36   gboolean cm = FALSE;
37   int c = 0;
38   GtsFile * fp;
39 
40   /* parse options using getopt */
41   while (c != EOF) {
42 #ifdef HAVE_GETOPT_LONG
43     static struct option long_options[] = {
44       {"cm", no_argument, NULL, 'c'},
45       {"help", no_argument, NULL, 'h'},
46       {"verbose", no_argument, NULL, 'v'}
47     };
48     int option_index = 0;
49     switch ((c = getopt_long (argc, argv, "hvc",
50 			      long_options, &option_index))) {
51 #else /* not HAVE_GETOPT_LONG */
52     switch ((c = getopt (argc, argv, "hvc"))) {
53 #endif /* not HAVE_GETOPT_LONG */
54     case 'c': /* cm */
55       cm = TRUE;
56       break;
57     case 'v': /* verbose */
58       verbose = TRUE;
59       break;
60     case 'h': /* help */
61       fprintf (stderr,
62              "Usage: volume [OPTION] < file.gts\n"
63 	     "Compute the volume of the domain bounded by the surface defined by file.srf.\n"
64 	     "Print the volume and exit successfully if the surface is a closed orientable\n"
65 	     "manifold. Exit unsuccessfully otherwise.\n"
66 	     "\n"
67 	     "  -v    --verbose  print statistics about the surface\n"
68 	     "  -c    --cm       output center of mass and volume\n"
69 	     "  -h    --help     display this help and exit\n"
70 	     "\n"
71 	     "Reports bugs to %s\n",
72 	     GTS_MAINTAINER);
73       return 0; /* success */
74       break;
75     case '?': /* wrong options */
76       fprintf (stderr, "Try `volume --help' for more information.\n");
77       return 1; /* failure */
78     }
79   }
80 
81   /* read surface in */
82   s = gts_surface_new (gts_surface_class (),
83 		       gts_face_class (),
84 		       gts_edge_class (),
85 		       gts_vertex_class ());
86   fp = gts_file_new (stdin);
87   if (gts_surface_read (s, fp)) {
88     fputs ("volume: the file on standard input is not a valid GTS file\n",
89 	   stderr);
90     fprintf (stderr, "stdin:%d:%d: %s\n", fp->line, fp->pos, fp->error);
91     return 1; /* failure */
92   }
93 
94   /* if verbose on print stats */
95   if (verbose)
96     gts_surface_print_stats (s, stdout);
97 
98   /* test if surface is a closed and orientable manifold.
99      we don't need to test if s is a manifold since both tests below
100      implies that. */
101   if (!gts_surface_is_closed (s) || !gts_surface_is_orientable (s))
102     return 1; /* failure */
103 
104   /* print volume */
105   printf ("%g\n", gts_surface_volume (s));
106 
107   if (cm) {
108     GtsVector cm;
109 
110     /* print center of mass */
111     gts_surface_center_of_mass (s, cm);
112     printf ("(%g,%g,%g)\n", cm[0], cm[1], cm[2]);
113   }
114 
115   return 0; /* success */
116 }
117