Campbell Barton 2008-02-12 14:47:55 +00:00
parent c371346601
commit 3974a0a3c1
8 changed files with 218 additions and 17 deletions

@ -40,7 +40,8 @@ extern int join_mesh(void);
extern void sort_faces(void);
extern void objects_bake_render_menu(void);
extern void objects_bake_render(short event);
extern void objects_bake_render_ui(short event);
extern void objects_bake_render(short event, char **error_msg);
extern long mesh_octree_table(struct Object *ob, float *co, char mode);
extern int mesh_get_x_mirror_vert(struct Object *ob, int index);

@ -1,5 +1,5 @@
/*
* $Id: BGL.c 12267 2007-10-17 09:51:13Z campbellbarton $
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
@ -1099,7 +1099,7 @@ PyObject *BGL_Init(void)
if( PyType_Ready( &buffer_Type) < 0)
Py_RETURN_NONE;
#define EXPP_ADDCONST(x) EXPP_dict_set_item_str(dict, #x, PyInt_FromLong(x))
#define EXPP_ADDCONST(x) EXPP_dict_set_item_str(dict, #x, PyInt_FromLong((int)x))
/* So, for example:
* EXPP_ADDCONST(GL_CURRENT_BIT) becomes
@ -1126,7 +1126,8 @@ PyObject *BGL_Init(void)
EXPP_ADDCONST(GL_TEXTURE_BIT);
EXPP_ADDCONST(GL_SCISSOR_BIT);
EXPP_ADDCONST(GL_ALL_ATTRIB_BITS);
EXPP_ADDCONST(GL_CLIENT_ALL_ATTRIB_BITS);
EXPP_ADDCONST(GL_FALSE);
EXPP_ADDCONST(GL_TRUE);

@ -74,6 +74,24 @@ attribute. One of the following modes can be active:
horizontally or vertically
- SCALE: Stretch or squeeze the viewport to fill the display window.
@type BakeModes: readonly dictionary
@var BakeModes: Constant dict used for with L{RenderData.bakeMode}
attribute. One of the following modes can be active:
- LIGHT: Bake lighting only.
- ALL: Bake all render lighting.
- AO: Bake ambient occlusion.
- NORMALS: Bake a normal map.
- TEXTURE: Bake textures.
- DISPLACEMENT: Bake displacement.
@type BakeNormalSpaceModes: readonly dictionary
@var BakeNormalSpaceModes: Constant dict used for with L{RenderData.bakeNormalSpace}
attribute. One of the following modes can be active:
- CAMERA: Bake normals relative to the camera.
- WORLD: Bake normals in worldspace.
- OBJECT: Bake normals relative to the object.
- TANGENT: Bake tangent space normals.
@var INTERNAL: The internal rendering engine. Use with setRenderer()
@var YAFRAY: Yafray rendering engine. Use with setRenderer()
@ -367,6 +385,18 @@ class RenderData:
@type yafrayGIPhotons: boolean
@ivar yafrayGITunePhotons: If true the photonmap is shown directly in the render for tuning.
@type yafrayGITunePhotons: boolean
@ivar bakeMode: The method used when baking, see L{BakeModes}.
@type bakeMode: int
@ivar bakeNormalSpace: The method used when baking, see L{BakeNormalSpaceModes}.
@type bakeNormalSpace: int
@ivar bakeClear: When enabled, baking clears the image first.
@type bakeClear: bool
@ivar bakeToActive: When enabled, selected objects are baked onto the active object.
@type bakeToActive: bool
@ivar bakeMargin: The pixel distance to extend baked pixels past the boundry (reduces bleeding when mipmapping)
@type bakeMargin: int
@ivar bakeDist: The distance in blender units to use when bakeToActive is enabled and geomtry does not overlap.
@type bakeDist: float
"""
def currentFrame(frame = None):
@ -383,6 +413,11 @@ class RenderData:
Render the scene.
"""
def bake():
"""
Bake selected objects in the scene.
"""
def renderAnim():
"""
Render a series of frames to an output directory.

@ -7,6 +7,6 @@
# set posix locale so regex works properly for [A-Z]*.py
LC_ALL=POSIX
epydoc -o BPY_API --url "http://www.blender.org" --top API_intro \
epydoc -v -o BPY_API --url "http://www.blender.org" --top API_intro \
--name "Blender" --no-private --no-frames \
$( ls [A-Z]*.py )

@ -47,6 +47,7 @@ struct View3D; /* keep me up here */
#include "BIF_drawscene.h"
#include "BIF_renderwin.h"
#include "BIF_writeimage.h"
#include "BIF_meshtools.h"
#include "BLI_blenlib.h"
@ -86,6 +87,10 @@ enum rend_constants {
EXPP_RENDER_ATTR_SIZEY,
EXPP_RENDER_ATTR_GAUSSFILTER,
EXPP_RENDER_ATTR_MBLURFACTOR,
EXPP_RENDER_ATTR_BAKEMARGIN,
EXPP_RENDER_ATTR_BAKEMODE,
EXPP_RENDER_ATTR_BAKEDIST,
EXPP_RENDER_ATTR_BAKENORMALSPACE
};
#define EXPP_RENDER_ATTR_CFRA 2
@ -133,6 +138,7 @@ static PyObject *RenderData_SetRenderer( BPy_RenderData * self,
static PyObject *RenderData_SetImageType( BPy_RenderData * self,
PyObject * args );
static PyObject *RenderData_Render( BPy_RenderData * self );
static PyObject *RenderData_Bake( BPy_RenderData * self );
/* BPy_RenderData Internal Protocols */
@ -492,6 +498,28 @@ PyObject *RenderData_Render( BPy_RenderData * self )
Py_RETURN_NONE;
}
/***************************************************************************/
/* BPy_Bake Function Definitions */
/***************************************************************************/
PyObject *RenderData_Bake( BPy_RenderData * self )
{
char *error_msg = NULL;
Scene *oldsce;
oldsce = G.scene;
set_scene( self->scene );
objects_bake_render(0, &error_msg);
set_scene( oldsce );
if (error_msg)
return EXPP_ReturnPyObjError( PyExc_RuntimeError, error_msg );
Py_RETURN_NONE;
}
/*
* This will save the rendered image to an output file path already defined.
*/
@ -1849,6 +1877,9 @@ static PyObject *RenderData_getFloatAttr( BPy_RenderData *self, void *type )
case EXPP_RENDER_ATTR_FPS_BASE:
param = self->renderContext->frs_sec_base;
break;
case EXPP_RENDER_ATTR_BAKEDIST:
param = self->renderContext->bake_maxdist;
break;
default:
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"undefined type constant in RenderData_getFloatAttr" );
@ -1882,6 +1913,13 @@ static int RenderData_setFloatAttrClamp( BPy_RenderData *self, PyObject *value,
max = 120.0f;
param = &self->renderContext->frs_sec_base;
break;
case EXPP_RENDER_ATTR_BAKEDIST:
min = 0.0f;
max = 10.0f;
param = &self->renderContext->bake_maxdist;
break;
default:
return EXPP_ReturnIntError( PyExc_RuntimeError,
"undefined type constant in RenderData_setFloatAttrClamp" );
@ -1928,6 +1966,15 @@ static PyObject *RenderData_getIValueAttr( BPy_RenderData *self, void *type )
case EXPP_RENDER_ATTR_SIZEY:
param = self->renderContext->ysch;
break;
case EXPP_RENDER_ATTR_BAKEMARGIN:
param = self->renderContext->bake_filter;
break;
case EXPP_RENDER_ATTR_BAKEMODE:
param = self->renderContext->bake_mode;
break;
case EXPP_RENDER_ATTR_BAKENORMALSPACE:
param = self->renderContext->bake_normal_space;
break;
default:
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"undefined type constant in RenderData_setIValueAttrClamp" );
@ -2006,6 +2053,24 @@ static int RenderData_setIValueAttrClamp( BPy_RenderData *self, PyObject *value,
size = 'h';
param = &self->renderContext->ysch;
break;
case EXPP_RENDER_ATTR_BAKEMARGIN:
min = 0;
max = 32;
size = 'h';
param = &self->renderContext->bake_filter;
break;
case EXPP_RENDER_ATTR_BAKEMODE:
min = RE_BAKE_LIGHT;
max = RE_BAKE_DISPLACEMENT;
size = 'h';
param = &self->renderContext->bake_mode;
break;
case EXPP_RENDER_ATTR_BAKENORMALSPACE:
min = R_BAKE_SPACE_CAMERA;
max = R_BAKE_SPACE_TANGENT;
size = 'h';
param = &self->renderContext->bake_normal_space;
break;
default:
return EXPP_ReturnIntError( PyExc_RuntimeError,
"undefined type constant in RenderData_setIValueAttrClamp" );
@ -2451,6 +2516,32 @@ static int RenderData_setActiveLayer( BPy_RenderData *self, PyObject *value )
return 0;
}
static int RenderData_setBakeMode( BPy_RenderData *self, PyObject *value,
void *type )
{
/* use negative numbers to flip truth */
int param = PyObject_IsTrue( value );
if( param == -1 )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected True/False or 0/1" );
if (param) {
self->renderContext->bake_flag |= (int)type;
} else {
self->renderContext->bake_flag &= ~(int)type;
}
return 0;
}
static PyObject *RenderData_getBakeMode( BPy_RenderData *self, void *type )
{
int itype = (int)type;
/* use negative numbers to flip truth */
if (self->renderContext->bake_flag & itype) Py_RETURN_TRUE;
else Py_RETURN_FALSE;
}
/***************************************************************************/
/* BPy_RenderData attribute def */
/***************************************************************************/
@ -2791,7 +2882,32 @@ static PyGetSetDef BPy_RenderData_getseters[] = {
(getter)RenderData_getYafrayGITunePhotons, (setter)RenderData_setYafrayGITunePhotons,
"If true the photonmap is shown directly in the render for tuning",
NULL},
/* Bake stuff */
{"bakeClear",
(getter)RenderData_getBakeMode, (setter)RenderData_setBakeMode,
"Clear the image before baking",
(void *)R_BAKE_CLEAR},
{"bakeToActive",
(getter)RenderData_getBakeMode, (setter)RenderData_setBakeMode,
"Bake selection to active",
(void *)R_BAKE_TO_ACTIVE},
{"bakeMargin",
(getter)RenderData_getIValueAttr, (setter)RenderData_setIValueAttrClamp,
"number of pixels to use as a margin for the edges of the image",
(void *)EXPP_RENDER_ATTR_BAKEMARGIN},
{"bakeMode",
(getter)RenderData_getIValueAttr, (setter)RenderData_setIValueAttrClamp,
"The mode for baking, see Blender.Scene.Render.BakeModes",
(void *)EXPP_RENDER_ATTR_BAKEMODE},
{"bakeNormalSpace",
(getter)RenderData_getIValueAttr, (setter)RenderData_setIValueAttrClamp,
"The mode for baking, see Blender.Scene.Render.BakeNormalSpaceModes",
(void *)EXPP_RENDER_ATTR_BAKENORMALSPACE},
{"bakeDist",
(getter)RenderData_getFloatAttr, (setter)RenderData_setFloatAttrClamp,
"Distance in blender units",
(void *)EXPP_RENDER_ATTR_BAKEDIST},
{NULL,NULL,NULL,NULL,NULL}
};
@ -2801,6 +2917,8 @@ static PyGetSetDef BPy_RenderData_getseters[] = {
static PyMethodDef BPy_RenderData_methods[] = {
{"render", ( PyCFunction ) RenderData_Render, METH_NOARGS,
"() - render the scene"},
{"bake", ( PyCFunction ) RenderData_Bake, METH_NOARGS,
"() - bake current selection"},
{"saveRenderedImage", (PyCFunction)RenderData_SaveRenderedImage, METH_VARARGS,
"(filename) - save an image generated by a call to render() (set output path first)"},
{"renderAnim", ( PyCFunction ) RenderData_RenderAnim, METH_NOARGS,
@ -3660,6 +3778,39 @@ static PyObject *M_Render_GameFramingDict( void )
return M;
}
static PyObject *M_Render_BakeModesDict( void )
{
PyObject *M = PyConstant_New( );
if( M ) {
BPy_constant *d = ( BPy_constant * ) M;
PyConstant_Insert( d, "LIGHT", PyInt_FromLong( RE_BAKE_LIGHT ) );
PyConstant_Insert( d, "ALL", PyInt_FromLong( RE_BAKE_ALL ) );
PyConstant_Insert( d, "AO", PyInt_FromLong( RE_BAKE_AO ) );
PyConstant_Insert( d, "NORMALS", PyInt_FromLong( RE_BAKE_NORMALS ) );
PyConstant_Insert( d, "TEXTURE", PyInt_FromLong( RE_BAKE_TEXTURE ) );
PyConstant_Insert( d, "DISPLACEMENT", PyInt_FromLong( RE_BAKE_DISPLACEMENT ) );
}
return M;
}
static PyObject *M_Render_BakeNormalSpaceDict( void )
{
PyObject *M = PyConstant_New( );
if( M ) {
BPy_constant *d = ( BPy_constant * ) M;
PyConstant_Insert( d, "CAMERA", PyInt_FromLong( R_BAKE_SPACE_CAMERA ) );
PyConstant_Insert( d, "WORLS", PyInt_FromLong( R_BAKE_SPACE_WORLD ) );
PyConstant_Insert( d, "OBJECT", PyInt_FromLong( R_BAKE_SPACE_OBJECT ) );
PyConstant_Insert( d, "TANGENT", PyInt_FromLong( R_BAKE_SPACE_TANGENT ) );
}
return M;
}
/***************************************************************************/
/* Render Module Init */
/***************************************************************************/
@ -3669,7 +3820,9 @@ PyObject *Render_Init( void )
PyObject *ModesDict = M_Render_ModesDict( );
PyObject *SceModesDict = M_Render_SceModesDict( );
PyObject *GFramingDict = M_Render_GameFramingDict( );
PyObject *BakeModesDict = M_Render_BakeModesDict( );
PyObject *BakeNormalSpaceDict = M_Render_BakeNormalSpaceDict( );
if( PyType_Ready( &RenderData_Type ) < 0 )
return NULL;
@ -3685,7 +3838,11 @@ PyObject *Render_Init( void )
PyModule_AddObject( submodule, "SceModes", SceModesDict );
if( GFramingDict )
PyModule_AddObject( submodule, "FramingModes", GFramingDict );
if( BakeModesDict )
PyModule_AddObject( submodule, "BakeModes", BakeModesDict );
if( BakeNormalSpaceDict )
PyModule_AddObject( submodule, "BakeNormalSpaceModes", BakeNormalSpaceDict );
/* ugh: why aren't these in a constant dict? */
PyModule_AddIntConstant( submodule, "INTERNAL", R_INTERN );

@ -2058,7 +2058,7 @@ static void render_panel_output(void)
static void do_bake_func(void *unused_v, void *unused_p)
{
objects_bake_render(0);
objects_bake_render_ui(0);
}
static void render_panel_bake(void)

@ -1763,7 +1763,7 @@ void do_info_render_bakemenu(void *arg, int event)
G.scene->r.bake_flag ^= event;
break;
default:
objects_bake_render(event);
objects_bake_render_ui(event);
}
allqueue(REDRAWINFO, 0);

@ -1011,11 +1011,10 @@ void objects_bake_render_menu(void)
event= pupmenu("Bake Selected Meshes %t|Full Render %x1|Ambient Occlusion %x2|Normals %x3|Texture Only %x4|Displacement %x5");
objects_bake_render(event);
objects_bake_render_ui(event);
}
/* all selected meshes with UV maps are rendered for current scene visibility */
void objects_bake_render(short event)
void objects_bake_render(short event, char **error_msg)
{
Object *actob= OBACT;
int active= G.scene->r.bake_flag & R_BAKE_TO_ACTIVE;
@ -1024,8 +1023,8 @@ void objects_bake_render(short event)
if(event==0) event= G.scene->r.bake_mode;
if(G.scene->r.renderer!=R_INTERN) {
error("Bake only supported for Internal Renderer");
return;
*error_msg = "Bake only supported for Internal Renderer";
return;
}
if(active && !actob)
@ -1048,7 +1047,7 @@ void objects_bake_render(short event)
if(event==RE_BAKE_AO) {
if(G.scene->world==NULL) {
error("No world set up");
*error_msg = "No world set up";
return;
}
@ -1099,7 +1098,7 @@ void objects_bake_render(short event)
RE_Database_Free(re);
waitcursor(0);
if(tot==0) error("No Images found to bake to");
if(tot==0) *error_msg = "No Images found to bake to";
else {
Image *ima;
/* force OpenGL reload and mipmap recalc */
@ -1131,3 +1130,11 @@ void objects_bake_render(short event)
}
}
/* all selected meshes with UV maps are rendered for current scene visibility */
void objects_bake_render_ui(short event)
{
char *error_msg = NULL;
objects_bake_render(event, &error_msg);
if (error_msg)
error(error_msg);
}