2011-02-23 10:52:22 +00:00
/*
2010-03-21 01:14:04 +00:00
* $ Id $
2010-02-11 14:08:22 +00:00
*
* * * * * * BEGIN GPL LICENSE BLOCK * * * * *
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software Foundation ,
2010-02-12 13:34:04 +00:00
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
2010-02-11 14:08:22 +00:00
*
* Contributor ( s ) : Campbell Barton
*
* * * * * * END GPL LICENSE BLOCK * * * * *
*/
2011-02-27 20:10:08 +00:00
/** \file blender/python/intern/bpy.c
* \ ingroup pythonintern
*/
2010-02-11 14:08:22 +00:00
/* This file defines the '_bpy' module which is used by python's 'bpy' package.
* a script writer should never directly access this module */
2010-11-29 07:56:45 +00:00
# define WITH_PYTHON /* for AUD_PyInit.h, possibly others */
2010-03-03 13:59:57 +00:00
2011-02-14 04:15:25 +00:00
# include <Python.h>
2011-02-13 10:52:18 +00:00
# include "bpy.h"
2010-03-03 13:59:57 +00:00
# include "bpy_util.h"
2010-02-11 14:08:22 +00:00
# include "bpy_rna.h"
# include "bpy_app.h"
# include "bpy_props.h"
# include "bpy_operator.h"
2010-05-11 07:08:32 +00:00
2010-02-11 14:08:22 +00:00
# include "BLI_path_util.h"
2011-04-06 06:29:10 +00:00
# include "BLI_string.h"
2010-05-11 07:08:32 +00:00
# include "BLI_bpath.h"
2011-01-07 18:36:47 +00:00
# include "BLI_utildefines.h"
2010-10-13 23:25:08 +00:00
2011-04-20 12:55:42 +00:00
# include "BKE_main.h"
2010-12-06 00:52:30 +00:00
# include "BKE_global.h" /* XXX, G.main only */
2011-04-11 13:56:58 +00:00
# include "BKE_blender.h"
2010-10-13 23:25:08 +00:00
2011-03-02 04:51:43 +00:00
# include "RNA_access.h"
2010-12-05 23:14:48 +00:00
# include "MEM_guardedalloc.h"
2010-02-11 14:08:22 +00:00
/* external util modules */
2010-10-25 22:44:01 +00:00
# include "../generic/mathutils.h"
2010-02-28 14:57:26 +00:00
# include "../generic/bgl.h"
2010-12-09 17:31:42 +00:00
# include "../generic/blf_py_api.h"
2010-02-11 14:08:22 +00:00
# include "../generic/IDProp.h"
2010-02-16 15:01:34 +00:00
2011-02-20 23:39:29 +00:00
PyObject * bpy_package_py = NULL ;
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( bpy_script_paths_doc ,
2010-07-15 20:02:53 +00:00
" .. function:: script_paths() \n "
2010-02-16 15:01:34 +00:00
" \n "
2010-07-15 20:02:53 +00:00
" Return 2 paths to blender scripts directories. \n "
2010-02-16 15:01:34 +00:00
" \n "
2010-07-15 20:02:53 +00:00
" :return: (system, user) strings will be empty when not found. \n "
2011-04-11 13:56:58 +00:00
" :rtype: tuple of strings \n "
2011-05-24 16:05:51 +00:00
) ;
2011-02-13 10:52:18 +00:00
static PyObject * bpy_script_paths ( PyObject * UNUSED ( self ) )
2010-02-11 14:08:22 +00:00
{
2010-07-15 20:02:53 +00:00
PyObject * ret = PyTuple_New ( 2 ) ;
2010-03-22 09:30:00 +00:00
char * path ;
2011-04-21 13:11:51 +00:00
2010-07-15 20:02:53 +00:00
path = BLI_get_folder ( BLENDER_SYSTEM_SCRIPTS , NULL ) ;
2011-05-21 05:34:20 +00:00
PyTuple_SET_ITEM ( ret , 0 , PyUnicode_FromString ( path ? path : " " ) ) ;
path = BLI_get_folder ( BLENDER_USER_SCRIPTS , NULL ) ;
2010-03-22 09:30:00 +00:00
PyTuple_SET_ITEM ( ret , 1 , PyUnicode_FromString ( path ? path : " " ) ) ;
2011-04-21 13:11:51 +00:00
2010-03-22 09:30:00 +00:00
return ret ;
2010-02-11 14:08:22 +00:00
}
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( bpy_blend_paths_doc ,
2010-05-11 07:08:32 +00:00
" .. function:: blend_paths(absolute=False) \n "
" \n "
2010-08-07 18:34:16 +00:00
" Returns a list of paths to external files referenced by the loaded .blend file. \n "
2010-05-11 07:08:32 +00:00
" \n "
" :arg absolute: When true the paths returned are made absolute. \n "
" :type absolute: boolean \n "
" :return: path list. \n "
2011-04-11 13:56:58 +00:00
" :rtype: list of strings \n "
2011-05-24 16:05:51 +00:00
) ;
2010-10-13 23:25:08 +00:00
static PyObject * bpy_blend_paths ( PyObject * UNUSED ( self ) , PyObject * args , PyObject * kw )
2010-05-11 07:08:32 +00:00
{
2010-12-05 23:14:48 +00:00
struct BPathIterator * bpi ;
PyObject * list , * st ; /* stupidly big string to be safe */
2010-05-11 07:08:32 +00:00
/* be sure there is low chance of the path being too short */
char filepath_expanded [ 1024 ] ;
2010-11-11 07:51:12 +00:00
const char * lib ;
2010-05-11 07:08:32 +00:00
2011-03-19 11:12:48 +00:00
int absolute = 0 ;
static const char * kwlist [ ] = { " absolute " , NULL } ;
2010-05-11 07:08:32 +00:00
2010-12-03 17:05:21 +00:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kw , " |i:blend_paths " , ( char * * ) kwlist , & absolute ) )
2010-05-11 07:08:32 +00:00
return NULL ;
2010-12-05 23:14:48 +00:00
list = PyList_New ( 0 ) ;
2011-04-20 12:55:42 +00:00
for ( BLI_bpathIterator_init ( & bpi , G . main , G . main - > name , 0 ) ; ! BLI_bpathIterator_isDone ( bpi ) ; BLI_bpathIterator_step ( bpi ) ) {
2010-05-11 07:08:32 +00:00
/* build the list */
if ( absolute ) {
2010-12-05 23:14:48 +00:00
BLI_bpathIterator_getPathExpanded ( bpi , filepath_expanded ) ;
2010-05-11 07:08:32 +00:00
}
else {
2011-03-19 11:12:48 +00:00
lib = BLI_bpathIterator_getLib ( bpi ) ;
2011-04-06 06:03:48 +00:00
if ( lib & & ( BLI_path_cmp ( lib , BLI_bpathIterator_getBasePath ( bpi ) ) ) ) { /* relative path to the library is NOT the same as our blendfile path, return an absolute path */
2010-12-05 23:14:48 +00:00
BLI_bpathIterator_getPathExpanded ( bpi , filepath_expanded ) ;
2010-05-11 07:08:32 +00:00
}
else {
2010-12-05 23:14:48 +00:00
BLI_bpathIterator_getPath ( bpi , filepath_expanded ) ;
2010-05-11 07:08:32 +00:00
}
}
2010-12-05 23:14:48 +00:00
st = PyUnicode_DecodeFSDefault ( filepath_expanded ) ;
2010-05-11 07:08:32 +00:00
PyList_Append ( list , st ) ;
Py_DECREF ( st ) ;
}
2010-12-05 23:14:48 +00:00
BLI_bpathIterator_free ( bpi ) ;
2010-05-11 07:08:32 +00:00
return list ;
}
2010-10-03 20:00:22 +00:00
2011-05-24 16:05:51 +00:00
// PyDoc_STRVAR(bpy_user_resource_doc[]= // now in bpy/utils.py
2010-10-13 23:25:08 +00:00
static PyObject * bpy_user_resource ( PyObject * UNUSED ( self ) , PyObject * args , PyObject * kw )
2010-10-03 20:00:22 +00:00
{
char * type ;
char * subdir = NULL ;
int folder_id ;
2011-03-19 11:12:48 +00:00
static const char * kwlist [ ] = { " type " , " subdir " , NULL } ;
2010-10-03 20:00:22 +00:00
char * path ;
2010-12-03 17:05:21 +00:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kw , " s|s:user_resource " , ( char * * ) kwlist , & type , & subdir ) )
2010-10-03 20:00:22 +00:00
return NULL ;
/* stupid string compare */
if ( ! strcmp ( type , " DATAFILES " ) ) folder_id = BLENDER_USER_DATAFILES ;
else if ( ! strcmp ( type , " CONFIG " ) ) folder_id = BLENDER_USER_CONFIG ;
else if ( ! strcmp ( type , " SCRIPTS " ) ) folder_id = BLENDER_USER_SCRIPTS ;
else if ( ! strcmp ( type , " AUTOSAVE " ) ) folder_id = BLENDER_USER_AUTOSAVE ;
else {
PyErr_SetString ( PyExc_ValueError , " invalid resource argument " ) ;
return NULL ;
}
/* same logic as BLI_get_folder_create(), but best leave it up to the script author to create */
path = BLI_get_folder ( folder_id , subdir ) ;
if ( ! path )
2011-03-19 11:12:48 +00:00
path = BLI_get_user_folder_notest ( folder_id , subdir ) ;
2010-10-03 20:00:22 +00:00
2011-03-08 01:23:42 +00:00
return PyUnicode_DecodeFSDefault ( path ? path : " " ) ;
2010-10-03 20:00:22 +00:00
}
2011-05-24 16:05:51 +00:00
PyDoc_STRVAR ( bpy_resource_path_doc ,
2011-04-11 13:56:58 +00:00
" .. function:: resource_path(type, major=2, minor=57) \n "
" \n "
" Return the base path for storing system files. \n "
" \n "
" :arg type: string in ['USER', 'LOCAL', 'SYSTEM']. \n "
" :type type: string \n "
" :arg major: major version, defaults to current. \n "
" :type major: int \n "
" :arg minor: minor version, defaults to current. \n "
" :type minor: string \n "
" :return: the resource path (not necessarily existing). \n "
" :rtype: string \n "
2011-05-24 16:05:51 +00:00
) ;
2011-04-11 13:56:58 +00:00
static PyObject * bpy_resource_path ( PyObject * UNUSED ( self ) , PyObject * args , PyObject * kw )
{
char * type ;
int major = BLENDER_VERSION / 100 , minor = BLENDER_VERSION % 100 ;
static const char * kwlist [ ] = { " type " , " major " , " minor " , NULL } ;
int folder_id ;
char * path ;
if ( ! PyArg_ParseTupleAndKeywords ( args , kw , " s|ii:resource_path " , ( char * * ) kwlist , & type , & major , & minor ) )
return NULL ;
/* stupid string compare */
if ( ! strcmp ( type , " USER " ) ) folder_id = BLENDER_RESOURCE_PATH_USER ;
else if ( ! strcmp ( type , " LOCAL " ) ) folder_id = BLENDER_RESOURCE_PATH_LOCAL ;
else if ( ! strcmp ( type , " SYSTEM " ) ) folder_id = BLENDER_RESOURCE_PATH_SYSTEM ;
else {
PyErr_SetString ( PyExc_ValueError , " invalid resource argument " ) ;
return NULL ;
}
path = BLI_get_folder_version ( folder_id , ( major * 100 ) + minor , FALSE ) ;
return PyUnicode_DecodeFSDefault ( path ) ;
}
2011-03-19 11:12:48 +00:00
static PyMethodDef meth_bpy_script_paths = { " script_paths " , ( PyCFunction ) bpy_script_paths , METH_NOARGS , bpy_script_paths_doc } ;
static PyMethodDef meth_bpy_blend_paths = { " blend_paths " , ( PyCFunction ) bpy_blend_paths , METH_VARARGS | METH_KEYWORDS , bpy_blend_paths_doc } ;
static PyMethodDef meth_bpy_user_resource = { " user_resource " , ( PyCFunction ) bpy_user_resource , METH_VARARGS | METH_KEYWORDS , NULL } ;
2011-04-11 13:56:58 +00:00
static PyMethodDef meth_bpy_resource_path = { " resource_path " , ( PyCFunction ) bpy_resource_path , METH_VARARGS | METH_KEYWORDS , bpy_resource_path_doc } ;
2010-02-11 14:08:22 +00:00
2011-02-20 23:39:29 +00:00
static PyObject * bpy_import_test ( const char * modname )
2010-02-11 14:08:22 +00:00
{
2010-12-03 17:05:21 +00:00
PyObject * mod = PyImport_ImportModuleLevel ( ( char * ) modname , NULL , NULL , NULL , 0 ) ;
2010-02-11 14:08:22 +00:00
if ( mod ) {
Py_DECREF ( mod ) ;
}
else {
PyErr_Print ( ) ;
PyErr_Clear ( ) ;
2011-02-20 23:39:29 +00:00
}
return mod ;
2010-02-11 14:08:22 +00:00
}
/*****************************************************************************
* Description : Creates the bpy module and adds it to sys . modules for importing
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-06-02 08:29:16 +00:00
void BPy_init_modules ( void )
2010-02-11 14:08:22 +00:00
{
2010-03-03 08:56:48 +00:00
extern BPy_StructRNA * bpy_context_module ;
library loading api.
this is not well suited to RNA so this is a native python api.
This uses:
bpy.data.libraries.load(filepath, link=False, relative=False)
however the return value needs to use pythons context manager, this means the library loading is confined to a block of code and python cant leave a half loaded library state.
eg, load a single scene we know the name of:
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.scenes = ["Scene"]
eg, load all scenes:
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.scenes = data_from.scenes
eg, load all objects starting with 'A'
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.objects = [name for name in data_from.objects if name.startswith("A")]
As you can see gives 2 objects like 'bpy.data', but containing lists of strings which can be moved from one into another.
2011-03-12 16:06:37 +00:00
extern int bpy_lib_init ( PyObject * ) ;
2010-06-09 19:31:10 +00:00
PointerRNA ctx_ptr ;
2010-02-11 14:08:22 +00:00
PyObject * mod ;
/* Needs to be first since this dir is needed for future modules */
Windows installer and Path changes, fixing various issues:
* Windows installer not working for non-admin users and multiple users
* Addon scripts not installing next to user configuration
* Portable install not being taken into account in all places
The main problem was the windows installer was installing system scripts in
AppData next to the user configuration directory, which is not shared between
users. Now these are installed in ProgramFiles, and only addon scripts added
by the users go to AppData.
On all platforms, addon scripts were sometimes getting installed between
system scripts, because the scripts folder in the executable directory was
given precedence over the user configuration folder, that is no longer done
now. So addons now behave like user configuration, they are preserved even
if you download a newer build of the same blender version.
If you have an installation of 2.57 on windows, the addon install location
will not change until we do the version bump to 2.58, to avoid conflicts with
the existing the installed 2.57 version.
The old behavior of giving precedence to the local folder was done to support
portable install, where all configuration is written to the local folder. This
is now implemented differently: if and only if a "config" folder exists in the
local folder, portable install will be assumed, and files will only be written
to that local folder.
2011-05-27 09:57:53 +00:00
char * modpath = BLI_get_folder ( BLENDER_SYSTEM_SCRIPTS , " modules " ) ;
2010-02-11 14:08:22 +00:00
if ( modpath ) {
2010-04-18 14:47:45 +00:00
// printf("bpy: found module path '%s'.\n", modpath);
2010-02-11 14:08:22 +00:00
PyObject * sys_path = PySys_GetObject ( " path " ) ; /* borrow */
PyObject * py_modpath = PyUnicode_FromString ( modpath ) ;
PyList_Insert ( sys_path , 0 , py_modpath ) ; /* add first */
Py_DECREF ( py_modpath ) ;
}
2010-04-18 14:47:45 +00:00
else {
printf ( " bpy: couldnt find 'scripts/modules', blender probably wont start. \n " ) ;
}
2010-02-11 14:08:22 +00:00
/* stand alone utility modules not related to blender directly */
2010-10-29 22:59:39 +00:00
IDProp_Init_Types ( ) ; /* not actually a submodule, just types */
2010-02-11 14:08:22 +00:00
2011-03-19 11:12:48 +00:00
mod = PyModule_New ( " _bpy " ) ;
2010-02-11 14:08:22 +00:00
/* add the module so we can import it */
2010-08-14 05:33:20 +00:00
PyDict_SetItemString ( PyImport_GetModuleDict ( ) , " _bpy " , mod ) ;
2010-02-11 14:08:22 +00:00
Py_DECREF ( mod ) ;
/* run first, initializes rna types */
BPY_rna_init ( ) ;
2011-06-02 08:29:16 +00:00
PyModule_AddObject ( mod , " types " , BPY_rna_types ( ) ) ; /* needs to be first so bpy_types can run */
2011-02-16 02:51:56 +00:00
PyModule_AddObject ( mod , " StructMetaPropGroup " , ( PyObject * ) & pyrna_struct_meta_idprop_Type ) ; /* metaclass for idprop types, bpy_types.py needs access */
library loading api.
this is not well suited to RNA so this is a native python api.
This uses:
bpy.data.libraries.load(filepath, link=False, relative=False)
however the return value needs to use pythons context manager, this means the library loading is confined to a block of code and python cant leave a half loaded library state.
eg, load a single scene we know the name of:
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.scenes = ["Scene"]
eg, load all scenes:
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.scenes = data_from.scenes
eg, load all objects starting with 'A'
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.objects = [name for name in data_from.objects if name.startswith("A")]
As you can see gives 2 objects like 'bpy.data', but containing lists of strings which can be moved from one into another.
2011-03-12 16:06:37 +00:00
bpy_lib_init ( mod ) ; /* adds '_bpy._library_load', must be called before 'bpy_types' which uses it */
2010-02-11 14:08:22 +00:00
bpy_import_test ( " bpy_types " ) ;
2011-06-02 08:29:16 +00:00
PyModule_AddObject ( mod , " data " , BPY_rna_module ( ) ) ; /* imports bpy_types by running this */
2010-02-11 14:08:22 +00:00
bpy_import_test ( " bpy_types " ) ;
2011-06-02 08:29:16 +00:00
PyModule_AddObject ( mod , " props " , BPY_rna_props ( ) ) ;
PyModule_AddObject ( mod , " ops " , BPY_operator_module ( ) ) ; /* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
PyModule_AddObject ( mod , " app " , BPY_app_struct ( ) ) ;
2010-02-11 14:08:22 +00:00
/* bpy context */
2010-12-07 04:12:15 +00:00
RNA_pointer_create ( NULL , & RNA_Context , ( void * ) BPy_GetContext ( ) , & ctx_ptr ) ;
2010-06-09 19:31:10 +00:00
bpy_context_module = ( BPy_StructRNA * ) pyrna_struct_CreatePyObject ( & ctx_ptr ) ;
/* odd that this is needed, 1 ref on creation and another for the module
* but without we get a crash on exit */
Py_INCREF ( bpy_context_module ) ;
2010-03-03 08:56:48 +00:00
PyModule_AddObject ( mod , " context " , ( PyObject * ) bpy_context_module ) ;
2010-02-11 14:08:22 +00:00
/* utility func's that have nowhere else to go */
2010-10-03 20:00:22 +00:00
PyModule_AddObject ( mod , meth_bpy_script_paths . ml_name , ( PyObject * ) PyCFunction_New ( & meth_bpy_script_paths , NULL ) ) ;
PyModule_AddObject ( mod , meth_bpy_blend_paths . ml_name , ( PyObject * ) PyCFunction_New ( & meth_bpy_blend_paths , NULL ) ) ;
PyModule_AddObject ( mod , meth_bpy_user_resource . ml_name , ( PyObject * ) PyCFunction_New ( & meth_bpy_user_resource , NULL ) ) ;
2011-04-11 13:56:58 +00:00
PyModule_AddObject ( mod , meth_bpy_resource_path . ml_name , ( PyObject * ) PyCFunction_New ( & meth_bpy_resource_path , NULL ) ) ;
2010-02-11 14:08:22 +00:00
2011-02-11 00:11:17 +00:00
/* register funcs (bpy_rna.c) */
PyModule_AddObject ( mod , meth_bpy_register_class . ml_name , ( PyObject * ) PyCFunction_New ( & meth_bpy_register_class , NULL ) ) ;
PyModule_AddObject ( mod , meth_bpy_unregister_class . ml_name , ( PyObject * ) PyCFunction_New ( & meth_bpy_unregister_class , NULL ) ) ;
2010-02-11 14:08:22 +00:00
/* add our own modules dir, this is a python package */
2011-02-20 23:39:29 +00:00
bpy_package_py = bpy_import_test ( " bpy " ) ;
2010-02-11 14:08:22 +00:00
}