- based on a request by Campbell (he also provided a patch for scene.Layer) access to layers was improved a little, keeping the old method (ob.Layers is a bitmask) and adding the nicer one (ob.layers is a list of ints).  Done for objects and scenes.  House-cleaning: .Layer was renamed to .Layers (actually just using strncmp instead of strcmp, so both work, same done for Window.ViewLayers).
- finally committing patch by Ken Hughes to let .clearScriptLinks() accept a parameter (list of strings) to clear only specified texts.
- doc updates and fixes (JMS reported a problem in nmesh.transform() example code).

Thanks all who contributed.
This commit is contained in:
2005-04-21 19:44:52 +00:00
parent c5214c1571
commit 589ce4a005
24 changed files with 657 additions and 347 deletions

View File

@@ -25,7 +25,7 @@
*
* This is a new part of Blender.
*
* Contributor(s): Willian P. Germano, Johnny Matthews
* Contributor(s): Willian P. Germano, Johnny Matthews, Ken Hughes
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -125,7 +125,7 @@ static PyObject *Camera_setDrawSize( BPy_Camera * self, PyObject * args );
static PyObject *Camera_setScale( BPy_Camera * self, PyObject * args );
static PyObject *Camera_getScriptLinks( BPy_Camera * self, PyObject * args );
static PyObject *Camera_addScriptLink( BPy_Camera * self, PyObject * args );
static PyObject *Camera_clearScriptLinks( BPy_Camera * self );
static PyObject *Camera_clearScriptLinks( BPy_Camera * self, PyObject * args );
static PyObject *Camera_insertIpoKey( BPy_Camera * self, PyObject * args );
Camera *GetCameraByName( char *name );
@@ -187,7 +187,8 @@ static PyMethodDef BPy_Camera_methods[] = {
"(evt) string: FrameChanged or Redraw."},
{"clearScriptLinks", ( PyCFunction ) Camera_clearScriptLinks,
METH_NOARGS,
"() - Delete all scriptlinks from this camera."},
"() - Delete all scriptlinks from this camera.\n"
"([s1<,s2,s3...>]) - Delete specified scriptlinks from this camera."},
{NULL, NULL, 0, NULL}
};
@@ -784,22 +785,18 @@ static PyObject *Camera_addScriptLink( BPy_Camera * self, PyObject * args )
slink = &( cam )->scriptlink;
if( !EXPP_addScriptLink( slink, args, 0 ) )
return EXPP_incr_ret( Py_None );
else
return NULL;
return EXPP_addScriptLink( slink, args, 0 );
}
/* cam.clearScriptLinks */
static PyObject *Camera_clearScriptLinks( BPy_Camera * self )
static PyObject *Camera_clearScriptLinks( BPy_Camera * self, PyObject * args )
{
Camera *cam = self->camera;
ScriptLink *slink = NULL;
slink = &( cam )->scriptlink;
return EXPP_incr_ret( Py_BuildValue
( "i", EXPP_clearScriptLinks( slink ) ) );
return EXPP_clearScriptLinks( slink, args );
}
/* cam.getScriptLinks */

View File

@@ -24,7 +24,8 @@
*
* This is a new part of Blender.
*
* Contributor(s): Willian P. Germano, Nathan Letwory
* Contributor(s): Willian P. Germano, Nathan Letwory, Stephen Swaney,
* Ken Hughes
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -215,7 +216,7 @@ static PyObject *Lamp_setColorComponent( BPy_Lamp * self, char *key,
PyObject * args );
static PyObject *Lamp_getScriptLinks( BPy_Lamp * self, PyObject * args );
static PyObject *Lamp_addScriptLink( BPy_Lamp * self, PyObject * args );
static PyObject *Lamp_clearScriptLinks( BPy_Lamp * self );
static PyObject *Lamp_clearScriptLinks( BPy_Lamp * self, PyObject * args );
/*****************************************************************************/
/* Python BPy_Lamp methods table: */
@@ -303,8 +304,9 @@ static PyMethodDef BPy_Lamp_methods[] = {
"(text) - string: an existing Blender Text name;\n"
"(evt) string: FrameChanged or Redraw."},
{"clearScriptLinks", ( PyCFunction ) Lamp_clearScriptLinks,
METH_NOARGS,
"() - Delete all scriptlinks from this lamp."},
METH_VARARGS,
"() - Delete all scriptlinks from this lamp.\n"
"([s1<,s2,s3...>]) - Delete specified scriptlinks from this lamp."},
{"getIpo", ( PyCFunction ) Lamp_getIpo, METH_NOARGS,
"() - get IPO for this lamp"},
{"clearIpo", ( PyCFunction ) Lamp_clearIpo, METH_NOARGS,
@@ -1231,22 +1233,18 @@ static PyObject *Lamp_addScriptLink( BPy_Lamp * self, PyObject * args )
slink = &( lamp )->scriptlink;
if( !EXPP_addScriptLink( slink, args, 0 ) )
return EXPP_incr_ret( Py_None );
else
return NULL;
return EXPP_addScriptLink( slink, args, 0 );
}
/* lamp.clearScriptLinks */
static PyObject *Lamp_clearScriptLinks( BPy_Lamp * self )
static PyObject *Lamp_clearScriptLinks( BPy_Lamp * self, PyObject * args )
{
Lamp *lamp = self->lamp;
ScriptLink *slink = NULL;
slink = &( lamp )->scriptlink;
return EXPP_incr_ret( Py_BuildValue
( "i", EXPP_clearScriptLinks( slink ) ) );
return EXPP_clearScriptLinks( slink, args );
}
/* mat.getScriptLinks */

View File

@@ -26,7 +26,7 @@
* This is a new part of Blender.
*
* Contributor(s): Willian P. Germano, Michel Selten, Alex Mole,
* Alexander Szakaly, Campbell Barton
* Alexander Szakaly, Campbell Barton, Ken Hughes
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -487,11 +487,9 @@ static PyObject *Material_clearTexture( BPy_Material * self, PyObject * args );
static PyObject *Material_setColorComponent( BPy_Material * self, char *key,
PyObject * args );
static PyObject *Material_getScriptLinks( BPy_Material * self,
PyObject * args );
static PyObject *Material_addScriptLink( BPy_Material * self,
PyObject * args );
static PyObject *Material_clearScriptLinks( BPy_Material * self );
static PyObject *Material_getScriptLinks(BPy_Material *self, PyObject * args );
static PyObject *Material_addScriptLink(BPy_Material * self, PyObject * args );
static PyObject *Material_clearScriptLinks(BPy_Material *self, PyObject *args);
static PyObject *Material_insertIpoKey( BPy_Material * self, PyObject * args );
@@ -668,8 +666,9 @@ static PyMethodDef BPy_Material_methods[] = {
"(text) - string: an existing Blender Text name;\n"
"(evt) string: FrameChanged or Redraw."},
{"clearScriptLinks", ( PyCFunction ) Material_clearScriptLinks,
METH_NOARGS,
"() - Delete all scriptlinks from this material."},
METH_VARARGS,
"() - Delete all scriptlinks from this material.\n"
"([s1<,s2,s3...>]) - Delete specified scriptlinks from this material."},
{NULL, NULL, 0, NULL}
};
@@ -1977,22 +1976,18 @@ static PyObject *Material_addScriptLink( BPy_Material * self, PyObject * args )
slink = &( mat )->scriptlink;
if( !EXPP_addScriptLink( slink, args, 0 ) )
return EXPP_incr_ret( Py_None );
else
return NULL;
return EXPP_addScriptLink( slink, args, 0 );
}
/* mat.clearScriptLinks */
static PyObject *Material_clearScriptLinks( BPy_Material * self )
static PyObject *Material_clearScriptLinks(BPy_Material *self, PyObject *args )
{
Material *mat = self->material;
ScriptLink *slink = NULL;
slink = &( mat )->scriptlink;
return EXPP_incr_ret( Py_BuildValue
( "i", EXPP_clearScriptLinks( slink ) ) );
return EXPP_clearScriptLinks( slink, args );
}
/* mat.getScriptLinks */

View File

