2011-02-23 10:52:22 +00:00
/*
2010-03-21 01:14:04 +00:00
* $ Id $
2009-08-26 06:15:43 +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 .
2009-08-26 06:15:43 +00:00
*
* Contributor ( s ) : Michel Selten , Willian P . Germano , Stephen Swaney ,
* Chris Keith , Chris Want , Ken Hughes , Campbell Barton
*
* * * * * * END GPL LICENSE BLOCK * * * * *
*/
2011-02-27 20:10:08 +00:00
/** \file blender/python/intern/bpy_interface.c
* \ ingroup pythonintern
*/
2009-08-26 06:15:43 +00:00
/* grr, python redefines */
# ifdef _POSIX_C_SOURCE
# undef _POSIX_C_SOURCE
# endif
2010-10-27 06:05:22 +00:00
# include <Python.h>
2008-11-29 13:36:08 +00:00
2011-01-07 18:36:47 +00:00
# include "MEM_guardedalloc.h"
2011-03-02 04:51:43 +00:00
# include "RNA_types.h"
2010-02-11 14:08:22 +00:00
# include "bpy.h"
2008-11-29 13:36:08 +00:00
# include "bpy_rna.h"
2009-06-05 16:11:35 +00:00
# include "bpy_util.h"
2011-02-22 11:32:29 +00:00
# include "bpy_traceback.h"
2009-02-28 13:27:45 +00:00
# include "DNA_space_types.h"
2009-03-04 13:26:33 +00:00
# include "DNA_text_types.h"
2009-04-11 02:18:24 +00:00
2010-02-11 14:08:22 +00:00
# include "BLI_path_util.h"
2010-03-15 18:52:22 +00:00
# include "BLI_math_base.h"
2010-09-04 09:27:21 +00:00
# include "BLI_string.h"
2011-01-07 18:36:47 +00:00
# include "BLI_utildefines.h"
2009-04-11 02:18:24 +00:00
2011-01-07 19:18:31 +00:00
2009-04-11 02:18:24 +00:00
# include "BKE_context.h"
# include "BKE_text.h"
2010-07-26 04:21:44 +00:00
# include "BKE_font.h" /* only for utf8towchar */
2009-11-20 15:01:09 +00:00
# include "BKE_main.h"
2010-02-27 01:27:22 +00:00
# include "BKE_global.h" /* only for script checking */
2009-04-11 02:18:24 +00:00
2.5
More cleanup!
- removed old UI font completely, including from uiBeginBlock
- emboss hints for uiBlock only have three types now;
Regular, Pulldown, or "Nothing" (only icon/text)
- removed old font path from Userdef
- removed all old button theme hinting
- removed old "auto block" to merge buttons in groups
(was only in use for radiosity buttons)
And went over all warnings. One hooray for make giving clean output :)
Well, we need uniform definitions for warnings, so people at least fix
them... here's the real bad bugs I found:
- in mesh code, a call to editmesh mixed *em and *me
- in armature, ED_util.h was not included, so no warnings for wrong call
to ED_undo_push()
- The extern Py api .h was not included in the bpy_interface.c, showing
a several calls using different args.
Further just added the missing includes, and removed unused vars.
2009-04-14 15:59:52 +00:00
# include "BPY_extern.h"
2009-06-17 20:33:34 +00:00
# include "../generic/bpy_internal_import.h" // our own imports
2010-09-18 15:30:03 +00:00
# include "../generic/py_capi_utils.h"
2009-06-17 20:33:34 +00:00
2011-02-14 04:15:25 +00:00
/* inittab initialization functions */
# include "../generic/noise_py_api.h"
# include "../generic/mathutils.h"
# include "../generic/bgl.h"
# include "../generic/blf_py_api.h"
2009-08-07 16:20:19 +00:00
/* for internal use, when starting and ending python scripts */
/* incase a python script triggers another python call, stop bpy_context_clear from invalidating */
static int py_call_level = 0 ;
2010-02-11 14:08:22 +00:00
BPy_StructRNA * bpy_context_module = NULL ; /* for fast access */
2009-08-09 13:20:12 +00:00
2011-01-19 09:13:24 +00:00
// #define TIME_PY_RUN // simple python tests. prints on exit.
2009-08-09 13:20:12 +00:00
# ifdef TIME_PY_RUN
# include "PIL_time.h"
2011-03-19 11:12:48 +00:00
static int bpy_timer_count = 0 ;
2009-08-09 13:20:12 +00:00
static double bpy_timer ; /* time since python starts */
static double bpy_timer_run ; /* time for each python script run */
static double bpy_timer_run_tot ; /* accumulate python runs */
# endif
2009-08-07 16:20:19 +00:00
void bpy_context_set ( bContext * C , PyGILState_STATE * gilstate )
{
py_call_level + + ;
if ( gilstate )
2011-03-19 11:12:48 +00:00
* gilstate = PyGILState_Ensure ( ) ;
2009-08-07 16:20:19 +00:00
if ( py_call_level = = 1 ) {
if ( C ) { // XXX - should always be true.
BPy_SetContext ( C ) ;
bpy_import_main_set ( CTX_data_main ( C ) ) ;
}
else {
fprintf ( stderr , " ERROR: Python context called with a NULL Context. this should not happen! \n " ) ;
}
2009-08-09 13:20:12 +00:00
2011-01-05 02:08:54 +00:00
BPY_modules_update ( C ) ; /* can give really bad results if this isnt here */
2009-11-05 11:17:09 +00:00
2009-08-09 13:20:12 +00:00
# ifdef TIME_PY_RUN
if ( bpy_timer_count = = 0 ) {
/* record time from the beginning */
bpy_timer = PIL_check_seconds_timer ( ) ;
2011-03-19 11:12:48 +00:00
bpy_timer_run = bpy_timer_run_tot = 0.0 ;
2009-08-09 13:20:12 +00:00
}
bpy_timer_run = PIL_check_seconds_timer ( ) ;
bpy_timer_count + + ;
# endif
2009-08-07 16:20:19 +00:00
}
}
2010-10-13 23:25:08 +00:00
/* context should be used but not now because it causes some bugs */
void bpy_context_clear ( bContext * UNUSED ( C ) , PyGILState_STATE * gilstate )
2009-08-07 16:20:19 +00:00
{
py_call_level - - ;
if ( gilstate )
PyGILState_Release ( * gilstate ) ;
if ( py_call_level < 0 ) {
fprintf ( stderr , " ERROR: Python context internal state bug. this should not happen! \n " ) ;
}
else if ( py_call_level = = 0 ) {
// XXX - Calling classes currently wont store the context :\, cant set NULL because of this. but this is very flakey still.
//BPy_SetContext(NULL);
//bpy_import_main_set(NULL);
2009-08-09 13:20:12 +00:00
# ifdef TIME_PY_RUN
bpy_timer_run_tot + = PIL_check_seconds_timer ( ) - bpy_timer_run ;
bpy_timer_count + + ;
# endif
2009-08-07 16:20:19 +00:00
}
}
2011-01-05 02:08:54 +00:00
void BPY_text_free_code ( Text * text )
2009-03-04 13:26:33 +00:00
{
2011-03-19 11:12:48 +00:00
if ( text - > compiled ) {
Py_DECREF ( ( PyObject * ) text - > compiled ) ;
text - > compiled = NULL ;
2009-03-04 13:26:33 +00:00
}
}
2008-11-29 13:36:08 +00:00
2011-01-05 02:08:54 +00:00
void BPY_modules_update ( bContext * C )
2009-04-11 16:17:39 +00:00
{
2009-08-15 09:53:38 +00:00
#if 0 // slow, this runs all the time poll, draw etc 100's of time a sec.
2009-04-11 16:17:39 +00:00
PyObject * mod = PyImport_ImportModuleLevel ( " bpy " , NULL , NULL , NULL , 0 ) ;
2011-03-19 11:12:48 +00:00
PyModule_AddObject ( mod , " data " , BPY_rna_module ( ) ) ;
PyModule_AddObject ( mod , " types " , BPY_rna_types ( ) ) ; // atm this does not need updating
2009-08-15 09:53:38 +00:00
# endif
/* refreshes the main struct */
BPY_update_rna_module ( ) ;
2010-12-07 06:47:40 +00:00
bpy_context_module - > ptr . data = ( void * ) C ;
2009-04-11 16:17:39 +00:00
}
2009-07-03 04:38:55 +00:00
/* must be called before Py_Initialize */
2011-02-20 23:39:29 +00:00
# ifndef WITH_PYTHON_MODULE
2011-02-13 10:52:18 +00:00
static void bpy_python_start_path ( void )
2009-07-03 04:38:55 +00:00
{
2010-07-04 15:35:23 +00:00
char * py_path_bundle = BLI_get_folder ( BLENDER_PYTHON , NULL ) ;
2009-07-03 04:38:55 +00:00
2011-03-30 06:27:39 +00:00
if ( py_path_bundle = = NULL ) {
/* Common enough to have bundled *nix python but complain on OSX/Win */
# if defined(__APPLE__) || defined(_WIN32)
2011-03-30 07:21:41 +00:00
fprintf ( stderr , " Warning! bundled python not found and is expected on this platform. (if you built with CMake: 'install' target may have not been built) \n " ) ;
2011-03-30 06:27:39 +00:00
# endif
2009-07-03 04:38:55 +00:00
return ;
2011-03-30 06:27:39 +00:00
}
2009-07-03 04:38:55 +00:00
/* set the environment path */
printf ( " found bundled python: %s \n " , py_path_bundle ) ;
2009-12-08 12:16:34 +00:00
# ifdef __APPLE__
/* OSX allow file/directory names to contain : character (represented as / in the Finder)
but current Python lib ( release 3.1 .1 ) doesn ' t handle these correctly */
if ( strchr ( py_path_bundle , ' : ' ) )
printf ( " Warning : Blender application is located in a path containing : or / chars \
\ nThis may make python import function fail \ n " );
# endif
2010-01-11 11:11:21 +00:00
# ifdef _WIN32
/* cmake/MSVC debug build crashes without this, why only
in this case is unknown . . */
{
2010-09-15 15:29:31 +00:00
BLI_setenv ( " PYTHONPATH " , py_path_bundle ) ;
2010-01-11 11:11:21 +00:00
}
2009-09-13 18:09:13 +00:00
# endif
{
2010-07-26 04:21:44 +00:00
static wchar_t py_path_bundle_wchar [ FILE_MAX ] ;
2010-07-27 04:02:09 +00:00
/* cant use this, on linux gives bug: #23018, TODO: try LANG="en_US.UTF-8" /usr/bin/blender, suggested 22008 */
/* mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR); */
2010-07-26 04:21:44 +00:00
utf8towchar ( py_path_bundle_wchar , py_path_bundle ) ;
2009-09-13 18:09:13 +00:00
Py_SetPythonHome ( py_path_bundle_wchar ) ;
2010-07-26 04:21:44 +00:00
// printf("found python (wchar_t) '%ls'\n", py_path_bundle_wchar);
2009-09-13 18:09:13 +00:00
}
2009-07-03 04:38:55 +00:00
}
2011-02-20 23:39:29 +00:00
# endif
2009-11-13 09:28:05 +00:00
2011-01-05 02:08:54 +00:00
void BPY_context_set ( bContext * C )
2009-11-13 09:28:05 +00:00
{
BPy_SetContext ( C ) ;
}
2011-02-14 04:15:25 +00:00
/* defined in AUD_C-API.cpp */
2010-10-29 22:59:39 +00:00
extern PyObject * AUD_initPython ( void ) ;
static struct _inittab bpy_internal_modules [ ] = {
2010-12-03 17:05:21 +00:00
{ ( char * ) " noise " , BPyInit_noise } ,
{ ( char * ) " mathutils " , BPyInit_mathutils } ,
// {(char *)"mathutils.geometry", BPyInit_mathutils_geometry},
{ ( char * ) " bgl " , BPyInit_bgl } ,
{ ( char * ) " blf " , BPyInit_blf } ,
{ ( char * ) " aud " , AUD_initPython } ,
2010-10-29 22:59:39 +00:00
{ NULL , NULL }
} ;
2011-01-05 02:08:54 +00:00
/* call BPY_context_set first */
2011-02-19 12:05:20 +00:00
void BPY_python_start ( int argc , const char * * argv )
2008-11-29 13:36:08 +00:00
{
2011-02-20 23:39:29 +00:00
# ifndef WITH_PYTHON_MODULE
2011-03-19 11:12:48 +00:00
PyThreadState * py_tstate = NULL ;
2011-02-20 23:39:29 +00:00
2010-08-01 15:15:57 +00:00
/* not essential but nice to set our name */
static wchar_t bprogname_wchar [ FILE_MAXDIR + FILE_MAXFILE ] ; /* python holds a reference */
utf8towchar ( bprogname_wchar , bprogname ) ;
Py_SetProgramName ( bprogname_wchar ) ;
2009-07-03 04:38:55 +00:00
2011-03-25 01:55:00 +00:00
/* must run before python initializes */
2010-10-29 22:59:39 +00:00
PyImport_ExtendInittab ( bpy_internal_modules ) ;
2011-02-13 10:52:18 +00:00
bpy_python_start_path ( ) ; /* allow to use our own included python */
2010-07-02 20:09:42 +00:00
2011-02-08 06:22:06 +00:00
/* Python 3.2 now looks for '2.56/python/include/python3.2d/pyconfig.h' to parse
* from the ' sysconfig ' module which is used by ' site ' , so for now disable site .
* alternatively we could copy the file . */
Py_NoSiteFlag = 1 ;
2011-03-19 11:12:48 +00:00
Py_Initialize ( ) ;
2008-11-29 13:36:08 +00:00
2011-03-19 11:12:48 +00:00
// PySys_SetArgv(argc, argv); // broken in py3, not a huge deal
2009-07-08 09:23:49 +00:00
/* sigh, why do python guys not have a char** version anymore? :( */
{
int i ;
PyObject * py_argv = PyList_New ( argc ) ;
for ( i = 0 ; i < argc ; i + + )
2010-10-04 01:18:47 +00:00
PyList_SET_ITEM ( py_argv , i , PyC_UnicodeFromByte ( argv [ i ] ) ) ; /* should fix bug #20021 - utf path name problems, by replacing PyUnicode_FromString */
2009-07-08 09:23:49 +00:00
PySys_SetObject ( " argv " , py_argv ) ;
Py_DECREF ( py_argv ) ;
}
2008-11-29 13:36:08 +00:00
/* Initialize thread support (also acquires lock) */
PyEval_InitThreads ( ) ;
2011-02-20 23:39:29 +00:00
# else
( void ) argc ;
( void ) argv ;
2011-03-25 01:55:00 +00:00
/* must run before python initializes */
2011-02-20 23:39:29 +00:00
PyImport_ExtendInittab ( bpy_internal_modules ) ;
# endif
2009-04-11 16:17:39 +00:00
/* bpy.* and lets us import it */
2010-02-11 14:08:22 +00:00
BPy_init_modules ( ) ;
2009-04-11 16:17:39 +00:00
2011-03-29 16:12:25 +00:00
bpy_import_init ( PyEval_GetBuiltins ( ) ) ;
2008-11-29 13:36:08 +00:00
2009-08-15 09:53:38 +00:00
pyrna_alloc_types ( ) ;
2011-02-20 23:39:29 +00:00
# ifndef WITH_PYTHON_MODULE
2011-03-19 11:12:48 +00:00
py_tstate = PyGILState_GetThisThreadState ( ) ;
2008-11-29 13:36:08 +00:00
PyEval_ReleaseThread ( py_tstate ) ;
2011-02-20 23:39:29 +00:00
# endif
2008-11-29 13:36:08 +00:00
}
2011-01-05 02:08:54 +00:00
void BPY_python_end ( void )
2008-11-29 13:36:08 +00:00
{
2009-08-14 13:13:36 +00:00
// fprintf(stderr, "Ending Python!\n");
2009-08-14 12:29:55 +00:00
2008-11-29 13:36:08 +00:00
PyGILState_Ensure ( ) ; /* finalizing, no need to grab the state */
// free other python data.
2009-08-14 12:29:55 +00:00
pyrna_free_types ( ) ;
/* clear all python data from structs */
2008-11-29 13:36:08 +00:00
2011-03-19 11:12:48 +00:00
Py_Finalize ( ) ;
2009-03-11 17:28:37 +00:00
2009-08-09 13:20:12 +00:00
# ifdef TIME_PY_RUN
// measure time since py started
2011-03-19 11:12:48 +00:00
bpy_timer = PIL_check_seconds_timer ( ) - bpy_timer ;
2009-08-09 13:20:12 +00:00
printf ( " *bpy stats* - " ) ;
printf ( " tot exec: %d, " , bpy_timer_count ) ;
printf ( " tot run: %.4fsec, " , bpy_timer_run_tot ) ;
if ( bpy_timer_count > 0 )
printf ( " average run: %.6fsec, " , ( bpy_timer_run_tot / bpy_timer_count ) ) ;
if ( bpy_timer > 0.0 )
printf ( " tot usage %.4f%% " , ( bpy_timer_run_tot / bpy_timer ) * 100.0 ) ;
printf ( " \n " ) ;
2009-08-14 13:13:36 +00:00
// fprintf(stderr, "Ending Python Done!\n");
2009-08-14 12:29:55 +00:00
2009-08-09 13:20:12 +00:00
# endif
2008-11-29 13:36:08 +00:00
}
2011-02-22 11:32:29 +00:00
static void python_script_error_jump_text ( struct Text * text )
{
int lineno ;
int offset ;
python_script_error_jump ( text - > id . name + 2 , & lineno , & offset ) ;
if ( lineno ! = - 1 ) {
/* select the line with the error */
txt_move_to ( text , lineno - 1 , INT_MAX , FALSE ) ;
txt_move_to ( text , lineno - 1 , offset , TRUE ) ;
}
}
2011-02-01 09:02:49 +00:00
/* super annoying, undo _PyModule_Clear(), bug [#23871] */
# define PYMODULE_CLEAR_WORKAROUND
# ifdef PYMODULE_CLEAR_WORKAROUND
/* bad!, we should never do this, but currently only safe way I could find to keep namespace.
* from being cleared . - campbell */
typedef struct {
PyObject_HEAD
PyObject * md_dict ;
/* ommit other values, we only want the dict. */
} PyModuleObject ;
# endif
2011-02-26 15:30:38 +00:00
static int python_script_exec ( bContext * C , const char * fn , struct Text * text , struct ReportList * reports , const short do_jump )
2008-11-29 13:36:08 +00:00
{
2011-02-01 12:37:53 +00:00
PyObject * main_mod = NULL ;
2010-11-24 10:23:23 +00:00
PyObject * py_dict = NULL , * py_result = NULL ;
2008-11-29 13:36:08 +00:00
PyGILState_STATE gilstate ;
2011-01-05 02:08:54 +00:00
2011-01-09 15:12:08 +00:00
BLI_assert ( fn | | text ) ;
2011-01-05 02:08:54 +00:00
2009-03-04 13:26:33 +00:00
if ( fn = = NULL & & text = = NULL ) {
return 0 ;
}
2010-08-02 02:55:12 +00:00
2009-08-07 16:20:19 +00:00
bpy_context_set ( C , & gilstate ) ;
2009-03-04 13:26:33 +00:00
2011-02-01 12:37:53 +00:00
PyC_MainModule_Backup ( & main_mod ) ;
2009-03-04 13:26:33 +00:00
if ( text ) {
2010-06-02 14:40:58 +00:00
char fn_dummy [ FILE_MAXDIR ] ;
2011-03-07 11:53:40 +00:00
bpy_text_filename_get ( fn_dummy , sizeof ( fn_dummy ) , text ) ;
2011-01-05 02:08:54 +00:00
2011-03-19 11:12:48 +00:00
if ( text - > compiled = = NULL ) { /* if it wasn't already compiled, do it now */
char * buf = txt_to_buf ( text ) ;
2009-03-04 13:26:33 +00:00
2011-03-19 11:12:48 +00:00
text - > compiled = Py_CompileString ( buf , fn_dummy , Py_file_input ) ;
2009-03-04 13:26:33 +00:00
2011-03-19 11:12:48 +00:00
MEM_freeN ( buf ) ;
2009-03-04 13:26:33 +00:00
2011-01-05 02:08:54 +00:00
if ( PyErr_Occurred ( ) ) {
2011-02-26 15:30:38 +00:00
if ( do_jump ) {
python_script_error_jump_text ( text ) ;
}
2011-01-05 02:08:54 +00:00
BPY_text_free_code ( text ) ;
2009-03-04 13:26:33 +00:00
}
}
2010-09-18 15:30:03 +00:00
if ( text - > compiled ) {
2011-03-19 11:12:48 +00:00
py_dict = PyC_DefaultNameSpace ( fn_dummy ) ;
py_result = PyEval_EvalCode ( text - > compiled , py_dict , py_dict ) ;
2010-09-18 15:30:03 +00:00
}
2011-01-05 02:08:54 +00:00
2010-06-02 14:40:58 +00:00
}
else {
2010-06-02 19:37:53 +00:00
FILE * fp = fopen ( fn , " r " ) ;
2009-07-26 18:18:14 +00:00
if ( fp ) {
2011-03-19 11:12:48 +00:00
py_dict = PyC_DefaultNameSpace ( fn ) ;
2010-09-18 15:30:03 +00:00
2009-11-11 13:27:54 +00:00
# ifdef _WIN32
2011-01-05 02:08:54 +00:00
/* Previously we used PyRun_File to run directly the code on a FILE
2009-11-11 13:27:54 +00:00
* object , but as written in the Python / C API Ref Manual , chapter 2 ,
2011-01-05 02:08:54 +00:00
* ' FILE structs for different C libraries can be different and
2009-11-11 13:27:54 +00:00
* incompatible ' .
* So now we load the script file data to a buffer */
2010-09-18 19:38:27 +00:00
{
char * pystring ;
2009-11-11 13:27:54 +00:00
2010-09-18 19:38:27 +00:00
fclose ( fp ) ;
2009-11-11 13:27:54 +00:00
2010-09-18 19:38:27 +00:00
pystring = MEM_mallocN ( strlen ( fn ) + 32 , " pystring " ) ;
pystring [ 0 ] = ' \0 ' ;
sprintf ( pystring , " exec(open(r'%s').read()) " , fn ) ;
2011-03-19 11:12:48 +00:00
py_result = PyRun_String ( pystring , Py_file_input , py_dict , py_dict ) ;
2010-09-18 19:38:27 +00:00
MEM_freeN ( pystring ) ;
}
2009-11-11 13:27:54 +00:00
# else
2011-03-19 11:12:48 +00:00
py_result = PyRun_File ( fp , fn , Py_file_input , py_dict , py_dict ) ;
2009-07-26 18:18:14 +00:00
fclose ( fp ) ;
2009-11-11 13:27:54 +00:00
# endif
2009-07-26 18:18:14 +00:00
}
else {
2011-02-18 06:04:05 +00:00
PyErr_Format ( PyExc_IOError , " Python file \" %s \" could not be opened: %s " , fn , strerror ( errno ) ) ;
2009-07-26 18:18:14 +00:00
py_result = NULL ;
}
2009-03-04 13:26:33 +00:00
}
2011-01-05 02:08:54 +00:00
2009-03-04 13:26:33 +00:00
if ( ! py_result ) {
2011-02-22 11:32:29 +00:00
if ( text ) {
2011-02-26 15:30:38 +00:00
if ( do_jump ) {
python_script_error_jump_text ( text ) ;
}
2011-02-22 11:32:29 +00:00
}
2009-06-14 12:53:47 +00:00
BPy_errors_to_report ( reports ) ;
2011-03-19 11:12:48 +00:00
}
else {
Py_DECREF ( py_result ) ;
2009-03-04 13:26:33 +00:00
}
2010-11-24 10:23:23 +00:00
if ( py_dict ) {
# ifdef PYMODULE_CLEAR_WORKAROUND
2011-02-01 09:02:49 +00:00
PyModuleObject * mmod = ( PyModuleObject * ) PyDict_GetItemString ( PyThreadState_GET ( ) - > interp - > modules , " __main__ " ) ;
2011-03-19 11:12:48 +00:00
PyObject * dict_back = mmod - > md_dict ;
2011-02-01 09:02:49 +00:00
/* freeing the module will clear the namespace,
* gives problems running classes defined in this namespace being used later . */
mmod - > md_dict = NULL ;
Py_DECREF ( dict_back ) ;
2010-11-24 10:23:23 +00:00
# endif
2011-02-01 09:02:49 +00:00
# undef PYMODULE_CLEAR_WORKAROUND
2010-11-24 10:23:23 +00:00
}
2011-01-05 02:08:54 +00:00
2011-02-01 12:37:53 +00:00
PyC_MainModule_Restore ( main_mod ) ;
2009-08-07 16:20:19 +00:00
bpy_context_clear ( C , & gilstate ) ;
2011-01-05 02:08:54 +00:00
return ( py_result ! = NULL ) ;
2008-11-29 13:36:08 +00:00
}
2009-02-28 13:27:45 +00:00
2011-01-05 02:08:54 +00:00
/* Can run a file or text block */
int BPY_filepath_exec ( bContext * C , const char * filepath , struct ReportList * reports )
2009-02-28 13:27:45 +00:00
{
2011-02-26 15:30:38 +00:00
return python_script_exec ( C , filepath , NULL , reports , FALSE ) ;
2009-02-28 13:27:45 +00:00
}
2011-02-26 15:30:38 +00:00
int BPY_text_exec ( bContext * C , struct Text * text , struct ReportList * reports , const short do_jump )
2009-02-28 13:27:45 +00:00
{
2011-02-26 15:30:38 +00:00
return python_script_exec ( C , NULL , text , reports , do_jump ) ;
2009-02-28 13:27:45 +00:00
}
2009-04-01 12:43:07 +00:00
void BPY_DECREF ( void * pyob_ptr )
{
2011-03-19 11:12:48 +00:00
PyGILState_STATE gilstate = PyGILState_Ensure ( ) ;
2009-04-01 12:43:07 +00:00
Py_DECREF ( ( PyObject * ) pyob_ptr ) ;
2009-12-08 10:36:46 +00:00
PyGILState_Release ( gilstate ) ;
2009-04-01 12:43:07 +00:00
}
2011-01-05 02:08:54 +00:00
int BPY_button_exec ( bContext * C , const char * expr , double * value )
2009-08-10 11:58:53 +00:00
{
PyGILState_STATE gilstate ;
2010-08-01 13:57:04 +00:00
PyObject * py_dict , * mod , * retval ;
2011-03-19 11:12:48 +00:00
int error_ret = 0 ;
2011-02-01 12:37:53 +00:00
PyObject * main_mod = NULL ;
2009-08-10 11:58:53 +00:00
2010-02-27 22:53:37 +00:00
if ( ! value | | ! expr ) return - 1 ;
if ( expr [ 0 ] = = ' \0 ' ) {
* value = 0.0 ;
return error_ret ;
}
2009-08-10 11:58:53 +00:00
bpy_context_set ( C , & gilstate ) ;
2011-02-01 12:37:53 +00:00
PyC_MainModule_Backup ( & main_mod ) ;
2010-09-18 15:30:03 +00:00
py_dict = PyC_DefaultNameSpace ( " <blender button> " ) ;
2009-10-22 23:23:09 +00:00
2011-03-19 11:12:48 +00:00
mod = PyImport_ImportModule ( " math " ) ;
2009-10-22 23:23:09 +00:00
if ( mod ) {
2010-08-01 13:57:04 +00:00
PyDict_Merge ( py_dict , PyModule_GetDict ( mod ) , 0 ) ; /* 0 - dont overwrite existing values */
2009-10-22 23:23:09 +00:00
Py_DECREF ( mod ) ;
2010-02-27 22:53:37 +00:00
}
else { /* highly unlikely but possibly */
PyErr_Print ( ) ;
PyErr_Clear ( ) ;
}
2009-10-22 23:23:09 +00:00
2011-03-19 11:12:48 +00:00
retval = PyRun_String ( expr , Py_eval_input , py_dict , py_dict ) ;
2009-08-10 11:58:53 +00:00
if ( retval = = NULL ) {
error_ret = - 1 ;
}
else {
user interface units, off by default.
- currently only distances work.
- user preferences, edit section to set the units and scale.
- option to display pairs (nicer for imperial display?)
- support for evaluating multiple comma separated values eg: 2',11" ..or.. 5ft, 4mil
- comma separated expressions/values accumulate 1+1,2**3,4cm/3
- attempted fast conversion from a value to a string so button drawing isn't too slow.
* imperial long/short *
- mile, mi
- yard, yd
- foot, '
- inch, "
- thou, mil
* metric long/short *
kilometer, km
meter, m
centimeter, cm
millimeter, mm
micrometer, um
nanometer, nm
picometer, pm
2009-08-11 18:53:01 +00:00
double val ;
if ( PyTuple_Check ( retval ) ) {
/* Users my have typed in 10km, 2m
* add up all values */
int i ;
val = 0.0 ;
for ( i = 0 ; i < PyTuple_GET_SIZE ( retval ) ; i + + ) {
val + = PyFloat_AsDouble ( PyTuple_GET_ITEM ( retval , i ) ) ;
}
}
else {
2011-03-19 11:12:48 +00:00
val = PyFloat_AsDouble ( retval ) ;
user interface units, off by default.
- currently only distances work.
- user preferences, edit section to set the units and scale.
- option to display pairs (nicer for imperial display?)
- support for evaluating multiple comma separated values eg: 2',11" ..or.. 5ft, 4mil
- comma separated expressions/values accumulate 1+1,2**3,4cm/3
- attempted fast conversion from a value to a string so button drawing isn't too slow.
* imperial long/short *
- mile, mi
- yard, yd
- foot, '
- inch, "
- thou, mil
* metric long/short *
kilometer, km
meter, m
centimeter, cm
millimeter, mm
micrometer, um
nanometer, nm
picometer, pm
2009-08-11 18:53:01 +00:00
}
2009-08-10 11:58:53 +00:00
Py_DECREF ( retval ) ;
if ( val = = - 1 & & PyErr_Occurred ( ) ) {
error_ret = - 1 ;
}
2010-03-14 21:04:02 +00:00
else if ( ! finite ( val ) ) {
* value = 0.0 ;
}
2009-08-10 11:58:53 +00:00
else {
* value = val ;
}
}
if ( error_ret ) {
BPy_errors_to_report ( CTX_wm_reports ( C ) ) ;
}
2010-07-28 23:24:17 +00:00
2011-02-01 12:37:53 +00:00
PyC_MainModule_Backup ( & main_mod ) ;
2010-08-01 13:57:04 +00:00
2009-08-10 11:58:53 +00:00
bpy_context_clear ( C , & gilstate ) ;
return error_ret ;
}
2011-01-05 02:08:54 +00:00
int BPY_string_exec ( bContext * C , const char * expr )
2010-05-30 14:05:58 +00:00
{
PyGILState_STATE gilstate ;
2011-02-01 12:37:53 +00:00
PyObject * main_mod = NULL ;
2010-08-01 13:57:04 +00:00
PyObject * py_dict , * retval ;
2011-03-19 11:12:48 +00:00
int error_ret = 0 ;
2010-05-30 14:05:58 +00:00
if ( ! expr ) return - 1 ;
if ( expr [ 0 ] = = ' \0 ' ) {
return error_ret ;
}
bpy_context_set ( C , & gilstate ) ;
2011-02-01 12:37:53 +00:00
PyC_MainModule_Backup ( & main_mod ) ;
2010-09-18 15:30:03 +00:00
py_dict = PyC_DefaultNameSpace ( " <blender string> " ) ;
2010-05-30 14:05:58 +00:00
2011-03-19 11:12:48 +00:00
retval = PyRun_String ( expr , Py_eval_input , py_dict , py_dict ) ;
2010-05-30 14:05:58 +00:00
if ( retval = = NULL ) {
error_ret = - 1 ;
BPy_errors_to_report ( CTX_wm_reports ( C ) ) ;
}
else {
Py_DECREF ( retval ) ;
}
2011-02-01 12:37:53 +00:00
PyC_MainModule_Restore ( main_mod ) ;
2010-05-30 14:05:58 +00:00
bpy_context_clear ( C , & gilstate ) ;
2010-08-01 13:57:04 +00:00
2010-05-30 14:05:58 +00:00
return error_ret ;
}
2011-01-05 02:08:54 +00:00
void BPY_modules_load_user ( bContext * C )
2009-11-20 15:01:09 +00:00
{
PyGILState_STATE gilstate ;
2010-01-10 20:01:13 +00:00
Main * bmain = CTX_data_main ( C ) ;
2009-11-20 15:01:09 +00:00
Text * text ;
2010-01-10 20:01:13 +00:00
/* can happen on file load */
if ( bmain = = NULL )
return ;
2009-11-20 15:01:09 +00:00
bpy_context_set ( C , & gilstate ) ;
for ( text = CTX_data_main ( C ) - > text . first ; text ; text = text - > id . next ) {
if ( text - > flags & TXT_ISSCRIPT & & BLI_testextensie ( text - > id . name + 2 , " .py " ) ) {
2010-02-27 12:01:10 +00:00
if ( ! ( G . f & G_SCRIPT_AUTOEXEC ) ) {
2010-02-27 01:27:22 +00:00
printf ( " scripts disabled for \" %s \" , skipping '%s' \n " , bmain - > name , text - > id . name + 2 ) ;
2009-11-20 15:01:09 +00:00
}
else {
2010-02-27 01:27:22 +00:00
PyObject * module = bpy_text_import ( text ) ;
if ( module = = NULL ) {
PyErr_Print ( ) ;
PyErr_Clear ( ) ;
}
else {
Py_DECREF ( module ) ;
}
2009-11-20 15:01:09 +00:00
}
}
}
bpy_context_clear ( C , & gilstate ) ;
}
2009-10-29 09:25:11 +00:00
2011-01-05 02:08:54 +00:00
int BPY_context_member_get ( bContext * C , const char * member , bContextDataResult * result )
2009-10-29 09:25:11 +00:00
{
PyObject * pyctx = ( PyObject * ) CTX_py_dict_get ( C ) ;
PyObject * item = PyDict_GetItemString ( pyctx , member ) ;
PointerRNA * ptr = NULL ;
int done = 0 ;
if ( item = = NULL ) {
/* pass */
}
else if ( item = = Py_None ) {
/* pass */
}
else if ( BPy_StructRNA_Check ( item ) ) {
ptr = & ( ( ( BPy_StructRNA * ) item ) - > ptr ) ;
//result->ptr= ((BPy_StructRNA *)item)->ptr;
CTX_data_pointer_set ( result , ptr - > id . data , ptr - > type , ptr - > data ) ;
done = 1 ;
}
2009-10-29 10:03:34 +00:00
else if ( PySequence_Check ( item ) ) {
PyObject * seq_fast = PySequence_Fast ( item , " bpy_context_get sequence conversion " ) ;
if ( seq_fast = = NULL ) {
PyErr_Print ( ) ;
PyErr_Clear ( ) ;
}
else {
int len = PySequence_Fast_GET_SIZE ( seq_fast ) ;
int i ;
2011-03-19 11:12:48 +00:00
for ( i = 0 ; i < len ; i + + ) {
2009-10-29 10:03:34 +00:00
PyObject * list_item = PySequence_Fast_GET_ITEM ( seq_fast , i ) ;
if ( BPy_StructRNA_Check ( list_item ) ) {
/*
CollectionPointerLink * link = MEM_callocN ( sizeof ( CollectionPointerLink ) , " bpy_context_get " ) ;
link - > ptr = ( ( BPy_StructRNA * ) item ) - > ptr ;
BLI_addtail ( & result - > list , link ) ;
*/
ptr = & ( ( ( BPy_StructRNA * ) list_item ) - > ptr ) ;
CTX_data_list_add ( result , ptr - > id . data , ptr - > type , ptr - > data ) ;
}
else {
printf ( " List item not a valid type \n " ) ;
}
2009-10-29 09:25:11 +00:00
}
2009-10-29 10:03:34 +00:00
Py_DECREF ( seq_fast ) ;
2009-10-29 09:25:11 +00:00
2009-10-29 10:03:34 +00:00
done = 1 ;
2009-10-29 09:25:11 +00:00
}
}
if ( done = = 0 ) {
2009-11-10 19:57:04 +00:00
if ( item ) printf ( " Context '%s' not a valid type \n " , member ) ;
else printf ( " Context '%s' not found \n " , member ) ;
}
2010-01-31 21:52:26 +00:00
else {
2009-11-10 19:57:04 +00:00
printf ( " Context '%s' found \n " , member ) ;
2009-10-29 09:25:11 +00:00
}
return done ;
}
2011-02-20 23:39:29 +00:00
# ifdef WITH_PYTHON_MODULE
2011-02-21 13:13:08 +00:00
# include "BLI_storage.h"
2011-02-20 23:39:29 +00:00
/* TODO, reloading the module isnt functional at the moment. */
extern int main_python ( int argc , const char * * argv ) ;
2011-03-19 11:12:48 +00:00
static struct PyModuleDef bpy_proxy_def = {
2011-02-20 23:39:29 +00:00
PyModuleDef_HEAD_INIT ,
" bpy " , /* m_name */
NULL , /* m_doc */
0 , /* m_size */
NULL , /* m_methods */
NULL , /* m_reload */
NULL , /* m_traverse */
NULL , /* m_clear */
NULL , /* m_free */
} ;
2011-02-22 14:19:09 +00:00
typedef struct {
PyObject_HEAD
/* Type-specific fields go here. */
PyObject * mod ;
} dealloc_obj ;
/* call once __file__ is set */
void bpy_module_delay_init ( PyObject * bpy_proxy )
2011-02-20 23:39:29 +00:00
{
2011-02-22 14:19:09 +00:00
const int argc = 1 ;
const char * argv [ 2 ] ;
2011-03-09 04:58:44 +00:00
PyObject * filename_obj = PyModule_GetFilenameObject ( bpy_proxy ) ; /* updating the module dict below will loose the reference to __file__ */
const char * filename_rel = _PyUnicode_AsString ( filename_obj ) ; /* can be relative */
2011-02-22 14:19:09 +00:00
char filename_abs [ 1024 ] ;
BLI_strncpy ( filename_abs , filename_rel , sizeof ( filename_abs ) ) ;
BLI_path_cwd ( filename_abs ) ;
2011-03-09 04:58:44 +00:00
2011-02-22 14:19:09 +00:00
argv [ 0 ] = filename_abs ;
argv [ 1 ] = NULL ;
// printf("module found %s\n", argv[0]);
2011-02-21 13:13:08 +00:00
2011-02-20 23:39:29 +00:00
main_python ( argc , argv ) ;
/* initialized in BPy_init_modules() */
2011-02-22 14:19:09 +00:00
PyDict_Update ( PyModule_GetDict ( bpy_proxy ) , PyModule_GetDict ( bpy_package_py ) ) ;
}
static void dealloc_obj_dealloc ( PyObject * self ) ;
2011-03-19 11:12:48 +00:00
static PyTypeObject dealloc_obj_Type = { { { 0 } } } ;
2011-02-22 14:19:09 +00:00
/* use our own dealloc so we can free a property if we use one */
static void dealloc_obj_dealloc ( PyObject * self )
{
bpy_module_delay_init ( ( ( dealloc_obj * ) self ) - > mod ) ;
/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
dealloc_obj_Type . tp_free ( self ) ;
}
PyMODINIT_FUNC
PyInit_bpy ( void )
{
PyObject * bpy_proxy = PyModule_Create ( & bpy_proxy_def ) ;
/* Problem:
* 1 ) this init function is expected to have a private member defined - ' md_def '
* but this is only set for C defined modules ( not py packages )
* so we cant return ' bpy_package_py ' as is .
*
* 2 ) there is a ' bpy ' C module for python to load which is basically all of blender ,
* and there is scripts / bpy / __init__ . py ,
* we may end up having to rename this module so there is no naming conflict here eg :
* ' from blender import bpy '
*
* 3 ) we dont know the filename at this point , workaround by assigning a dummy value
* which calls back when its freed so the real loading can take place .
*/
/* assign an object which is freed after __file__ is assigned */
dealloc_obj * dob ;
2011-02-20 23:39:29 +00:00
2011-02-22 14:19:09 +00:00
/* assign dummy type */
2011-03-19 11:12:48 +00:00
dealloc_obj_Type . tp_name = " dealloc_obj " ;
dealloc_obj_Type . tp_basicsize = sizeof ( dealloc_obj ) ;
dealloc_obj_Type . tp_dealloc = dealloc_obj_dealloc ;
dealloc_obj_Type . tp_flags = Py_TPFLAGS_DEFAULT ;
2011-02-20 23:39:29 +00:00
2011-02-22 14:19:09 +00:00
if ( PyType_Ready ( & dealloc_obj_Type ) < 0 )
return NULL ;
dob = ( dealloc_obj * ) dealloc_obj_Type . tp_alloc ( & dealloc_obj_Type , 0 ) ;
dob - > mod = bpy_proxy ; /* borrow */
PyModule_AddObject ( bpy_proxy , " __file__ " , ( PyObject * ) dob ) ; /* borrow */
return bpy_proxy ;
2011-02-20 23:39:29 +00:00
}
2011-02-22 14:19:09 +00:00
2011-02-20 23:39:29 +00:00
# endif