Revision: 41815
          http://brlcad.svn.sourceforge.net/brlcad/?rev=41815&view=rev
Author:   indianlarry
Date:     2010-12-28 18:59:30 +0000 (Tue, 28 Dec 2010)

Log Message:
-----------
Added 'screengrab' command to libged along with hooks for both mged and archer. 
Added '-o imagename.ext' option to 'preview' command to capture a screen grab 
of the active graphics window for each frame of an 'rt' script. Modified the 
'preview' command to get functioning for common 'rt' frame commands. 

Modified Paths:
--------------
    brlcad/trunk/include/dm.h
    brlcad/trunk/include/ged.h
    brlcad/trunk/src/libdm/dm-Null.c
    brlcad/trunk/src/libdm/dm-X.c
    brlcad/trunk/src/libdm/dm-ogl.c
    brlcad/trunk/src/libdm/dm-plot.c
    brlcad/trunk/src/libdm/dm-ps.c
    brlcad/trunk/src/libdm/dm-rtgl.c
    brlcad/trunk/src/libdm/dm-tk.c
    brlcad/trunk/src/libdm/dm-wgl.c
    brlcad/trunk/src/libdm/dm_obj.c
    brlcad/trunk/src/libged/Makefile.am
    brlcad/trunk/src/libged/png.c
    brlcad/trunk/src/libged/preview.c
    brlcad/trunk/src/libged/rt.c
    brlcad/trunk/src/libtclcad/ged_obj.c
    brlcad/trunk/src/mged/cmd.c
    brlcad/trunk/src/mged/cmd.h
    brlcad/trunk/src/mged/setup.c
    brlcad/trunk/src/tclscripts/lib/Ged.tcl
    brlcad/trunk/src/tclscripts/mged/help.tcl

Added Paths:
-----------
    brlcad/trunk/src/libged/screengrab.c

Modified: brlcad/trunk/include/dm.h
===================================================================
--- brlcad/trunk/include/dm.h   2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/include/dm.h   2010-12-28 18:59:30 UTC (rev 41815)
@@ -164,6 +164,28 @@
        (_dr) == (_sr) &&\
        (_dg) == (_sg) &&\
        (_db) == (_sb))
+#if defined(DM_X) || defined(DM_OGL)
+#define DM_REVERSE_COLOR_BYTE_ORDER(_shift, _mask) {   \
+       _shift = 24 - _shift;                           \
+       switch (_shift) {                               \
+           case 0:                                     \
+               _mask >>= 24;                           \
+               break;                                  \
+           case 8:                                     \
+               _mask >>= 8;                            \
+               break;                                  \
+           case 16:                                    \
+               _mask <<= 8;                            \
+               break;                                  \
+           case 24:                                    \
+               _mask <<= 24;                           \
+               break;                                  \
+       }                                               \
+    }
+#else
+/* Do nothing */
+#define DM_REVERSE_COLOR_BYTE_ORDER(_shift, _mask)
+#endif
 
 /* Command parameter to dmr_viewchange() */
 #define DM_CHGV_REDO   0       /* Display has changed substantially */
@@ -217,6 +239,7 @@
     int (*dm_endDList)();
     int (*dm_drawDList)();
     int (*dm_freeDLists)();
+    int (*dm_getDisplayImage)(struct dm *dmp, unsigned char **image);
     unsigned long dm_id;          /**< @brief window id */
     int dm_displaylist;                /**< @brief !0 means device has 
displaylist */
     int dm_stereo;                /**< @brief stereo flag */
@@ -228,6 +251,8 @@
     int dm_top;                   /**< @brief !0 means toplevel window */
     int dm_width;
     int dm_height;
+    int dm_bytes_per_pixel;
+    int dm_bits_per_channel;  /* bits per color channel */
     int dm_lineWidth;
     int dm_lineStyle;
     fastf_t dm_aspect;
@@ -299,6 +324,7 @@
 #define DM_ENDDLIST(_dmp) _dmp->dm_endDList(_dmp)
 #define DM_DRAWDLIST(_dmp, _list) _dmp->dm_drawDList(_dmp, _list)
 #define DM_FREEDLISTS(_dmp, _list, _range) _dmp->dm_freeDLists(_dmp, _list, 
_range)
+#define DM_GET_DISPLAY_IMAGE(_dmp, _image) _dmp->dm_getDisplayImage(_dmp, 
_image)
 
 DM_EXPORT extern struct dm dm_Null;
 
@@ -440,7 +466,8 @@
    HIDDEN int _dmtype##_beginDList(struct dm *dmp, unsigned int list); \
    HIDDEN int _dmtype##_endDList(struct dm *dmp); \
    HIDDEN int _dmtype##_drawDList(struct dm *dmp, unsigned int list); \
-   HIDDEN int _dmtype##_freeDLists(struct dm *dmp, unsigned int list, int 
range); 
+   HIDDEN int _dmtype##_freeDLists(struct dm *dmp, unsigned int list, int 
range); \
+   HIDDEN int _dmtype##_getDisplayImage(struct dm *dmp, unsigned char **image);
 
 #endif /* __DM_H__ */
 

Modified: brlcad/trunk/include/ged.h
===================================================================
--- brlcad/trunk/include/ged.h  2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/include/ged.h  2010-12-28 18:59:30 UTC (rev 41815)
@@ -495,6 +495,7 @@
     struct ged_drawable                *ged_gdp;
     struct ged_view            *ged_gvp;
 
+    void                       *ged_dmp;
     void                       *ged_refresh_clientdata;        /**< @brief  
client data passed to refresh handler */
     void                       (*ged_refresh_handler)();       /**< @brief  
function for handling refresh requests */
     void                       (*ged_output_handler)();        /**< @brief  
function for handling output */
@@ -2387,6 +2388,7 @@
  *     png [-s size] file.png
  */
 GED_EXPORT BU_EXTERN(int ged_png, (struct ged *gedp, int argc, const char 
*argv[]));
+GED_EXPORT BU_EXTERN(int ged_screen_grab, (struct ged *gedp, int argc, const 
char *argv[]));
 
 /**
  * Set point of view

Modified: brlcad/trunk/src/libdm/dm-Null.c
===================================================================
--- brlcad/trunk/src/libdm/dm-Null.c    2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/libdm/dm-Null.c    2010-12-28 18:59:30 UTC (rev 41815)
@@ -122,6 +122,7 @@
     Nu_int0,
     Nu_int0,
     Nu_int0,
+    Nu_int0, /* display to image function */
     0,
     0,                         /* no displaylist */
     0,                         /* no stereo */
@@ -130,13 +131,15 @@
     "nu",
     "Null Display",
     DM_TYPE_NULL,
+    0,/* top */
+    0,/* width */
+    0,/* height */
+    0,/* bytes per pixel */
+    0,/* bits per channel */
     0,
     0,
     0,
     0,
-    0,
-    0,
-    0,
     {0, 0},
     {0, 0, 0, 0, 0},           /* bu_vls path name*/
     {0, 0, 0, 0, 0},           /* bu_vls full name drawing window */