@@ -23,7 +23,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* This is a new part of Blender.
* This is a new part of Blender, but it borrows all the old NMesh code.
*
* Contributor(s): Willian P. Germano, Jordi Rovira i Bonet, Joseph Gilbert,
* Bala Gi, Alexander Szakaly, Stephane Soppera, Campbell Barton

View File

@@ -29,7 +29,8 @@
*
*
* Contributor(s): Michel Selten, Willian Germano, Jacques Guignot,
* Joseph Gilbert, Stephen Swaney, Bala Gi, Campbell Barton, Johnny Matthews
* Joseph Gilbert, Stephen Swaney, Bala Gi, Campbell Barton, Johnny Matthews,
* Ken Hughes
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -184,7 +185,7 @@ static PyObject *Object_copyAllPropertiesTo( BPy_Object * self,
PyObject * args );
static PyObject *Object_getScriptLinks( BPy_Object * self, PyObject * args );
static PyObject *Object_addScriptLink( BPy_Object * self, PyObject * args );
static PyObject *Object_clearScriptLinks( BPy_Object * self );
static PyObject *Object_clearScriptLinks( BPy_Object * self, PyObject *args );
static PyObject *Object_setDupliVerts ( BPy_Object * self, PyObject * args );
static PyObject *Object_getPIStrength( BPy_Object * self );
static PyObject *Object_setPIStrength( BPy_Object * self, PyObject * args );
@@ -501,8 +502,9 @@ works only if self and the object specified are of the same type."},
"(text) - string: an existing Blender Text name;\n"
"(evt) string: FrameChanged or Redraw."},
{"clearScriptLinks", ( PyCFunction ) Object_clearScriptLinks,
METH_NOARGS,
"() - Delete all scriptlinks from this object."},
METH_VARARGS,
"() - Delete all scriptlinks from this object.\n"
"([s1<,s2,s3...>]) - Delete specified scriptlinks from this object."},
{"setDupliVerts", ( PyCFunction ) Object_setDupliVerts,
METH_VARARGS, "() - set or reset duplicate child objects on all vertices"},
{NULL, NULL, 0, NULL}
@@ -2256,22 +2258,18 @@ static PyObject *Object_addScriptLink( BPy_Object * self, PyObject * args )
slink = &( obj )->scriptlink;
if( !EXPP_addScriptLink( slink, args, 0 ) )
return EXPP_incr_ret( Py_None );
else
return NULL;
return EXPP_addScriptLink( slink, args, 0 );
}
/* obj.clearScriptLinks */
static PyObject *Object_clearScriptLinks( BPy_Object * self )
static PyObject *Object_clearScriptLinks( BPy_Object * self, PyObject * args )
{
Object *obj = self->object;
ScriptLink *slink = NULL;
slink = &( obj )->scriptlink;
return EXPP_incr_ret( Py_BuildValue
( "i", EXPP_clearScriptLinks( slink ) ) );
return EXPP_clearScriptLinks( slink, args );
}
/* obj.getScriptLinks */
@@ -2479,8 +2477,31 @@ static PyObject *Object_getAttr( BPy_Object * obj, char *name )
}
return ( NULL );
}
if( StringEqual( name, "Layer" ) )
/* accept both Layer (old, for compatibility) and Layers */
if( strncmp( name, "Layer", 5 ) == 0)
return ( PyInt_FromLong( object->lay ) );
/* Layers returns a bitmask, layers returns a list of integers */
if( StringEqual( name, "layers" ) ) {
int layers, bit = 0, val = 0;
PyObject *item = NULL, *laylist = PyList_New( 0 );
if( !laylist )
return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
"couldn't create pylist!" ) );
layers = object->lay;
while( bit < 20 ) {
val = 1 << bit;
if( layers & val ) {
item = Py_BuildValue( "i", bit + 1 );
PyList_Append( laylist, item );
Py_DECREF( item );
}
bit++;
}
return laylist;
}
if( StringEqual( name, "parent" ) ) {
if( object->parent )
return ( Object_CreatePyObject( object->parent ) );
@@ -2658,7 +2679,8 @@ static int Object_setAttr( BPy_Object * obj, char *name, PyObject * value )
}
return ( 0 );
}
if( StringEqual( name, "Layer" ) ) {
/* accept both Layer (for compatibility) and Layers */
if( strncmp( name, "Layer", 5 ) == 0 ) {
/* usage note: caller of this func needs to do a
Blender.Redraw(-1) to update and redraw the interface */
@@ -2673,9 +2695,10 @@ static int Object_setAttr( BPy_Object * obj, char *name, PyObject * value )
/* uppper 2 nibbles are for local view */
newLayer &= 0x00FFFFFF;
if( newLayer == 0 ) /* bail if nothing to do */
return ( 0 );
if( newLayer == 0 )
return EXPP_ReturnIntError( PyExc_AttributeError,
"bitmask must have from 1 up to 20 bits set");
/* update any bases pointing to our object */
base = FIRSTBASE; /* first base in current scene */
while( base ){
@@ -2690,11 +2713,59 @@ static int Object_setAttr( BPy_Object * obj, char *name, PyObject * value )
return ( 0 );
}
if( StringEqual( name, "layers" ) ) {
/* usage note: caller of this func needs to do a
Blender.Redraw(-1) to update and redraw the interface */
Base *base;
int layers = 0, len_list = 0;
int local, i, val;
PyObject *list = NULL, *item = NULL;
if( !PyArg_Parse( value, "O!", &PyList_Type, &list ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected a list of integers" );
len_list = PyList_Size(list);
if (len_list == 0)
return EXPP_ReturnIntError( PyExc_AttributeError,
"list can't be empty, at least one layer must be set" );
for( i = 0; i < len_list; i++ ) {
item = PyList_GetItem( list, i );
if( !PyInt_Check( item ) )
return EXPP_ReturnIntError
( PyExc_AttributeError,
"list must contain only integer numbers" );
val = ( int ) PyInt_AsLong( item );
if( val < 1 || val > 20 )
return EXPP_ReturnIntError
( PyExc_AttributeError,
"layer values must be in the range [1, 20]" );
layers |= 1 << ( val - 1 );
}
/* update any bases pointing to our object */
base = FIRSTBASE; /* first base in current scene */
while( base ){
if( base->object == obj->object ) {
local = base->lay &= 0xFF000000;
base->lay = local | layers;
object->lay = base->lay;
}
base = base->next;
}
countall();
return ( 0 );
}
if( StringEqual( name, "parent" ) ) {
/* This is not allowed. */
EXPP_ReturnPyObjError( PyExc_AttributeError,
return EXPP_ReturnIntError( PyExc_AttributeError,
"Setting the parent is not allowed." );
return ( 0 );
}
if( StringEqual( name, "track" ) ) {
if( Object_makeTrack( obj, valtuple ) != Py_None )
@@ -2704,27 +2775,23 @@ static int Object_setAttr( BPy_Object * obj, char *name, PyObject * value )
}
if( StringEqual( name, "data" ) ) {
/* This is not allowed. */
EXPP_ReturnPyObjError( PyExc_AttributeError,
return EXPP_ReturnIntError( PyExc_AttributeError,
"Setting the data is not allowed." );
return ( 0 );
}
if( StringEqual( name, "ipo" ) ) {
/* This is not allowed. */
EXPP_ReturnPyObjError( PyExc_AttributeError,
return EXPP_ReturnIntError( PyExc_AttributeError,
"Setting the ipo is not allowed." );
return ( 0 );
}
if( StringEqual( name, "mat" ) ) {
/* This is not allowed. */
EXPP_ReturnPyObjError( PyExc_AttributeError,
return EXPP_ReturnIntError( PyExc_AttributeError,
"Setting the matrix is not allowed." );
return ( 0 );
}
if( StringEqual( name, "matrix" ) ) {
/* This is not allowed. */
EXPP_ReturnPyObjError( PyExc_AttributeError,
return EXPP_ReturnIntError( PyExc_AttributeError,
"Please use .setMatrix(matrix)" );
return ( 0 );
}
if( StringEqual( name, "colbits" ) )
return ( !PyArg_Parse( value, "h", &( object->colbits ) ) );

View File

@@ -93,6 +93,9 @@ struct PyMethodDef M_Scene_methods[] = {
//-----------------------BPy_Scene method declarations--------------------
static PyObject *Scene_getName( BPy_Scene * self );
static PyObject *Scene_setName( BPy_Scene * self, PyObject * arg );
static PyObject *Scene_getLayers( BPy_Scene * self );
static PyObject *Scene_setLayers( BPy_Scene * self, PyObject * arg );
static PyObject *Scene_setLayersMask( BPy_Scene * self, PyObject * arg );
static PyObject *Scene_copy( BPy_Scene * self, PyObject * arg );
static PyObject *Scene_makeCurrent( BPy_Scene * self );
static PyObject *Scene_update( BPy_Scene * self, PyObject * args );
@@ -105,19 +108,9 @@ static PyObject *Scene_getRenderingContext( BPy_Scene * self );
static PyObject *Scene_getRadiosityContext( BPy_Scene * self );
static PyObject *Scene_getScriptLinks( BPy_Scene * self, PyObject * args );
static PyObject *Scene_addScriptLink( BPy_Scene * self, PyObject * args );
static PyObject *Scene_clearScriptLinks( BPy_Scene * self );
static PyObject *Scene_clearScriptLinks( BPy_Scene * self, PyObject * args );
static PyObject *Scene_play( BPy_Scene * self, PyObject * args );
//deprecated methods
static PyObject *Scene_currentFrame( BPy_Scene * self, PyObject * args );
static PyObject *Scene_getWinSize( BPy_Scene * self );
static PyObject *Scene_setWinSize( BPy_Scene * self, PyObject * arg );
static PyObject *Scene_startFrame( BPy_Scene * self, PyObject * args );
static PyObject *Scene_endFrame( BPy_Scene * self, PyObject * args );
static PyObject *Scene_frameSettings( BPy_Scene * self, PyObject * args );
static PyObject *Scene_getRenderdir( BPy_Scene * self );
static PyObject *Scene_getBackbufdir( BPy_Scene * self );
//internal
static void Scene_dealloc( BPy_Scene * self );
static int Scene_setAttr( BPy_Scene * self, char *name, PyObject * v );
@@ -131,6 +124,11 @@ static PyMethodDef BPy_Scene_methods[] = {
"() - Return Scene name"},
{"setName", ( PyCFunction ) Scene_setName, METH_VARARGS,
"(str) - Change Scene name"},
{"getLayers", ( PyCFunction ) Scene_getLayers, METH_NOARGS,
"() - Return a list of layers int indices which are set in this Scene "},
{"setLayers", ( PyCFunction ) Scene_setLayers, METH_VARARGS,
"(layers) - Change layers which are set in this Scene\n"
"(layers) - list of integers in the range [1, 20]."},
{"copy", ( PyCFunction ) Scene_copy, METH_VARARGS,
"(duplicate_objects = 1) - Return a copy of this scene\n"
"The optional argument duplicate_objects defines how the scene\n"
@@ -160,39 +158,18 @@ static PyMethodDef BPy_Scene_methods[] = {
"(text) - string: an existing Blender Text name;\n"
"(evt) string: FrameChanged, OnLoad or Redraw."},
{"clearScriptLinks", ( PyCFunction ) Scene_clearScriptLinks,
METH_NOARGS,
"() - Delete all scriptlinks from this scene."},
METH_VARARGS,
"() - Delete all scriptlinks from this scene.\n"
"([s1<,s2,s3...>]) - Delete specified scriptlinks from this scene."},
{"setCurrentCamera", ( PyCFunction ) Scene_setCurrentCamera,
METH_VARARGS,
"() - Set the currently active Camera"},
//DEPRECATED
{"getWinSize", ( PyCFunction ) Scene_getWinSize, METH_NOARGS,
"() - Return Render window [x,y] dimensions"},
{"setWinSize", ( PyCFunction ) Scene_setWinSize, METH_VARARGS,
"(str) - Change Render window [x,y] dimensions"},
{"startFrame", ( PyCFunction ) Scene_startFrame, METH_VARARGS,
"(frame) - If frame is given, the start frame is set and"
"\nreturned in any case"},
{"endFrame", ( PyCFunction ) Scene_endFrame, METH_VARARGS,
"(frame) - If frame is given, the end frame is set and"
"\nreturned in any case"},
{"frameSettings", ( PyCFunction ) Scene_frameSettings, METH_VARARGS,
"(start, end, current) - Sets or retrieves the Scene's frame"
" settings.\nIf the frame arguments are specified, they are set. "
"A tuple (start, end, current) is returned in any case."},
{"getRenderdir", ( PyCFunction ) Scene_getRenderdir, METH_NOARGS,
"() - Return directory where rendered images are saved to"},
{"getBackbufdir", ( PyCFunction ) Scene_getBackbufdir, METH_NOARGS,
"() - Return location of the backbuffer image"},
{"getRenderingContext", ( PyCFunction ) Scene_getRenderingContext,
METH_NOARGS,
"() - Get the rendering context for the scene and return it as a BPy_RenderData"},
{"getRadiosityContext", ( PyCFunction ) Scene_getRadiosityContext,
METH_NOARGS,
"() - Get the radiosity context for this scene."},
{"currentFrame", ( PyCFunction ) Scene_currentFrame, METH_VARARGS,
"(frame) - If frame is given, the current frame is set and"
"\nreturned in any case"},
{"play", ( PyCFunction ) Scene_play, METH_VARARGS,
"(mode = 0, win = VIEW3D) - Play realtime animation in Blender"
" (not rendered).\n"
@@ -231,6 +208,7 @@ PyTypeObject Scene_Type = {
0, 0, 0, 0, 0, 0,
BPy_Scene_methods, /* tp_methods */
0, /* tp_members */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
//-----------------------Scene module Init())-----------------------------
PyObject *Scene_Init( void )
@@ -264,10 +242,16 @@ static PyObject *Scene_getAttr( BPy_Scene * self, char *name )
if( strcmp( name, "name" ) == 0 )
attr = PyString_FromString( self->scene->id.name + 2 );
/* accept both Layer (for compatibility with ob.Layer) and Layers */
else if( strncmp( name, "Layer", 5 ) == 0 )
attr = PyInt_FromLong( self->scene->lay );
/* Layers returns a bitmask, layers returns a list of integers */
else if( strcmp( name, "layers") == 0) {
return Scene_getLayers(self);
}
else if( strcmp( name, "__members__" ) == 0 )
attr = Py_BuildValue( "[s]", "name" );
attr = Py_BuildValue( "[ss]", "name", "Layers", "layers" );
if( !attr )
return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
@@ -302,8 +286,12 @@ static int Scene_setAttr( BPy_Scene * self, char *name, PyObject * value )
/* Now we just compare "name" with all possible BPy_Scene member variables */
if( strcmp( name, "name" ) == 0 )
error = Scene_setName( self, valtuple );
else if (strncmp(name, "Layer", 5) == 0)
error = Scene_setLayersMask(self, valtuple);
else if (strcmp(name, "layers") == 0)
error = Scene_setLayers(self, valtuple);
else { /* Error: no member with the given name was found */
else { /* Error: no member with the given name was found */
Py_DECREF( valtuple );
return ( EXPP_ReturnIntError( PyExc_AttributeError, name ) );
}
@@ -559,6 +547,114 @@ static PyObject *Scene_setName( BPy_Scene * self, PyObject * args )
return Py_None;
}
//-----------------------Scene.getLayers()---------------------------------
static PyObject *Scene_getLayers( BPy_Scene * self )
{
PyObject *laylist = PyList_New( 0 ), *item;
int layers, bit = 0, val = 0;
if( !laylist )
return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
"couldn't create pylist!" ) );
layers = self->scene->lay;
while( bit < 20 ) {
val = 1 << bit;
if( layers & val ) {
item = Py_BuildValue( "i", bit + 1 );
PyList_Append( laylist, item );
Py_DECREF( item );
}
bit++;
}
return laylist;
}
//-----------------------Scene.setLayers()---------------------------------
static PyObject *Scene_setLayers( BPy_Scene * self, PyObject * args )
{
PyObject *list = NULL, *item = NULL;
int layers = 0, val, i, len_list;
if( !PyArg_ParseTuple( args, "O!", &PyList_Type, &list ) )
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a list of integers in the range [1, 20]" ) );
len_list = PyList_Size(list);
if (len_list == 0)
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
"list can't be empty, at least one layer must be set" ) );
for( i = 0; i < len_list; i++ ) {
item = PyList_GetItem( list, i );
if( !PyInt_Check( item ) )
return EXPP_ReturnPyObjError
( PyExc_AttributeError,
"list must contain only integer numbers" );
val = ( int ) PyInt_AsLong( item );
if( val < 1 || val > 20 )
return EXPP_ReturnPyObjError
( PyExc_AttributeError,
"layer values must be in the range [1, 20]" );
layers |= 1 << ( val - 1 );
}
self->scene->lay = layers;
if (G.vd && (self->scene == G.scene)) {
int bit = 0;
G.vd->lay = layers;
while( bit < 20 ) {
val = 1 << bit;
if( layers & val ) {
G.vd->layact = val;
break;
}
bit++;
}
}
return EXPP_incr_ret(Py_None);
}
/* only used by setAttr */
static PyObject *Scene_setLayersMask(BPy_Scene *self, PyObject *args)
{
int laymask = 0;
if (!PyArg_ParseTuple(args , "i", &laymask)) {
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected an integer (bitmask) as argument" );
}
if (laymask <= 0 || laymask > 1048575) /* binary: 1111 1111 1111 1111 1111 */
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"bitmask must have from 1 up to 20 bits set");
self->scene->lay = laymask;
/* if this is the current scene then apply the scene layers value
* to the view layers value: */
if (G.vd && (self->scene == G.scene)) {
int val, bit = 0;
G.vd->lay = laymask;
while( bit < 20 ) {
val = 1 << bit;
if( laymask & val ) {
G.vd->layact = val;
break;
}
bit++;
}
}
return EXPP_incr_ret(Py_None);
}
//-----------------------Scene.copy()------------------------------------
static PyObject *Scene_copy( BPy_Scene * self, PyObject * args )
{
@@ -825,14 +921,11 @@ static PyObject *Scene_addScriptLink( BPy_Scene * self, PyObject * args )
slink = &( scene )->scriptlink;
if( !EXPP_addScriptLink( slink, args, 1 ) )
return EXPP_incr_ret( Py_None );
else
return NULL;
return EXPP_addScriptLink( slink, args, 1 );
}
/* scene.clearScriptLinks */
static PyObject *Scene_clearScriptLinks( BPy_Scene * self )
static PyObject *Scene_clearScriptLinks( BPy_Scene * self, PyObject * args )
{
Scene *scene = self->scene;
ScriptLink *slink = NULL;
@@ -843,8 +936,7 @@ static PyObject *Scene_clearScriptLinks( BPy_Scene * self )
slink = &( scene )->scriptlink;
return EXPP_incr_ret( Py_BuildValue
( "i", EXPP_clearScriptLinks( slink ) ) );
return EXPP_clearScriptLinks( slink, args );
}
/* scene.getScriptLinks */
@@ -926,62 +1018,3 @@ static PyObject *Scene_play( BPy_Scene * self, PyObject * args )
return ret;
}
/*****************************************************************************/
// DEPRECATED
/*****************************************************************************/
//-----------------------Scene.getRenderdir ()---------------------------
static PyObject *Scene_getRenderdir( BPy_Scene * self )
{
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Deprecated:use RenderData.getRenderPath()" );
}
//-----------------------Scene.getBackbufdir ()--------------------------
static PyObject *Scene_getBackbufdir( BPy_Scene * self )
{
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Deprecated:use RenderData.getBackbufPath()" );
}
//-----------------------Scene.startFrame ()-----------------------------
static PyObject *Scene_startFrame( BPy_Scene * self, PyObject * args )
{
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Deprecated:use RenderData.startFrame()" );
}
//-----------------------Scene.endFrame ()-------------------------------
static PyObject *Scene_endFrame( BPy_Scene * self, PyObject * args )
{
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Deprecated:use RenderData.endFrame()" );
}
//-----------------------Scene.getWinSize ()-----------------------------
static PyObject *Scene_getWinSize( BPy_Scene * self )
{
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Deprecated:use RenderData.imageSizeX() and RenderData.imageSizeY" );
}
//-----------------------Scene.setWinSize()------------------------------
static PyObject *Scene_setWinSize( BPy_Scene * self, PyObject * args )
{
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Deprecated:use RenderData.imageSizeX() and RenderData.imageSizeY" );
}
//-----------------------Scene.frameSettings()---------------------------
static PyObject *Scene_frameSettings( BPy_Scene * self, PyObject * args )
{
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Deprecated:use RenderData.startFrame(), RenderData.endFrame, RenderData.currentFrame" );
}
//-----------------------Scene.currentFrame()----------------------------
static PyObject *Scene_currentFrame( BPy_Scene * self, PyObject * args )
{
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Deprecated:use RenderData.currentFrame" );
}

View File

@@ -90,7 +90,7 @@ static PyObject *M_Window_GetPerspMatrix( PyObject * self );
static PyObject *M_Window_FileSelector( PyObject * self, PyObject * args );
static PyObject *M_Window_ImageSelector( PyObject * self, PyObject * args );
static PyObject *M_Window_EditMode( PyObject * self, PyObject * args );
static PyObject *M_Window_ViewLayer( PyObject * self, PyObject * args );
static PyObject *M_Window_ViewLayers( PyObject * self, PyObject * args );
static PyObject *M_Window_CameraView( PyObject * self, PyObject * args );
static PyObject *M_Window_QTest( PyObject * self );
static PyObject *M_Window_QRead( PyObject * self );
@@ -178,7 +178,7 @@ Returns the current status. This function is mostly useful to leave\n\
edit mode before applying changes to a mesh (otherwise the changes will\n\
be lost) and then returning to it upon leaving.";
static char M_Window_ViewLayer_doc[] =
static char M_Window_ViewLayers_doc[] =
"(layers = []) - Get/set active layers in all 3d View windows.\n\
() - Make no changes, only return currently visible layers.\n\
(layers = []) - a list of integers, each in the range [1, 20].\n\
@@ -317,8 +317,11 @@ struct PyMethodDef M_Window_methods[] = {
M_Window_GetPerspMatrix_doc},
{"EditMode", ( PyCFunction ) M_Window_EditMode, METH_VARARGS,
M_Window_EditMode_doc},
{"ViewLayer", ( PyCFunction ) M_Window_ViewLayer, METH_VARARGS,
M_Window_ViewLayer_doc},
{"ViewLayers", ( PyCFunction ) M_Window_ViewLayers, METH_VARARGS,
M_Window_ViewLayers_doc},
/* typo, deprecate someday: */
{"ViewLayer", ( PyCFunction ) M_Window_ViewLayers, METH_VARARGS,
M_Window_ViewLayers_doc},
{"CameraView", ( PyCFunction ) M_Window_CameraView, METH_VARARGS,
M_Window_CameraView_doc},
{"QTest", ( PyCFunction ) M_Window_QTest, METH_NOARGS,
@@ -882,15 +885,15 @@ static PyObject *M_Window_EditMode( PyObject * self, PyObject * args )
return Py_BuildValue( "h", G.obedit ? 1 : 0 );
}
static PyObject *M_Window_ViewLayer( PyObject * self, PyObject * args )
static PyObject *M_Window_ViewLayers( PyObject * self, PyObject * args )
{
PyObject *item = NULL;
PyObject *list = NULL, *resl = NULL;
int val, i, bit = 0, layer = 0;
if( !G.vd ) {
if( !G.scene ) {
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"this function can only be used after a 3d View has been initialized" );
"can't get pointer to global scene" );
}
if( !PyArg_ParseTuple( args, "|O!", &PyList_Type, &list ) )
@@ -898,7 +901,13 @@ static PyObject *M_Window_ViewLayer( PyObject * self, PyObject * args )
"expected nothing or a list of ints as argument" );
if( list ) {
for( i = 0; i < PyList_Size( list ); i++ ) {
int len_list = PyList_Size(list);
if (len_list == 0)
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"list can't be empty, at list one layer must be set" );
for( i = 0; i < len_list; i++ ) {
item = PyList_GetItem( list, i );
if( !PyInt_Check( item ) )
return EXPP_ReturnPyObjError
@@ -913,15 +922,18 @@ static PyObject *M_Window_ViewLayer( PyObject * self, PyObject * args )
layer |= 1 << ( val - 1 );
}
G.vd->lay = layer;
G.scene->lay = layer;
if (G.vd) {
G.vd->lay = layer;
while( bit < 20 ) {
val = 1 << bit;
if( layer & val ) {
G.vd->layact = val;
break;
while( bit < 20 ) {
val = 1 << bit;
if( layer & val ) {
G.vd->layact = val;
break;
}
bit++;
}
bit++;
}
}
@@ -930,7 +942,7 @@ static PyObject *M_Window_ViewLayer( PyObject * self, PyObject * args )
return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
"couldn't create pylist!" ) );
layer = G.vd->lay;
layer = G.scene->lay;
bit = 0;
while( bit < 20 ) {

View File

@@ -97,7 +97,7 @@ static PyObject *World_getMist( BPy_World * self );
static PyObject *World_setMist( BPy_World * self, PyObject * args );
static PyObject *World_getScriptLinks( BPy_World * self, PyObject * args );
static PyObject *World_addScriptLink( BPy_World * self, PyObject * args );
static PyObject *World_clearScriptLinks( BPy_World * self );
static PyObject *World_clearScriptLinks( BPy_World * self, PyObject * args );
static PyObject *World_setCurrent( BPy_World * self );
@@ -217,8 +217,9 @@ static PyMethodDef BPy_World_methods[] = {
"(text) - string: an existing Blender Text name;\n"
"(evt) string: FrameChanged or Redraw."},
{"clearScriptLinks", ( PyCFunction ) World_clearScriptLinks,
METH_NOARGS,
"() - Delete all scriptlinks from this world :)."},
METH_VARARGS,
"() - Delete all scriptlinks from this world.\n"
"([s1<,s2,s3...>]) - Delete specified scriptlinks from this world."},
{"setCurrent", ( PyCFunction ) World_setCurrent, METH_NOARGS,
"() - Makes this world the active world for the current scene."},
{"makeActive", ( PyCFunction ) World_setCurrent, METH_NOARGS,
@@ -856,22 +857,18 @@ static PyObject *World_addScriptLink( BPy_World * self, PyObject * args )
slink = &( world )->scriptlink;
if( !EXPP_addScriptLink( slink, args, 0 ) )
return EXPP_incr_ret( Py_None );
else
return NULL;
return EXPP_addScriptLink( slink, args, 0 );
}
/* world.clearScriptLinks */
static PyObject *World_clearScriptLinks( BPy_World * self )
static PyObject *World_clearScriptLinks( BPy_World * self, PyObject * args )
{
World *world = self->world;
ScriptLink *slink = NULL;
slink = &( world )->scriptlink;
return EXPP_incr_ret( Py_BuildValue
( "i", EXPP_clearScriptLinks( slink ) ) );
return EXPP_clearScriptLinks( slink, args );
}
/* world.getScriptLinks */

View File

@@ -30,8 +30,8 @@ The Blender Python API Reference
- L{NMesh} (*)
- L{Noise}
- L{Object} (*)
- L{Registry}
- L{Scene}
- L{Registry} (*)
- L{Scene} (*)
- L{Radio}
- L{Render}
- L{Sound}

View File

@@ -238,29 +238,32 @@ Introduction:
Configuring scripts:
--------------------
Configuration data is simple data used by your script (bools, ints, floats,
strings) to define default behaviors.
The L{Blender.Registry<Registry>} module provides a simplified way to keep
scripts configuration options in memory and also saved in config files.
And with the "Scripts Config Editor" script in the System menu users can later
view and edit the options easily.
For example, an exporter might have:
- EXPORT_LIGHTS = False: a bool variable (True / False) to determine if it
should also export lights setup information;
- VERSION = 2.0: an int to define an specific version of the export format;
Let's first clarify what we mean by config options: they are simple data
(bools, ints, floats, strings) used by programs to conform to user
preferences. The buttons in Blender's User Preferences window are a good
example.
For example, a particular exporter might include:
- SEPARATE_MATS = False: a bool variable (True / False) to determine if it
should write materials to a separate file;
- VERSION = 2: an int to define an specific version of the export format;
- TEX_DIR = "/path/to/textures": a default texture dir to prepend to all
exported texture filenames instead of their actual paths.
To properly handle this, script writers had to keep this information in a
separate config file (at L{Blender.Get}('udatadir') or, if not available,
L{Blender.Get}('datadir')), provide a GUI to edit it and update the file
whenever needed.
The script needs to provide users a GUI to configure these options -- or else
directly editing the source code would be the only way to change them. And to
store changes made to the GUI so they can be reloaded any time the script is
executed, programmers have to write and load their own config files (ideally at
L{Blender.Get}('udatadir') or, if not available, L{Blender.Get}('datadir')).
There are facilities in BPython now to take care of this in a simplified (and
much recommended) way.
The L{Registry} module functions L{GetKey<Registry.GetKey>} and
L{SetKey<Registry.SetKey>} take care of both keeping the data in Blender
and (new) storing it in config files at the proper dir. And the 'Scripts
Configuration Editor' script provides a GUI for users to view and edit
configuration data.
This section describes BPython facilities (based on the L{Registry} module and
the config editor) that can take care of this in a simplified (and much
recommended) way.
Here's how it works::
@@ -269,16 +272,18 @@ Introduction:
from Blender import Registry
# First define all config variables with their default values:
EXPORT_LIGHTS = True
VERBOSE = True
SEPARATE_MATERIALS = True
VERSION = True
TEX_DIR = ''
EXPORT_DIR = ''
# Then define a function to update the Registry:
def registry_update():
# populate a dict with current config values:
d = {
'EXPORT_LIGHTS': EXPORT_LIGHTS,
'VERBOSE': VERBOSE,
'SEPARATE_MATERIALS': SEPARATE_MATERIALS,
'VERSION': VERSION,
'TEX_DIR': TEX_DIR,
'EXPORT_DIR': EXPORT_DIR
}
# store the key (optional 3rd arg tells if
@@ -292,9 +297,17 @@ Introduction:
# If this key already exists, update config variables with its values:
if regdict:
EXPORT_LIGHTS = regdict['EXPORT_LIGHTS']
VERBOSE = regdict['VERBOSE']
EXPORT_DIR = regdict['EXPORT_DIR']
try:
SEPARATE_MATERIALS = regdict['SEPARATE_MATERIALS']
VERSION = regdict['VERSION']
TEX_DIR = regdict['TEX_DIR']
EXPORT_DIR = regdict['EXPORT_DIR']
# if data was corrupted (or a new version of the script changed
# (expanded, removed, renamed) the config vars and users may have
# the old config file around):
except: update_registry() # rewrite it
else: # if the key doesn't exist yet, use our function to create it:
update_registry()
@@ -303,27 +316,25 @@ Introduction:
Hint: nicer code than the simplistic example above can be written by keeping
config var names in a list of strings and using the exec function.
B{Note}: if you have a gui and the user uses it to change config vars,
call the registry_update() function to save the changes.
B{Note}: if your script's GUI lets users change config vars, call the
registry_update() function in the button events callback to save the changes.
On the other hand, you don't need to handle configuration
in your own gui, it can be left for the 'Scripts Config Editor',
which should have access to your script's config key as soon as the
above code is executed once.
above code is executed once (as soon as SetKey is executed).
B{Note} (limits for config vars): strings longer than 300 characters are
clamped and the number of items in dictionaries, sequences and the config key
itself is limited to 60.
As written above, config vars can be bools, ints, floats or strings. This is
what the Config Editor supports, with sensible but generous limits for the
number of vars and the size of each string. Restrictions were suggested or
imposed to these facilities related to the Registry module because it's meant
for configuration info, not for large volumes of data. For that you can
trivially store it in a file or Blender Text yourself -- and tell the user
about it, specially if your script keeps megabytes of data in the Registry
memory.
B{Scripts Configuration Editor}:
This script should be available from the Help menu and provides a GUI to
view and edit saved configuration data, both from the Registry dictionary in
memory and the scripts config data dir.
This script should be available from the System menu in the Scripts window.
It provides a GUI to view and edit saved configuration data, both from the
Registry dictionary in memory and the scripts config data dir. This is
useful for all scripts with config vars, but specially for those without GUI's,
like most importers and exporters, since this editor will provide one for them.
The example above already gives a good idea of how the information can be
prepared to be accessible from this editor, but there is more worth knowing:
@@ -339,8 +350,8 @@ Introduction:
3. The following information refers to extra config variables that may be
added specifically to aid the configuration editor script. To clarify, in the
example code above these variables (the string 'script' and the dictionaries
'tooltips' and 'limits') would appear along with EXPORT_LIGHTS, VERBOSE and
EXPORT_DIR, wherever they are written.
'tooltips' and 'limits') would appear along with SEPARATE_MATERIALS, VERSION,
TEX_DIR and EXPORT_DIR, wherever they are written.
Minor note: these names are case insensitive: tooltips, TOOLTIPS, etc. are all
recognized.
@@ -364,7 +375,7 @@ Introduction:
tooltips = {
'EXPORT_DIR': 'default folder where exported files should be saved',
'VERBOSE': 'print info and warning messages to the console',
'EXPORT_LIGHTS': 'export scene lighting setup'
'SEPARATE_MATERIALS': 'write materials to their own file'
}
3.3 Int and float button sliders need min and max limits. This can be passed
@@ -373,5 +384,18 @@ Introduction:
limits = {'ivar1': [-10, 10], 'ivar2': [0, 100], 'fvar1': [-12.3, 15.4]}
4. The Config Editor itself maintains a Registry key called "General", with
general options relevant to many scripts, like "verbose" to tell if the user
wants messages printed to the console and "confirm overwrite", to know if
a script should ask for confirmation before overwriting files (all exporters
are recommended to access the General key and check this var -- L{sys.exists
<Sys.exists>} tells if files or folders already exist).
Hint: for actual examples, try the ac3d importer and exporter (it's enough to
call them from the menus then cancel with ESC), as those have been updated to
use this config system. After calling them their config data will be available
in the Config Editor. We also recommend adding a section about config vars
in your script's help info, as done in the ac3d ones.
L{Back to Main Page<API_intro>}
"""

View File

@@ -60,7 +60,8 @@ def Get (request):
- 'udatadir': the path to the user defined data dir. This may not be
available (is None if not found), but users that define uscriptsdir
have a place for their own scripts and script data that won't be
erased when a new version of Blender is installed.
erased when a new version of Blender is installed. For this reason
we recommend scripts check this dir first and use it, if available.
- 'scriptsdir': the path to the main dir where scripts are stored.
- 'uscriptsdir': the path to the user defined dir for scripts. (*)
- 'yfexportdir': the path to the user defined dir for yafray export. (*)

View File

@@ -3,7 +3,7 @@
"""
The Blender.Camera submodule.
B{New}: L{Camera.getScale}, L{Camera.setScale} for ortho cameras.
B{New}: L{Camera.clearScriptLinks} accepts a parameter now.
Camera Data
===========
@@ -211,11 +211,12 @@ class Camera:
'event' type) or None if there are no script links at all.
"""
def clearScriptLinks ():
def clearScriptLinks (links = None):
"""
Delete all this Camera's script links.
@rtype: bool
@return: 0 if some internal problem occurred or 1 if successful.
Delete script links from this Camera. If no list is specified, all
script links are deleted.
@type links: list of strings
@param links: None (default) or a list of Blender L{Text} names.
"""
def addScriptLink (text, event):

View File

@@ -3,7 +3,7 @@
"""
The Blender.Lamp submodule.
B{New}: scriptLink methods: L{Lamp.getScriptLinks}, ...
B{New}: L{Lamp.clearScriptLinks} accepts a parameter now.
Lamp Data
=========
@@ -335,11 +335,12 @@ class Lamp:
'event' type) or None if there are no script links at all.
"""
def clearScriptLinks ():
def clearScriptLinks (links = None):
"""
Delete all this Lamp's script links.
@rtype: bool
@return: 0 if some internal problem occurred or 1 if successful.
Delete script links from this Lamp. If no list is specified, all
script links are deleted.
@type links: list of strings
@param links: None (default) or a list of Blender L{Text} names.
"""
def addScriptLink (text, event):

View File

@@ -3,7 +3,7 @@
"""
The Blender.Material submodule.
B{New}: scriptLink methods: L{Material.getScriptLinks}, ...
B{New}: L{Material.clearScriptLinks} accepts a parameter now.
Material
========
@@ -643,11 +643,12 @@ class Material:
'event' type) or None if there are no script links at all.
"""
def clearScriptLinks ():
def clearScriptLinks (links = None):
"""
Delete all this Material's script links.
@rtype: bool
@return: 0 if some internal problem occurred or 1 if successful.
Delete script links from this Material. If no list is specified, all
script links are deleted.
@type links: list of strings
@param links: None (default) or a list of Blender L{Text} names.
"""
def addScriptLink (text, event):

View File

@@ -601,7 +601,7 @@ class NMesh:
from Blender import NMesh, Object
ob = Object.GetSelected()[0] # Get the first selected object
me = NMesh.GetRawFromObject(ob) # Get the objects deformed mesh data
me = NMesh.GetRawFromObject(ob.name) # Get the objects deformed mesh data
me.transform(ob.matrix)
for v in me.verts:

View File

@@ -3,8 +3,13 @@
"""
The Blender.Object submodule
B{New}: L{Object.getData} now accepts an optional bool keyword argument to
define if the user wants the data object or just its name.
B{New}:
- L{Object.getData} now accepts an optional bool keyword argument to
define if the user wants the data object or just its name.
- L{Object.clearScriptLinks} accepts a parameter now.
- Object attributes: renamed Layer to L{Layers<Object.Object.Layers>} and
added the easier L{layers<Object.Object.layers>}. The old form "Layer"
will continue to work.
Object
======
@@ -135,13 +140,31 @@ class Object:
@cvar EffX: The X effector coordinate of the object. Only applies to IKA.
@cvar EffY: The Y effector coordinate of the object. Only applies to IKA.
@cvar EffZ: The Z effector coordinate of the object. Only applies to IKA.
@cvar Layer: The object layer. This value is a bitmask with one position
set for each of the 20 possible layers starting from the low order bit.
The easiest way to deal with these values in in hexadecimal notation.
@type Layers: integer (bitmask)
@cvar Layers: The object layers (also check the newer attribute
L{layers<Object.Object.layers>}). This value is a bitmask with at
least one position set for the 20 possible layers starting from the low
order bit. The easiest way to deal with these values in in hexadecimal
notation.
Example::
ob.Layer = 0x04 # sets layer 3 ( bit pattern 0100 )
After setting the Layer value, call Blender.Redraw( -1 ) to update
the interface.
@type layers: list of integers
@cvar layers: The layers this object is visible in (also check the older
attribute L{Layers<Object.Object.Layers>}). This returns a list of
integers in the range [1, 20], each number representing the respective
layer. Setting is done by passing a list of ints or an empty list for
no layers.
Example::
ob.layers = [] # object won't be visible
ob.layers = [1, 4] # object visible only in layers 1 and 4
ls = o.layers
ls.append([10])
o.layers = ls
print ob.layers # will print: [1, 4, 10]
B{Note}: changes will only be visible after the screen (at least
the 3d View and Buttons windows) is redrawn.
@cvar parent: The parent object of the object. (Read-only)
@cvar track: The object tracking this object. (Read-only)
@cvar data: The data of the object. (Read-only)
@@ -578,11 +601,12 @@ class Object:
'event' type) or None if there are no script links at all.
"""
def clearScriptLinks ():
def clearScriptLinks (links = None):
"""
Delete all this Object's script links.
@rtype: bool
@return: 0 if some internal problem occurred or 1 if successful.
Delete script links from this Object. If no list is specified, all
script links are deleted.
@type links: list of strings
@param links: None (default) or a list of Blender L{Text} names.
"""
def addScriptLink (text, event):

View File

@@ -3,55 +3,35 @@
"""
The Blender.Registry submodule.
B{New}: L{GetKey} and L{SetKey} can respectively load and save data to disk now.
B{New}: L{GetKey} and L{SetKey} have been updated to save and load scripts
*configuration data* to files.
Registry
========
This module provides a way to create, retrieve and edit B{persistent data} in
Blender. When a script runs in Blender, it has its own private global
dictionary, which is deleted when the script finishes. This is done to avoid
problems with name clashes and garbage collecting. But the result is that
data created by a script isn't kept after it leaves, for itself or others to
access later: the data isn't persistent. The Registry module was created to
give script authors a way around this limitation.
Blender.
In Python terms, the Registry holds a dictionary of dictionaries.
You should use it to save Python objects only, not BPython (Blender Python)
objects -- but you can save BPython object names, since those are strings.
Also, if you need to save a considerable amount of data, we recommend saving
it to a file instead. There's no need to keep huge blocks of memory around when
they can simply be read from a file.
When a script is executed it has its own private global dictionary,
which is deleted when the script exits. This is done to avoid problems with
name clashes and garbage collecting. But because of this, the data created by
a script isn't kept after it leaves: the data is not persistent. The Registry
module was created to give programmers a way around this limitation.
Examples of what this module can be used for:
a) Saving data from a script that another script will need to access later.
b) Saving configuration data for a script. Users can view and edit this data
using the "Scripts Configuration Editor" script, then.
c) Saving configuration data from your script's gui (button values) so that the
next time the user runs your script, the changes will still be there.
Possible uses:
- saving arbitrary data from a script that itself or another one will need
to access later.
- saving configuration data for a script: users can view and edit this data
using the "Scripts Configuration Editor" script.
- saving the current state of a script's GUI (its button values) to restore it
when the script is executed again.
Example::
import Blender
from Blender import Registry
# first declare your global variables:
myvar1 = 0
myvar2 = 3.2
mystr = "hello"
# then check if they are already at the Registry (saved on a
# previous execution of this script) or on disk:
rdict = Registry.GetKey('MyScript', True)
if rdict: # if found, get the values saved there
myvar1 = rdict['myvar1']
myvar2 = rdict['myvar2']
mystr = rdict['mystr']
# let's create a function to update the Registry when we need to:
# this function updates the Registry when we need to:
def update_Registry():
d = {}
d['myvar1'] = myvar1
@@ -60,14 +40,49 @@ Example::
# cache = True: data is also saved to a file
Blender.Registry.SetKey('MyScript', d, True)
# first declare global variables that should go to the Registry:
myvar1 = 0
myvar2 = 3.2
mystr = "hello"
# then check if they are already there (saved on a
# previous execution of this script):
rdict = Registry.GetKey('MyScript', True) # True to check on disk also
if rdict: # if found, get the values saved there
try:
myvar1 = rdict['myvar1']
myvar2 = rdict['myvar2']
mystr = rdict['mystr']
except: update_Registry() # if data isn't valid rewrite it
# ...
# here goes the main part of the script ...
# ...
# at the end, before exiting, we use our helper function:
# if at some point the data is changed, we update the Registry:
update_Registry()
# note1: better not update the Registry when the user cancels the script
# note2: most scripts shouldn't need to register more than one key.
@note: In Python terms, the Registry holds a dictionary of dictionaries.
Technically any Python or BPython object can be stored: there are no
restrictions, but ...
@note: We have a few recommendations:
Data saved to the Registry is kept in memory, so if you decide to store large
amounts your script users should be clearly informed about it --
always keep in mind that you have no idea about their resources and the
applications they are running at a given time (unless you are the only
user), so let them decide.
There are restrictions to the data that gets automatically saved to disk by
L{SetKey}(keyname, dict, True): this feature is only meant for simple data
(bools, ints, floats, strings and dictionaries or sequences of these types).
Strings are clamped if longer than 300 characters and at most 60 elements are
allowed. Since this is only meant for scripts configuration variables,
these are sensible restrictions, generous enough for the task.
For more demanding needs, it's of course trivial to save data to another
file or to a L{Blender Text<Text>}.
"""
def Keys ():
@@ -97,7 +112,9 @@ def SetKey (key, dict, cache = False):
@type cache: bool
@param cache: if True the given key data will also be saved as a file
in the config subdir of the scripts user or default data dir (see
L{Blender.Get}.
L{Blender.Get}).
@warn: as stated in the notes above, there are restrictions to what can
be automatically stored in config files.
"""
def RemoveKey (key):

