[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [14040] trunk/blender/source/blender/ python/api2_2x: Applied [#7076] Updated Python Image API to use float buffers in getPixelF/setPixelF

Campbell Barton ideasman42 at gmail.com
Mon Mar 10 13:17:58 CET 2008


Revision: 14040
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=14040
Author:   campbellbarton
Date:     2008-03-10 13:17:58 +0100 (Mon, 10 Mar 2008)

Log Message:
-----------
Applied [#7076] Updated Python Image API to use float buffers in getPixelF/setPixelF
and added an image.updateDisplay() function to update imbuf->rect from imbuf->rect_float
also corrected some docstrings and epydocs

Modified Paths:
--------------
    trunk/blender/source/blender/python/api2_2x/Image.c
    trunk/blender/source/blender/python/api2_2x/bpy_data.c
    trunk/blender/source/blender/python/api2_2x/doc/Armature.py
    trunk/blender/source/blender/python/api2_2x/doc/Group.py
    trunk/blender/source/blender/python/api2_2x/doc/Image.py

Modified: trunk/blender/source/blender/python/api2_2x/Image.c
===================================================================
--- trunk/blender/source/blender/python/api2_2x/Image.c	2008-03-10 11:39:37 UTC (rev 14039)
+++ trunk/blender/source/blender/python/api2_2x/Image.c	2008-03-10 12:17:58 UTC (rev 14040)
@@ -38,6 +38,7 @@
 #include "BKE_library.h"
 #include "BKE_image.h"
 #include "BKE_idprop.h"
+#include "BKE_utildefines.h"
 #include "BIF_drawimage.h"
 #include "BLI_blenlib.h"
 #include "DNA_space_types.h"	/* FILE_MAXDIR = 160 */
@@ -106,6 +107,7 @@
 static PyObject *Image_setEnd( BPy_Image * self, PyObject * args );
 static PyObject *Image_setSpeed( BPy_Image * self, PyObject * args );
 static PyObject *Image_reload( BPy_Image * self );
+static PyObject *Image_updateDisplay( BPy_Image * self );
 static PyObject *Image_glLoad( BPy_Image * self );
 static PyObject *Image_glFree( BPy_Image * self );
 static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args );
@@ -126,11 +128,11 @@
 static PyMethodDef BPy_Image_methods[] = {
 	/* name, method, flags, doc */
 	{"getPixelF", ( PyCFunction ) Image_getPixelF, METH_VARARGS,
-	 "(int, int) - Get pixel color as floats 0.0-1.0 returns [r,g,b,a]"},
+	 "(int, int) - Get pixel color as floats returns [r,g,b,a]"},
 	{"getPixelI", ( PyCFunction ) Image_getPixelI, METH_VARARGS,
 	 "(int, int) - Get pixel color as ints 0-255 returns [r,g,b,a]"},
 	{"setPixelF", ( PyCFunction ) Image_setPixelF, METH_VARARGS,
-	 "(int, int, [f r,f g,f b,f a]) - Set pixel color using floats 0.0-1.0"},
+	 "(int, int, [f r,f g,f b,f a]) - Set pixel color using floats"},
 	{"setPixelI", ( PyCFunction ) Image_setPixelI, METH_VARARGS,
 	 "(int, int, [i r, i g, i b, i a]) - Set pixel color using ints 0-255"},
 	{"getMaxXY", ( PyCFunction ) Image_getMaxXY, METH_NOARGS,
@@ -159,6 +161,8 @@
 	 "() - Return Image object's bind code value"},
 	{"reload", ( PyCFunction ) Image_reload, METH_NOARGS,
 	 "() - Reload the image from the filesystem"},
+	{"updateDisplay", ( PyCFunction ) Image_updateDisplay, METH_NOARGS,
+	 "() - Update the display image from the floating point buffer (if it exists)"},
 	{"glLoad", ( PyCFunction ) Image_glLoad, METH_NOARGS,
 	 "() - Load the image data in OpenGL texture memory.\n\
 	The bindcode (int) is returned."},
@@ -199,7 +203,7 @@
 static char M_Image_doc[] = "The Blender Image module\n\n";
 
 static char M_Image_New_doc[] =
-	"() - return a new Image object";
+	"(name, width, height, depth) - all args are optional, return a new Image object";
 
 static char M_Image_Get_doc[] =
 	"(name) - return the image with the name 'name', \
@@ -243,7 +247,7 @@
 	if (width > 5000 || height > 5000 || width < 1 || height < 1)
 		return ( EXPP_ReturnPyObjError( PyExc_TypeError,
 					"Image width and height must be between 1 and 5000" ) );
-	image = BKE_add_image_size(width, height, name, 0, 0, color);
+	image = BKE_add_image_size(width, height, name, depth==128 ? 1 : 0, 0, color);
 	if( !image )
 		return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
 						"couldn't create PyObject Image_Type" ) );
