[Bf-python] Resubmission of patch for Draw.Image()
Campbell J Barton
cbarton at metavr.com
Wed Nov 24 16:09:31 CET 2004
Hi, I like this function, its better in some ways then using glLoad()
glLoad seams to be a bit buggy, I have a scene with 130 images in it and
whenever a do a glLoad (using my thumbnail browser) it segfaults on some
images every time. - needs to be looked into,
But yours sidesteps the issue of having to have all textures loaded into
openGL memory it once.
- Cam
Jonathan Merritt wrote:
> Hi Everyone,
>
> Is it time yet for me to re-submit my patch for Blender.Draw.Image()?
> I've attached it to this email again, against the current CVS. I'm
> not sure whether I'm meant to wait for BCon-1 to come back up again on
> blender.org, but I noticed a string of commits earlier today, so I
> thought we might be rolling again. :-] I'm really quite eager to get
> this in so that I can start re-structuring a lot of my stuff around it.
>
> Just a quick summary once more:
>
> Blender.Draw.Image(image, x, y, zoomx=1.0, zoomy=1.0, clipx=0,
> clipy=0, clipw=-1, cliph=-1):
>
> Draws a Blender.Image on the screen using raster operations.
>
> (image) - Blender.Image to draw.
> (x, y) - Raster coordinates of the lower-left corner of the image
> (can be negative).
> (zoomx, zoomy) - Horizontal and vertical zoom factors.
> (clipx, clipy, clipw, cliph) - Image space clipping rectangle.
>
> The method itself, and epydoc documentation (more extensive than the
> quick summary above) are both provided in the patch. btw: is this the
> correct mailing list for these patches? It's terribly unclear whether
> Python extension module patches should be submitted here or to
> bf-committers... :-/
>
> Thanks, :-)
>
> Jonathan Merritt.
>
>------------------------------------------------------------------------
>
>Index: source/blender/python/api2_2x/Draw.c
>===================================================================
>RCS file: /cvsroot/bf-blender/blender/source/blender/python/api2_2x/Draw.c,v
>retrieving revision 1.31
>diff -u -r1.31 Draw.c
>--- source/blender/python/api2_2x/Draw.c 9 Nov 2004 14:07:25 -0000 1.31
>+++ source/blender/python/api2_2x/Draw.c 24 Nov 2004 12:58:31 -0000
>@@ -55,6 +55,7 @@
> #include "DNA_text_types.h"
>
> #include "BKE_global.h"
>+#include "BKE_image.h"
> #include "BKE_library.h"
> #include "BKE_object.h"
>
>@@ -67,6 +68,10 @@
>
> #include "BPI_script.h" /* script struct */
>
>+#include "Image.h" /* for accessing Blender.Image objects */
>+#include "IMB_imbuf_types.h" /* for the IB_rect define */
>+#include "blendef.h" /* for the CLAMP() macro */
>+
> #include "interface.h"
> #include "mydevice.h" /*@ for all the event constants */
>
>@@ -112,6 +117,8 @@
> static PyObject *Method_PupIntInput( PyObject * self, PyObject * args );
> static PyObject *Method_PupFloatInput( PyObject * self, PyObject * args );
> static PyObject *Method_PupStrInput( PyObject * self, PyObject * args );
>+/* next by Jonathan Merritt (lancelet): */
>+static PyObject *Method_Image( PyObject * self, PyObject * args);
>
> static uiBlock *Get_uiBlock( void );
> static void py_slider_update( void *butv, void *data2_unused );
>@@ -267,6 +274,14 @@
> the float value show.\n\
> Return the user input value or None on user exit";
>
>+static char Method_Image_doc[] =
>+ "(image, x, y, zoomx = 1.0, zoomy = 1.0, [clipx, clipy, clipw, cliph])) \n\
>+ - Draw an image.\n\
>+(image) - Blender.Image to draw.\n\
>+(x, y) - floats specifying the location of the image.\n\
>+(zoomx, zoomy) - float zoom factors in horizontal and vertical directions.\n\
>+(clipx, clipy, clipw, cliph) - integers specifying a clipping rectangle within the original image.";
>+
> static char Method_PupStrInput_doc[] =
> "(text, default, max = 20) - Display a float pop-up input.\n\
> (text) - text string to display on the button;\n\
>@@ -304,6 +319,7 @@
> MethodDef( PupIntInput ),
> MethodDef( PupFloatInput ),
> MethodDef( PupStrInput ),
>+ MethodDef( Image ),
> MethodDef( Exit ),
> MethodDef( Redraw ),
> MethodDef( Draw ),
>@@ -1196,6 +1212,107 @@
> "couldn't create a PyString" );
> }
>
>+/*****************************************************************************
>+ * Function: Method_Image *
>+ * Python equivalent: Blender.Draw.Image *
>+ * *
>+ * @author Jonathan Merritt <j.merritt at pgrad.unimelb.edu.au> *
>+ ****************************************************************************/
>+static PyObject *Method_Image( PyObject * self, PyObject * args )
>+{
>+ PyObject *pyObjImage;
>+ BPy_Image *py_img;
>+ Image *image;
>+ float originX, originY;
>+ float zoomX = 1.0, zoomY = 1.0;
>+ int clipX = 0, clipY = 0, clipW = -1, clipH = -1;
>+ GLfloat scissorBox[4];
>+
>+ /* parse the arguments passed-in from Python */
>+ if( !PyArg_ParseTuple( args, "Off|ffiiii", &pyObjImage,
>+ &originX, &originY, &zoomX, &zoomY,
>+ &clipX, &clipY, &clipW, &clipH ) )
>+ return EXPP_ReturnPyObjError( PyExc_TypeError,
>+ "expected a Blender.Image and 2 floats, and " \
>+ "optionally 2 floats and 4 ints as arguments" );
>+ /* check that the first PyObject is actually a Blender.Image */
>+ if( !Image_CheckPyObject( pyObjImage ) )
>+ return EXPP_ReturnPyObjError( PyExc_TypeError,
>+ "expected a Blender.Image and 2 floats, and " \
>+ "optionally 2 floats and 4 ints as arguments" );
>+ /* check that the zoom factors are valid */
>+ if( ( zoomX <= 0.0 ) || ( zoomY <= 0.0 ) )
>+ return EXPP_ReturnPyObjError( PyExc_TypeError,
>+ "invalid zoom factors - they must be >= 0.0" );
>+
>+ /* fetch a C Image pointer from the passed-in Python object */
>+ py_img = ( BPy_Image * ) pyObjImage;
>+ image = py_img->image;
>+
>+ /* load the image data if necessary */
>+ if( !image->ibuf ) /* if no image data is available ... */
>+ load_image( image, IB_rect, "", 0 ); /* ... load it */
>+ if( !image->ibuf ) /* if failed to load the image */
>+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
>+ "couldn't load image data in Blender" );
>+
>+ /* set up a valid clipping rectangle. if no clip rectangle was
>+ * given, this results in inclusion of the entire image. otherwise,
>+ * the clipping is just checked against the bounds of the image.
>+ * if clipW or clipH are less than zero then they include as much of
>+ * the image as they can. */
>+ CLAMP( clipX, 0, image->ibuf->x );
>+ CLAMP( clipY, 0, image->ibuf->y );
>+ if( ( clipW < 0 ) || ( clipW > ( image->ibuf->x - clipW ) ) )
>+ clipW = image->ibuf->x - clipX;
>+ if( ( clipH < 0 ) || ( clipH > ( image->ibuf->y - clipH ) ) )
>+ clipH = image->ibuf->y - clipY;
>+
>+ /* -- we are "Go" to Draw! -- */
>+
>+ /* set the raster position.
>+ *
>+ * If the raster position is negative, then using glRasterPos2i()
>+ * directly would cause it to be clipped. Instead, we first establish
>+ * a valid raster position within the clipping rectangle of the
>+ * window and then use glBitmap() with a NULL image pointer to offset
>+ * it to the true position we require. To pick an initial valid
>+ * raster position within the viewport, we query the clipping rectangle
>+ * and use its lower-left pixel.
>+ *
>+ * This particular technique is documented in the glRasterPos() man
>+ * page, although I haven't seen it used elsewhere in Blender.
>+ */
>+ glGetFloatv( GL_SCISSOR_BOX, scissorBox );
>+ glRasterPos2i( scissorBox[0], scissorBox[1] );
>+ glBitmap( 0, 0, 0.0, 0.0,
>+ originX-scissorBox[0], originY-scissorBox[1], NULL );
>+
>+ /* set the zoom */
>+ glPixelZoom( zoomX, zoomY );
>+
>+ /* set the width of the image (ROW_LENGTH), and the offset to the
>+ * clip origin within the image in x (SKIP_PIXELS) and
>+ * y (SKIP_ROWS) */
>+ glPixelStorei( GL_UNPACK_ROW_LENGTH, image->ibuf->x );
>+ glPixelStorei( GL_UNPACK_SKIP_PIXELS, clipX );
>+ glPixelStorei( GL_UNPACK_SKIP_ROWS, clipY );
>+
>+ /* draw the image */
>+ glDrawPixels( clipW, clipH, GL_RGBA, GL_UNSIGNED_BYTE,
>+ image->ibuf->rect );
>+
>+ /* restore the defaults for some parameters (we could also use a
>+ * glPushClientAttrib() and glPopClientAttrib() pair). */
>+ glPixelZoom( 1.0, 1.0 );
>+ glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
>+ glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
>+ glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
>+
>+ Py_INCREF( Py_None );
>+ return Py_None;
>+
>+}
>
> PyObject *Draw_Init( void )
> {
>Index: source/blender/python/api2_2x/doc/Draw.py
>===================================================================
>RCS file: /cvsroot/bf-blender/blender/source/blender/python/api2_2x/doc/Draw.py,v
>retrieving revision 1.13
>diff -u -r1.13 Draw.py
>--- source/blender/python/api2_2x/doc/Draw.py 16 Jul 2004 03:08:43 -0000 1.13
>+++ source/blender/python/api2_2x/doc/Draw.py 24 Nov 2004 12:58:34 -0000
>@@ -594,6 +594,67 @@
> @return: The width of I{string} drawn with the chosen I{fontsize}.
> """
>
>+def Image(image, x, y, zoomx=1.0, zoomy=1.0, clipx=0, clipy=0, clipw=-1, cliph=-1):
>+ """
>+ Draw an image on the screen.
>+
>+ The image is drawn at the location specified by the coordinates (x,y). A
>+ pair of optional zoom factors (in horizontal and vertical directions) can
>+ be applied to the image as it is drawn, and an additional clipping rectangle
>+ can be applied to extract a particular sub-region of the image to draw.
>+
>+ Note that the clipping rectangle is given in image space coordinates. In
>+ image space, the origin is located at the bottom left, with x coordinates
>+ increasing to the right and y coordinates increasing upwards. No matter
>+ where the clipping rectangle is placed in image space, the lower-left pixel
>+ drawn on the screen is always placed at the coordinates (x,y). The
>+ clipping rectangle is itself clipped to the dimensions of the image. If
>+ either the width or the height of the clipping rectangle are negative then
>+ the corresponding dimension (width or height) is set to include as much of
>+ the image as possible.
>+
>+ Example::
>+ import Blender
>+ from Blender import BGL, Image, Draw
>+
>+ myimage = Image.Load('myimage.png')
>+
>+ def gui():
>+ Draw.Image(myimage, 50, 50)
>+ def event(evt, val):
>+ if evt == Draw.ESCKEY:
>+ Draw.Exit()
>+
>+ Draw.Register(gui, event, None)
>+
>+ @type image: Blender.Image
>+ @param image: The image to draw.
>+ @type x: int
>+ @param x: The lower left x (horizontal) position of the origin of the image.
>+ @type y: int
>+ @param y: The lower left y (vertical) position of the origin of the image.
>+ @type zoomx: float
>+ @param zoomx: The x (horizontal) zoom factor to use when drawing the image.
>+ @type zoomy: float
>+ @param zoomy: The y (vertical) zoom factor to use when drawing the image.
>+ @type clipx: int
>+ @param clipx: The lower left x (horizontal) origin of the clipping rectangle
>+ within the image. A value of 0 indicates the left of the
>+ image.
>+ @type clipy: int
>+ @param clipy: The lower left y (vertical) origin of the clipping rectangle
>+ within the image. A value of 0 indicates the bottom of the
>+ image.
>+ @type clipw: int
>+ @param clipw: The width of the clipping rectangle within the image. If this
>+ value is negative then the clipping rectangle includes as much
>+ of the image as possible in the x (horizontal) direction.
>+ @type cliph: int
>+ @param cliph: The height of the clipping rectangle within the image. If this
>+ value is negative then the clipping rectangle includes as much
>+ of the image as possible in the y (vertical) direction.
>+ """
>+
> class Button:
> """
> The Button object
>
>
>------------------------------------------------------------------------
>
>_______________________________________________
>Bf-python mailing list
>Bf-python at projects.blender.org
>http://projects.blender.org/mailman/listinfo/bf-python
>
>
--
Campbell J Barton
133 Hope Street
Geelong West, Victoria 3218 Australia
URL: http://www.metavr.com
e-mail: cbarton at metavr.com
phone: AU (03) 5229 0241
More information about the Bf-python
mailing list