View File

@@ -3,7 +3,10 @@
"""
The Blender.Scene submodule.
B{New}: OnSave script link event: L{Scene.getScriptLinks}.
B{New}:
- L{Scene.clearScriptLinks} accepts a parameter now.
- L{Scene.getLayers}, L{Scene.setLayers} and the L{layers<Scene.layers>} and
L{Layers<Scene.Layers>} Scene attributes.
Scene
=====
@@ -75,7 +78,28 @@ class Scene:
The Scene object
================
This object gives access to Scene data in Blender.
@type name: string
@cvar name: The Scene name.
@type Layers: integer (bitmask)
@cvar Layers: The Scene layers (check also the easier to use
L{layers<Scene.Scene.layers>}). This value is a bitmask with at least
one position set for the 20 possible layers starting from the low order
bit. The easiest way to deal with these values in in hexadecimal
notation.
Example::
scene.Layers = 0x04 # sets layer 3 ( bit pattern 0100 )
scene.Layers |= 0x01
print scene.Layers # will print: 5 ( meaning bit pattern 0101)
After setting the Layers value, the interface (at least the 3d View and
the Buttons window) needs to be redrawn to show the changes.
@type layers: list of integers
@cvar layers: The Scene layers (check also L{Layers<Scene.Scene.Layers>}).
This attribute accepts and returns a list of integer values in the
range [1, 20].
Example::
scene.layers = [3] # set layer 3
scene.layers = scene.layers.append(1)
print scene.layers # will print: [1, 3]
"""
def getName():
@@ -91,6 +115,25 @@ class Scene:
@param name: The new name.
"""
def getLayers():
"""
Get the layers set for this Scene.
@rtype: list of integers
@return: a list where each number means the layer with that number is
set.
"""
def setLayers(layers):
"""
Set the visible layers for this scene.
@type layers: list of integers
@param layers: a list of integers in the range [1, 20], where each available
index makes the layer with that number visible.
@note: if this Scene is the current one, the 3D View layers are also
updated, but the screen needs to be redrawn (at least 3D Views and
Buttons windows) for the changes to be seen.
"""
def copy(duplicate_objects = 1):
"""
Make a copy of this Scene.
@@ -139,6 +182,11 @@ class Scene:
Get all objects linked to this Scene.
@rtype: list of Blender Objects
@return: A list with all Blender Objects linked to this Scene.
@note: L{Object.Get} will return all objects currently in Blender, which
means all objects from all available scenes. In most cases (exporter
scripts, for example), it's probably better to use this
scene.GetChildren instead, since it will only access objects from this
particular scene.
"""
def getCurrentCamera():
@@ -179,11 +227,12 @@ class Scene:
'event' type) or None if there are no script links at all.
"""
def clearScriptLinks ():
def clearScriptLinks (links = None):
"""
Delete all this Scene's script links.
@rtype: bool
@return: 0 if some internal problem occurred or 1 if successful.
Delete script links from this Scene. If no list is specified, all
script links are deleted.
@type links: list of strings
@param links: None (default) or a list of Blender L{Text} names.
"""
def addScriptLink (text, event):