@@ -382,27 +386,25 @@
 /**
  * getPixelF( x, y )
  *  returns float list of pixel colors in rgba order.
- *  returned values are floats normalized to 0.0 - 1.0.
- *  blender images are all 4x8 bit at the moment apr-2005
- */
+ *  returned values are floats , in the full range of the float image source.
+  */
 
 static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args )
 {
 
 	PyObject *attr;
 	ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
-	char *pixel;		/* image data */
 	int index;		/* offset into image data */
 	int x = 0;
 	int y = 0;
-	int pixel_size = 4;	/* each pixel is 4 x 8-bits packed in unsigned int */
+	int pixel_size = 4;	/* each pixel is 4 x 32 bit float */
 	int i;
 	
 	if( !PyArg_ParseTuple( args, "ii", &x, &y ) )
 		return EXPP_ReturnPyObjError( PyExc_TypeError,
 					      "expected 2 integers" );
 
-	if( !ibuf || !ibuf->rect )	/* loading didn't work */
+	if( !ibuf || (!ibuf->rect_float && !ibuf->rect))	/* loading didn't work */
 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 					      "couldn't load image data in Blender" );
 
@@ -428,15 +430,26 @@
 				      "couldn't allocate memory for color list" );
 	
 	index = ( x + y * ibuf->x ) * pixel_size;
-
-	pixel = ( char * ) ibuf->rect;
-	for (i=0; i<4; i++) {
-		PyList_SetItem( attr, i, PyFloat_FromDouble( ( ( double ) pixel[index+i] ) / 255.0 ));
+	
+	/* if a float buffer exists, use it, otherwise convert the 8bpc buffer to float values */
+	if (ibuf->rect_float) {
+		float *pixelf;		/* image data */
+		
+		pixelf = ibuf->rect_float;
+		for (i=0; i<4; i++) {
+			PyList_SetItem( attr, i, PyFloat_FromDouble( (double)pixelf[index+i] ) );
+		}
+	} else {
+		char *pixelc;		/* image data */
+		
+		pixelc = ( char * ) ibuf->rect;
+		for (i=0; i<4; i++) {
+			PyList_SetItem( attr, i, PyFloat_FromDouble( ( ( double ) pixelc[index+i] ) / 255.0 ));
+		}
 	}
 	return attr;
 }
 
-
 /**
  * getPixelI( x, y )
  *  returns integer list of pixel colors in rgba order.
@@ -497,12 +510,11 @@
 static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args )
 {
 	ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
-	char *pixel;		/* image data */
+	float *pixel;		/* image data */
 	int index;		/* offset into image data */
 	int x = 0;
 	int y = 0;
-	int a = 0;
-	int pixel_size = 4;	/* each pixel is 4 x 8-bits packed in unsigned int */
+	int pixel_size = 4;	/* each pixel is 4 x 32 bit float */
 	float p[4];
 
 	if( !PyArg_ParseTuple
@@ -510,7 +522,7 @@
 		return EXPP_ReturnPyObjError( PyExc_TypeError,
 					      "expected 2 integers and an array of 4 floats" );
 
-	if( !ibuf || !ibuf->rect )	/* didn't work */
+	if( !ibuf )	/* didn't work */
 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 					      "couldn't load image data in Blender" );
 
@@ -522,29 +534,17 @@
 	    || y > ( ibuf->y - 1 )
 	    || x < ibuf->xorig || y < ibuf->yorig )
 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
-					      "x or y is out of ruange" );
+					      "x or y is out of range" );
 
-	for( a = 0; a < 4; a++ ) {
-		if( p[a] > 1.0 || p[a] < 0.0 )
-			return EXPP_ReturnPyObjError( PyExc_RuntimeError,
-						      "r, g, b, or a is out of range" );
-	}
-
-
-	/* 
-	   assumption: from looking at source, skipx is often not set,
-	   so we calc ourselves
-	 */
-
+	/* if no float buffer already exists, add it */
+	if (!ibuf->rect_float) imb_addrectfloatImBuf(ibuf);
+	
 	index = ( x + y * ibuf->x ) * pixel_size;
 
-	pixel = ( char * ) ibuf->rect;
+	pixel = ibuf->rect_float + index;
+	
+	QUATCOPY(pixel, p);
 