Modified: brlcad/trunk/src/libdm/dm-X.c
===================================================================
--- brlcad/trunk/src/libdm/dm-X.c       2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/libdm/dm-X.c       2010-12-28 18:59:30 UTC (rev 41815)
@@ -1397,7 +1397,221 @@
     return TCL_OK;
 }
 
+HIDDEN int
+X_getDisplayImage(struct dm *dmp, unsigned char **image)
+{
+    XImage *ximage_p;
+    unsigned char **rows;
+    unsigned char *idata;
+    unsigned char *irow;
+    int bytes_per_pixel;
+    int bytes_per_pixel_output = 3; /* limit for current bu_image raw pix 
usage */
+    int bytes_per_line_output;
+    int bits_per_channel = 8;  /* bits per color channel */
+    int i, j, k;
+    unsigned char *dbyte0, *dbyte1, *dbyte2, *dbyte3;
+    int red_shift;
+    int green_shift;
+    int blue_shift;
+    int red_bits;
+    int green_bits;
+    int blue_bits;
 
+
+    ximage_p = XGetImage(((struct dm_xvars *)dmp->dm_vars.pub_vars)->dpy,
+                        ((struct dm_xvars *)dmp->dm_vars.pub_vars)->win,
+                        0, 0,
+                        dmp->dm_width,
+                        dmp->dm_height,
+                        ~0, ZPixmap);
+
+    if (!ximage_p) {
+       bu_log("png: could not get XImage\n", (char *)NULL);
+       return TCL_ERROR;
+    }
+
+    bytes_per_pixel = ximage_p->bytes_per_line / ximage_p->width;
+
+    if (bytes_per_pixel == 4) {
+       unsigned long mask;
+       unsigned long tmask;
+
+       /* This section assumes 8 bits per channel */
+
+       mask = ximage_p->red_mask;
+       tmask = 1;
+       for (red_shift = 0; red_shift < 32; red_shift++) {
+           if (tmask & mask)
+               break;
+           tmask = tmask << 1;
+       }
+
+       mask = ximage_p->green_mask;
+       tmask = 1;
+       for (green_shift = 0; green_shift < 32; green_shift++) {
+           if (tmask & mask)
+               break;
+           tmask = tmask << 1;
+       }
+
+       mask = ximage_p->blue_mask;
+       tmask = 1;
+       for (blue_shift = 0; blue_shift < 32; blue_shift++) {
+           if (tmask & mask)
+               break;
+           tmask = tmask << 1;
+       }
+
+       /*
+        * We need to reverse things if the image byte order
+        * is different from the system's byte order.
+        */
+       if (((bu_byteorder() == BU_BIG_ENDIAN) && (ximage_p->byte_order == 
LSBFirst)) ||
+           ((bu_byteorder() == BU_LITTLE_ENDIAN) && (ximage_p->byte_order == 
MSBFirst))) {
+           DM_REVERSE_COLOR_BYTE_ORDER(red_shift, ximage_p->red_mask);
+           DM_REVERSE_COLOR_BYTE_ORDER(green_shift, ximage_p->green_mask);
+           DM_REVERSE_COLOR_BYTE_ORDER(blue_shift, ximage_p->blue_mask);
+       }
+
+    } else if (bytes_per_pixel == 2) {
+       unsigned long mask;
+       unsigned long tmask;
+       int bpb = 8;   /* bits per byte */
+
+       /*XXX
+        * This section probably needs logic similar
+        * to the previous section (i.e. bytes_per_pixel == 4).
+        * That is we may need to reverse things depending on
+        * the image byte order and the system's byte order.
+        */
+
+       mask = ximage_p->red_mask;
+       tmask = 1;
+       for (red_shift = 0; red_shift < 16; red_shift++) {
+           if (tmask & mask)
+               break;
+           tmask = tmask << 1;
+       }
+       for (red_bits = red_shift; red_bits < 16; red_bits++) {
+           if (!(tmask & mask))
+               break;
+           tmask = tmask << 1;
+       }
+
+       red_bits = red_bits - red_shift;
+       if (red_shift == 0)
+           red_shift = red_bits - bpb;
+       else
+           red_shift = red_shift - (bpb - red_bits);
+
+       mask = ximage_p->green_mask;
+       tmask = 1;
+       for (green_shift = 0; green_shift < 16; green_shift++) {
+           if (tmask & mask)
+               break;
+           tmask = tmask << 1;
+       }
+       for (green_bits = green_shift; green_bits < 16; green_bits++) {
+           if (!(tmask & mask))
+               break;
+           tmask = tmask << 1;
+       }
+
+       green_bits = green_bits - green_shift;
+       green_shift = green_shift - (bpb - green_bits);
+
+       mask = ximage_p->blue_mask;
+       tmask = 1;
+       for (blue_shift = 0; blue_shift < 16; blue_shift++) {
+           if (tmask & mask)
+               break;
+           tmask = tmask << 1;
+       }
+       for (blue_bits = blue_shift; blue_bits < 16; blue_bits++) {
+           if (!(tmask & mask))
+               break;
+           tmask = tmask << 1;
+       }
+       blue_bits = blue_bits - blue_shift;
+
+       if (blue_shift == 0)
+           blue_shift = blue_bits - bpb;
+       else
+           blue_shift = blue_shift - (bpb - blue_bits);
+    } else {
+       bu_log("png: %d bytes per pixel is not yet supported\n", 
bytes_per_pixel);
+       return TCL_ERROR;
+    }
+
+    rows = (unsigned char **)bu_calloc(ximage_p->height, sizeof(unsigned char 
*), "rows");
+    idata = (unsigned char *)bu_calloc(ximage_p->height * ximage_p->width, 
bytes_per_pixel_output, "png data");
+    *image = idata;
+
+    /* for each scanline */
+    bytes_per_line_output = ximage_p->width * bytes_per_pixel_output;
+    for (i = ximage_p->height - 1, j = 0; 0 <= i; --i, ++j) {
+       /* irow points to the current scanline in ximage_p */
+       irow = (unsigned char *)(ximage_p->data + 
((ximage_p->height-i-1)*ximage_p->bytes_per_line));
+
+       if (bytes_per_pixel == 4) {
+           unsigned int pixel;
+
+           /* rows[j] points to the current scanline in idata */
+           rows[j] = (unsigned char *)(idata + 
((ximage_p->height-i-1)*bytes_per_line_output));
+
+           /* for each pixel in current scanline of ximage_p */
+           for (k = 0; k < ximage_p->width; k++) {
+               pixel = *((unsigned int *)(irow + k*bytes_per_pixel));
+
+               dbyte0 = rows[j] + k*bytes_per_pixel_output;
+               dbyte1 = dbyte0 + 1;
+               dbyte2 = dbyte0 + 2;
+
+               *dbyte0 = (pixel & ximage_p->red_mask) >> red_shift;
+               *dbyte1 = (pixel & ximage_p->green_mask) >> green_shift;
+               *dbyte2 = (pixel & ximage_p->blue_mask) >> blue_shift;
+           }
+       } else if (bytes_per_pixel == 2) {
+           unsigned short spixel;
+           unsigned long pixel;
+
+           /* rows[j] points to the current scanline in idata */
+           rows[j] = (unsigned char *)(idata + 
((ximage_p->height-i-1)*bytes_per_line_output));
+
+           /* for each pixel in current scanline of ximage_p */
+           for (k = 0; k < ximage_p->width; k++) {
+               spixel = *((unsigned short *)(irow + k*bytes_per_pixel));
+               pixel = spixel;
+
+               dbyte0 = rows[j] + k*bytes_per_pixel_output;
+               dbyte1 = dbyte0 + 1;
+               dbyte2 = dbyte0 + 2;
+
+               if (0 <= red_shift)
+                   *dbyte0 = (pixel & ximage_p->red_mask) >> red_shift;
+               else
+                   *dbyte0 = (pixel & ximage_p->red_mask) << -red_shift;
+
+               *dbyte1 = (pixel & ximage_p->green_mask) >> green_shift;
+
+               if (0 <= blue_shift)
+                   *dbyte2 = (pixel & ximage_p->blue_mask) >> blue_shift;
+               else
+                   *dbyte2 = (pixel & ximage_p->blue_mask) << -blue_shift;
+           }
+       } else {
+           bu_free(rows, "rows");
+           bu_free(idata, "image data");
+
+           bu_log("png: not supported for this platform\n", (char *)NULL);
+           return TCL_ERROR;
+       }
+    }
+
+    bu_free(rows, "rows");
+    return TCL_OK;
+}
+
 /* Display Manager package interface */
 struct dm dm_X = {
     X_close,
@@ -1427,6 +1641,7 @@
     Nu_int0,
     Nu_int0,
     Nu_int0,
+    X_getDisplayImage, /* display to image function */
     0,
     0,                         /* no displaylist */
     0,                            /* no stereo */
@@ -1438,6 +1653,8 @@
     1,
     0,
     0,
+    0,/* bytes per pixel */
+    0,/* bits per channel */
     0,
     0,
     1.0, /* aspect ratio */

Modified: brlcad/trunk/src/libdm/dm-ogl.c
===================================================================
--- brlcad/trunk/src/libdm/dm-ogl.c     2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/libdm/dm-ogl.c     2010-12-28 18:59:30 UTC (rev 41815)
@@ -127,6 +127,7 @@
 HIDDEN int ogl_endDList(struct dm *dmp);
 HIDDEN int ogl_drawDList(struct dm *dmp, unsigned int list);
 HIDDEN int ogl_freeDLists(struct dm *dmp, unsigned int list, int range);
+HIDDEN int ogl_getDisplayImage(struct dm *dmp, unsigned char **image);
 
 HIDDEN int ogl_drawString2D(struct dm *dmp, char *str, fastf_t x, fastf_t y, 
int size, int use_aspect);
 HIDDEN int ogl_setLight(struct dm *dmp, int lighting_on);
@@ -160,6 +161,7 @@
     ogl_endDList,
     ogl_drawDList,
     ogl_freeDLists,
+    ogl_getDisplayImage, /* display to image function */
     0,
     1,                         /* has displaylist */
     0,                          /* no stereo by default */
@@ -171,6 +173,8 @@
     1,
     0,
     0,
+    0,/* bytes per pixel */
+    0,/* bits per channel */
     0,
     0,
     1.0, /* aspect ratio */
@@ -693,6 +697,8 @@
     *dmp = dm_ogl; /* struct copy */
     dmp->dm_interp = interp;
     dmp->dm_lineWidth = 1;
+       dmp->dm_bytes_per_pixel = sizeof(GLuint);
+       dmp->dm_bits_per_channel = 8;
 
     dmp->dm_vars.pub_vars = (genptr_t)bu_calloc(1, sizeof(struct dm_xvars), 
"ogl_open: dm_xvars");
     if (dmp->dm_vars.pub_vars == (genptr_t)NULL) {
@@ -2054,7 +2060,7 @@
     return TCL_OK;
 }
 
-int
+HIDDEN int
 ogl_beginDList(struct dm *dmp, unsigned int list)
 {
     if (dmp->dm_debugLevel)
@@ -2071,7 +2077,7 @@
     return TCL_OK;
 }
 
-int
+HIDDEN int
 ogl_endDList(struct dm *dmp)
 {
     if (dmp->dm_debugLevel)
@@ -2081,7 +2087,7 @@
     return TCL_OK;
 }
 
-int
+HIDDEN int
 ogl_drawDList(struct dm *dmp, unsigned int list)
 {
     if (dmp->dm_debugLevel)
@@ -2091,7 +2097,7 @@
     return TCL_OK;
 }
 
-int
+HIDDEN int
 ogl_freeDLists(struct dm *dmp, unsigned int list, int range)
 {
     if (dmp->dm_debugLevel)
@@ -2108,6 +2114,107 @@
     return TCL_OK;
 }
 
+HIDDEN int
+ogl_getDisplayImage(struct dm *dmp, unsigned char **image)
+{
+    unsigned char *idata = NULL;
+    int width = 0;
+    int height = 0;
+    int found_valid_dm = 0;
+    int bytes_per_pixel = 3; /*rgb no alpha for raw pix */
+    GLuint *pixels;
+    unsigned int pixel;
+    unsigned int red_mask = 0xff000000;
+    unsigned int green_mask = 0x00ff0000;
+    unsigned int blue_mask = 0x0000ff00;
+    unsigned int alpha_mask = 0x000000ff;
+    int h,w;
+    int big_endian, swap_bytes;
+
+    if ((bu_byteorder() == BU_BIG_ENDIAN))
+       big_endian = 1;
+    else
+       big_endian = 0;
+
+#if defined(DM_WGL)
+    /* WTF */
+    swap_bytes = !big_endian;
+#else
+    swap_bytes = big_endian;
+#endif
+
+    if (dmp->dm_type == DM_TYPE_WGL || dmp->dm_type == DM_TYPE_OGL) {
+       int make_ret = 0;
+       found_valid_dm = 1;
+       width = dmp->dm_width;
+       height = dmp->dm_height;
+
+       pixels = bu_calloc(width * height, sizeof(GLuint), "pixels");
+
+#if defined(DM_WGL)
+       make_ret = wglMakeCurrent(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->hdc,
+                                 ((struct wgl_vars 
*)dmp->dm_vars.priv_vars)->glxc);
+#else
+       make_ret = glXMakeCurrent(((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->dpy,
+                                 ((struct dm_xvars 
*)dmp->dm_vars.pub_vars)->win,
+                                 ((struct ogl_vars 
*)dmp->dm_vars.priv_vars)->glxc);
+#endif
+
+       {
+
+
+           glReadBuffer(GL_FRONT);
+#if defined(DM_WGL)
+           /* XXX GL_UNSIGNED_INT_8_8_8_8 is currently not
+            * available on windows.  Need to update when it
+            * becomes available.
+            */
+           glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 
pixels);
+#else
+           glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 
pixels);
+#endif
+
+           idata = (unsigned char *)bu_calloc(height * width * 
bytes_per_pixel,sizeof(unsigned char),"rgb data");
+           *image = idata;
+
+           for (h = 0; h < height; h++) {
+                   for (w = 0; w < width; w++) {
+                       int i = h*width + w;
+                       int i_h_inv = (height - h - 1)*width + w;
+                       int j = i*bytes_per_pixel;
+                               unsigned char *value = (unsigned char *)(idata 
+ j);
+                               unsigned char alpha;
+                               pixel = pixels[i_h_inv];
+
+                               value[0] = (pixel & red_mask) >> 24;
+                               value[1] = (pixel & green_mask) >> 16;
+                               value[2] = (pixel & blue_mask) >> 8;
+                               alpha = pixel & alpha_mask;
+#if defined(DM_WGL)
+                               if (swap_bytes) {
+                                       unsigned char tmp_byte;
+
+                                       value[0] = alpha;
+                                       /* swap byte1 and byte2 */
+                                       tmp_byte = value[1];
+                                       value[1] = value[2];
+                                       value[2] = tmp_byte;
+                               }
+#endif
+                       }
+
+           }
+
+           bu_free(pixels, "pixels");
+       }
+    } else {
+       bu_log("ogl_getDisplayImage: Display type not set as OGL or WGL\n");
+       return TCL_ERROR;
+    }
+
+    return TCL_OK; /* caller will need to bu_free(idata, "image data"); */
+}
+
 #endif /* DM_OGL */
 
 /*

Modified: brlcad/trunk/src/libdm/dm-plot.c
===================================================================
--- brlcad/trunk/src/libdm/dm-plot.c    2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/libdm/dm-plot.c    2010-12-28 18:59:30 UTC (rev 41815)
@@ -85,6 +85,7 @@
     Nu_int0,
     Nu_int0,
     Nu_int0,
+    Nu_int0, /* display to image function */
     0,
     0,                         /* no displaylist */
     0,                         /* no stereo */
@@ -96,6 +97,8 @@
     0,
     0,
     0,
+    0,/* bytes per pixel */
+    0,/* bits per channel */
     0,
     0,
     1.0, /* aspect ratio */

Modified: brlcad/trunk/src/libdm/dm-ps.c
===================================================================
--- brlcad/trunk/src/libdm/dm-ps.c      2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/libdm/dm-ps.c      2010-12-28 18:59:30 UTC (rev 41815)
@@ -85,6 +85,7 @@
     Nu_int0,
     Nu_int0,
     Nu_int0,
+    Nu_int0, /* display to image function */
     0,
     0,                         /* no displaylist */
     0,                            /* no stereo */
@@ -96,6 +97,8 @@
     0,
     0,
     0,
+    0,/* bytes per pixel */
+    0,/* bits per channel */
     0,
     0,
     1.0, /* aspect ratio */

Modified: brlcad/trunk/src/libdm/dm-rtgl.c
===================================================================
--- brlcad/trunk/src/libdm/dm-rtgl.c    2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/libdm/dm-rtgl.c    2010-12-28 18:59:30 UTC (rev 41815)
@@ -115,6 +115,7 @@
     rtgl_endDList,
     rtgl_drawDList,
     rtgl_freeDLists,
+    Nu_int0, /* display to image function */
     0,
     1,                         /* has displaylist */
     0,                          /* no stereo by default */
@@ -126,6 +127,8 @@
     1,
     0,
     0,
+    0,/* bytes per pixel */
+    0,/* bits per channel */
     0,
     0,
     1.0, /* aspect ratio */

Modified: brlcad/trunk/src/libdm/dm-tk.c
===================================================================
--- brlcad/trunk/src/libdm/dm-tk.c      2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/libdm/dm-tk.c      2010-12-28 18:59:30 UTC (rev 41815)
@@ -105,6 +105,7 @@
     Nu_int0,
     Nu_int0,
     Nu_int0,
+    Nu_int0, /* display to image function */
     0,
     0,                         /* no displaylist */
     0,                            /* no stereo */
@@ -116,6 +117,8 @@
     1,
     0,
     0,
+    0,/* bytes per pixel */
+    0,/* bits per channel */
     0,
     0,
     1.0, /* aspect ratio */

Modified: brlcad/trunk/src/libdm/dm-wgl.c
===================================================================
--- brlcad/trunk/src/libdm/dm-wgl.c     2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/libdm/dm-wgl.c     2010-12-28 18:59:30 UTC (rev 41815)
@@ -2052,6 +2052,7 @@
     wgl_endDList,
     wgl_drawDList,
     wgl_freeDLists,
+    Nu_int0, /* display to image function */
     0,
     1,                         /* has displaylist */
     0,                            /* no stereo by default */
@@ -2063,6 +2064,8 @@
     1,
     0,
     0,
+    0,/* bytes per pixel */
+    0,/* bits per channel */
     1,
     0,
     1.0, /* aspect ratio */

Modified: brlcad/trunk/src/libdm/dm_obj.c
===================================================================
--- brlcad/trunk/src/libdm/dm_obj.c     2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/libdm/dm_obj.c     2010-12-28 18:59:30 UTC (rev 41815)
@@ -2331,29 +2331,6 @@
 
 #if defined(DM_X) || defined(DM_OGL)
 
-#if 1
-#define DM_REVERSE_COLOR_BYTE_ORDER(_shift, _mask) {   \
-       _shift = 24 - _shift;                           \
-       switch (_shift) {                               \
-           case 0:                                     \
-               _mask >>= 24;                           \
-               break;                                  \
-           case 8:                                     \
-               _mask >>= 8;                            \
-               break;                                  \
-           case 16:                                    \
-               _mask <<= 8;                            \
-               break;                                  \
-           case 24:                                    \
-               _mask <<= 24;                           \
-               break;                                  \
-       }                                               \
-    }
-#else
-/* Do nothing */
-#define DM_REVERSE_COLOR_BYTE_ORDER(_shift, _mask)
-#endif
-
 HIDDEN int
 dmo_png_cmd(struct dm_obj *dmop,
            Tcl_Interp *interp,

Modified: brlcad/trunk/src/libged/Makefile.am
===================================================================
--- brlcad/trunk/src/libged/Makefile.am 2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/libged/Makefile.am 2010-12-28 18:59:30 UTC (rev 41815)
@@ -200,6 +200,7 @@
        scale_superell.c \
        scale_tgc.c \
        scale_tor.c \
+       screengrab.c \
        search.c \
        select.c \
        set_output_script.c \

Modified: brlcad/trunk/src/libged/png.c
===================================================================
--- brlcad/trunk/src/libged/png.c       2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/libged/png.c       2010-12-28 18:59:30 UTC (rev 41815)
@@ -35,6 +35,7 @@
 #include "vmath.h"
 #include "bn.h"
 #include "solid.h"
+#include "dm.h"
 
 #include "./ged_private.h"
 
@@ -479,7 +480,6 @@
     return ret;
 }
 
