Revision: 37473
          http://brlcad.svn.sourceforge.net/brlcad/?rev=37473&view=rev
Author:   bob1961
Date:     2010-01-29 16:05:58 +0000 (Fri, 29 Jan 2010)

Log Message:
-----------
Added ged_dbot_dump() for dumping the displayed bots and auxiliary data (i.e. 
arrows, lines and axes) to obj format.

Modified Paths:
--------------
    brlcad/trunk/src/libged/bot_dump.c

Modified: brlcad/trunk/src/libged/bot_dump.c
===================================================================
--- brlcad/trunk/src/libged/bot_dump.c  2010-01-29 15:57:50 UTC (rev 37472)
+++ brlcad/trunk/src/libged/bot_dump.c  2010-01-29 16:05:58 UTC (rev 37473)
@@ -39,6 +39,9 @@
 #include "raytrace.h"
 #include "wdb.h"
 
+#include "mater.h"
+#include "solid.h"
+
 #include "./ged_private.h"
 
 
@@ -58,20 +61,37 @@
     struct ged *gedp;
     FILE *fp;
     int fd;
-    struct bu_vls *file_name;
     char *file_ext;
 };
 
-static enum otype output_type = OTYPE_STL;
-static int binary = 0;
-static int normals = 0;
-static fastf_t cfactor = 1.0;
-static int v_offset = 1;
-static char *output_file = NULL;       /* output filename */
-static char *output_directory = NULL;  /* directory name to hold output files 
*/
-static unsigned int total_faces = 0;
+struct _ged_obj_material {
+    struct bu_list l;
+    struct bu_vls name;
+    unsigned char r;
+    unsigned char g;
+    unsigned char b;
+    fastf_t a;
+};
 
-static int curr_line_num = 0;
+struct bu_list HeadObjMaterials;
+struct bu_vls obj_materials_file;
+FILE *obj_materials_fp;
+int num_obj_materials;
+int curr_obj_red;
+int curr_obj_green;
+int curr_obj_blue;
+fastf_t curr_obj_alpha;
+
+static enum otype output_type;
+static int binary;
+static int normals;
+static fastf_t cfactor;
+static char *output_file;      /* output filename */
+static char *output_directory; /* directory name to hold output files */
+static unsigned int total_faces;
+static int v_offset;
+static int curr_line_num;
+
 static int curr_body_id;
 static int curr_lump_id;
 static int curr_shell_id;
@@ -93,7 +113,53 @@
        | ((r & 0xff000000) >> 24);
 }
 
+static struct _ged_obj_material *
+ged_get_obj_material(int red, int green, int blue, fastf_t transparency)
+{
+    struct _ged_obj_material *gomp;
+
+    for (BU_LIST_FOR(gomp, _ged_obj_material, &HeadObjMaterials)) {
+       if (gomp->r == red &&
+           gomp->g == green &&
+           gomp->b == blue &&
+           gomp->a == transparency) {
+           return gomp;
+       }
+    }
+
+    BU_GETSTRUCT(gomp, _ged_obj_material);
+    BU_LIST_APPEND(&HeadObjMaterials, &gomp->l);
+    gomp->r = red;
+    gomp->g = green;
+    gomp->b = blue;
+    gomp->a = transparency;
+    bu_vls_init(&gomp->name);
+    bu_vls_printf(&gomp->name, "matl_%d", ++num_obj_materials);
+
+    /* Write out newmtl to mtl file */
+    fprintf(obj_materials_fp, "newmtl %s\n", bu_vls_addr(&gomp->name));
+    fprintf(obj_materials_fp, "Kd %lf %lf %lf\n",
+           (fastf_t)gomp->r / 255.0,
+           (fastf_t)gomp->g / 255.0,
+           (fastf_t)gomp->b / 255.0);
+    fprintf(obj_materials_fp, "d %lf\n", gomp->a);
+    fprintf(obj_materials_fp, "illum 1\n");
+
+    return gomp;
+}
+
 static void