View File

@@ -3,6 +3,9 @@
"""
The Blender.Window submodule.
B{New}: renamed ViewLayer to L{ViewLayers} (actually added an alias, so both
forms will work).
Window
======
@@ -263,7 +266,7 @@ def EditMode(enable = -1, undo_msg = 'From script'):
because the normal mesh will be rebuilt based on its unchanged edit mesh.
"""
def ViewLayer (layers = []):
def ViewLayers (layers = []):
"""
Get and optionally set the currently visible layers in all 3d Views.
@type layers: list of ints

View File

@@ -3,10 +3,10 @@
"""
The Blender.World submodule
B{New}: L{GetCurrent}, L{World.setCurrent}.
B{New}: L{World.clearScriptLinks} accepts a parameter now.
INTRODUCTION
============
World
=====
The module world allows you to access all the data of a Blender World.
@@ -299,11 +299,12 @@ class World:
'event' type) or None if there are no script links at all.
"""
def clearScriptLinks ():
def clearScriptLinks (links = None):
"""
Delete all this World's script links!
@rtype: bool
@return: 0 if some internal problem occurred or 1 if successful.
Delete script links from this World :). If no list is specified, all
script links are deleted.
@type links: list of strings
@param links: None (default) or a list of Blender L{Text} names.
"""
def addScriptLink (text, event):

View File

@@ -25,7 +25,7 @@
*
* This is a new part of Blender.
*
* Contributor(s): Michel Selten, Willian P. Germano, Alex Mole
* Contributor(s): Michel Selten, Willian P. Germano, Alex Mole, Ken Hughes
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -332,25 +332,106 @@ PyObject *EXPP_getScriptLinks( ScriptLink * slink, PyObject * args,
return list;
}
int EXPP_clearScriptLinks( ScriptLink * slink )
PyObject *EXPP_clearScriptLinks( ScriptLink * slink, PyObject * args )
{
/* actually !scriptlink shouldn't happen ... */
if( !slink || !slink->totscript )
return -1;
int i, j, totLinks, deleted = 0;
PyObject *seq = NULL;
ID **stmp = NULL;
short *ftmp = NULL;
if( slink->scripts )
MEM_freeN( slink->scripts );
if( slink->flag )
MEM_freeN( slink->flag );
/* check for an optional list of strings */
if( !PyArg_ParseTuple( args, "|O", &seq ) )
return ( EXPP_ReturnPyObjError
( PyExc_TypeError,
"expected no arguments or a list of strings" ) );
slink->scripts = NULL;
slink->flag = NULL;
slink->totscript = slink->actscript = 0;
return 0; /* normal return */
/* if there was a parameter, handle it */
if ( seq != NULL ) {
/* check that parameter IS list of strings */
if ( !PyList_Check ( seq ) )
return ( EXPP_ReturnPyObjError
( PyExc_TypeError,
"expected a list of strings" ) );
totLinks = PyList_Size ( seq );
for ( i = 0 ; i < totLinks ; ++i ) {
if ( !PyString_Check ( PySequence_GetItem( seq, i ) ) )
return ( EXPP_ReturnPyObjError
( PyExc_TypeError,
"expected list to contain strings" ) );
}
/*
parameters OK: now look for each script, and delete
its link as we find it (this handles multiple links)
*/
for ( i = 0 ; i < totLinks ; ++i )
{
char *str;
str = PyString_AsString ( PySequence_GetItem( seq, i ) );
for ( j = 0 ; j < slink->totscript ; ++j ) {
if ( slink->scripts[j] && !strcmp ( slink->scripts[j]->name+2, str ) ) {
slink->scripts[j] = NULL;
++deleted;
}
}
}
}
/* if no parameter, then delete all scripts */
else {
deleted = slink->totscript;
}
/*
if not all scripts deleted, create new lists and copy remaining
links to them
*/
if ( slink->totscript > deleted ) {
slink->totscript -= deleted;
stmp = slink->scripts;
slink->scripts =
MEM_mallocN( sizeof( ID * ) * ( slink->totscript ),
"bpySlinkL" );
ftmp = slink->flag;
slink->flag =
MEM_mallocN( sizeof( short * ) * ( slink->totscript ),
"bpySlinkF" );
for ( i = 0, j = 0 ; i < slink->totscript ; ++j ) {
if ( stmp[j] != NULL ) {
memcpy( slink->scripts+i, stmp+j, sizeof( ID * ) );
memcpy( slink->flag+i, ftmp+j, sizeof( short ) );
++i;
}
}
MEM_freeN( stmp );
MEM_freeN( ftmp );
/*EXPP_allqueue (REDRAWBUTSSCRIPT, 0 );*/
slink->actscript = 1;
} else {
/* all scripts deleted, so delete entire list and free memory */
if( slink->scripts )
MEM_freeN( slink->scripts );
if( slink->flag )
MEM_freeN( slink->flag );
slink->scripts = NULL;
slink->flag = NULL;
slink->totscript = slink->actscript = 0;
}
return EXPP_incr_ret( Py_None );
}
int EXPP_addScriptLink( ScriptLink * slink, PyObject * args, int is_scene )
PyObject *EXPP_addScriptLink(ScriptLink *slink, PyObject *args, int is_scene)
{
int event = 0, found_txt = 0;
void *stmp = NULL, *ftmp = NULL;
@@ -360,13 +441,13 @@ int EXPP_addScriptLink( ScriptLink * slink, PyObject * args, int is_scene )
/* !scriptlink shouldn't happen ... */
if( !slink ) {
return EXPP_ReturnIntError( PyExc_RuntimeError,
"internal error: no scriptlink!" );
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"internal error: no scriptlink!" );
}
if( !PyArg_ParseTuple( args, "ss", &textname, &eventname ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected two strings as arguments" );
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected two strings as arguments" );
while( bltxt ) {
if( !strcmp( bltxt->id.name + 2, textname ) ) {
@@ -377,8 +458,8 @@ int EXPP_addScriptLink( ScriptLink * slink, PyObject * args, int is_scene )
}
if( !found_txt )
return EXPP_ReturnIntError( PyExc_AttributeError,
"no such Blender Text." );
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"no such Blender Text" );
if( !strcmp( eventname, "FrameChanged" ) )
event = SCRIPT_FRAMECHANGED;
@@ -390,7 +471,7 @@ int EXPP_addScriptLink( ScriptLink * slink, PyObject * args, int is_scene )
event = SCRIPT_ONSAVE;
else
return EXPP_ReturnIntError( PyExc_AttributeError,
"invalid event name." );
"invalid event name" );
stmp = slink->scripts;
slink->scripts =
@@ -420,5 +501,5 @@ int EXPP_addScriptLink( ScriptLink * slink, PyObject * args, int is_scene )
if( slink->actscript < 1 )
slink->actscript = 1;
return 0; /* normal exit */
return EXPP_incr_ret (Py_None); /* normal exit */
}

View File

@@ -89,10 +89,9 @@ int EXPP_map_getStrVal( const EXPP_map_pair * map,
int ival, const char **sval );
/* scriplinks-related: */
PyObject *EXPP_getScriptLinks( ScriptLink * slink, PyObject * args,
int is_scene );
int EXPP_clearScriptLinks( ScriptLink * slink );
int EXPP_addScriptLink( ScriptLink * slink, PyObject * args, int is_scene );
PyObject *EXPP_getScriptLinks(ScriptLink *slink, PyObject *args, int is_scene);
PyObject *EXPP_addScriptLink(ScriptLink *slink, PyObject *args, int is_scene);
PyObject *EXPP_clearScriptLinks(ScriptLink *slink, PyObject *args);
/* this queues redraws if we're not in background mode: */
void EXPP_allqueue(unsigned short event, short val);

View File

@@ -119,6 +119,7 @@ PyTypeObject ThemeSpace_Type = {
0, 0, 0, 0, 0, 0,
0, //BPy_ThemeSpace_methods, /* tp_methods */
0, /* tp_members */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
static void ThemeSpace_dealloc( BPy_ThemeSpace * self )
@@ -295,6 +296,7 @@ PyTypeObject ThemeUI_Type = {
0, 0, 0, 0, 0, 0,
0, //BPy_ThemeUI_methods, /* tp_methods */
0, /* tp_members */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
static void ThemeUI_dealloc( BPy_ThemeUI * self )
@@ -468,8 +470,9 @@ PyTypeObject Theme_Type = {
0, 0, 0, 0, 0, 0,
0, /* tp_doc */
0, 0, 0, 0, 0, 0,
0, //BPy_Theme_methods, /* tp_methods */
0, /*BPy_Theme_methods,*/ /* tp_methods */
0, /* tp_members */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
static PyObject *M_Theme_New( PyObject * self, PyObject * args )