-
 /*
  * Local Variables:
  * tab-width: 8

Modified: brlcad/trunk/src/libged/preview.c
===================================================================
--- brlcad/trunk/src/libged/preview.c   2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/libged/preview.c   2010-12-28 18:59:30 UTC (rev 41815)
@@ -43,6 +43,8 @@
 static int preview_finalframe;
 static int preview_currentframe;
 static int preview_tree_walk_needed;
+static int draw_eye_path;
+static char *image_name = NULL;
 
 #define MAXARGS 9000 /* restore locally until preview command is sorted out */
 static char rt_cmd_storage[MAXARGS*9];
@@ -77,7 +79,7 @@
     /* Free animation structures */
     db_free_anim(_ged_current_gedp->ged_wdbp->dbip);
 
-    preview_tree_walk_needed = 1;
+    preview_tree_walk_needed = 0;
     return 0;
 }
 
@@ -136,7 +138,7 @@
        av[1] = NULL;
 
        (void)ged_zap(_ged_current_gedp, 1, av);
-       _ged_drawtrees(_ged_current_gedp, 
_ged_current_gedp->ged_gdp->gd_rt_cmd_len, (const char 
**)_ged_current_gedp->ged_gdp->gd_rt_cmd, preview_mode, (struct 
_ged_client_data *)0);
+       _ged_drawtrees(_ged_current_gedp, 
_ged_current_gedp->ged_gdp->gd_rt_cmd_len, (const char 
**)&_ged_current_gedp->ged_gdp->gd_rt_cmd[1], preview_mode, (struct 
_ged_client_data *)0);
        ged_color_soltab(&_ged_current_gedp->ged_gdp->gd_headDisplay);
     }
 