+ged_free_obj_materials() {
+    struct _ged_obj_material *gomp;
+
+    while (BU_LIST_WHILE(gomp, _ged_obj_material, &HeadObjMaterials)) {
+       BU_LIST_DEQUEUE(&gomp->l);
+       bu_vls_free(&gomp->name);
+       bu_free(gomp, "_ged_obj_material");
+    }
+}
+
+static void
 write_bot_sat(struct rt_bot_internal *bot, FILE *fp, char *name)
 {
     int i, j;
@@ -345,7 +411,14 @@
     vect_t CmA;
     vect_t norm;
     int i,vi;
+    struct _ged_obj_material *gomp;
 
+    gomp = ged_get_obj_material(curr_obj_red,
+                               curr_obj_green,
+                               curr_obj_blue,
+                               curr_obj_alpha);
+    fprintf(fp, "usemtl %s\n", bu_vls_addr(&gomp->name));
+
     num_vertices = bot->num_vertices;
     vertices = bot->vertices;
     num_faces = bot->num_faces;
@@ -506,34 +579,37 @@
 }
 
 static void
-bot_dump(struct directory *dp, struct rt_bot_internal *bot, FILE *fp, int fd, 
struct bu_vls *file_name, const char *file_ext, const char *db_name)
+bot_dump(struct directory *dp, struct rt_bot_internal *bot, FILE *fp, int fd, 
const char *file_ext, const char *db_name)
 {
     if (output_directory) {
        char *cp;
+       struct bu_vls file_name;
 
-       bu_vls_trunc(file_name, 0);
-       bu_vls_strcpy(file_name, output_directory);
-       bu_vls_putc(file_name, '/');
+       bu_vls_init(&file_name);
+       bu_vls_strcpy(&file_name, output_directory);
+       bu_vls_putc(&file_name, '/');
        cp = dp->d_namep;
        while (*cp != '\0') {
            if (*cp == '/') {
-               bu_vls_putc(file_name, '@');
+               bu_vls_putc(&file_name, '@');
            } else if (*cp == '.' || isspace(*cp)) {
-               bu_vls_putc(file_name, '_');
+               bu_vls_putc(&file_name, '_');
            } else {
-               bu_vls_putc(file_name, *cp);
+               bu_vls_putc(&file_name, *cp);
            }
            cp++;
        }
-       bu_vls_strcat(file_name, file_ext);
+       bu_vls_strcat(&file_name, file_ext);
 
        if (binary && output_type == OTYPE_STL) {
            char buf[81];       /* need exactly 80 chars for header */
            unsigned char tot_buffer[4];
 
-           if ((fd=open(bu_vls_addr(file_name), 
O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
-               perror(bu_vls_addr(file_name));
-               bu_exit(1, "Cannot open binary output file (%s) for writing\n", 
bu_vls_addr(file_name));
+           if ((fd=open(bu_vls_addr(&file_name), 
O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
+               perror(bu_vls_addr(&file_name));
+               bu_log("Cannot open binary output file (%s) for writing\n", 
bu_vls_addr(&file_name));
+               bu_vls_free(&file_name);
+               return;
            }
 
            /* Write out STL header */
@@ -557,9 +633,11 @@
 
            close(fd);
        } else {
-           if ((fp=fopen(bu_vls_addr(file_name), "wb+")) == NULL) {
-               perror(bu_vls_addr(file_name));
-               bu_exit(1, "Cannot open ASCII output file (%s) for writing\n", 
bu_vls_addr(file_name));
+           if ((fp=fopen(bu_vls_addr(&file_name), "wb+")) == NULL) {
+               perror(bu_vls_addr(&file_name));
+               bu_log("Cannot open ASCII output file (%s) for writing\n", 
bu_vls_addr(&file_name));
+               bu_vls_free(&file_name);
+               return;
            }
 
            switch (output_type) {
@@ -572,6 +650,7 @@
                break;
            case OTYPE_OBJ:
                v_offset = 1;
+               fprintf(fp, "mtllib %s\n", bu_vls_addr(&obj_materials_file));
                write_bot_obj(bot, fp, dp->d_namep);
                break;
            case OTYPE_SAT:
@@ -597,6 +676,8 @@
 
            fclose(fp);
        }
+
+       bu_vls_free(&file_name);
     } else {
        if (binary && output_type == OTYPE_STL) {
            total_faces += bot->num_faces;
@@ -664,40 +745,26 @@
     }
 
     bot = (struct rt_bot_internal *)intern.idb_ptr;
-    bot_dump(dp, bot, gbdcdp->fp, gbdcdp->fd, gbdcdp->file_name, 
gbdcdp->file_ext, gbdcdp->gedp->ged_wdbp->dbip->dbi_filename);
+    bot_dump(dp, bot, gbdcdp->fp, gbdcdp->fd, gbdcdp->file_ext, 
gbdcdp->gedp->ged_wdbp->dbip->dbi_filename);
     rt_db_free_internal(&intern);
 
     return curtree;
 }
 
-int
-ged_bot_dump(struct ged *gedp, int argc, const char *argv[])
+static int
+ged_bot_dump_get_args(struct ged *gedp, int argc, const char *argv[])
 {
-    char idbuf[132];           /* First ID record info */
-    struct rt_db_internal intern;
-    struct rt_bot_internal *bot;
-    struct directory *dp;
-    struct bu_vls file_name;
-    char *file_ext = '\0';
-    FILE *fp = (FILE *)0;
-    int fd = -1;
     char c;
-    mat_t mat;
-    int i;
-    const char *cmd_name;
 
-    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
-    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
-
-    /* initialize result */
-    bu_vls_trunc(&gedp->ged_result_str, 0);
-
-    /* must be wanting help */
-    if (argc == 1) {
-       bu_vls_printf(&gedp->ged_result_str, usage, argv[0]);
-       return GED_HELP;
-    }
-
+    output_type = OTYPE_STL;
+    binary = 0;
+    normals = 0;
+    cfactor = 1.0;
+    output_file = NULL;
+    output_directory = NULL;
+    total_faces = 0;
+    v_offset = 1;
+    curr_line_num = 0;
     bu_optind = 1;
 
     /* Get command line options. */
@@ -711,7 +778,6 @@
                break;
            case 'm':
                output_directory = bu_optarg;
-               bu_vls_init(&file_name);
                break;
            case 'o':           /* Output file name. */
                output_file = bu_optarg;
@@ -725,8 +791,10 @@
                    output_type = OTYPE_SAT;
                else if (!strcmp("stl", bu_optarg))
                    output_type = OTYPE_STL;
-               else
-                   bu_exit(1, usage, argv[0]);
+               else {
+                   bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", 
argv[0], usage);
+                   return GED_ERROR;
+               }
                break;
            case 'u':
                if ((cfactor = bu_units_conversion(bu_optarg)) == 0.0)
@@ -736,11 +804,43 @@
 
                break;
            default:
-               bu_exit(1, usage, argv[0]);
-               break;
+               bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], 
usage);
+               return GED_ERROR;
        }
     }
 
+    return GED_OK;
+}
+
+int
+ged_bot_dump(struct ged *gedp, int argc, const char *argv[])
+{
+    char idbuf[132];           /* First ID record info */
+    struct rt_db_internal intern;
+    struct rt_bot_internal *bot;
+    struct directory *dp;
+    char *file_ext = '\0';
+    FILE *fp = (FILE *)0;
+    int fd = -1;
+    mat_t mat;
+    int i;
+    const char *cmd_name;
+
+    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+    /* initialize result */
+    bu_vls_trunc(&gedp->ged_result_str, 0);
+
+    /* must be wanting help */
+    if (argc == 1) {
+       bu_vls_printf(&gedp->ged_result_str, usage, argv[0]);
+       return GED_HELP;
+    }
+
+    if (ged_bot_dump_get_args(gedp, argc, argv) == GED_ERROR)
+       return GED_ERROR;
+
     if (bu_optind > argc) {
        bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
        return GED_ERROR;
@@ -805,7 +905,6 @@
                    fprintf(fp, "08 BRL-CAD-bot_dump-4.0 11 ACIS 4.0 NT 24 Thur 
Sep 25 15:00:00 2008\n");
 #endif
                    fprintf(fp, "1 9.9999999999999995e-007 1e-010\n");
-                   curr_line_num = 0;
                    break;
                default:
                    break;
@@ -820,16 +919,6 @@
     argc -= bu_optind;
     argv += bu_optind;
 
-    RT_INIT_DB_INTERNAL(&intern);
-
-#if 0
-    /* skip past the database name */
-    --argc;
-    ++argv;
-#endif
-
-    MAT_IDN(mat);
-
     if (output_directory) {
        switch (output_type) {
            case OTYPE_DXF:
@@ -848,6 +937,8 @@
        }
     }
 
+    MAT_IDN(mat);
+
     if (argc < 1) {
        /* dump all the bots */
        FOR_ALL_DIRECTORY_START(dp, gedp->ged_wdbp->dbip) {
@@ -868,7 +959,7 @@
            }
 
            bot = (struct rt_bot_internal *)intern.idb_ptr;
-           bot_dump(dp, bot, fp, fd, &file_name, file_ext, 
gedp->ged_wdbp->dbip->dbi_filename);
+           bot_dump(dp, bot, fp, fd, file_ext, 
gedp->ged_wdbp->dbip->dbi_filename);
            rt_db_free_internal(&intern);
 
        } FOR_ALL_DIRECTORY_END;
@@ -884,7 +975,6 @@
        gbdcdp->gedp = gedp;
        gbdcdp->fp = fp;
        gbdcdp->fd = fd;
-       gbdcdp->file_name = &file_name;
        gbdcdp->file_ext = file_ext;
 
        for (i = 0; i < argc; ++i) {
@@ -937,6 +1027,530 @@
     return GED_OK;
 }
 
+static void
+write_data_arrows(struct ged_data_arrow_state *gdasp, FILE *fp, int sflag)
+{
+    register int i;
+
+    if (gdasp->gdas_draw) {
+       struct _ged_obj_material *gomp;
+
+       gomp = ged_get_obj_material(gdasp->gdas_color[0],
+                                   gdasp->gdas_color[1],
+                                   gdasp->gdas_color[2],
+                                   1);
+       fprintf(fp, "usemtl %s\n", bu_vls_addr(&gomp->name));
+
+       if (sflag)
+           fprintf(fp, "g sdata_arrows\n");
+       else
+           fprintf(fp, "g data_arrows\n");
+
+       for (i = 0; i < gdasp->gdas_num_points; i += 2) {
+           point_t A, B;
+           point_t BmA;
+           point_t offset;
+           point_t perp1, perp2;
+           point_t a_base;
+           point_t a_pt1, a_pt2, a_pt3, a_pt4;
+
+           VMOVE(A, gdasp->gdas_points[i]);
+           VMOVE(B, gdasp->gdas_points[i+1]);
+
+           VSUB2(BmA, B, A);
+
+           VUNITIZE(BmA);
+           VSCALE(offset, BmA, -gdasp->gdas_tip_length);
+
+           bn_vec_perp(perp1, BmA);
+           VUNITIZE(perp1);
+
+           VCROSS(perp2, BmA, perp1);
+           VUNITIZE(perp2);
+
+           VSCALE(perp1, perp1, gdasp->gdas_tip_width);
+           VSCALE(perp2, perp2, gdasp->gdas_tip_width);
+
+           VADD2(a_base, B, offset);
+           VADD2(a_pt1, a_base, perp1);
+           VADD2(a_pt2, a_base, perp2);
+           VSUB2(a_pt3, a_base, perp1);
+           VSUB2(a_pt4, a_base, perp2);
+
+           fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(A));
+           fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(B));
+           fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(a_pt1));
+           fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(a_pt2));
+           fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(a_pt3));
+           fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(a_pt4));
+       }
+
+       for (i = 0; i < gdasp->gdas_num_points; i += 2) {
+           fprintf(fp, "l %d %d\n", (i/2*6)+v_offset, (i/2*6)+v_offset+1);
+           fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+1, (i/2*6)+v_offset+2);
+           fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+1, (i/2*6)+v_offset+3);
+           fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+1, (i/2*6)+v_offset+4);
+           fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+1, (i/2*6)+v_offset+5);
+           fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+2, (i/2*6)+v_offset+3);
+           fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+3, (i/2*6)+v_offset+4);
+           fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+4, (i/2*6)+v_offset+5);
+           fprintf(fp, "l %d %d\n", (i/2*6)+v_offset+5, (i/2*6)+v_offset+2);
+       }
+
+       v_offset += ((gdasp->gdas_num_points/2)*6);
+    }
+}
+
+static void
+write_data_axes(struct ged_data_axes_state *gdasp, FILE *fp, int sflag)
+{
+    register int i;
+
+    if (gdasp->gdas_draw) {
+       fastf_t halfAxesSize;
+       struct _ged_obj_material *gomp;
+
+       halfAxesSize = gdasp->gdas_size * 0.5;
+
+       gomp = ged_get_obj_material(gdasp->gdas_color[0],
+                                   gdasp->gdas_color[1],
+                                   gdasp->gdas_color[2],
+                                   1);
+       fprintf(fp, "usemtl %s\n", bu_vls_addr(&gomp->name));
+
+       if (sflag)
+           fprintf(fp, "g sdata_axes\n");
+       else
+           fprintf(fp, "g data_axes\n");
+
+       for (i = 0; i < gdasp->gdas_num_points; ++i) {
+           point_t A, B;
+
+           /* draw X axis with x/y offsets */
+           VSET(A,
+                gdasp->gdas_points[i][X] - halfAxesSize,
+                gdasp->gdas_points[i][Y],
+                gdasp->gdas_points[i][Z]);
+           VSET(B,
+                gdasp->gdas_points[i][X] + halfAxesSize,
+                gdasp->gdas_points[i][Y],
+                gdasp->gdas_points[i][Z]);
+
+           fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(A));
+           fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(B));
+
+           /* draw Y axis with x/y offsets */
+           VSET(A,
+                gdasp->gdas_points[i][X],
+                gdasp->gdas_points[i][Y] - halfAxesSize,
+                gdasp->gdas_points[i][Z]);
+           VSET(B,
+                gdasp->gdas_points[i][X],
+                gdasp->gdas_points[i][Y] + halfAxesSize,
+                gdasp->gdas_points[i][Z]);
+
+           fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(A));
+           fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(B));
+
+           /* draw Z axis with x/y offsets */
+           VSET(A,
+                gdasp->gdas_points[i][X],
+                gdasp->gdas_points[i][Y],
+                gdasp->gdas_points[i][Z] - halfAxesSize);
+           VSET(B,
+                gdasp->gdas_points[i][X],
+                gdasp->gdas_points[i][Y],
+                gdasp->gdas_points[i][Z] + halfAxesSize);
+
+           fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(A));
+           fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(B));
+       }
+
+       for (i = 0; i < gdasp->gdas_num_points; ++i) {
+           fprintf(fp, "l %d %d\n", (i*6)+v_offset, (i*6)+v_offset+1);
+           fprintf(fp, "l %d %d\n", (i*6)+v_offset+2, (i*6)+v_offset+3);
+           fprintf(fp, "l %d %d\n", (i*6)+v_offset+4, (i*6)+v_offset+5);
+       }
+
+       
+       v_offset += (gdasp->gdas_num_points*6);
+    }
+}
+
+static void
+write_data_lines(struct ged_data_line_state *gdlsp, FILE *fp, int sflag)
+{
+    register int i;
+
+    if (gdlsp->gdls_draw) {
+       struct _ged_obj_material *gomp;
+
+       gomp = ged_get_obj_material(gdlsp->gdls_color[0],
+                                   gdlsp->gdls_color[1],
+                                   gdlsp->gdls_color[2],
+                                   1);
+       fprintf(fp, "usemtl %s\n", bu_vls_addr(&gomp->name));
+
+       if (sflag)
+           fprintf(fp, "g sdata_lines\n");
+       else
+           fprintf(fp, "g data_lines\n");
+
+       for (i = 0; i < gdlsp->gdls_num_points; i += 2) {
+           point_t A, B;
+
+           VMOVE(A, gdlsp->gdls_points[i]);
+           VMOVE(B, gdlsp->gdls_points[i+1]);
+
+           fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(A));
+           fprintf(fp, "v %f %f %f\n", V3ARGS_SCALE(B));
+       }
+
+       for (i = 0; i < gdlsp->gdls_num_points; i += 2) {
+           fprintf(fp, "l %d %d\n", i+v_offset, i+v_offset+1);
+       }
+
+       v_offset += gdlsp->gdls_num_points;
+    }
+}
+
+static void
+write_data_obj(struct ged *gedp, FILE *fp)
+{
+    write_data_arrows(&gedp->ged_gvp->gv_data_arrows, fp, 0);
+    write_data_arrows(&gedp->ged_gvp->gv_sdata_arrows, fp, 1);
+
+    write_data_axes(&gedp->ged_gvp->gv_data_axes, fp, 0);
+    write_data_axes(&gedp->ged_gvp->gv_sdata_axes, fp, 1);
+
+    write_data_lines(&gedp->ged_gvp->gv_data_lines, fp, 0);
+    write_data_lines(&gedp->ged_gvp->gv_sdata_lines, fp, 1);
+}
+
+static int
+ged_data_dump(struct ged *gedp, FILE *fp, int fd, const char *file_ext)
+{
+    switch (output_type) {
+    case OTYPE_DXF:
+       break;
+    case OTYPE_OBJ:
+       if (output_directory) {
+           char *cp;
+           struct bu_vls filepath;
+           FILE *data_fp;
+
+           cp = strrchr(output_directory, '/');
+           if (!cp)
+               cp = (char *)output_directory;
+           else
+               ++cp;
+
+           if (*cp == '\0') {
+               bu_vls_printf(&gedp->ged_result_str, "ged_data_dump: bad 
dirname - %s\n", output_directory);
+               return GED_ERROR;
+           }
+
+           bu_vls_init(&filepath);
+           bu_vls_printf(&filepath, "%s/%s_data.obj", output_directory, cp);
+
+           if ((data_fp=fopen(bu_vls_addr(&filepath), "wb+")) == NULL) {
+               bu_vls_printf(&gedp->ged_result_str, "ged_data_dump: failed to 
open %V\n", &filepath);
+               bu_vls_free(&filepath);
+               return GED_ERROR;
+           }
+
+           bu_vls_free(&filepath);
+           write_data_obj(gedp, data_fp);
+           fclose(data_fp);
+       } else
+           write_data_obj(gedp, fp);
+       break;
+    case OTYPE_SAT:
+       break;
+    case OTYPE_STL:
+    default:
+       break;
+    }
+
+    return GED_OK;
+}
+
+int
+ged_dbot_dump(struct ged *gedp, int argc, const char *argv[])
+{
+    char *file_ext = '\0';
+    FILE *fp = (FILE *)0;
+    int fd = -1;
+    mat_t mat;
+    struct ged_display_list *gdlp;
+    const char *cmd_name;
+
+    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+    GED_CHECK_DRAWABLE(gedp, GED_ERROR);
+    GED_CHECK_VIEW(gedp, GED_ERROR);
+    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+    /* initialize result */
+    bu_vls_trunc(&gedp->ged_result_str, 0);
+
+    /* must be wanting help */
+    if (argc == 1) {
+       bu_vls_printf(&gedp->ged_result_str, usage, argv[0]);
+       return GED_HELP;
+    }
+
+    if (ged_bot_dump_get_args(gedp, argc, argv) == GED_ERROR)
+       return GED_ERROR;
+
+    if (bu_optind != argc) {
+       bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_ERROR;
+    }
+
+    if (output_file && output_directory) {
+       fprintf(stderr, "ERROR: options \"-o\" and \"-m\" are mutually 
exclusive\n");
+       return GED_ERROR;
+    }
+
+    if (!output_file && !output_directory) {
+       if (binary) {
+           bu_vls_printf(&gedp->ged_result_str, "Can't output binary to 
stdout\nUsage: %s %s", argv[0], usage);
+           return GED_ERROR;
+       }
+       fp = stdout;
+
+       /* Set this to something non-null in order to possibly write eof */
+       output_file = "stdout";
+    }
+
+    if (output_file) {
+       if (binary && output_type == OTYPE_STL) {
+           char buf[81];       /* need exactly 80 chars for header */
+
+           /* Open binary output file */
+           if ((fd=open(output_file, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
+               perror(argv[0]);
+               bu_vls_printf(&gedp->ged_result_str, "Cannot open binary output 
file (%s) for writing\n", output_file);
+               return GED_ERROR;
+           }
+
+           /* Write out STL header if output file is binary */
+           memset(buf, 0, sizeof(buf));
+           bu_strlcpy(buf, "BRL-CAD generated STL FILE", sizeof(buf));
+           write(fd, &buf, 80);
+
+           /* write a place keeper for the number of triangles */
+           memset(buf, 0, 4);
+           write(fd, &buf, 4);
+       } else {
+           /* Open ASCII output file */
+           if ((fp=fopen(output_file, "wb+")) == NULL) {
+               perror(argv[0]);
+               bu_vls_printf(&gedp->ged_result_str, "Cannot open ascii output 
file (%s) for writing\n", output_file);
+               return GED_ERROR;
+           }
+
+           switch (output_type) {
+               case OTYPE_DXF:
+                   /* output DXF header and start of TABLES section */
+                   fprintf(fp,
+                           "0\nSECTION\n2\nHEADER\n999\n%s (All 
Bots)\n0\nENDSEC\n0\nSECTION\n2\nENTITIES\n",
+                           argv[argc-1]);
+                   break;
+               case OTYPE_SAT:
+                   fprintf(fp, "400 0 1 0\n");
+                   /*XXX Temporarily hardwired */
+#if 1
+                   fprintf(fp, "37 SolidWorks(2008000)-Sat-Convertor-2.0 11 
ACIS 8.0 NT 24 Wed Dec 03 09:26:53 2003\n");
+#else
+                   fprintf(fp, "08 BRL-CAD-bot_dump-4.0 11 ACIS 4.0 NT 24 Thur 
Sep 25 15:00:00 2008\n");
+#endif
+                   fprintf(fp, "1 9.9999999999999995e-007 1e-010\n");
+                   break;
+               default:
+                   break;
+           }
+       }
+    }
+
+    /* save the command name */
+    cmd_name = argv[0];
+
+    if (output_directory) {
+       switch (output_type) {
+           case OTYPE_DXF:
+               file_ext = ".dxf";
+               break;
+           case OTYPE_OBJ:
+               file_ext = ".obj";
+
+               BU_LIST_INIT(&HeadObjMaterials);
+
+               {
+                   char *cp;
+                   struct bu_vls filepath;
+
+                   cp = strrchr(output_directory, '/');
+                   if (!cp)
+                       cp = (char *)output_directory;
+                   else
+                       ++cp;
+
+                   if (*cp == '\0') {
+                       bu_vls_printf(&gedp->ged_result_str, "%s: bad dirname - 
%s\n", cmd_name, output_directory);
+                       return GED_ERROR;
+                   }
+
+                   bu_vls_init(&obj_materials_file);
+                   bu_vls_printf(&obj_materials_file, "%s.mtl", cp);
+
+                   bu_vls_init(&filepath);
+                   bu_vls_printf(&filepath, "%s/%V", output_directory, 
&obj_materials_file);
+
+                   if ((obj_materials_fp=fopen(bu_vls_addr(&filepath), "wb+")) 
== NULL) {
+                       bu_vls_printf(&gedp->ged_result_str, "%s: failed to 
open %V\n", cmd_name, &filepath);
+                       bu_vls_free(&obj_materials_file);
+                       bu_vls_free(&filepath);
+                       return GED_ERROR;
+                   }
+
+                   bu_vls_free(&filepath);
+               }
+
+               num_obj_materials = 0;
+
+               break;
+           case OTYPE_SAT:
+               file_ext = ".sat";
+               break;
+           case OTYPE_STL:
+           default:
+               file_ext = ".stl";
+               break;
+       }
+    } else if (output_type == OTYPE_OBJ) {
+       char *cp;
+
+       bu_vls_init(&obj_materials_file);
+
+       cp = strrchr(output_file, '.');
+       if (!cp)
+           bu_vls_printf(&obj_materials_file, "%s.mtl", output_file);
+       else {
+           /* ignore everything after the last '.' */
+           *cp = '\0';
+           bu_vls_printf(&obj_materials_file, "%s.mtl", output_file);
+           *cp = '.';
+       }
+
+       BU_LIST_INIT(&HeadObjMaterials);
+
+       if ((obj_materials_fp=fopen(bu_vls_addr(&obj_materials_file), "wb+")) 
== NULL) {
+           bu_vls_printf(&gedp->ged_result_str, "%s: failed to open %V\n", 
cmd_name, &obj_materials_file);
+           bu_vls_free(&obj_materials_file);
+           return GED_ERROR;
+       }
+
+       num_obj_materials = 0;
+
+       fprintf(fp, "mtllib %s\n", bu_vls_addr(&obj_materials_file));
+    }
+ 
+    MAT_IDN(mat);
+
+    for (BU_LIST_FOR(gdlp, ged_display_list, &gedp->ged_gdp->gd_headDisplay)) {
+       struct solid *sp;
+
+       FOR_ALL_SOLIDS(sp, &gdlp->gdl_headSolid) {
+           int ret;
+           struct directory *dp;
+           struct rt_db_internal intern;
+           struct rt_bot_internal *bot;
+
+           dp = sp->s_fullpath.fp_names[sp->s_fullpath.fp_len-1];
+
+           /* get the internal form */
+           ret=rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, mat, 
&rt_uniresource);
+
+           if (ret < 0) {
+               bu_log("%s: rt_get_internal failure %d on %s\n", cmd_name, ret, 
dp->d_namep);
+               continue;
+           }
+
+           if (ret != ID_BOT) {
+               bu_log("%s: %s is not a bot (ignored)\n", cmd_name, 
dp->d_namep);
+               rt_db_free_internal(&intern);
+               continue;
+           }
+
+           /* Write out materials */
+           if (output_type == OTYPE_OBJ) {
+#if 0
+               struct _ged_obj_material *gomp;
+
+               gomp = ged_get_obj_material(sp->s_color[0],
+                                           sp->s_color[1],
+                                           sp->s_color[2],
+                                           sp->s_transparency);
+
+               /* Write out usemtl to obj file */
+               fprintf(fp, "usemtl %s\n", bu_vls_addr(&gomp->name));
+#else
+               curr_obj_red = sp->s_color[0];
+               curr_obj_green = sp->s_color[1];
+               curr_obj_blue = sp->s_color[2];
+               curr_obj_alpha = sp->s_transparency;
+#endif
+           }
+
+           bot = (struct rt_bot_internal *)intern.idb_ptr;
+           bot_dump(dp, bot, fp, fd, file_ext, 
gedp->ged_wdbp->dbip->dbi_filename);
+           rt_db_free_internal(&intern);
+       }
+    }
+
+    ged_data_dump(gedp, fp, fd, file_ext);
+
+    if (output_file) {
+       if (binary && output_type == OTYPE_STL) {
+           unsigned char tot_buffer[4];
+
+           /* Re-position pointer to 80th byte */
+           lseek(fd, 80, SEEK_SET);
+
+           /* Write out number of triangles */
+           bu_plong(tot_buffer, (unsigned long)total_faces);
+           lswap((unsigned int *)tot_buffer);
+           write(fd, tot_buffer, 4);
+
+           close(fd);
+       } else {
+           /* end of layers section, start of ENTITIES SECTION */
+           switch (output_type) {
+               case OTYPE_DXF:
+                   fprintf(fp, "0\nENDSEC\n0\nEOF\n");
+                   break;
+               case OTYPE_SAT:
+                   fprintf(fp, "End-of-ACIS-data\n");
+                   break;
+               default:
+                   break;
+           }
+
+           fclose(fp);
+       }
+    }
+
+    if (output_type == OTYPE_OBJ) {
+       bu_vls_free(&obj_materials_file);
+       ged_free_obj_materials();
+       fclose(obj_materials_fp);
+    }
+
+    return GED_OK;
+}
+
+
 /*
  * Local Variables:
  * tab-width: 8


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
BRL-CAD Source Commits mailing list
brlcad-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to