diff options
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.c | 324 |
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 | |||
29 | typedef struct { | ||
30 | guint32 n_objects; | ||
31 | guint32 n_vertices; | ||
32 | guint32 n_faces; | ||
33 | guint32 n_textures; | ||
34 | } FileStats; | ||
35 | |||
36 | typedef struct { | ||
37 | guint32 n_success; | ||
38 | guint32 n_failure; | ||
39 | GSList *no_objects; | ||
40 | GSList *no_faces; | ||
41 | GSList *no_vertices; | ||
42 | } PluginStats; | ||
43 | |||
44 | typedef struct { | ||
45 | G3DContext *context; | ||
46 | gboolean use_color; | ||
47 | FILE *ftree; | ||
48 | } Config; | ||
49 | |||
50 | static gboolean quit = FALSE; | ||
51 | |||
52 | static void show_help(void); | ||
53 | static Config *get_config(gint *argc, gchar ***argv); | ||
54 | static gboolean dir_stat(Config *config, const char *dirname); | ||
55 | static gboolean file_stat(Config *config, const char *filename, | ||
56 | gboolean detailed, FileStats *stats, gchar **plugin_used); | ||
57 | |||
58 | static void sighandler(int signal) | ||
59 | { | ||
60 | quit = TRUE; | ||
61 | fprintf(stderr, "signal %d received, quitting\n", signal); | ||
62 | } | ||
63 | |||
64 | static 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 | |||
75 | static 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 | |||
95 | int 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 | |||
125 | static 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 | |||
162 | static 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 | |||
174 | static 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 | |||
231 | static 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 | |||
253 | static 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 | |||
269 | static 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 | |||
307 | static 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 | } | ||