@@ -189,7 +191,7 @@
        cp += strlen(cp) + 1;
     }
     _ged_current_gedp->ged_gdp->gd_rt_cmd[i] = (char *)0;
-    _ged_current_gedp->ged_gdp->gd_rt_cmd_len = i;
+    _ged_current_gedp->ged_gdp->gd_rt_cmd_len = i-1;
 
     preview_tree_walk_needed = 1;
 
@@ -230,7 +232,39 @@
      0,                0, 0}   /* END */
 };
 
+int
+ged_loadframe(struct ged *gedp, FILE *fp)
+{
+    char *cmd;
+    int        c;
+    vect_t temp;
 
+    int end = 0;
+    while (!end && ((cmd = rt_read_cmd(fp)) != NULL)) {
+       /* Hack to prevent running framedone scripts prematurely */
+       if (cmd[0] == '!') {
+           if (preview_currentframe < preview_desiredframe ||
+               (preview_finalframe && preview_currentframe > 
preview_finalframe)) {
+               bu_free((genptr_t)cmd, "preview ! cmd");
+               continue;
+           }
+       }
+
+       if ( cmd[0] == 'e' && strncmp( cmd, "end", 3 ) == 0 ) {
+               end = 1;
+       }
+
+       if (rt_do_cmd((struct rt_i *)0, cmd, ged_preview_cmdtab) < 0)
+           bu_vls_printf(&gedp->ged_result_str, "command failed: %s\n", cmd);
+       bu_free((genptr_t)cmd, "preview cmd");
+    }
+
+    if (end) {
+       return GED_OK; //possible more frames
+    }
+    return GED_ERROR; //end of frames
+}
+
 /**
  * Preview a new style RT animation script.
  * Note that the RT command parser code is used, rather than the
@@ -245,14 +279,18 @@
 int
 ged_preview(struct ged *gedp, int argc, const char *argv[])
 {
-    static const char *usage = "[-v] [-d sec_delay] [-D start frame] [-K last 
frame] rt_script_file";
+    static const char *usage = "[-v] [-e] [-o image_name.ext]  [-d sec_delay] 
[-D start frame] [-K last frame] rt_script_file";
 
     FILE *fp;
     char *cmd;
     int c;
     vect_t temp;
     char **vp;
-    const char *argv0 = NULL;
+    size_t args = 0;
+    genptr_t dmp = NULL;
+    struct bu_vls extension;
+    struct bu_vls name;
+    char *dot;
 
     GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
     GED_CHECK_DRAWABLE(gedp, GED_ERROR);
@@ -276,12 +314,13 @@
     preview_mode = 1;                  /* wireframe drawing */
     preview_desiredframe = 0;
     preview_finalframe = 0;
