BPython -- a few fixes:
-- fixed bug #1689: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1689&group_id=9 Reported by Tom Musgrove (thanks), the problem was that Window.QHandle was not passing events to windows that had id's below the current active window. It was a stupid mistake (mine), the code was iterating from curarea instead of from the first area in the areabase list. -- fixed bug #1568: http://projects.blender.org/tracker/index.php?func=detail&aid=1568&group_id=9&atid=125 Stephen investigated the problem, reported by Gabriel Beloin, and left hints in the bug report, thanks :). I also implemented what he suggested, now Effect.Get('objname') returns a list with all objname's effects and as before, Get('objname, position') returns the effect at position 'position'. Ref doc already updated. -- Allowed menu registration lines to appear commented out -- Python comments: '#', of course -- (suggested by Michael Reimpell) in scripts: Some Python doc tools need the doc strings between triple double-quotes, so to avoid conflicts scripts writers can now comment out the registration code, it should work anyway. Michael also provided a patch for this a few days ago, too (thanks), but to keep changes at a minimum because of proximity to a release I didn't use it.
This commit is contained in:
@@ -597,15 +597,18 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
|
||||
struct stat st;
|
||||
struct dirent *dir_entry;
|
||||
BPyMenu *pymenu;
|
||||
char *s, *fname, str[FILE_MAXFILE + FILE_MAXDIR];
|
||||
char *s, *fname, pathstr[FILE_MAXFILE + FILE_MAXDIR];
|
||||
char line[100], w[100];
|
||||
char name[100], submenu[100], subarg[100], tooltip[100];
|
||||
int res = 0, version = 0;
|
||||
|
||||
dir = opendir( dirname );
|
||||
|
||||
if( !dir )
|
||||
if( !dir ) {
|
||||
if ( DEBUG )
|
||||
printf("BPyMenus warning: could not open dir %s.\n", dirname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* we scan the dir for filenames ending with .py and starting with the
|
||||
* right 'magic number': '#!BPY'. All others are ignored. */
|
||||
@@ -621,18 +624,18 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
|
||||
if( !s || *( s + 3 ) != '\0' )
|
||||
continue;
|
||||
|
||||
BLI_make_file_string( "/", str, dirname, fname );
|
||||
BLI_make_file_string( "/", pathstr, dirname, fname );
|
||||
|
||||
/* paranoia: check if this is really a file and not a disguised dir */
|
||||
if( ( stat( str, &st ) == -1 ) || !S_ISREG( st.st_mode ) )
|
||||
if( ( stat( pathstr, &st ) == -1 ) || !S_ISREG( st.st_mode ) )
|
||||
continue;
|
||||
|
||||
fp = fopen( str, "rb" );
|
||||
fp = fopen( pathstr, "rb" );
|
||||
|
||||
if( !fp ) {
|
||||
if( DEBUG )
|
||||
printf( "BPyMenus error: couldn't open %s.\n",
|
||||
str );
|
||||
pathstr );
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -647,8 +650,7 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
|
||||
|
||||
/* file passed the tests, look for the three double-quotes */
|
||||
while( fgets( line, 100, fp ) ) {
|
||||
if( line[0] == '"' && line[1] == '"'
|
||||
&& line[2] == '"' ) {
|
||||
if( strstr( line, "\"\"\"" )) {
|
||||
res = 1; /* found */
|
||||
break;
|
||||
}
|
||||
@@ -658,13 +660,15 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
|
||||
goto discard;
|
||||
|
||||
/* Now we're ready to get the registration info. A little more structure
|
||||
* was imposed to their format, for speed. The registration
|
||||
* lines must appear between the first pair of triple double-quotes and
|
||||
* follow this order (the single-quotes are part of the format):
|
||||
* was imposed to the format, for speed. The registration lines must
|
||||
* appear between the first pair of triple double-quotes and
|
||||
* follow this order (the single-quotes are part of the format,
|
||||
* but as noted below, now the whole registration part can be commented
|
||||
* out so external Python tools can ignore them):
|
||||
*
|
||||
* Name: 'script name for the menu'
|
||||
* Group: 'group name' (defines menu)
|
||||
* Blender: <short int> (minimal Blender version)
|
||||
* Group: 'group name' (defines menu)
|
||||
* Submenu: 'submenu name' related_1word_arg
|
||||
* Tooltip: 'tooltip for the menu'
|
||||
*
|
||||
@@ -673,40 +677,42 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
|
||||
* submenus and the tooltip are optional;
|
||||
* - the Blender version is the same number reported by
|
||||
* Blender.Get('version') in BPython or G.version in C;
|
||||
* - only the first letter of each token is checked, both lower
|
||||
* and upper cases, so that's all that matters for recognition:
|
||||
* n 'script name' is enough for the name line, for example. */
|
||||
* - NEW in 2.35: Michael Reimpell suggested and even provided
|
||||
* a patch (read but not used to keep changes to a minimum for
|
||||
* now, shame on me) to make registration code also accept
|
||||
* commented out registration lines, so that BPython menu
|
||||
* registration doesn't mess with Python documentation tools. */
|
||||
|
||||
/* first the name: */
|
||||
res = fscanf( fp, "%[^']'%[^'\r\n]'\n", w, name );
|
||||
if( ( res != 2 ) || ( w[0] != 'n' && w[0] != 'N' ) ) {
|
||||
if( ( res != 2 ) || !strstr(w, "Name") ) {
|
||||
if( DEBUG )
|
||||
printf( "BPyMenus error: wrong 'name' line in %s.\n", str );
|
||||
printf( "BPyMenus error: wrong 'Name' line in %s.\n", pathstr );
|
||||
goto discard;
|
||||
}
|
||||
|
||||
/* minimal Blender version: */
|
||||
res = fscanf( fp, "%s %d\n", w, &version );
|
||||
if( ( res != 2 ) || !strstr(w, "Blender") ) {
|
||||
if( DEBUG )
|
||||
printf( "BPyMenus error: wrong 'Blender' line in %s.\n", pathstr );
|
||||
goto discard;
|
||||
}
|
||||
|
||||
line[0] = '\0'; /* used as group for this part */
|
||||
|
||||
/* minimal Blender version: */
|
||||
res = fscanf( fp, "%s %d\n", w, &version );
|
||||
if( ( res != 2 ) || ( w[0] != 'b' && w[0] != 'B' ) ) {
|
||||
if( DEBUG )
|
||||
printf( "BPyMenus error: wrong 'blender' line in %s.\n", str );
|
||||
goto discard;
|
||||
}
|
||||
|
||||
/* the group: */
|
||||
res = fscanf( fp, "%[^']'%[^'\r\n]'\n", w, line );
|
||||
if( ( res != 2 ) || ( w[0] != 'g' && w[0] != 'G' ) ) {
|
||||
if( ( res != 2 ) || !strstr(w, "Group" ) ) {
|
||||
if( DEBUG )
|
||||
printf( "BPyMenus error: wrong 'group' line in %s.\n", str );
|
||||
printf( "BPyMenus error: wrong 'Group' line in %s.\n", pathstr );
|
||||
goto discard;
|
||||
}
|
||||
|
||||
res = bpymenu_group_atoi( line );
|
||||
if( res < 0 ) {
|
||||
if( DEBUG )
|
||||
printf( "BPyMenus error: unknown 'group' %s in %s.\n", line, str );
|
||||
printf( "BPyMenus error: unknown 'Group' %s in %s.\n", line, pathstr );
|
||||
goto discard;
|
||||
}
|
||||
|
||||
@@ -714,7 +720,7 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
|
||||
whichdir, NULL );
|
||||
if( !pymenu ) {
|
||||
if( DEBUG )
|
||||
printf( "BPyMenus error: couldn't create entry for %s.\n", str );
|
||||
printf( "BPyMenus error: couldn't create entry for %s.\n", pathstr );
|
||||
fclose( fp );
|
||||
closedir( dir );
|
||||
return -2;
|
||||
@@ -724,14 +730,14 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
|
||||
while( fgets( line, 100, fp ) ) {
|
||||
res = sscanf( line, "%[^']'%[^'\r\n]'%s\n", w, submenu,
|
||||
subarg );
|
||||
if( ( res != 3 ) || ( w[0] != 's' && w[0] != 'S' ) )
|
||||
if( ( res != 3 ) || !strstr( w, "Submenu" ) )
|
||||
break;
|
||||
bpymenu_AddSubEntry( pymenu, submenu, subarg );
|
||||
}
|
||||
|
||||
/* the (optional) tooltip: */
|
||||
res = sscanf( line, "%[^']'%[^'\r\n]'\n", w, tooltip );
|
||||
if( ( res == 2 ) && ( w[0] == 't' || w[0] == 'T' ) ) {
|
||||
if( ( res == 2 ) && (!strstr( w, "Tooltip") || !strstr( w, "Tip" ))) {
|
||||
bpymenu_set_tooltip( pymenu, tooltip );
|
||||
}
|
||||
|
||||
|
||||
@@ -133,41 +133,74 @@ PyObject *M_Effect_Get( PyObject * self, PyObject * args )
|
||||
{
|
||||
/*arguments : string object name
|
||||
int : position of effect in the obj's effect list */
|
||||
char *name = 0;
|
||||
char *name = NULL;
|
||||
Object *object_iter;
|
||||
Effect *eff;
|
||||
BPy_Effect *wanted_eff;
|
||||
int num, i;
|
||||
int num = -1, i;
|
||||
|
||||
if( !PyArg_ParseTuple( args, "|si", &name, &num ) )
|
||||
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
|
||||
"expected string int argument" ) );
|
||||
|
||||
object_iter = G.main->object.first;
|
||||
|
||||
if( !object_iter )
|
||||
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
|
||||
"Scene contains no object" ) );
|
||||
if( name ) {
|
||||
|
||||
if( name ) { /* (name, num = -1) - try to find the given object */
|
||||
|
||||
while( object_iter ) {
|
||||
if( strcmp( name, object_iter->id.name + 2 ) ) {
|
||||
object_iter = object_iter->id.next;
|
||||
continue;
|
||||
|
||||
if( !strcmp( name, object_iter->id.name + 2 ) ) {
|
||||
|
||||
eff = object_iter->effect.first; /*can be NULL: None will be returned*/
|
||||
|
||||
if (num >= 0) { /* return effect in given num position if available */
|
||||
|
||||
for( i = 0; i < num; i++ ) {
|
||||
if (!eff) break;
|
||||
eff = eff->next;
|
||||
}
|
||||
|
||||
|
||||
if( object_iter->effect.first != NULL ) {
|
||||
eff = object_iter->effect.first;
|
||||
for( i = 0; i < num; i++ )
|
||||
eff = eff->next;
|
||||
wanted_eff =
|
||||
( BPy_Effect * )
|
||||
PyObject_NEW( BPy_Effect,
|
||||
&Effect_Type );
|
||||
if (eff) {
|
||||
wanted_eff = (BPy_Effect *)PyObject_NEW(BPy_Effect, &Effect_Type);
|
||||
wanted_eff->effect = eff;
|
||||
return ( PyObject * ) wanted_eff;
|
||||
} else { /* didn't find any effect in the given position */
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
}
|
||||
|
||||
else {/*return a list with all effects linked to the given object*/
|
||||
/* this was pointed by Stephen Swaney */
|
||||
PyObject *effectlist = PyList_New( 0 );
|
||||
|
||||
while (eff) {
|
||||
BPy_Effect *found_eff = (BPy_Effect *)PyObject_NEW(BPy_Effect,
|
||||
&Effect_Type);
|
||||
found_eff->effect = eff;
|
||||
PyList_Append( effectlist, ( PyObject * ) found_eff );
|
||||
Py_DECREF((PyObject *)found_eff); /* PyList_Append incref'ed it */
|
||||
eff = eff->next;
|
||||
}
|
||||
return effectlist;
|
||||
}
|
||||
}
|
||||
|
||||
object_iter = object_iter->id.next;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (!object_iter)
|
||||
return EXPP_ReturnPyObjError (PyExc_AttributeError,
|
||||
"no such object");
|
||||
}
|
||||
|
||||
else { /* () - return a list with all effects currently in Blender */
|
||||
PyObject *effectlist = PyList_New( 0 );
|
||||
|
||||
while( object_iter ) {
|
||||
if( object_iter->effect.first != NULL ) {
|
||||
eff = object_iter->effect.first;
|
||||
@@ -180,6 +213,7 @@ PyObject *M_Effect_Get( PyObject * self, PyObject * args )
|
||||
PyList_Append( effectlist,
|
||||
( PyObject * )
|
||||
found_eff );
|
||||
Py_DECREF((PyObject *)found_eff);
|
||||
eff = eff->next;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ hierarchy (faster)"},
|
||||
if i is nonzero, empty slots are not ignored: they are returned as None's."},
|
||||
{"getMatrix", ( PyCFunction ) Object_getMatrix, METH_VARARGS,
|
||||
"(str = 'worldspace') - Returns the object matrix.\n\
|
||||
(str = 'localspace') - the wanted matrix: worldspace (default), localspace\n\
|
||||
(str = 'worldspace') - the wanted matrix: worldspace (default), localspace\n\
|
||||
or old_worldspace.\n\
|
||||
\n\
|
||||
'old_worldspace' was the only behavior before Blender 2.34. With it the\n\
|
||||
@@ -957,7 +957,7 @@ static PyObject *Object_getMaterials( BPy_Object * self, PyObject * args )
|
||||
static PyObject *Object_getMatrix( BPy_Object * self, PyObject * args )
|
||||
{
|
||||
PyObject *matrix;
|
||||
char *space = "worldspace"; /* default to local */
|
||||
char *space = "worldspace"; /* default to world */
|
||||
|
||||
if( !PyArg_ParseTuple( args, "|s", &space ) ) {
|
||||
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
|
||||
|
||||
@@ -971,7 +971,7 @@ static PyObject *M_Window_QAdd( PyObject * self, PyObject * args )
|
||||
static PyObject *M_Window_QHandle( PyObject * self, PyObject * args )
|
||||
{
|
||||
short win;
|
||||
ScrArea *sa = curarea;
|
||||
ScrArea *sa = G.curscreen->areabase.first;
|
||||
ScrArea *oldsa = NULL;
|
||||
|
||||
if( !PyArg_ParseTuple( args, "h", &win ) )
|
||||
|
||||
@@ -18,7 +18,7 @@ The Blender Python API Reference
|
||||
- L{Camera}
|
||||
- L{Curve}
|
||||
- L{Draw}
|
||||
- L{Effect}
|
||||
- L{Effect} (*)
|
||||
- L{Image}
|
||||
- L{Ipo}
|
||||
- L{Lamp}
|
||||
@@ -97,15 +97,16 @@ Registering scripts:
|
||||
The header should be like this one (all double and single apostrophes below
|
||||
are required)::
|
||||
#!BPY
|
||||
\"\"\"
|
||||
Name: 'Script Name'
|
||||
Blender: 233
|
||||
Group: 'Export'
|
||||
Submenu: 'All' all
|
||||
Submenu: 'Selected' sel
|
||||
Submenu: 'Configure (gui)' gui
|
||||
Tooltip: 'Export to some format.'
|
||||
\"\"\"
|
||||
|
||||
# \"\"\"
|
||||
# Name: 'Script Name'
|
||||
# Blender: 233
|
||||
# Group: 'Export'
|
||||
# Submenu: 'All' all
|
||||
# Submenu: 'Selected' sel
|
||||
# Submenu: 'Configure (gui)' gui
|
||||
# Tooltip: 'Export to some format.'
|
||||
# \"\"\"
|
||||
|
||||
where:
|
||||
- B{Name} is the string that will appear in the menu;
|
||||
@@ -115,6 +116,15 @@ Registering scripts:
|
||||
- B{Submenu} adds optional submenus for further control;
|
||||
- B{Tooltip} is the (short) tooltip string for the menu entry.
|
||||
|
||||
note:
|
||||
- all double and single apostrophes above are required;
|
||||
- B{*NEW*}: you can "comment out" the header above, by starting lines with
|
||||
'#', like we did. This is not required (except for the first line, #!BPY,
|
||||
of course), but this way the header won't conflict with Python tools that
|
||||
you can use to generate documentation for your script code. Just
|
||||
remember to keep this header above any other line with triple
|
||||
double-quotes (\"\"\") in your script.
|
||||
|
||||
Submenu lines are not required, use them if you want to provide extra
|
||||
options. To see which submenu the user chose, check the "__script__"
|
||||
dictionary in your code: __script__['arg'] has the defined keyword (the word
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
"""
|
||||
The Blender.Effect submodule
|
||||
|
||||
B{new}: now L{Get}('objname') (without specifying second paramenter: 'position') returns a list of all effects linked to object "objname".
|
||||
|
||||
INTRODUCTION
|
||||
|
||||
The module effect allows you to access all the data of an effect.
|
||||
@@ -39,16 +41,17 @@ def New (type):
|
||||
@return: The created Effect.
|
||||
"""
|
||||
|
||||
def Get (objname,position):
|
||||
def Get (objname, position = None):
|
||||
"""
|
||||
Get an Effect from Blender.
|
||||
@type objname: string
|
||||
@param objname: The name of object to which is linked the effect.
|
||||
@type position: string
|
||||
@param position: The position of the effect in the list of effects liked to the object.
|
||||
@type position: int
|
||||
@param position: The position of the effect in the list of effects linked to the object.
|
||||
@rtype: Blender Effect or a list of Blender Effects
|
||||
@return: It depends on the 'objname,position' parameters:
|
||||
- (objname,position): The Effect linked to the given object at the given position;
|
||||
@return: It depends on the 'objname, position' parameters:
|
||||
- (objname): A list with all Effects linked to the given object (new);
|
||||
- (objname, position): The Effect linked to the given object at the given position;
|
||||
- (): A list with all Effects in the current scene.
|
||||
"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user