-	pixel[index] = ( char ) ( p[0] * 255.0 );
-	pixel[index + 1] = ( char ) ( p[1] * 255.0 );
-	pixel[index + 2] = ( char ) ( p[2] * 255.0 );
-	pixel[index + 3] = ( char ) ( p[3] * 255.0 );
-
 	ibuf->userflags |= IB_BITMAPDIRTY;
 	Py_RETURN_NONE;
 }
@@ -821,8 +821,11 @@
 	if( !ibuf )	/* didn't work */
 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 					      "couldn't load image data in Blender" );
-
-	return PyInt_FromLong( (long)ibuf->depth );
+	if (ibuf->rect_float) {
+		return PyInt_FromLong( (long)128 );
+	} else {
+		return PyInt_FromLong( (long)ibuf->depth );
+	}
 }
 
 
@@ -865,6 +868,21 @@
 	Py_RETURN_NONE;
 }
 
+static PyObject *Image_updateDisplay( BPy_Image * self )
+{
+	ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
+
+	if( !ibuf )	/* didn't work */
+		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+					      "couldn't load image data in Blender" );
+
+	IMB_rect_from_float(ibuf);
+
+	Py_RETURN_NONE;
+}
+
+
+
 static PyObject *Image_glFree( BPy_Image * self )
 {
 	Image *image = self->image;

Modified: trunk/blender/source/blender/python/api2_2x/bpy_data.c
===================================================================
--- trunk/blender/source/blender/python/api2_2x/bpy_data.c	2008-03-10 11:39:37 UTC (rev 14039)
+++ trunk/blender/source/blender/python/api2_2x/bpy_data.c	2008-03-10 12:17:58 UTC (rev 14040)
@@ -394,7 +394,7 @@
 {
 	ID *id = NULL;
 	char *name=NULL, *filename=NULL, *data_type=NULL;
-	int img_width=256, img_height=256;
+	int img_width=256, img_height=256, img_depth=32;
 	float color[] = {0, 0, 0, 1};
 	short data_code = 0;
 	int user_count = 0;
@@ -456,8 +456,8 @@
 	
 	/* New Data */
 	if (self->type == ID_IM) {
-		/* Image, accepts width and height*/
-		if( !PyArg_ParseTuple( args, "|sii", &name, &img_width, &img_height ) )
+		/* Image, accepts width and height, depth */
+		if( !PyArg_ParseTuple( args, "|siii", &name, &img_width, &img_height, &img_depth ) )
 			return EXPP_ReturnPyObjError( PyExc_TypeError,
 				"one string and two ints expected as arguments" );
 		CLAMP(img_width,  4, 5000);
@@ -538,7 +538,7 @@
 		break;
 	case ID_IM: 
 	{
-		id = (ID *)BKE_add_image_size(img_width, img_height, name?name:"Image", 0, 0, color);
+		id = (ID *)BKE_add_image_size(img_width, img_height, name?name:"Image", img_depth==128 ? 1:0, 0, color);
 		if( !id )
 			return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
 				"couldn't create PyObject Image_Type" ) );
@@ -562,14 +562,14 @@
 		break;
 	case ID_VF:
 		return EXPP_ReturnPyObjError( PyExc_TypeError,
-			"Cannot create new fonts, use the load() function to load from a file" );
+			"Cannot create new fonts, use the new(name, filename) function to load from a file" );
 	case ID_TXT:
 		id = (ID *)add_empty_text( name?name:"Text" );
 		user_count = 1;
 		break;
 	case ID_SO:
 		return EXPP_ReturnPyObjError( PyExc_TypeError,
-			"Cannot create new sounds, use the load() function to load from a file" );
+			"Cannot create new sounds, use the new(name, filename) function to load from a file" );
 	case ID_GR:	
 		id = (ID *)add_group( name?name:"Group" );
 		user_count = 1;

Modified: trunk/blender/source/blender/python/api2_2x/doc/Armature.py
===================================================================
--- trunk/blender/source/blender/python/api2_2x/doc/Armature.py	2008-03-10 11:39:37 UTC (rev 14039)
+++ trunk/blender/source/blender/python/api2_2x/doc/Armature.py	2008-03-10 12:17:58 UTC (rev 14040)
@@ -192,6 +192,16 @@
 		@note: Must have called makeEditable() first.
 		@rtype: None
 		"""
+	def copy():
+		"""
+		Return a copy of this armature.
+		@rtype: Armature
+		"""
+	def __copy__():
+		"""
+		Return a copy of this armature.
+		@rtype: Armature
+		"""
 
 import id_generics
 Armature.__doc__ += id_generics.attributes 

Modified: trunk/blender/source/blender/python/api2_2x/doc/Group.py
===================================================================

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list