+    draw_eye_path = 0;
     _ged_current_gedp = gedp;
-    argv0 = argv[0]; /* temp stash */
+    image_name = NULL;
 
     /* Parse options */
     bu_optind = 1;                     /* re-init bu_getopt() */
-    while ((c=bu_getopt(argc, (char * const *)argv, "d:vD:K:")) != EOF) {
+    while ((c=bu_getopt(argc, (char * const *)argv, "d:evD:K:o:")) != EOF) {
        switch (c) {
            case 'd':
                preview_delay = atof(bu_optarg);
@@ -289,9 +328,15 @@
            case 'D':
                preview_desiredframe = atof(bu_optarg);
                break;
-           case 'K':
+           case 'e':
+               draw_eye_path = 1;
+               break;
+               case 'K':
                preview_finalframe = atof(bu_optarg);
                break;
+           case 'o':
+               image_name = bu_optarg;
+               break;
            case 'v':
                preview_mode = 3;       /* Like "ev" */
                break;
@@ -299,9 +344,12 @@
                {
                    bu_vls_printf(&gedp->ged_result_str, "option '%c' 
unknown\n", c);
                    bu_vls_printf(&gedp->ged_result_str, "        -d#     
inter-frame delay\n");
+                   bu_vls_printf(&gedp->ged_result_str, "        -e      
overlay plot of eye path\n");
                    bu_vls_printf(&gedp->ged_result_str, "        -v      
polygon rendering (visual)\n");
                    bu_vls_printf(&gedp->ged_result_str, "        -D#     
desired starting frame\n");
                    bu_vls_printf(&gedp->ged_result_str, "        -K#     final 
frame\n");
+                   bu_vls_printf(&gedp->ged_result_str, "        -o 
image_name.ext     output frame to file typed by extension(defaults to PIX)\n");
+                   return GED_ERROR;
                }
 
                break;
@@ -315,15 +363,16 @@
        return GED_ERROR;
     }
 
+    args = argc + 2 + ged_count_tops(gedp);
+    gedp->ged_gdp->gd_rt_cmd = (char **)bu_calloc(args, sizeof(char *), "alloc 
gd_rt_cmd");
+    vp = &gedp->ged_gdp->gd_rt_cmd[0];
+    *vp++ = bu_strdup("tree");
+
     /* Build list of top-level objects in view, in 
_ged_current_gedp->ged_gdp->gd_rt_cmd[] */
-    vp = _ged_current_gedp->ged_gdp->gd_rt_cmd;
-    _ged_current_gedp->ged_gdp->gd_rt_cmd_len = vp - 
_ged_current_gedp->ged_gdp->gd_rt_cmd;
-    _ged_current_gedp->ged_gdp->gd_rt_cmd_len += ged_build_tops(gedp, 
-                                                               vp, 
&_ged_current_gedp->ged_gdp->gd_rt_cmd[MAXARGS]);
-
+    _ged_current_gedp->ged_gdp->gd_rt_cmd_len = ged_build_tops(gedp, vp, 
&_ged_current_gedp->ged_gdp->gd_rt_cmd[args]);
     /* Print out the command we are about to run */
     vp = &_ged_current_gedp->ged_gdp->gd_rt_cmd[0];
-    while (*vp)
+    while ((vp != NULL) && (*vp))
        bu_vls_printf(&gedp->ged_result_str, "%s ", *vp++);
     
     bu_vls_printf(&gedp->ged_result_str, "\n");
@@ -332,6 +381,7 @@
 
     bu_vls_printf(&gedp->ged_result_str, "eyepoint at (0, 0, 1) viewspace\n");
 
+
     /*
      * Initialize the view to the current one provided by the ged
      * structure in case a view specification is never given.
@@ -340,23 +390,51 @@
     VSET(temp, 0.0, 0.0, 1.0);
     MAT4X3PNT(_ged_eye_model, gedp->ged_gvp->gv_view2model, temp);
 
-    while ((cmd = rt_read_cmd(fp)) != NULL) {
-       /* Hack to prevent running framedone scripts prematurely */
-       if (cmd[0] == '!') {
-           if (preview_currentframe < preview_desiredframe ||
-               (preview_finalframe && preview_currentframe > 
preview_finalframe)) {
-               bu_free((genptr_t)cmd, "preview ! cmd");
-               continue;
-           }
+    if (image_name) {
+       /* parse file name and possible extension */
+       bu_vls_init(&name);
+       bu_vls_init(&extension);
+       if ((dot = strrchr(image_name, '.')) != (char *) NULL) {
+           bu_vls_strncpy(&name, image_name, dot - image_name);
+           bu_vls_strcpy(&extension, dot);
+       } else {
+           bu_vls_strcpy(&extension, "");
+           bu_vls_strcpy(&name, image_name);
        }
-       if (rt_do_cmd((struct rt_i *)0, cmd, ged_preview_cmdtab) < 0)
-           bu_vls_printf(&gedp->ged_result_str, "command failed: %s\n", cmd);
-       bu_free((genptr_t)cmd, "preview cmd");
     }
+    while (ged_loadframe(gedp, fp) == GED_OK) {
+       if (image_name) {
+           struct bu_vls fullname;
+           char *screengrab_args[3];
+           int screengrab_argc = 0;
+           struct view_obj *vop;
+
+           bu_vls_init(&fullname);
+
+           screengrab_args[screengrab_argc++] = "screengrab";
+
+           bu_vls_sprintf(&fullname, "%s%05d%s", bu_vls_addr(&name),
+                   preview_currentframe, bu_vls_addr(&extension));
+           screengrab_args[screengrab_argc++] = bu_vls_addr(&fullname);
+
+           /* ged_png(gedp,screengrab_argc,screengrab_args); */
+           ged_screen_grab(gedp, screengrab_argc, screengrab_args);
+
+           bu_vls_free(&fullname);
+       }
+    }
+
+    if (image_name) {
+       bu_vls_free(&name);
+       bu_vls_free(&extension);
+    }
+
     fclose(fp);
     fp = NULL;
 
-    _ged_cvt_vlblock_to_solids(gedp, preview_vbp, "EYE_PATH", 0);
+    if (draw_eye_path)
+       _ged_cvt_vlblock_to_solids(gedp, preview_vbp, "EYE_PATH", 0);
+
     if (preview_vbp) {
        rt_vlblock_free(preview_vbp);
        preview_vbp = (struct bn_vlblock *)NULL;

Modified: brlcad/trunk/src/libged/rt.c
===================================================================
--- brlcad/trunk/src/libged/rt.c        2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/libged/rt.c        2010-12-28 18:59:30 UTC (rev 41815)
@@ -517,15 +517,18 @@
        if (gdlp->gdl_dp->d_addr == RT_DIR_PHONY_ADDR)
            continue;
 
-       if (vp < end)
-           *vp++ = bu_vls_addr(&gdlp->gdl_path);
+       if ((vp != NULL) && (vp < end))
+           *vp++ = bu_strdup(bu_vls_addr(&gdlp->gdl_path));
        else {
            bu_vls_printf(&gedp->ged_result_str, "libged: ran out of command 
vector space at %s\n", gdlp->gdl_dp->d_namep);
            break;
        }
     }
 
-    *vp = (char *) 0;
+    if ((vp != NULL) && (vp < end)) {
+       *vp = (char *) 0;
+    }
+
     return vp-start;
 }
 

Added: brlcad/trunk/src/libged/screengrab.c
===================================================================
--- brlcad/trunk/src/libged/screengrab.c                                (rev 0)
+++ brlcad/trunk/src/libged/screengrab.c        2010-12-28 18:59:30 UTC (rev 
41815)
@@ -0,0 +1,117 @@
+/*                         S C R E E N G R A B . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-2010 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file screengrab.c
+ *
+ * The screengrab command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "bu.h"
+#include "dm.h"
+
+#include "./ged_private.h"
+
+int
+ged_screen_grab(struct ged *gedp,int argc, const char *argv[])
+{
+
+    FILE *fp;
+    int i;
+    int width = 0;
+    int height = 0;
+    int bytes_per_pixel = 0;
+    int bits_per_channel = 0;
+    int bytes_per_line = 0;
+    static const char *usage = "image_name.ext";
+    unsigned char **rows = NULL;
+    unsigned char *idata = NULL;
+    struct bu_image_file *bif = NULL;  /* bu image for saving image formats */
+    struct dm *dmp = NULL;
+
+    if ((dmp = ( struct dm *)gedp->ged_dmp) == NULL) {
+               bu_vls_printf(&gedp->ged_result_str, "Bad display pointer.");
+               return GED_ERROR;
+       }
+
+    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+    GED_CHECK_VIEW(gedp, GED_ERROR);
+    GED_CHECK_DRAWABLE(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: %s %s", argv[0], usage);
+       return GED_HELP;
+    }
+
+    if (argc != 2) {
+       bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_ERROR;
+    }
+
+    width = dmp->dm_width;
+    height = dmp->dm_height;
+    bytes_per_pixel = 3;
+    bits_per_channel = dmp->dm_bits_per_channel;
+    bytes_per_line = dmp->dm_width * bytes_per_pixel;
+
+    /* create image file */
+    if ((bif = bu_image_save_open(argv[1], BU_IMAGE_AUTO, width, height, 
bytes_per_pixel)) == NULL)  {
+       bu_vls_printf(&gedp->ged_result_str, "%s: could not create bu_image_ 
write structure.", argv[1]);
+               return GED_ERROR;
+       }
+
+    rows = (unsigned char **)bu_calloc(height, sizeof(unsigned char *), 
"rows");
+
+    DM_GET_DISPLAY_IMAGE(dmp,&idata);
+
+    for (i = 0; i < height; ++i) {
+       rows[i] = (unsigned char *)(idata + ((height-i-1)*bytes_per_line));
+       bu_image_save_writeline(bif, i, (const unsigned char *)rows[i]);
+    }
+
+    if (bif != NULL)
+       bu_image_save_close(bif);
+    bif = NULL;
+
+    bu_free(rows, "rows");
+    bu_free(idata, "image data");
+
+    return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * mode: C
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */


Property changes on: brlcad/trunk/src/libged/screengrab.c
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native

Modified: brlcad/trunk/src/libtclcad/ged_obj.c
===================================================================
--- brlcad/trunk/src/libtclcad/ged_obj.c        2010-12-28 18:58:31 UTC (rev 
41814)
+++ brlcad/trunk/src/libtclcad/ged_obj.c        2010-12-28 18:59:30 UTC (rev 
41815)
@@ -611,6 +611,12 @@
                        ged_func_ptr func,
                        const char *usage,
                        int maxargs);
+HIDDEN int go_dm_func(struct ged *gedp,
+                       int argc,
+                       const char *argv[],
+                       ged_func_ptr func,
+                       const char *usage,
+                       int maxargs);
 
 /* Utility Functions */
 HIDDEN void go_drawSolid(struct dm *dmp, struct solid *sp);
@@ -840,7 +846,7 @@
     {"pov",    "center quat scale eye_pos perspective", 7, go_view_func, 
ged_pmat},
     {"prcolor",        (char *)0, GO_UNLIMITED, go_pass_through_func, 
ged_prcolor},
     {"prefix", (char *)0, GO_UNLIMITED, go_pass_through_func, ged_prefix},
-    {"preview",        "[options] script", GO_UNLIMITED, go_view_func, 
ged_preview},
+    {"preview",        "[options] script", GO_UNLIMITED, go_dm_func, 
ged_preview},
     {"prim_label",     "[prim_1 prim_2 ... prim_N]", GO_UNLIMITED, 
go_prim_label, GED_FUNC_PTR_NULL},
     {"ps",     "[options] file.ps", 16, go_view_func, ged_ps},
     {"protate",        (char *)0, GO_UNLIMITED, go_pass_through_func, 
ged_protate},
@@ -894,6 +900,7 @@
     {"scale_mode",     "x y", GO_UNLIMITED, go_scale_mode, GED_FUNC_PTR_NULL},
     {"screen2model",   "x y", GO_UNLIMITED, go_screen2model, 
GED_FUNC_PTR_NULL},
     {"screen2view",    "x y", GO_UNLIMITED, go_screen2view, GED_FUNC_PTR_NULL},
+    {"screengrab",     "imagename.ext", GO_UNLIMITED, go_dm_func, 
ged_screen_grab},
     {"sdata_arrows",   "???", GO_UNLIMITED, go_data_arrows, GED_FUNC_PTR_NULL},
     {"sdata_axes",     "???", GO_UNLIMITED, go_data_axes, GED_FUNC_PTR_NULL},
     {"sdata_labels",   "???", GO_UNLIMITED, go_data_labels, GED_FUNC_PTR_NULL},
@@ -8299,7 +8306,64 @@
     return ret;
 }
 
+HIDDEN int
+go_dm_func(struct ged *gedp,
+            int argc,
+            const char *argv[],
+            ged_func_ptr func,
+            const char *usage,
+            int maxargs)
+{
+    register int i;
+    int ret;
+    int ac;
+    char **av;
+    struct ged_dm_view *gdvp;
 
+    /* initialize result */
+    bu_vls_trunc(&gedp->ged_result_str, 0);
+    av = bu_calloc(argc+1, sizeof(char *), "alloc av copy");
+
+    /* must be wanting help */
+    if (argc == 1) {
+       bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_HELP;
+    }
+
+    if (maxargs != GO_UNLIMITED && maxargs < argc) {
+       bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return BRLCAD_ERROR;
+    }
+
+    for (BU_LIST_FOR(gdvp, ged_dm_view, &go_current_gop->go_head_views.l)) {
+       if (!strcmp(bu_vls_addr(&gdvp->gdv_name), argv[1]))
+           break;
+    }
+
+    if (BU_LIST_IS_HEAD(&gdvp->l, &go_current_gop->go_head_views.l)) {
+       bu_vls_printf(&gedp->ged_result_str, "View not found - %s", argv[1]);
+       return BRLCAD_ERROR;
+    }
+
+    /* Copy argv into av while skipping argv[1] (i.e. the view name) */
+    gedp->ged_gvp = gdvp->gdv_view;
+    gedp->ged_dmp = (void *)gdvp->gdv_dmp;
+    gedp->ged_refresh_clientdata = (void *)gdvp;
+    av[0] = (char *)argv[0];
+    ac = argc-1;
+    for (i = 2; i < argc; ++i)
+       av[i-1] = (char *)argv[i];
+    av[i-1] = (char *)0;
+    ret = (*func)(gedp, ac, (const char **)av);
+
+    bu_free(av, "free av copy");
+
+    /* Keep the view's perspective in sync with its corresponding display 
manager */
+    gdvp->gdv_dmp->dm_perspective = gdvp->gdv_view->gv_perspective;
+
+    return ret;
+}
+
 /*************************** Local Utility Functions 
***************************/
 HIDDEN void
 go_drawSolid(struct dm *dmp, struct solid *sp)

Modified: brlcad/trunk/src/mged/cmd.c
===================================================================
--- brlcad/trunk/src/mged/cmd.c 2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/mged/cmd.c 2010-12-28 18:59:30 UTC (rev 41815)
@@ -584,7 +584,36 @@
     return TCL_OK;
 }
 
+int
+cmd_ged_dm_wrapper(ClientData clientData, Tcl_Interp *interpreter, int argc, 
const char *argv[])
+{
+    int ret;
+    struct cmdtab *ctp = (struct cmdtab *)clientData;
 
+    if (gedp == GED_NULL)
+       return TCL_OK;
+
+    if (setjmp(jmp_env) == 0)
+       (void)signal(SIGINT, sig3);  /* allow interrupts */
+    else
+       return TCL_OK;
+
+    if (!gedp->ged_gvp)
+       gedp->ged_gvp = view_state->vs_gvp;
+    gedp->ged_dmp = (void *)curr_dm_list->dml_dmp;
+
+    ret = (*ctp->ged_func)(gedp, argc, (const char **)argv);
+    Tcl_AppendResult(interpreter, bu_vls_addr(&gedp->ged_result_str), NULL);
+
+    (void)signal(SIGINT, SIG_IGN);
+
+    if (ret & GED_HELP || ret == GED_OK)
+       return TCL_OK;
+
+    return TCL_ERROR;
+}
+
+
 /**
  * C M D _ T K
  *
@@ -2147,7 +2176,6 @@
     return wdb_stub_cmd(wdbp, interpreter, argc, argv);
 }
 
-
 /*
  * Local Variables:
  * mode: C

Modified: brlcad/trunk/src/mged/cmd.h
===================================================================
--- brlcad/trunk/src/mged/cmd.h 2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/mged/cmd.h 2010-12-28 18:59:30 UTC (rev 41815)
@@ -48,6 +48,7 @@
 BU_EXTERN(int cmd_ged_more_wrapper, (ClientData, Tcl_Interp *, int, const char 
*[]));
 BU_EXTERN(int cmd_ged_plain_wrapper, (ClientData, Tcl_Interp *, int, const 
char *[]));
 BU_EXTERN(int cmd_ged_view_wrapper, (ClientData, Tcl_Interp *, int, const char 
*[]));
+BU_EXTERN(int cmd_ged_dm_wrapper, (ClientData, Tcl_Interp *, int, const char 
*[]));
 BU_EXTERN(int cmd_E, (ClientData, Tcl_Interp *, int, const char *[]));
 BU_EXTERN(int cmd_arot, (ClientData, Tcl_Interp *, int, const char *[]));
 BU_EXTERN(int cmd_autoview, (ClientData, Tcl_Interp *, int, const char *[]));

Modified: brlcad/trunk/src/mged/setup.c
===================================================================
--- brlcad/trunk/src/mged/setup.c       2010-12-28 18:58:31 UTC (rev 41814)
+++ brlcad/trunk/src/mged/setup.c       2010-12-28 18:59:30 UTC (rev 41815)
@@ -249,12 +249,13 @@
     {"permute", f_permute, GED_FUNC_PTR_NULL},
     {"pl", f_pl, GED_FUNC_PTR_NULL},
     {"plot", cmd_ged_plain_wrapper, ged_plot},
+    {"png", cmd_ged_plain_wrapper, ged_png},
     {"polybinout", f_polybinout, GED_FUNC_PTR_NULL},
     {"pov", cmd_pov, GED_FUNC_PTR_NULL},
     {"prcolor", cmd_ged_plain_wrapper, ged_prcolor},
     {"prefix", cmd_ged_plain_wrapper, ged_prefix},
     {"press", f_press, GED_FUNC_PTR_NULL},
-    {"preview", cmd_ged_view_wrapper, ged_preview},
+    {"preview", cmd_ged_dm_wrapper, ged_preview},
     {"ps", f_ps, GED_FUNC_PTR_NULL},
     {"push", cmd_ged_plain_wrapper, ged_push},
     {"put", cmd_ged_plain_wrapper, ged_put},
@@ -302,6 +303,7 @@
     {"savekey", cmd_ged_plain_wrapper, ged_savekey},
     {"saveview", cmd_ged_plain_wrapper, ged_saveview},
     {"sca", cmd_sca, GED_FUNC_PTR_NULL},
+    {"screengrab", cmd_ged_dm_wrapper, ged_screen_grab},
     {"search", cmd_search, GED_FUNC_PTR_NULL},
     {"sed", f_sed, GED_FUNC_PTR_NULL},
     {"sed_apply", f_sedit_apply, GED_FUNC_PTR_NULL},

Modified: brlcad/trunk/src/tclscripts/lib/Ged.tcl
===================================================================
--- brlcad/trunk/src/tclscripts/lib/Ged.tcl     2010-12-28 18:58:31 UTC (rev 
41814)
+++ brlcad/trunk/src/tclscripts/lib/Ged.tcl     2010-12-28 18:59:30 UTC (rev 
41815)
@@ -349,6 +349,7 @@
        method pane_savekey {_pane args}
        method pane_saveview {_pane args}
        method pane_sca {_pane args}
+       method pane_screengrab {_pane args}
        method pane_scale_mode {_pane args}
        method pane_screen2view {args}
        method pane_set_coord {_pane args}
@@ -429,6 +430,7 @@
        method savekey {args}
        method saveview {args}
        method sca {args}
+       method screengrab {args}
        method protate {args}
        method protate_mode {args}
        method pscale {args}
@@ -1924,6 +1926,10 @@
     eval $mGed sca $itk_component($_pane) $args
 }
 
+::itcl::body cadwidgets::Ged::pane_screengrab {_pane args} {
+    eval $mGed screengrab $itk_component($_pane) $args
+}
+
 ::itcl::body cadwidgets::Ged::pane_scale_mode {_pane args} {
     eval $mGed scale_mode $itk_component($_pane) $args
 }
@@ -2279,6 +2285,10 @@
     eval $mGed sca $itk_component($itk_option(-pane)) $args
 }
 
+::itcl::body cadwidgets::Ged::screengrab {args} {
+    eval $mGed screengrab $itk_component($itk_option(-pane)) $args
+}
+
 ::itcl::body cadwidgets::Ged::screen2view {args} {
     eval $mGed screen2view $itk_component($itk_option(-pane)) $args
 }
@@ -4137,6 +4147,7 @@
     $help add savekey          {{file [time]} {save key frame data to file}}
     $help add saveview         {{[-e] [-i] [-l] [-o] filename [args]} {save 
the current view to file}}
     $help add sca              {{sfactor} {scale by sfactor}}
+    $help add screengrab       {{imagename.ext}        {output active graphics 
window to image file typed by extension(i.e. mged> screengrab 
imagename.png)\n");}}
     $help add search           {{options} {see search man page}}
     $help add select           {{vx vy {vr | vw vh}} {select objects within 
the specified circle or rectangle}}
     $help add setview          {{x y z} {set the view given angles x, y, and z 
in degrees}}

Modified: brlcad/trunk/src/tclscripts/mged/help.tcl
===================================================================
--- brlcad/trunk/src/tclscripts/mged/help.tcl   2010-12-28 18:58:31 UTC (rev 
41814)
+++ brlcad/trunk/src/tclscripts/mged/help.tcl   2010-12-28 18:59:30 UTC (rev 
41815)
@@ -219,13 +219,14 @@
 set mged_help_data(permute)    {{tuple}        {permute vertices of an ARB}}
 set mged_help_data(plot)       {{[-float] [-zclip] [-2d] [-grid] [out_file] 
[|filter]} {make UNIX-plot of view}}
 set mged_help_data(pl)         {{[-float] [-zclip] [-2d] [-grid] [out_file] 
[|filter]} {Experimental - uses dm-plot:make UNIX-plot of view}}
+set mged_help_data(png)                {{[-c r/g/b] [-s size] file}    {save 
graphics window to PNG image file}}
 set mged_help_data(polybinout) {{file} {store vlist polygons into polygon file 
(experimental)}}
 set mged_help_data(pov)                $helplib_data(vo_pov)
 set mged_help_data(prcolor)    $helplib_data(wdb_prcolor)
 set mged_help_data(prefix)     {{new_prefix object(s)} {prefix each occurrence 
of object name(s)}}
 set mged_help_data(press)      {{button_label} {emulate button press}}
 set mged_help_data(prj_add)    {{ [-t] [-b] [-n] shaderfile [image_file] 
[image_width] [image_height]} {Appends image filename + current view parameters 
to shaderfile}}
-set mged_help_data(preview)    {{[-v] [-d sec_delay] [-D start frame] [-K last 
frame] rt_script_file}  {preview new style RT animation script}}
+set mged_help_data(preview)    {{[-v] [-o imagename.ext] [-d sec_delay] [-D 
start frame] [-K last frame] rt_script_file}       {preview new style RT 
animation script}}
 set mged_help_data(ps)         {{[-f font] [-t title] [-c creator] [-s size in 
inches] [-l linewidth] file}    {creates a postscript file of the current view}}
 set mged_help_data(push)       $helplib_data(wdb_push)
 set mged_help_data(put)                $helplib_data(wdb_put)
@@ -282,6 +283,7 @@
       -i inputfile   specify input data file (default is opendb filepath)
 }}
 set mged_help_data(sca)                $helplib_data(vo_sca)
+set mged_help_data(screengrab) {{imagename.ext}        {output active graphics 
window to image file typed by extension(i.e. mged> screengrab 
imagename.png)\n");}}
 set mged_help_data(search)     $helplib_data(wdb_search)
 set mged_help_data(sed)                {{<path>}       {solid-edit named 
solid}}
 set mged_help_data(setview)    $helplib_data(vo_setview)


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

------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and, 
should the need arise, upgrade to a full multi-node Oracle RAC database 
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to