Home | API | File List | Examples | Download

3dsdump.c

00001 /*
00002     Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
00003     All rights reserved.
00004     
00005     This program is free  software: you can redistribute it and/or modify 
00006     it under the terms of the GNU Lesser General Public License as published 
00007     by the Free Software Foundation, either version 2.1 of the License, or 
00008     (at your option) any later version.
00009 
00010     Thisprogram  is  distributed in the hope that it will be useful, 
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of 
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
00013     GNU Lesser General Public License for more details.
00014     
00015     You should  have received a copy of the GNU Lesser General Public License
00016     along with  this program; If not, see <http://www.gnu.org/licenses/>. 
00017 */
00018 
00024 #include <lib3ds.h>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 #include <assert.h>
00029 
00030 #ifdef _MSC_VER
00031 #pragma warning ( disable : 4996 )
00032 #endif
00033 
00034 
00035 static void
00036 help() {
00037     fprintf(stderr,
00038             "The 3D Studio File Format Library - 3dsdump\n"
00039             "Copyright (C) 1996-2007 by Jan Eric Kyprianidis <www.kyprianidis.com>\n"
00040             "All rights reserved.\n"
00041             "\n"
00042             "Syntax: 3dsdump [options] filename [options]\n"
00043             "\n"
00044             "Options:\n"
00045             "  -h           This help\n"
00046             "  -d=level     Set log level (0=ERROR, 1=WARN, 2=INFO, 3=DEBUG)\n"
00047             "  -m           Dump materials\n"
00048             "  -t           Dump trimeshes\n"
00049             "  -i           Dump instances\n"
00050             "  -c           Dump cameras\n"
00051             "  -l           Dump lights\n"
00052             "  -n           Dump node hierarchy\n"
00053             "  -w=filename  Write new 3ds file to disk\n"
00054             "\n"
00055            );
00056     exit(1);
00057 }
00058 
00059 
00060 typedef enum Flags {
00061     LIB3DSDUMP_MATERIALS  = 0x0004,
00062     LIB3DSDUMP_TRIMESHES  = 0x0008,
00063     LIB3DSDUMP_INSTANCES  = 0x0010,
00064     LIB3DSDUMP_CAMERAS    = 0x0020,
00065     LIB3DSDUMP_LIGHTS     = 0x0040,
00066     LIB3DSDUMP_NODES      = 0x0080
00067 } Flags;
00068 
00069 
00070 static const char* filename = 0;
00071 static const char* output = 0;
00072 static unsigned flags = 0;
00073 static int  log_level = LIB3DS_LOG_INFO;
00074 
00075 
00076 static void
00077 parse_args(int argc, char **argv) {
00078     int i;
00079 
00080     for (i = 1; i < argc; ++i) {
00081         if (argv[i][0] == '-') {
00082             if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) {
00083                 help();
00084             } else if ((argv[i][1] == 'd') && (argv[i][2] == '='))  {
00085                 log_level =  atoi(&argv[i][3]);
00086             } else if (argv[i][1] == 'm') {
00087                 flags |= LIB3DSDUMP_MATERIALS;
00088             } else if (argv[i][1] == 't') {
00089                 flags |= LIB3DSDUMP_TRIMESHES;
00090             } else if (argv[i][1] == 'i') {
00091                 flags |= LIB3DSDUMP_INSTANCES;
00092             } else if (argv[i][1] == 'c') {
00093                 flags |= LIB3DSDUMP_CAMERAS;
00094             } else if (argv[i][1] == 'l') {
00095                 flags |= LIB3DSDUMP_LIGHTS;
00096             } else if (argv[i][1] == 'n') {
00097                 flags |= LIB3DSDUMP_NODES;
00098             } else if ((argv[i][1] == 'w') && (argv[i][2] == '='))  {
00099                 output =  &argv[i][3];
00100             } else {
00101                 help();
00102             }
00103         } else {
00104             if (filename) {
00105                 help();
00106             }
00107             filename = argv[i];
00108         }
00109     }
00110     if (!filename) {
00111         help();
00112     }
00113 }
00114 
00115 
00116 static long
00117 fileio_seek_func(void *self, long offset, Lib3dsIoSeek origin) {
00118     FILE *f = (FILE*)self;
00119     int o;
00120     switch (origin) {
00121         case LIB3DS_SEEK_SET:
00122             o = SEEK_SET;
00123             break;
00124 
00125         case LIB3DS_SEEK_CUR:
00126             o = SEEK_CUR;
00127             break;
00128 
00129         case LIB3DS_SEEK_END:
00130             o = SEEK_END;
00131             break;
00132     }
00133     return (fseek(f, offset, o));
00134 }
00135 
00136 
00137 static long
00138 fileio_tell_func(void *self) {
00139     FILE *f = (FILE*)self;
00140     return(ftell(f));
00141 }
00142 
00143 
00144 static size_t
00145 fileio_read_func(void *self, void *buffer, size_t size) {
00146     FILE *f = (FILE*)self;
00147     return (fread(buffer, 1, size, f));
00148 }
00149 
00150 
00151 static size_t
00152 fileio_write_func(void *self, const void *buffer, size_t size) {
00153     FILE *f = (FILE*)self;
00154     return (fwrite(buffer, 1, size, f));
00155 }
00156 
00157 
00158 static void 
00159 fileio_log_func(void *self, Lib3dsLogLevel level, int indent, const char *msg)
00160 {
00161     static const char * level_str[] = {
00162         "ERROR", "WARN", "INFO", "DEBUG"
00163     };
00164     if (log_level >=  level) {
00165         int i;
00166         printf("%5s : ", level_str[level]);
00167         for (i = 1; i < indent; ++i) printf("\t");
00168         printf("%s\n", msg);
00169     }
00170 }
00171 
00172 
00173 static void
00174 matrix_dump(float matrix[4][4]) {
00175     int i, j;
00176 
00177     for (i = 0; i < 4; ++i) {
00178         for (j = 0; j < 4; ++j) {
00179             printf("%f ", matrix[j][i]);
00180         }
00181         printf("\n");
00182     }
00183 }
00184 
00185 
00186 static void
00187 viewport_dump(Lib3dsViewport *vp) {
00188     Lib3dsView *view;
00189     int i;
00190     assert(vp);
00191 
00192     printf("  viewport:\n");
00193     printf("    layout:\n");
00194     printf("      style:       %d\n", vp->layout_style);
00195     printf("      active:      %d\n", vp->layout_active);
00196     printf("      swap:        %d\n", vp->layout_swap);
00197     printf("      swap_prior:  %d\n", vp->layout_swap_prior);
00198     printf("      position:    %d,%d\n", vp->layout_position[0], vp->layout_position[1]);
00199     printf("      size:        %d,%d\n", vp->layout_size[0], vp->layout_size[1]);
00200     printf("      views:       %ld\n", vp->layout_nviews);
00201 
00202     for (i = 0; i < vp->layout_nviews; ++i) {
00203         view = &vp->layout_views[i];
00204 
00205         printf("        view %d:\n", i);
00206         printf("          type:         %d\n", view->type);
00207         printf("          axis_lock:    %d\n", view->axis_lock);
00208         printf("          position:     (%d,%d)\n", view->position[0], view->position[1]);
00209         printf("          size:         (%d,%d)\n", view->size[0], view->size[1]);
00210         printf("          zoom:         %g\n", view->zoom);
00211         printf("          center:       (%g,%g,%g)\n", view->center[0], view->center[1], view->center[2]);
00212         printf("          horiz_angle:  %g\n", view->horiz_angle);
00213         printf("          vert_angle:   %g\n", view->vert_angle);
00214         printf("          camera:       %s\n", view->camera);
00215     }
00216 
00217     printf("    default:\n");
00218     printf(" type:         %d\n", vp->default_type);
00219     printf(" position:     (%g,%g,%g)\n", vp->default_position[0], vp->default_position[1], vp->default_position[2]);
00220     printf(" width:        %g\n", vp->default_width);
00221     printf(" horiz_angle:  %g\n", vp->default_horiz_angle);
00222     printf(" vert_angle:   %g\n", vp->default_vert_angle);
00223     printf(" roll_angle:   %g\n", vp->default_roll_angle);
00224     printf(" camera:       %s\n", vp->default_camera);
00225 }
00226 
00227 
00228 static void
00229 texture_dump(const char *maptype, Lib3dsTextureMap *texture) {
00230     assert(texture);
00231     if (strlen(texture->name) == 0) {
00232         return;
00233     }
00234     printf("  %s:\n", maptype);
00235     printf("    name:          %s\n", texture->name);
00236     printf("    flags:         %X\n", (unsigned)texture->flags);
00237     printf("    percent:       %f\n", texture->percent);
00238     printf("    blur:          %f\n", texture->blur);
00239     printf("    scale:         (%f, %f)\n", texture->scale[0], texture->scale[1]);
00240     printf("    offset:        (%f, %f)\n", texture->offset[0], texture->offset[1]);
00241     printf("    rotation:      %f\n", texture->rotation);
00242     printf("    tint_1:        (%f, %f, %f)\n",
00243         texture->tint_1[0], texture->tint_1[1], texture->tint_1[2]);
00244     printf("    tint_2:        (%f, %f, %f)\n",
00245         texture->tint_2[0], texture->tint_2[1], texture->tint_2[2]);
00246     printf("    tint_r:        (%f, %f, %f)\n",
00247         texture->tint_r[0], texture->tint_r[1], texture->tint_r[2]);
00248     printf("    tint_g:        (%f, %f, %f)\n",
00249         texture->tint_g[0], texture->tint_g[1], texture->tint_g[2]);
00250     printf("    tint_b:        (%f, %f, %f)\n",
00251         texture->tint_b[0], texture->tint_b[1], texture->tint_b[2]);
00252 }
00253 
00254 
00255 static void
00256 material_dump(Lib3dsMaterial *material) {
00257     assert(material);
00258     printf("  name:            %s\n", material->name);
00259     printf("  ambient:         (%f, %f, %f)\n",
00260         material->ambient[0], material->ambient[1], material->ambient[2]);
00261     printf("  diffuse:         (%f, %f, %f)\n",
00262         material->diffuse[0], material->diffuse[1], material->diffuse[2]);
00263     printf("  specular:        (%f, %f, %f)\n",
00264         material->specular[0], material->specular[1], material->specular[2]);
00265     printf("  shininess:       %f\n", material->shininess);
00266     printf("  shin_strength:   %f\n", material->shin_strength);
00267     printf("  use_blur:        %s\n", material->use_blur ? "yes" : "no");
00268     printf("  blur:            %f\n", material->blur);
00269     printf("  falloff:         %f\n", material->falloff);
00270     printf("  is_additive:     %s\n", material->is_additive ? "yes" : "no");
00271     printf("  use_falloff:     %s\n", material->use_falloff ? "yes" : "no");
00272     printf("  self_illum_flag: %s\n", material->self_illum_flag ? "yes" : "no");
00273     printf("  self_illum:      %f\n", material->self_illum);
00274     printf("  shading:         %d\n", material->shading);
00275     printf("  soften:          %s\n", material->soften ? "yes" : "no");
00276     printf("  face_map:        %s\n", material->face_map ? "yes" : "no");
00277     printf("  two_sided:       %s\n", material->two_sided ? "yes" : "no");
00278     printf("  map_decal:       %s\n", material->map_decal ? "yes" : "no");
00279     printf("  use_wire:        %s\n", material->use_wire ? "yes" : "no");
00280     printf("  use_wire_abs:    %s\n", material->use_wire_abs ? "yes" : "no");
00281     printf("  wire_size:       %f\n", material->wire_size);
00282     texture_dump("texture1_map", &material->texture1_map);
00283     texture_dump("texture1_mask", &material->texture1_mask);
00284     texture_dump("texture2_map", &material->texture2_map);
00285     texture_dump("texture2_mask", &material->texture2_mask);
00286     texture_dump("opacity_map", &material->opacity_map);
00287     texture_dump("opacity_mask", &material->opacity_mask);
00288     texture_dump("bump_map", &material->bump_map);
00289     texture_dump("bump_mask", &material->bump_mask);
00290     texture_dump("specular_map", &material->specular_map);
00291     texture_dump("specular_mask", &material->specular_mask);
00292     texture_dump("shininess_map", &material->shininess_map);
00293     texture_dump("shininess_mask", &material->shininess_mask);
00294     texture_dump("self_illum_map", &material->self_illum_map);
00295     texture_dump("self_illum_mask", &material->self_illum_mask);
00296     texture_dump("reflection_map", &material->reflection_map);
00297     texture_dump("reflection_mask", &material->reflection_mask);
00298     printf("  autorefl_map:\n");
00299     printf("    flags          %X\n", (unsigned)material->autorefl_map_flags);
00300     printf("    level          %d\n", (int)material->autorefl_map_anti_alias);
00301     printf("    size           %d\n", (int)material->autorefl_map_size);
00302     printf("    frame_step     %d\n", (int)material->autorefl_map_frame_step);
00303     printf("\n");
00304 }
00305 
00306 
00307 static void
00308 camera_dump(Lib3dsCamera *camera) {
00309     assert(camera);
00310     printf("  name:       %s\n", camera->name);
00311     printf("  position:   (%f, %f, %f)\n",
00312         camera->position[0], camera->position[1], camera->position[2]);
00313     printf("  target      (%f, %f, %f)\n",
00314         camera->target[0], camera->target[1], camera->target[2]);
00315     printf("  roll:       %f\n", camera->roll);
00316     printf("  fov:        %f\n", camera->fov);
00317     printf("  see_cone:   %s\n", camera->see_cone ? "yes" : "no");
00318     printf("  near_range: %f\n", camera->near_range);
00319     printf("  far_range:  %f\n", camera->far_range);
00320     printf("\n");
00321 }
00322 
00323 
00324 static void
00325 light_dump(Lib3dsLight *light) {
00326     assert(light);
00327     printf("  name:             %s\n", light->name);
00328     printf("  spot_light:       %s\n", light->spot_light ? "yes" : "no");
00329     printf("  see_cone:         %s\n", light->see_cone ? "yes" : "no");
00330     printf("  color:            (%f, %f, %f)\n",
00331         light->color[0], light->color[1], light->color[2]);
00332     printf("  position          (%f, %f, %f)\n",
00333         light->position[0], light->position[1], light->position[2]);
00334     printf("  target              (%f, %f, %f)\n",
00335         light->target[0], light->target[1], light->target[2]);
00336     printf("  roll:             %f\n", light->roll);
00337     printf("  off:              %s\n", light->off ? "yes" : "no");
00338     printf("  outer_range:      %f\n", light->outer_range);
00339     printf("  inner_range:      %f\n", light->inner_range);
00340     printf("  multiplier:       %f\n", light->multiplier);
00341     printf("  attenuation:      %f\n", light->attenuation);
00342     printf("  rectangular_spot: %s\n", light->rectangular_spot ? "yes" : "no");
00343     printf("  shadowed:         %s\n", light->shadowed ? "yes" : "no");
00344     printf("  shadow_bias:      %f\n", light->shadow_bias);
00345     printf("  shadow_filter:    %f\n", light->shadow_filter);
00346     printf("  shadow_size:      %d\n", light->shadow_size);
00347     printf("  spot_aspect:      %f\n", light->spot_aspect);
00348     printf("  use_projector:    %s\n", light->use_projector ? "yes" : "no");
00349     printf("  projector:        %s\n", light->projector);
00350     printf("  spot_overshoot:   %d\n", (int)light->spot_overshoot);
00351     printf("  ray_shadows:      %s\n", light->ray_shadows ? "yes" : "no");
00352     printf("  ray_bias:         %f\n", light->ray_bias);
00353     printf("  hotspot:         %f\n", light->hotspot);
00354     printf("  falloff:         %f\n", light->falloff);
00355     printf("\n");
00356 }
00357 
00358 
00359 static void
00360 mesh_dump(Lib3dsMesh *mesh) {
00361     int i;
00362     float p[3];
00363 
00364     assert(mesh);
00365     printf("  %s vertices=%ld faces=%ld\n",
00366         mesh->name,
00367         mesh->nvertices,
00368         mesh->nfaces);
00369     printf("  matrix:\n");
00370     matrix_dump(mesh->matrix);
00371     printf("  vertices (x, y, z, u, v):\n");
00372     for (i = 0; i < mesh->nvertices; ++i) {
00373         lib3ds_vector_copy(p, mesh->vertices[i]);
00374         printf("    %10.5f %10.5f %10.5f", p[0], p[1], p[2]);
00375         if (mesh->texcos) {
00376             printf("%10.5f %10.5f", mesh->texcos[i][0], mesh->texcos[i][1]);
00377         }
00378         printf("\n");
00379     }
00380     printf("  facelist:\n");
00381     for (i = 0; i < mesh->nfaces; ++i) {
00382         printf("    %4d %4d %4d  flags:%X  smoothing:%X  material:\"%d\"\n",
00383             mesh->faces[i].index[0],
00384             mesh->faces[i].index[1],
00385             mesh->faces[i].index[2],
00386             mesh->faces[i].flags,
00387             mesh->faces[i].smoothing_group,
00388             mesh->faces[i].material
00389             );
00390     }
00391 }
00392 
00393 
00394 static void
00395 dump_instances(Lib3dsNode *node, const char* parent) {
00396     Lib3dsNode *p;
00397     char name[255];
00398 
00399     strcpy(name, parent);
00400     strcat(name, ".");
00401     strcat(name, node->name);
00402     if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
00403         Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
00404         printf("  %s : %s\n", name, n->instance_name);
00405     }
00406     for (p = node->childs; p != 0; p = p->next) {
00407         dump_instances(p, parent);
00408     }
00409 }
00410 
00411 
00412 static const char* node_names_table[] = {
00413     "Ambient",
00414     "Mesh",
00415     "Camera",
00416     "Camera Target",
00417     "Omnilight",
00418     "Spotlight",
00419     "Spotlight Target"
00420 };
00421 
00422 
00423 static void
00424 node_dump(Lib3dsNode *node, int level) {
00425     Lib3dsNode *p;
00426     char l[128];
00427 
00428     assert(node);
00429     memset(l, ' ', 2*level);
00430     l[2*level] = 0;
00431 
00432     if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
00433         Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node; 
00434         printf("%s%s [%s] (%s)\n",
00435             l,
00436             node->name,
00437             n->instance_name,
00438             node_names_table[node->type]
00439         );
00440     } else {
00441         printf("%s%s (%s)\n",
00442             l,
00443             node->name,
00444             node_names_table[node->type]
00445         );
00446     }
00447 
00448     for (p = node->childs; p != 0; p = p->next) {
00449         node_dump(p, level + 1);
00450     }
00451 }
00452 
00453 
00454 int
00455 main(int argc, char **argv) {
00456     FILE *file;
00457     Lib3dsFile *f = 0;
00458     Lib3dsIo io;
00459     int result;
00460     int i;
00461 
00462     parse_args(argc, argv);
00463 
00464     file = fopen(filename, "rb");
00465     if (!file) {
00466         fprintf(stderr, "***ERROR***\nFile not found: %s\n", filename);
00467         exit(1);
00468     }
00469 
00470     f = lib3ds_file_new();
00471  
00472     memset(&io, 0, sizeof(io));
00473     io.self = file;
00474     io.seek_func = fileio_seek_func;
00475     io.tell_func = fileio_tell_func;
00476     io.read_func = fileio_read_func;
00477     io.write_func = fileio_write_func;
00478     io.log_func = fileio_log_func;
00479 
00480     result =  lib3ds_file_read(f, &io);
00481 
00482     fclose(file);
00483  
00484     if (!result) {
00485         fprintf(stderr, "***ERROR***\nLoading file failed: %s\n", filename);
00486         exit(1);
00487     }
00488 
00489     if (flags & LIB3DSDUMP_MATERIALS) {
00490         printf("Dumping materials:\n");
00491         for (i = 0; i < f->nmaterials; ++i) material_dump(f->materials[i]);
00492         printf("\n");
00493     }
00494     if (flags & LIB3DSDUMP_TRIMESHES) {
00495         printf("Dumping meshes:\n");
00496         for (i = 0; i < f->nmeshes; ++i) mesh_dump(f->meshes[i]);
00497         printf("\n");
00498     }
00499     if (flags & LIB3DSDUMP_INSTANCES) {
00500         Lib3dsNode *p;
00501         printf("Dumping instances:\n");
00502         for (p = f->nodes; p != 0; p = p->next) {
00503             dump_instances(p, "");
00504         }
00505         printf("\n");
00506     }
00507     if (flags & LIB3DSDUMP_CAMERAS) {
00508         printf("Dumping cameras:\n");
00509         for (i = 0; i < f->ncameras; ++i) camera_dump(f->cameras[i]);
00510         printf("\n");
00511     }
00512     if (flags & LIB3DSDUMP_LIGHTS) {
00513         printf("Dumping lights:\n");
00514         for (i = 0; i < f->nlights; ++i) light_dump(f->lights[i]);
00515         printf("\n");
00516     }
00517     if (flags & LIB3DSDUMP_NODES) {
00518         Lib3dsNode *p;
00519         printf("Dumping node hierarchy:\n");
00520         for (p = f->nodes; p != 0; p = p->next) {
00521             node_dump(p, 1);
00522         }
00523         printf("\n");
00524     }
00525     if (output) {
00526         if (!lib3ds_file_save(f, output)) {
00527             printf("***ERROR**** Writing %s\n", output);
00528         }
00529     }
00530 
00531     lib3ds_file_free(f);
00532     return 0;
00533 }