aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/programs/g3d-stat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/programs/g3d-stat.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/programs/g3d-stat.c324
1 files changed, 324 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/programs/g3d-stat.c b/src/others/mimesh/libg3d-0.0.8/programs/g3d-stat.c
new file mode 100644
index 0000000..af04835
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/programs/g3d-stat.c
@@ -0,0 +1,324 @@
1/* $Id:$ */
2
3/*
4 libg3d - 3D object loading library
5
6 Copyright (C) 2005-2009 Markus Dahms <mad@automagically.de>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21*/
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <signal.h>
26#include <g3d/g3d.h>
27#include <g3d/plugins.h>
28
29typedef struct {
30 guint32 n_objects;
31 guint32 n_vertices;
32 guint32 n_faces;
33 guint32 n_textures;
34} FileStats;
35
36typedef struct {
37 guint32 n_success;
38 guint32 n_failure;
39 GSList *no_objects;
40 GSList *no_faces;
41 GSList *no_vertices;
42} PluginStats;
43
44typedef struct {
45 G3DContext *context;
46 gboolean use_color;
47 FILE *ftree;
48} Config;
49
50static gboolean quit = FALSE;
51
52static void show_help(void);
53static Config *get_config(gint *argc, gchar ***argv);
54static gboolean dir_stat(Config *config, const char *dirname);
55static gboolean file_stat(Config *config, const char *filename,
56 gboolean detailed, FileStats *stats, gchar **plugin_used);
57
58static void sighandler(int signal)
59{
60 quit = TRUE;
61 fprintf(stderr, "signal %d received, quitting\n", signal);
62}
63
64static void _g_print(const gchar *str)
65{
66#if 0
67 fputs(str, stderr);
68#endif
69}
70
71#define ANSI_RESET "\033[0m"
72#define ANSI_GREEN "\033[32m"
73#define ANSI_RED "\033[31m"
74
75static void log_handler(const gchar *log_domain, GLogLevelFlags log_level,
76 const gchar *message, gpointer user_data)
77{
78 Config *config = user_data;
79
80 if(message[0] == '\\') {
81 if(config->use_color)
82 fprintf(config->ftree, ANSI_GREEN "%s\n" ANSI_RESET, message + 1);
83 else
84 fprintf(config->ftree, "%s\n", message + 1);
85 } else if(message[0] == '|') {
86 printf("%s\n", message + 1);
87 } else {
88 if(config->use_color)
89 printf(ANSI_RED "%s\n" ANSI_RESET, message);
90 else
91 printf("%s\n", message);
92 }
93}
94
95int main(int argc, char **argv)
96{
97 Config *config;
98
99 signal(SIGINT, sighandler);
100#ifdef SIGQUIT
101 signal(SIGQUIT, sighandler);
102#endif
103
104 config = get_config(&argc, &argv);
105
106 if(argc < 1) {
107 show_help();
108 exit(EXIT_FAILURE);
109 }
110
111 g_set_print_handler(_g_print);
112 g_set_printerr_handler(_g_print);
113 g_log_set_handler("LibG3D", G_LOG_LEVEL_MASK, log_handler, config);
114
115 config->context = g3d_context_new();
116
117 if(g_file_test(argv[0], G_FILE_TEST_IS_DIR)) {
118 return dir_stat(config, argv[0]);
119 }
120 else {
121 return file_stat(config, argv[0], TRUE, NULL, NULL);
122 }
123}
124
125static Config *get_config(gint *argc, gchar ***argv)
126{
127 Config *config;
128 guint32 skip = 1; /* skip program name by default */
129 gint32 i;
130 gchar *opt;
131
132 config = g_new0(Config, 1);
133 config->use_color = TRUE;
134 config->ftree = stdout;
135
136 for(i = 1; i < *argc; i ++) {
137 if(strncmp((*argv)[i], "--", 2) != 0)
138 break;
139 skip ++;
140 opt = (*argv)[i] + 2;
141 if(strcmp(opt, "help") == 0) {
142 show_help();
143 exit(EXIT_FAILURE);
144 } else if(strcmp(opt, "nocolor") == 0) {
145 config->use_color = FALSE;
146 } else if(strncmp(opt, "tree=", 5) == 0) {
147 config->use_color = FALSE;
148 config->ftree = fopen(opt + 5, "w");
149 if(config->ftree == NULL) {
150 perror("error opening tree output file");
151 exit(EXIT_FAILURE);
152 }
153 }
154 }
155
156 *argc -= skip;
157 *argv = &((*argv)[skip]);
158
159 return config;
160}
161
162static void show_help(void)
163{
164 fprintf(stderr,
165 "usage: g3d-stat [<option> ...] (file|directory)\n"
166 "\n"
167 "options:\n"
168 " --help show this message\n"
169 " --nocolor disable ANSI color output\n"
170 " --tree=<filename> redirect tree output to file <filename>\n"
171 );
172}
173
174static gboolean dir_stat_1(Config *config, const char *dirname,
175 GHashTable *plugins)
176{
177 GDir *dir;
178 FileStats *fstats;
179 PluginStats *pstats;
180 const gchar *fname;
181 gchar *filename, *plugin_used;
182 gboolean retval;
183
184 dir = g_dir_open(dirname, 0, NULL);
185 g_return_val_if_fail(dir != NULL, FALSE);
186 while((fname = g_dir_read_name(dir)) != NULL) {
187 filename = g_strdup_printf("%s%c%s",
188 dirname, G_DIR_SEPARATOR, fname);
189 if(quit)
190 return FALSE;
191 if(g_file_test(filename, G_FILE_TEST_IS_DIR))
192 dir_stat_1(config, filename, plugins);
193 else {
194 fstats = g_new0(FileStats, 1);
195 plugin_used = NULL;
196 fprintf(stderr, "*** DEBUG: %s\n", filename);
197 retval = file_stat(config, filename, FALSE, fstats, &plugin_used);
198 if(plugin_used) {
199 pstats = g_hash_table_lookup(plugins, plugin_used);
200 if(pstats)
201 g_free(plugin_used);
202 else {
203 pstats = g_new0(PluginStats, 1);
204 g_hash_table_insert(plugins, plugin_used, pstats);
205 }
206
207 /* update pstats for plugin */
208 if(retval)
209 pstats->n_success ++;
210 else
211 pstats->n_failure ++;
212
213 if(fstats->n_objects == 0)
214 pstats->no_objects = g_slist_append(pstats->no_objects,
215 g_strdup(filename));
216 else if(fstats->n_vertices == 0)
217 pstats->no_vertices = g_slist_append(pstats->no_vertices,
218 g_strdup(filename));
219 else if(fstats->n_faces == 0)
220 pstats->no_faces = g_slist_append(pstats->no_faces,
221 g_strdup(filename));
222 } /* plugin_used */
223 g_free(fstats);
224 } /* !directory */
225 g_free(filename);
226 }
227 g_dir_close(dir);
228 return TRUE;
229}
230
231static void output_plugin_stats(gpointer key, gpointer value, gpointer data)
232{
233 gchar *name = (gchar *)key;
234 PluginStats *pstats = (PluginStats *)value;
235 GSList *item;
236
237 printf("%s:\n"
238 " num success: %d\n"
239 " num failure: %d\n"
240 " num no objects: %d\n",
241 name, pstats->n_success, pstats->n_failure,
242 g_slist_length(pstats->no_objects));
243 for(item = pstats->no_objects; item != NULL; item = item->next)
244 printf(" %s\n", (gchar *)item->data);
245 printf(" num no vertices: %d\n", g_slist_length(pstats->no_vertices));
246 for(item = pstats->no_vertices; item != NULL; item = item->next)
247 printf(" %s\n", (gchar *)item->data);
248 printf(" num no faces: %d\n", g_slist_length(pstats->no_faces));
249 for(item = pstats->no_faces; item != NULL; item = item->next)
250 printf(" %s\n", (gchar *)item->data);
251}
252
253static gboolean dir_stat(Config *config, const char *dirname)
254{
255 GHashTable *plugins;
256
257 plugins = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
258
259 dir_stat_1(config, dirname, plugins);
260
261 /* output statistics */
262 g_hash_table_foreach(plugins, output_plugin_stats, NULL);
263
264 g_hash_table_destroy(plugins);
265
266 return TRUE;
267}
268
269static gboolean objects_stat(GSList *objects, gboolean detailed,
270 FileStats *stats, guint32 indent)
271{
272 GSList *item;
273 G3DObject *object;
274 gchar *istr;
275
276 if(stats)
277 stats->n_objects += g_slist_length(objects);
278
279 for(item = objects; item != NULL; item = item->next) {
280 object = (G3DObject *)item->data;
281 g_return_val_if_fail(object != NULL, FALSE);
282
283 if(stats) {
284 stats->n_vertices += object->vertex_count;
285 stats->n_faces += g_slist_length(object->faces);
286 }
287
288 if(detailed) {
289 istr = g_strnfill(indent * 2, ' ');
290 printf("%sobject name: %s\n"
291 "%sobject num vertices: %d\n"
292 "%sobject num faces: %d\n"
293 "%sobject num subobjects: %d\n",
294 istr, object->name,
295 istr, object->vertex_count,
296 istr, g_slist_length(object->faces),
297 istr, g_slist_length(object->objects));
298 g_free(istr);
299 }
300
301 objects_stat(object->objects, detailed, stats, indent + 1);
302 }
303
304 return TRUE;
305}
306
307static gboolean file_stat(Config *config, const char *filename,
308 gboolean detailed, FileStats *stats, gchar **plugin_used)
309{
310 G3DModel *model;
311
312 model = g3d_model_load(config->context, filename);
313 if(model == NULL) {
314 return FALSE;
315 }
316
317 objects_stat(model->objects, detailed, stats, 0);
318 if(plugin_used && model->plugin)
319 *plugin_used = g_strdup(model->plugin->name);
320
321 g3d_model_free(model);
322
323 return TRUE;
324}