Blender's debug mode only worked on startup:

- G.f's G_DEBUG flag was being erased in blenkernel/intern/blender.c's
  setup_app_data:

G.f= bfd->globalf

// added a line above it to fix this:

if (G.f & G_DEBUG) bfd->globalf |=G_DEBUG;
G.f= bfd->globalf;

BPython:
- debug info now only shown if Blender is started with '-d' option
- added ~/.blender/scripts to modules sys.path
- added two new functions to Blender.sys: basename and splitext
- added doc for Blender.sys, updated other docs
This commit is contained in:
Willian Padovani Germano 2004-01-23 19:24:45 +00:00
parent 5aad4bfceb
commit 23a3a51e16
10 changed files with 277 additions and 96 deletions

@ -283,6 +283,7 @@ static void setup_app_data(BlendFileData *bfd, char *filename) {
R.displaymode= bfd->displaymode;
G.curscreen= bfd->curscreen;
G.fileflags= bfd->fileflags;
if (G.f & G_DEBUG) bfd->globalf |=G_DEBUG;
G.f= bfd->globalf;
G.scene= G.curscreen->scene;

@ -73,3 +73,4 @@ void BPY_clear_script(struct Script *script);
void BPY_free_finished_script(struct Script *script);
void init_syspath(void);
void syspath_append(char *dir);

@ -146,12 +146,14 @@ void BPY_end_python(void)
return;
}
void syspath_append(PyObject *dir)
void syspath_append(char *dirname)
{
PyObject *mod_sys, *dict, *path;
PyObject *mod_sys, *dict, *path, *dir;
PyErr_Clear();
dir = Py_BuildValue("s", dirname);
mod_sys = PyImport_ImportModule("sys"); /* new ref */
dict = PyModule_GetDict(mod_sys); /* borrowed ref */
path = PyDict_GetItemString(dict, "path"); /* borrowed ref */
@ -198,19 +200,13 @@ void init_syspath(void)
if (execdir[n-1] == '.') n--; /*fix for when run as ./blender */
execdir[n] = '\0';
p = Py_BuildValue("s", execdir);
syspath_append(p); /* append to module search path */
syspath_append(execdir); /* append to module search path */
/* set Blender.sys.progname */
}
else
printf ("Warning: could not determine argv[0] path\n");
if (U.pythondir && U.pythondir[0] != '\0') {
p = Py_BuildValue("s", U.pythondir);
syspath_append(p); /* append to module search path */
}
/*
* bring in the site module so we can add
* site-package dirs to sys.path
@ -236,7 +232,7 @@ void init_syspath(void)
for (index = 0; index < size; index++) {
item = PySequence_GetItem (p, index); /* new ref */
if( item )
syspath_append (item);
syspath_append (PyString_AsString(item));
}
}
Py_DECREF(mod);
@ -273,7 +269,9 @@ void init_syspath(void)
/*****************************************************************************/
void BPY_post_start_python(void)
{
syspath_append(Py_BuildValue("s", U.pythondir));
if (U.pythondir && U.pythondir[0] != '\0')
syspath_append(U.pythondir); /* append to module search path */
BPyMenu_Init(0); /* get dynamic menus (registered scripts) data */
}

