Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * Contributor(s): Michel Selten, Willian P. Germano, Stephen Swaney, 00019 * Chris Keith, Chris Want, Ken Hughes, Campbell Barton 00020 * 00021 * ***** END GPL LICENSE BLOCK ***** 00022 */ 00023 00033 /* grr, python redefines */ 00034 #ifdef _POSIX_C_SOURCE 00035 # undef _POSIX_C_SOURCE 00036 #endif 00037 00038 #include <Python.h> 00039 00040 #include "MEM_guardedalloc.h" 00041 00042 #include "RNA_types.h" 00043 00044 #include "bpy.h" 00045 #include "gpu.h" 00046 #include "bpy_rna.h" 00047 #include "bpy_util.h" 00048 #include "bpy_traceback.h" 00049 #include "bpy_intern_string.h" 00050 00051 #include "DNA_space_types.h" 00052 #include "DNA_text_types.h" 00053 00054 #include "BLI_path_util.h" 00055 #include "BLI_math_base.h" 00056 #include "BLI_string.h" 00057 #include "BLI_string_utf8.h" 00058 #include "BLI_utildefines.h" 00059 00060 #include "BKE_context.h" 00061 #include "BKE_text.h" 00062 #include "BKE_main.h" 00063 #include "BKE_global.h" /* only for script checking */ 00064 00065 #include "CCL_api.h" 00066 00067 #include "BPY_extern.h" 00068 00069 #include "../generic/bpy_internal_import.h" // our own imports 00070 #include "../generic/py_capi_utils.h" 00071 00072 /* inittab initialization functions */ 00073 #include "../generic/bgl.h" 00074 #include "../generic/blf_py_api.h" 00075 #include "../mathutils/mathutils.h" 00076 00077 /* for internal use, when starting and ending python scripts */ 00078 00079 /* incase a python script triggers another python call, stop bpy_context_clear from invalidating */ 00080 static int py_call_level = 0; 00081 BPy_StructRNA *bpy_context_module = NULL; /* for fast access */ 00082 00083 // #define TIME_PY_RUN // simple python tests. prints on exit. 00084 00085 #ifdef TIME_PY_RUN 00086 #include "PIL_time.h" 00087 static int bpy_timer_count = 0; 00088 static double bpy_timer; /* time since python starts */ 00089 static double bpy_timer_run; /* time for each python script run */ 00090 static double bpy_timer_run_tot; /* accumulate python runs */ 00091 #endif 00092 00093 /* use for updating while a python script runs - in case of file load */ 00094 void bpy_context_update(bContext *C) 00095 { 00096 BPy_SetContext(C); 00097 bpy_import_main_set(CTX_data_main(C)); 00098 BPY_modules_update(C); /* can give really bad results if this isnt here */ 00099 } 00100 00101 void bpy_context_set(bContext *C, PyGILState_STATE *gilstate) 00102 { 00103 py_call_level++; 00104 00105 if (gilstate) 00106 *gilstate = PyGILState_Ensure(); 00107 00108 if (py_call_level == 1) { 00109 bpy_context_update(C); 00110 00111 #ifdef TIME_PY_RUN 00112 if (bpy_timer_count == 0) { 00113 /* record time from the beginning */ 00114 bpy_timer = PIL_check_seconds_timer(); 00115 bpy_timer_run = bpy_timer_run_tot = 0.0; 00116 } 00117 bpy_timer_run = PIL_check_seconds_timer(); 00118 00119 00120 bpy_timer_count++; 00121 #endif 00122 } 00123 } 00124 00125 /* context should be used but not now because it causes some bugs */ 00126 void bpy_context_clear(bContext *UNUSED(C), PyGILState_STATE *gilstate) 00127 { 00128 py_call_level--; 00129 00130 if (gilstate) 00131 PyGILState_Release(*gilstate); 00132 00133 if (py_call_level < 0) { 00134 fprintf(stderr, "ERROR: Python context internal state bug. this should not happen!\n"); 00135 } 00136 else if (py_call_level == 0) { 00137 /* XXX - Calling classes currently wont store the context :\, 00138 * cant set NULL because of this. but this is very flakey still. */ 00139 #if 0 00140 BPy_SetContext(NULL); 00141 bpy_import_main_set(NULL); 00142 #endif 00143 00144 #ifdef TIME_PY_RUN 00145 bpy_timer_run_tot += PIL_check_seconds_timer() - bpy_timer_run; 00146 bpy_timer_count++; 00147 #endif 00148 00149 } 00150 } 00151 00152 void BPY_text_free_code(Text *text) 00153 { 00154 if (text->compiled) { 00155 Py_DECREF((PyObject *)text->compiled); 00156 text->compiled = NULL; 00157 } 00158 } 00159 00160 void BPY_modules_update(bContext *C) 00161 { 00162 #if 0 // slow, this runs all the time poll, draw etc 100's of time a sec. 00163 PyObject *mod = PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); 00164 PyModule_AddObject(mod, "data", BPY_rna_module()); 00165 PyModule_AddObject(mod, "types", BPY_rna_types()); // atm this does not need updating 00166 #endif 00167 00168 /* refreshes the main struct */ 00169 BPY_update_rna_module(); 00170 bpy_context_module->ptr.data = (void *)C; 00171 } 00172 00173 void BPY_context_set(bContext *C) 00174 { 00175 BPy_SetContext(C); 00176 } 00177 00178 /* defined in AUD_C-API.cpp */ 00179 extern PyObject *AUD_initPython(void); 00180 00181 #ifdef WITH_CYCLES 00182 /* defined in cycles module */ 00183 static PyObject *CCL_initPython(void) 00184 { 00185 return (PyObject*)CCL_python_module_init(); 00186 } 00187 #endif 00188 00189 static struct _inittab bpy_internal_modules[] = { 00190 {(char *)"mathutils", PyInit_mathutils}, 00191 // {(char *)"mathutils.geometry", PyInit_mathutils_geometry}, 00192 // {(char *)"mathutils.noise", PyInit_mathutils_noise}, 00193 {(char *)"bgl", BPyInit_bgl}, 00194 {(char *)"blf", BPyInit_blf}, 00195 #ifdef WITH_AUDASPACE 00196 {(char *)"aud", AUD_initPython}, 00197 #endif 00198 #ifdef WITH_CYCLES 00199 {(char *)"_cycles", CCL_initPython}, 00200 #endif 00201 {(char *)"gpu", GPU_initPython}, 00202 {NULL, NULL} 00203 }; 00204 00205 /* call BPY_context_set first */ 00206 void BPY_python_start(int argc, const char **argv) 00207 { 00208 #ifndef WITH_PYTHON_MODULE 00209 PyThreadState *py_tstate = NULL; 00210 00211 /* not essential but nice to set our name */ 00212 static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */ 00213 BLI_strncpy_wchar_from_utf8(program_path_wchar, BLI_program_path(), sizeof(program_path_wchar) / sizeof(wchar_t)); 00214 Py_SetProgramName(program_path_wchar); 00215 00216 /* must run before python initializes */ 00217 PyImport_ExtendInittab(bpy_internal_modules); 00218 00219 /* allow to use our own included python */ 00220 PyC_SetHomePath(BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL)); 00221 00222 /* without this the sys.stdout may be set to 'ascii' 00223 * (it is on my system at least), where printing unicode values will raise 00224 * an error, this is highly annoying, another stumbling block for devs, 00225 * so use a more relaxed error handler and enforce utf-8 since the rest of 00226 * blender is utf-8 too - campbell */ 00227 BLI_setenv("PYTHONIOENCODING", "utf-8:surrogateescape"); 00228 00229 /* Python 3.2 now looks for '2.xx/python/include/python3.2d/pyconfig.h' to 00230 * parse from the 'sysconfig' module which is used by 'site', 00231 * so for now disable site. alternatively we could copy the file. */ 00232 Py_NoSiteFlag = 1; 00233 00234 Py_Initialize(); 00235 00236 // PySys_SetArgv(argc, argv); // broken in py3, not a huge deal 00237 /* sigh, why do python guys not have a char** version anymore? :( */ 00238 { 00239 int i; 00240 PyObject *py_argv = PyList_New(argc); 00241 for (i = 0; i < argc; i++) { 00242 /* should fix bug #20021 - utf path name problems, by replacing 00243 * PyUnicode_FromString, with this one */ 00244 PyList_SET_ITEM(py_argv, i, PyC_UnicodeFromByte(argv[i])); 00245 } 00246 00247 PySys_SetObject("argv", py_argv); 00248 Py_DECREF(py_argv); 00249 } 00250 00251 /* Initialize thread support (also acquires lock) */ 00252 PyEval_InitThreads(); 00253 #else 00254 (void)argc; 00255 (void)argv; 00256 00257 /* must run before python initializes */ 00258 PyImport_ExtendInittab(bpy_internal_modules); 00259 #endif 00260 00261 bpy_intern_string_init(); 00262 00263 /* bpy.* and lets us import it */ 00264 BPy_init_modules(); 00265 00266 bpy_import_init(PyEval_GetBuiltins()); 00267 00268 pyrna_alloc_types(); 00269 00270 BPY_atexit_register(); /* this can init any time */ 00271 00272 #ifndef WITH_PYTHON_MODULE 00273 py_tstate = PyGILState_GetThisThreadState(); 00274 PyEval_ReleaseThread(py_tstate); 00275 #endif 00276 } 00277 00278 void BPY_python_end(void) 00279 { 00280 // fprintf(stderr, "Ending Python!\n"); 00281 00282 PyGILState_Ensure(); /* finalizing, no need to grab the state */ 00283 00284 // free other python data. 00285 pyrna_free_types(); 00286 00287 /* clear all python data from structs */ 00288 00289 bpy_intern_string_exit(); 00290 00291 BPY_atexit_unregister(); /* without this we get recursive calls to WM_exit */ 00292 00293 Py_Finalize(); 00294 00295 #ifdef TIME_PY_RUN 00296 // measure time since py started 00297 bpy_timer = PIL_check_seconds_timer() - bpy_timer; 00298 00299 printf("*bpy stats* - "); 00300 printf("tot exec: %d, ", bpy_timer_count); 00301 printf("tot run: %.4fsec, ", bpy_timer_run_tot); 00302 if (bpy_timer_count > 0) 00303 printf("average run: %.6fsec, ", (bpy_timer_run_tot/bpy_timer_count)); 00304 00305 if (bpy_timer > 0.0) 00306 printf("tot usage %.4f%%", (bpy_timer_run_tot/bpy_timer) * 100.0); 00307 00308 printf("\n"); 00309 00310 // fprintf(stderr, "Ending Python Done!\n"); 00311 00312 #endif 00313 00314 } 00315 00316 static void python_script_error_jump_text(struct Text *text) 00317 { 00318 int lineno; 00319 int offset; 00320 python_script_error_jump(text->id.name + 2, &lineno, &offset); 00321 if (lineno != -1) { 00322 /* select the line with the error */ 00323 txt_move_to(text, lineno - 1, INT_MAX, FALSE); 00324 txt_move_to(text, lineno - 1, offset, TRUE); 00325 } 00326 } 00327 00328 /* super annoying, undo _PyModule_Clear(), bug [#23871] */ 00329 #define PYMODULE_CLEAR_WORKAROUND 00330 00331 #ifdef PYMODULE_CLEAR_WORKAROUND 00332 /* bad!, we should never do this, but currently only safe way I could find to keep namespace. 00333 * from being cleared. - campbell */ 00334 typedef struct { 00335 PyObject_HEAD 00336 PyObject *md_dict; 00337 /* ommit other values, we only want the dict. */ 00338 } PyModuleObject; 00339 #endif 00340 00341 static int python_script_exec(bContext *C, const char *fn, struct Text *text, 00342 struct ReportList *reports, const short do_jump) 00343 { 00344 PyObject *main_mod = NULL; 00345 PyObject *py_dict = NULL, *py_result = NULL; 00346 PyGILState_STATE gilstate; 00347 00348 BLI_assert(fn || text); 00349 00350 if (fn == NULL && text == NULL) { 00351 return 0; 00352 } 00353 00354 bpy_context_set(C, &gilstate); 00355 00356 PyC_MainModule_Backup(&main_mod); 00357 00358 if (text) { 00359 char fn_dummy[FILE_MAXDIR]; 00360 bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text); 00361 00362 if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */ 00363 char *buf = txt_to_buf(text); 00364 00365 text->compiled = Py_CompileString(buf, fn_dummy, Py_file_input); 00366 00367 MEM_freeN(buf); 00368 00369 if (PyErr_Occurred()) { 00370 if (do_jump) { 00371 python_script_error_jump_text(text); 00372 } 00373 BPY_text_free_code(text); 00374 } 00375 } 00376 00377 if (text->compiled) { 00378 py_dict = PyC_DefaultNameSpace(fn_dummy); 00379 py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict); 00380 } 00381 00382 } 00383 else { 00384 FILE *fp = fopen(fn, "r"); 00385 00386 if (fp) { 00387 py_dict = PyC_DefaultNameSpace(fn); 00388 00389 #ifdef _WIN32 00390 /* Previously we used PyRun_File to run directly the code on a FILE 00391 * object, but as written in the Python/C API Ref Manual, chapter 2, 00392 * 'FILE structs for different C libraries can be different and 00393 * incompatible'. 00394 * So now we load the script file data to a buffer */ 00395 { 00396 char *pystring; 00397 00398 fclose(fp); 00399 00400 pystring = MEM_mallocN(strlen(fn) + 32, "pystring"); 00401 pystring[0] = '\0'; 00402 sprintf(pystring, "exec(open(r'%s').read())", fn); 00403 py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict); 00404 MEM_freeN(pystring); 00405 } 00406 #else 00407 py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict); 00408 fclose(fp); 00409 #endif 00410 } 00411 else { 00412 PyErr_Format(PyExc_IOError, 00413 "Python file \"%s\" could not be opened: %s", 00414 fn, strerror(errno)); 00415 py_result = NULL; 00416 } 00417 } 00418 00419 if (!py_result) { 00420 if (text) { 00421 if (do_jump) { 00422 python_script_error_jump_text(text); 00423 } 00424 } 00425 BPy_errors_to_report(reports); 00426 } 00427 else { 00428 Py_DECREF(py_result); 00429 } 00430 00431 if (py_dict) { 00432 #ifdef PYMODULE_CLEAR_WORKAROUND 00433 PyModuleObject *mmod = (PyModuleObject *)PyDict_GetItemString(PyThreadState_GET()->interp->modules, "__main__"); 00434 PyObject *dict_back = mmod->md_dict; 00435 /* freeing the module will clear the namespace, 00436 * gives problems running classes defined in this namespace being used later. */ 00437 mmod->md_dict = NULL; 00438 Py_DECREF(dict_back); 00439 #endif 00440 00441 #undef PYMODULE_CLEAR_WORKAROUND 00442 } 00443 00444 PyC_MainModule_Restore(main_mod); 00445 00446 bpy_context_clear(C, &gilstate); 00447 00448 return (py_result != NULL); 00449 } 00450 00451 /* Can run a file or text block */ 00452 int BPY_filepath_exec(bContext *C, const char *filepath, struct ReportList *reports) 00453 { 00454 return python_script_exec(C, filepath, NULL, reports, FALSE); 00455 } 00456 00457 00458 int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const short do_jump) 00459 { 00460 return python_script_exec(C, NULL, text, reports, do_jump); 00461 } 00462 00463 void BPY_DECREF(void *pyob_ptr) 00464 { 00465 PyGILState_STATE gilstate = PyGILState_Ensure(); 00466 Py_DECREF((PyObject *)pyob_ptr); 00467 PyGILState_Release(gilstate); 00468 } 00469 00470 /* return -1 on error, else 0 */ 00471 int BPY_button_exec(bContext *C, const char *expr, double *value, const short verbose) 00472 { 00473 PyGILState_STATE gilstate; 00474 PyObject *py_dict, *mod, *retval; 00475 int error_ret = 0; 00476 PyObject *main_mod = NULL; 00477 00478 if (!value || !expr) return -1; 00479 00480 if (expr[0] == '\0') { 00481 *value = 0.0; 00482 return error_ret; 00483 } 00484 00485 bpy_context_set(C, &gilstate); 00486 00487 PyC_MainModule_Backup(&main_mod); 00488 00489 py_dict = PyC_DefaultNameSpace("<blender button>"); 00490 00491 mod = PyImport_ImportModule("math"); 00492 if (mod) { 00493 PyDict_Merge(py_dict, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */ 00494 Py_DECREF(mod); 00495 } 00496 else { /* highly unlikely but possibly */ 00497 PyErr_Print(); 00498 PyErr_Clear(); 00499 } 00500 00501 retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict); 00502 00503 if (retval == NULL) { 00504 error_ret = -1; 00505 } 00506 else { 00507 double val; 00508 00509 if (PyTuple_Check(retval)) { 00510 /* Users my have typed in 10km, 2m 00511 * add up all values */ 00512 int i; 00513 val = 0.0; 00514 00515 for (i = 0; i < PyTuple_GET_SIZE(retval); i++) { 00516 val += PyFloat_AsDouble(PyTuple_GET_ITEM(retval, i)); 00517 } 00518 } 00519 else { 00520 val = PyFloat_AsDouble(retval); 00521 } 00522 Py_DECREF(retval); 00523 00524 if (val == -1 && PyErr_Occurred()) { 00525 error_ret = -1; 00526 } 00527 else if (!finite(val)) { 00528 *value = 0.0; 00529 } 00530 else { 00531 *value = val; 00532 } 00533 } 00534 00535 if (error_ret) { 00536 if (verbose) { 00537 BPy_errors_to_report(CTX_wm_reports(C)); 00538 } 00539 else { 00540 PyErr_Clear(); 00541 } 00542 } 00543 00544 PyC_MainModule_Backup(&main_mod); 00545 00546 bpy_context_clear(C, &gilstate); 00547 00548 return error_ret; 00549 } 00550 00551 int BPY_string_exec(bContext *C, const char *expr) 00552 { 00553 PyGILState_STATE gilstate; 00554 PyObject *main_mod = NULL; 00555 PyObject *py_dict, *retval; 00556 int error_ret = 0; 00557 Main *bmain_back; /* XXX, quick fix for release (Copy Settings crash), needs further investigation */ 00558 00559 if (!expr) return -1; 00560 00561 if (expr[0] == '\0') { 00562 return error_ret; 00563 } 00564 00565 bpy_context_set(C, &gilstate); 00566 00567 PyC_MainModule_Backup(&main_mod); 00568 00569 py_dict = PyC_DefaultNameSpace("<blender string>"); 00570 00571 bmain_back = bpy_import_main_get(); 00572 bpy_import_main_set(CTX_data_main(C)); 00573 00574 retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict); 00575 00576 bpy_import_main_set(bmain_back); 00577 00578 if (retval == NULL) { 00579 error_ret = -1; 00580 00581 BPy_errors_to_report(CTX_wm_reports(C)); 00582 } 00583 else { 00584 Py_DECREF(retval); 00585 } 00586 00587 PyC_MainModule_Restore(main_mod); 00588 00589 bpy_context_clear(C, &gilstate); 00590 00591 return error_ret; 00592 } 00593 00594 00595 void BPY_modules_load_user(bContext *C) 00596 { 00597 PyGILState_STATE gilstate; 00598 Main *bmain = CTX_data_main(C); 00599 Text *text; 00600 00601 /* can happen on file load */ 00602 if (bmain == NULL) 00603 return; 00604 00605 /* update pointers since this can run from a nested script 00606 * on file load */ 00607 if (py_call_level) { 00608 bpy_context_update(C); 00609 } 00610 00611 bpy_context_set(C, &gilstate); 00612 00613 for (text = CTX_data_main(C)->text.first; text; text = text->id.next) { 00614 if (text->flags & TXT_ISSCRIPT && BLI_testextensie(text->id.name + 2, ".py")) { 00615 if (!(G.f & G_SCRIPT_AUTOEXEC)) { 00616 printf("scripts disabled for \"%s\", skipping '%s'\n", bmain->name, text->id.name + 2); 00617 } 00618 else { 00619 PyObject *module = bpy_text_import(text); 00620 00621 if (module == NULL) { 00622 PyErr_Print(); 00623 PyErr_Clear(); 00624 } 00625 else { 00626 Py_DECREF(module); 00627 } 00628 } 00629 } 00630 } 00631 bpy_context_clear(C, &gilstate); 00632 } 00633 00634 int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result) 00635 { 00636 PyObject *pyctx = (PyObject *)CTX_py_dict_get(C); 00637 PyObject *item = PyDict_GetItemString(pyctx, member); 00638 PointerRNA *ptr = NULL; 00639 int done = 0; 00640 00641 if (item == NULL) { 00642 /* pass */ 00643 } 00644 else if (item == Py_None) { 00645 /* pass */ 00646 } 00647 else if (BPy_StructRNA_Check(item)) { 00648 ptr = &(((BPy_StructRNA *)item)->ptr); 00649 00650 //result->ptr = ((BPy_StructRNA *)item)->ptr; 00651 CTX_data_pointer_set(result, ptr->id.data, ptr->type, ptr->data); 00652 done = 1; 00653 } 00654 else if (PySequence_Check(item)) { 00655 PyObject *seq_fast = PySequence_Fast(item, "bpy_context_get sequence conversion"); 00656 if (seq_fast == NULL) { 00657 PyErr_Print(); 00658 PyErr_Clear(); 00659 } 00660 else { 00661 int len = PySequence_Fast_GET_SIZE(seq_fast); 00662 int i; 00663 for (i = 0; i < len; i++) { 00664 PyObject *list_item = PySequence_Fast_GET_ITEM(seq_fast, i); 00665 00666 if (BPy_StructRNA_Check(list_item)) { 00667 /* 00668 CollectionPointerLink *link = MEM_callocN(sizeof(CollectionPointerLink), "bpy_context_get"); 00669 link->ptr = ((BPy_StructRNA *)item)->ptr; 00670 BLI_addtail(&result->list, link); 00671 */ 00672 ptr = &(((BPy_StructRNA *)list_item)->ptr); 00673 CTX_data_list_add(result, ptr->id.data, ptr->type, ptr->data); 00674 } 00675 else { 00676 printf("List item not a valid type\n"); 00677 } 00678 00679 } 00680 Py_DECREF(seq_fast); 00681 00682 done = 1; 00683 } 00684 } 00685 00686 if (done == 0) { 00687 if (item) printf("PyContext '%s' not a valid type\n", member); 00688 else printf("PyContext '%s' not found\n", member); 00689 } 00690 else { 00691 if (G.f & G_DEBUG) { 00692 printf("PyContext '%s' found\n", member); 00693 } 00694 } 00695 00696 return done; 00697 } 00698 00699 00700 #ifdef WITH_PYTHON_MODULE 00701 #include "BLI_fileops.h" 00702 /* TODO, reloading the module isnt functional at the moment. */ 00703 00704 static void bpy_module_free(void *mod); 00705 extern int main_python_enter(int argc, const char **argv); 00706 extern void main_python_exit(void); 00707 static struct PyModuleDef bpy_proxy_def = { 00708 PyModuleDef_HEAD_INIT, 00709 "bpy", /* m_name */ 00710 NULL, /* m_doc */ 00711 0, /* m_size */ 00712 NULL, /* m_methods */ 00713 NULL, /* m_reload */ 00714 NULL, /* m_traverse */ 00715 NULL, /* m_clear */ 00716 bpy_module_free, /* m_free */ 00717 }; 00718 00719 typedef struct { 00720 PyObject_HEAD 00721 /* Type-specific fields go here. */ 00722 PyObject *mod; 00723 } dealloc_obj; 00724 00725 /* call once __file__ is set */ 00726 void bpy_module_delay_init(PyObject *bpy_proxy) 00727 { 00728 const int argc = 1; 00729 const char *argv[2]; 00730 00731 /* updating the module dict below will loose the reference to __file__ */ 00732 PyObject *filename_obj = PyModule_GetFilenameObject(bpy_proxy); 00733 00734 const char *filename_rel = _PyUnicode_AsString(filename_obj); /* can be relative */ 00735 char filename_abs[1024]; 00736 00737 BLI_strncpy(filename_abs, filename_rel, sizeof(filename_abs)); 00738 BLI_path_cwd(filename_abs); 00739 00740 argv[0] = filename_abs; 00741 argv[1] = NULL; 00742 00743 // printf("module found %s\n", argv[0]); 00744 00745 main_python_enter(argc, argv); 00746 00747 /* initialized in BPy_init_modules() */ 00748 PyDict_Update(PyModule_GetDict(bpy_proxy), PyModule_GetDict(bpy_package_py)); 00749 } 00750 00751 static void dealloc_obj_dealloc(PyObject *self); 00752 00753 static PyTypeObject dealloc_obj_Type = {{{0}}}; 00754 00755 /* use our own dealloc so we can free a property if we use one */ 00756 static void dealloc_obj_dealloc(PyObject *self) 00757 { 00758 bpy_module_delay_init(((dealloc_obj *)self)->mod); 00759 00760 /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */ 00761 dealloc_obj_Type.tp_free(self); 00762 } 00763 00764 PyMODINIT_FUNC 00765 PyInit_bpy(void) 00766 { 00767 PyObject *bpy_proxy = PyModule_Create(&bpy_proxy_def); 00768 00769 /* Problem: 00770 * 1) this init function is expected to have a private member defined - 'md_def' 00771 * but this is only set for C defined modules (not py packages) 00772 * so we cant return 'bpy_package_py' as is. 00773 * 00774 * 2) there is a 'bpy' C module for python to load which is basically all of blender, 00775 * and there is scripts/bpy/__init__.py, 00776 * we may end up having to rename this module so there is no naming conflict here eg: 00777 * 'from blender import bpy' 00778 * 00779 * 3) we dont know the filename at this point, workaround by assigning a dummy value 00780 * which calls back when its freed so the real loading can take place. 00781 */ 00782 00783 /* assign an object which is freed after __file__ is assigned */ 00784 dealloc_obj *dob; 00785 00786 /* assign dummy type */ 00787 dealloc_obj_Type.tp_name = "dealloc_obj"; 00788 dealloc_obj_Type.tp_basicsize = sizeof(dealloc_obj); 00789 dealloc_obj_Type.tp_dealloc = dealloc_obj_dealloc; 00790 dealloc_obj_Type.tp_flags = Py_TPFLAGS_DEFAULT; 00791 00792 if (PyType_Ready(&dealloc_obj_Type) < 0) 00793 return NULL; 00794 00795 dob = (dealloc_obj *) dealloc_obj_Type.tp_alloc(&dealloc_obj_Type, 0); 00796 dob->mod = bpy_proxy; /* borrow */ 00797 PyModule_AddObject(bpy_proxy, "__file__", (PyObject *)dob); /* borrow */ 00798 00799 return bpy_proxy; 00800 } 00801 00802 static void bpy_module_free(void *UNUSED(mod)) 00803 { 00804 main_python_exit(); 00805 } 00806 00807 #endif