@ -52,6 +52,7 @@
#include <direct.h>
#endif
#include "BKE_global.h"
#include "BKE_utildefines.h"
#include "BLI_blenlib.h"
#include "MEM_guardedalloc.h"
@ -65,6 +66,8 @@
#define BPYMENU_DATAFILE "Bpymenus"
static int DEBUG;
/* BPyMenuTable holds all registered pymenus, as linked lists for each menu
* where they can appear (see PYMENUHOOKS enum in BPY_menus.h).
*/
@ -231,11 +234,13 @@ static BPyMenu *bpymenu_AddEntry (short group, short version, char *name,
next = menu->next;
}
else { /* they are in the same dir */
printf("\nWarning: script %s's menu name is already in use.\n", fname);
printf ("Edit the script and change its Name: '%s' field, please.\n"
if (DEBUG) {
printf("\nWarning: script %s's menu name is already in use.\n", fname);
printf ("Edit the script and change its Name: '%s' field, please.\n"
"Note: if you really want two scripts in the same menu with\n"
"the same name, keep one in the default dir and the other in\n"
"the user defined dir, where it will take precedence.\n", name);
}
return NULL;
}
}
@ -309,7 +314,7 @@ static int bpymenu_CreateFromFile (void)
fp = fopen(line, "rb");
if (!fp) {
printf("BPyMenus error: couldn't open config file %s.\n", line);
if (DEBUG) printf("BPyMenus error: couldn't open config file %s.\n", line);
return -1;
}
@ -340,7 +345,7 @@ static int bpymenu_CreateFromFile (void)
if (parsing == 1) { /* got menu group string */
group = bpymenu_group_atoi(w1);
if (group < 0) { /* invalid type */
if (group < 0 && DEBUG) { /* invalid type */
printf("BPyMenus error parsing config file: wrong group: %s, "
"will use 'Misc'.\n", w1);
}
@ -395,7 +400,7 @@ static void bpymenu_WriteDataFile(void)
fp = fopen(fname, "w");
if (!fp) {
printf("BPyMenus error: couldn't write %s file.", fname);
if (DEBUG) printf("BPyMenus error: couldn't write %s file.", fname);
return;
}
@ -498,7 +503,7 @@ static int bpymenu_CreateFromDir (char *dirname, int whichdir)
fp = fopen(str, "rb");
if (!fp) {
printf("BPyMenus error: couldn't open %s.\n", str);
if (DEBUG) printf("BPyMenus error: couldn't open %s.\n", str);
continue;
}
@ -542,7 +547,7 @@ static int bpymenu_CreateFromDir (char *dirname, int whichdir)
/* first the name: */
res = fscanf(fp, "%[^']'%[^'\r\n]'\n", w, name);
if ((res != 2) || (w[0] != 'n' && w[0] != 'N')) {
printf("BPyMenus error: wrong 'name' line in %s.\n", str);
if (DEBUG) printf("BPyMenus error: wrong 'name' line in %s.\n", str);
goto discard;
}
@ -551,26 +556,26 @@ static int bpymenu_CreateFromDir (char *dirname, int whichdir)
/* minimal Blender version: */
res = fscanf(fp, "%s %d\n", w, &version);
if ((res != 2) || (w[0] != 'b' && w[0] != 'B')) {
printf("BPyMenus error: wrong 'blender' line in %s.\n", str);
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')) {
printf("BPyMenus error: wrong 'group' line in %s.\n", str);
if (DEBUG) printf("BPyMenus error: wrong 'group' line in %s.\n", str);
goto discard;
}
res = bpymenu_group_atoi(line);
if (res < 0) {
printf("BPyMenus error: unknown 'group' %s in %s.\n", line, str);
if (DEBUG) printf("BPyMenus error: unknown 'group' %s in %s.\n", line, str);
goto discard;
}
pymenu = bpymenu_AddEntry(res, (short)version, name, fname, whichdir, NULL);
if (!pymenu) {
printf("BPyMenus error: couldn't create entry for %s.\n", str);
if (DEBUG) printf("BPyMenus error: couldn't create entry for %s.\n", str);
fclose(fp);
closedir(dir);
return -2;
@ -617,7 +622,7 @@ static int bpymenu_GetStatMTime(char *name, int is_file, time_t* mtime)
/* BPyMenu_Init:
* import the bpython menus data to Blender, either from:
* - the BPYMENU_DATAFILE file (~/Bpymenus) or
* - the BPYMENU_DATAFILE file (?/.blender/Bpymenus) or
* - the scripts dir(s), case newer than the datafile (then update the file).
* then fill the bpymenu table with this data.
* if param usedir != 0, then the data is recreated from the dir(s) anyway.
@ -630,6 +635,8 @@ int BPyMenu_Init(int usedir)
time_t tdir1, tdir2, tfile;
int res1, res2, resf = 0;
DEBUG = G.f & G_DEBUG; /* is Blender in debug mode (started with -d) ? */
/* init global bpymenu table (it is a list of pointers to struct BPyMenus
* for each available group: import, export, etc.) */
for (res1 = 0; res1 < PYMENU_TOTAL; res1++)
@ -643,20 +650,23 @@ int BPyMenu_Init(int usedir)
if (res1 < 0) {
tdir1 = 0;
printf ("\nDefault scripts dir: %s:\n%s\n", dirname, strerror(errno));
if (upydir)
printf("Getting scripts menu data from user defined dir: %s.\n",upydir);
if (DEBUG) {
printf ("\nDefault scripts dir: %s:\n%s\n", dirname, strerror(errno));
if (upydir)
printf("Getting scripts menu data from user defined dir: %s.\n",upydir);
}
}
else { syspath_append(dirname); }
if (upydir) {
res2 = bpymenu_GetStatMTime(U.pythondir, 0, &tdir2);
if (res2 < 0) {
tdir2 = 0;
printf("\nUser defined scripts dir: %s:\n%s.\n", upydir, strerror(errno));
if (DEBUG) printf("\nUser defined scripts dir: %s:\n%s.\n", upydir, strerror(errno));
if (res1 < 0) {
printf ("To have scripts in menus, please add them to the default "
"scripts dir: %s\n"
if (DEBUG) printf ("To have scripts in menus, please add them to the"
"default scripts dir: %s\n"
"and/or go to 'Info window -> File Paths tab' and set a valid\n"
"path for the user defined scripts dir.\n", dirname);
return -1;
@ -666,12 +676,14 @@ int BPyMenu_Init(int usedir)
else res2 = -1;
if ((res1 < 0) && (res2 < 0)) {
printf ("\nCannot register scripts in menus, no scripts dir available."
"\nExpected default dir in %s .\n", dirname);
if (DEBUG) {
printf ("\nCannot register scripts in menus, no scripts dir"
" available.\nExpected default dir in %s .\n", dirname);
}
return -1;
}
printf("\nRegistering scripts in Blender menus ...\n\n");
if (DEBUG) printf("\nRegistering scripts in Blender menus ...\n\n");
if (!usedir) { /* if we're not forced to use the dir */
BLI_make_file_string("/", fname, bpymenu_gethome(), BPYMENU_DATAFILE);
@ -683,13 +695,16 @@ int BPyMenu_Init(int usedir)
if ((tfile > tdir1) && (tfile > tdir2) && !resf) { /* file is newer */
resf = bpymenu_CreateFromFile(); /* -1 if an error occurred */
if (!resf) printf("Getting menu data for scripts from file: %s\n\n", fname);
if (!resf && DEBUG)
printf("Getting menu data for scripts from file: %s\n\n", fname);
}
else resf = -1; /* -1 to use dirs: didn't use file or it was corrupted */
if (resf == -1) { /* use dirs */
printf("Getting menu data for scripts from dir(s):\n%s\n", dirname);
if (upydir) printf("%s\n", upydir);
if (DEBUG) {
printf("Getting menu data for scripts from dir(s):\n%s\n", dirname);
if (upydir) printf("%s\n", upydir);
}
if (res1 == 0) bpymenu_CreateFromDir(dirname, 0);
if (res2 == 0) bpymenu_CreateFromDir(U.pythondir, 1);
@ -699,7 +714,7 @@ int BPyMenu_Init(int usedir)
/* if we got, recreate the file */
if (res1 < PYMENU_TOTAL) bpymenu_WriteDataFile();
else {
else if (DEBUG) {
printf ("\nWarning: Registering scripts in menus -- no info found.\n"
"Either your scripts dirs have no .py scripts or the scripts\n"
"don't have a header with registration data.\n"

@ -17,7 +17,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
@ -29,65 +29,142 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#include "BKE_utildefines.h"
#include "Sys.h"
static PyObject *g_sysmodule = NULL; /* pointer to Blender.sys module */
PyObject *sys_Init (void)
{
PyObject *submodule, *dict, *sep;
PyObject *submodule, *dict, *sep;
submodule = Py_InitModule3("Blender.sys", M_sys_methods, M_sys_doc);
submodule = Py_InitModule3("Blender.sys", M_sys_methods, M_sys_doc);
g_sysmodule = submodule;
g_sysmodule = submodule;
dict = PyModule_GetDict(submodule);
dict = PyModule_GetDict(submodule);
#ifdef WIN32
sep = Py_BuildValue("s", "\\");
sep = Py_BuildValue("s", "\\");
#else
sep = Py_BuildValue("s", "/");
sep = Py_BuildValue("s", "/");
#endif
if (sep) {
Py_INCREF(sep);
PyDict_SetItemString(dict, "dirsep" , sep);
PyDict_SetItemString(dict, "sep" , sep);
}
if (sep) {
Py_INCREF(sep);
PyDict_SetItemString(dict, "dirsep" , sep);
PyDict_SetItemString(dict, "sep" , sep);
}
return submodule;
return submodule;
}
static PyObject *M_sys_basename (PyObject *self, PyObject *args)
{
PyObject *c;
char *name, *p, basename[FILE_MAXFILE];
char sep;
int n, len;
if (!PyArg_ParseTuple(args, "s", &name))
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected string argument");
len = strlen(name);
c = PyObject_GetAttrString (g_sysmodule, "dirsep");
sep = PyString_AsString(c)[0];
Py_DECREF(c);
p = strrchr(name, sep);
if (p) {
n = name + len - p - 1; /* - 1 because we don't want the sep */
if (n > FILE_MAXFILE)
return EXPP_ReturnPyObjError(PyExc_RuntimeError, "path too long");
strncpy(basename, p+1, n); /* + 1 to skip the sep */
basename[n] = 0;
return Py_BuildValue("s", basename);
}
return Py_BuildValue("s", name);
}
static PyObject *M_sys_dirname (PyObject *self, PyObject *args)
{
PyObject *c;
PyObject *c;
char *name, *p, dirname[256];
char sep;
int n;
char *name, *p, dirname[FILE_MAXDIR];
char sep;
int n;
if (!PyArg_ParseTuple(args, "s", &name))
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected string argument");
if (!PyArg_ParseTuple(args, "s", &name))
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected string argument");
c = PyObject_GetAttrString (g_sysmodule, "dirsep");
sep = PyString_AsString(c)[0];
Py_DECREF(c);
c = PyObject_GetAttrString (g_sysmodule, "dirsep");
sep = PyString_AsString(c)[0];
Py_DECREF(c);
p = strrchr(name, sep);
p = strrchr(name, sep);
if (p) {
if (p) {
n = p - name;
if (n > 255) {
PyErr_SetString(PyExc_RuntimeError, "path too long");
return 0;
}
if (n > FILE_MAXDIR)
return EXPP_ReturnPyObjError (PyExc_RuntimeError, "path too long");
strncpy(dirname, name, n);
dirname[n] = 0;
return Py_BuildValue("s", dirname);
strncpy(dirname, name, n);
dirname[n] = 0;
return Py_BuildValue("s", dirname);
}
return Py_BuildValue("s", "."); /* XXX need to fix this? (is crossplatform?)*/
}
static PyObject *M_sys_splitext (PyObject *self, PyObject *args)
{
PyObject *c;
char *name, *dot, *p, path[FILE_MAXFILE], ext[FILE_MAXFILE];
char sep;
int n, len;
if (!PyArg_ParseTuple(args, "s", &name))
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected string argument");
len = strlen(name);
c = PyObject_GetAttrString (g_sysmodule, "dirsep");
sep = PyString_AsString(c)[0];
Py_DECREF(c);
dot = strrchr(name, '.');
if (!dot) return Py_BuildValue("ss", name, "");
p = strrchr(name, sep);
if (p) {
if (p > dot) return Py_BuildValue("ss", name, "");
}
n = name + len - dot;
/* loong extensions are supported -- foolish, but Python's os.path.splitext
* supports them, so ... */
if (n > FILE_MAXFILE || (len - n ) > FILE_MAXFILE)
EXPP_ReturnPyObjError(PyExc_RuntimeError, "path too long");
strncpy(ext, dot, n);
ext[n] = 0;
strncpy(path, name, dot - name);
path[dot - name] = 0;
return Py_BuildValue("ss", path, ext);
}

@ -40,7 +40,9 @@
/*****************************************************************************/
/* Python API function prototypes for the sys module. */
/*****************************************************************************/
static PyObject *M_sys_basename (PyObject *self, PyObject *args);
static PyObject *M_sys_dirname (PyObject *self, PyObject *args);
static PyObject *M_sys_splitext (PyObject *self, PyObject *args);
/*****************************************************************************/
/* The following string definitions are used for documentation strings. */
@ -50,16 +52,26 @@ static PyObject *M_sys_dirname (PyObject *self, PyObject *args);
static char M_sys_doc[] =
"The Blender.sys submodule\n\
\n\
This is a minimal sys module kept for compatibility. It may also still be\n\
useful for users without full Python installations.\n";
This is a minimal system module to supply simple functionality available\n\
in the default Python module os.";
static char M_sys_dirname_doc[] = "";
static char M_sys_basename_doc[]="(path) - Split 'path' in dir and filename.\n\
Return the filename.";
static char M_sys_dirname_doc[]="(path) - Split 'path' in dir and filename.\n\
Return the dir.";
static char M_sys_splitext_doc[]="(path) - Split 'path' in root and \
extension:\n/this/that/file.ext -> ('/this/that/file','.ext').\n\
Return the pair (root, extension).";
/*****************************************************************************/
/* Python method structure definition for Blender.sys module: */
/*****************************************************************************/
struct PyMethodDef M_sys_methods[] = {
{"basename", M_sys_basename, METH_VARARGS, M_sys_basename_doc},
{"dirname", M_sys_dirname, METH_VARARGS, M_sys_dirname_doc},
{"splitext", M_sys_splitext, METH_VARARGS, M_sys_splitext_doc},
{NULL, NULL, 0, NULL}
};

@ -8,7 +8,7 @@
# -n "Blender" --no-private --no-frames Blender.py \
# Types.py Scene.py Object.py NMesh.py Material.py Camera.py Lamp.py \
# Armature.py Metaball.py Effect.py Curve.py Ipo.py World.py BGL.py Window.py \
# Draw.py Image.py Text.py Lattice.py Texture.py
# Draw.py Image.py Text.py Lattice.py Texture.py Registry.py Sys.py
"""
The main Blender module.
@ -40,6 +40,7 @@ The Blender Python API Reference
- L{Types}
- L{Window}
- L{World}
- L{sys<Sys>}
Introduction:
-------------
@ -55,8 +56,8 @@ The Blender Python API Reference
open-source language.
@author: The Blender Python Team
@requires: Blender 2.31 or newer.
@version: 0.3
@requires: Blender 2.32 or newer.
@version: 0.4
@see: U{www.blender.org<http://www.blender.org>}
@see: U{projects.blender.org<http://projects.blender.org>}
@see: U{www.python.org<http://www.python.org>}
@ -65,7 +66,7 @@ The Blender Python API Reference
def Set (request, data):
"""
Update settings in Blender
Update settings in Blender.
@type request: string
@param request: The setting to change:
- 'curframe': the current animation frame
@ -89,19 +90,11 @@ def Get (request):
def Redraw ():
"""
Redraw all 3D windows
Redraw all 3D windows.
"""
def ReleaseGlobalDict (bool = None):
"""
Define whether the global Python Interpreter dictionary should be cleared
after the script is run. Default is to clear (non-zero bool).
@type bool: an int, actually
@param bool: The flag to release (non-zero bool) or not (bool = 0) the dict.
if no argument is passed, this function simply returns the current
behavior.
@rtype: int
@return: A bool value (0 or 1) telling the current behavior.
@warn: This function was added as a test and there's a good chance that it
won't be kept in the future, in favor of a better method.
@depreciated: this function doesn't work anymore and will be removed.
Look at the L{Registry} submodule for a better alternative.
"""

@ -289,6 +289,12 @@ class Object:
returned.
"""
def getSize():
"""
Returns the object's size.
@return: (SizeX, SizeY, SizeZ)
"""
def getTracked():
"""
Returns the object's tracked object.
@ -421,7 +427,18 @@ class Object:
@type name: String
@param name: The new name for the object.
"""
def setSize(x, y, z):
"""
Sets the object's size.
@type x: float
@param x: The X size multiplier.
@type y: float
@param y: The Y size multiplier.
@type z: float
@param z: The Z size multiplier.
"""
def shareFrom(object):
"""
Link data of self with object specified in the argument. This works only

@ -12,9 +12,9 @@ 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. In Python terms, the
Registry holds a dictionary of dictionaries.
give script authors a way around this limitation.
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, please save to a
@ -23,14 +23,14 @@ can simply be read from a file.
Two uses for this module:
a) Save configuration data from your script's gui (button values) so that the
a) To save data from a script that another script will need to access later.
b) To save 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. Later we
can make Blender save the Registry so that its data won't be lost after users
quit the program. And also add an option to save as a Text that can be kept in
a .blend file, letting users keep script data there.
b) Save data from a script that another one will need to access later.
Example::
import Blender
@ -40,15 +40,15 @@ Example::
myvar1 = 0
myvar2 = 3.2
mystr = "hello"
#
# then check if they are already at the Registry (saved on a
# previous execution of your script):
# previous execution of this script):
dict = Registry.GetKey('MyScript')
if dict: # if found, get the values saved there
myvar1 = dict['myvar1']
myvar2 = dict['myvar2']
mystr = dict['mystr']
#
# let's create a function to update the Registry when we need to:
def update_Registry():
d = {}
@ -56,9 +56,11 @@ Example::
d['myvar2'] = myvar2
d['mystr'] = mystr
Blender.Registry.SetKey('MyScript', d)
# ...
# here goes the main part of your script ...
# here goes the main part of the script ...
# ...
# at the end, before exiting, we use our helper function:
update_Registry()
# note1: better not update the Registry when the user cancels the script

@ -0,0 +1,65 @@
# Blender.sys module
"""
The Blender.sys submodule.
sys
===
This module provides a minimal set of helper functions and data. Its purpose
is to avoid the need for the standard Python module 'os', in special 'os.path',
though it is only meant for the simplest cases.
Example::
import Blender
filename = ""
def f(name): # file selector callback
global filename
filename = name
Blender.Window.FileSelector(f)
if filename:
print 'basename:', Blender.sys.basename(filename)
print 'dirname:', Blender.sys.dirname(filename)
print 'splitext:', Blender.sys.splitext(filename)
@type sep: char
@var sep: the platform-specific dir separator for this Blender: '/'
everywhere, except on Win systems, that use '\\'.
@type dirsep: char
@var dirsep: same as L{sep}.
@type progname: string
@var progname: the Blender executable (argv[0]).
@attention: The module is called sys, not Sys.
"""
def basename (path):
"""
Get the base name (filename stripped from dir info) of 'path'.
@type path: string
@param path: a path name
@rtype: string
@return: the base name
"""
def dirname (path):
"""
Get the dir name (dir path stripped from filename) of 'path'.
@type path: string
@param path: a path name
@rtype: string
@return: the dir name
"""
def splitext (path):
"""
Split 'path' into (root, ext), where 'ext' is a file extension.
@type path: string
@param path: a path name
@rtype: list with two strings
@return: (root, ext)
"""