diff options
author | Willian Padovani Germano <wpgermano@gmail.com> | 2004-07-25 20:55:45 +0400 |
---|---|---|
committer | Willian Padovani Germano <wpgermano@gmail.com> | 2004-07-25 20:55:45 +0400 |
commit | c50e3f374fe08713b573559904c5f53d852c5e13 (patch) | |
tree | c5bc2eb290f96c6ad4916de6f5b15c57ffcb79a7 | |
parent | fe9336eb880a1a97121e5f2a6a94c93870d4549b (diff) |
BPython:
- new submodule Scene.Radio, for radiosity: still incomplete, but in shape for demos, updated SConscript to include it;
- new functions in Window module;
- doc updates: adding a todo file and a new start page for our docs: API_intro.py + other updates;
- small fix in Ipo.c provided by Damien McGuinnes (thanks!): Nathan has a patch with IPO additions and fixes for this and more, but until it is committed, there's this fix for Ipo.getCurve('LocX'), LocY, Z and QuatW,X,Y,Z too, according to Damien.
Other files:
- radpreprocess.c: added check for "during_script()" so eventual msgs don't popup during scripts;
- drawmesh.c: made a pointer (display list) be checked before accessed, fixes crash in scripts that forget to update display lists for subsurf meshes when a 3d view is in textured view mode.
Script: updated bevel_center by Loic Berthe.
-rw-r--r-- | release/scripts/bevel_center.py | 20 | ||||
-rw-r--r-- | source/blender/python/SConscript | 4 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Ipo.c | 6 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Scene.c | 16 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Window.c | 71 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/API_intro.py | 198 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Blender.py | 62 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/NMesh.py | 5 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Object.py | 13 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Radio.py | 66 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Scene.py | 46 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Sys.py | 10 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Window.py | 54 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/epy_docgen.sh | 2 | ||||
-rw-r--r-- | source/blender/python/api2_2x/sceneRadio.c | 638 | ||||
-rw-r--r-- | source/blender/python/api2_2x/sceneRadio.h | 52 | ||||
-rw-r--r-- | source/blender/radiosity/intern/source/radpreprocess.c | 5 | ||||
-rw-r--r-- | source/blender/src/drawmesh.c | 7 |
18 files changed, 1145 insertions, 130 deletions
diff --git a/release/scripts/bevel_center.py b/release/scripts/bevel_center.py index e40c25b3ec1..37c7b64c12a 100644 --- a/release/scripts/bevel_center.py +++ b/release/scripts/bevel_center.py @@ -2,11 +2,13 @@ """ Registration info for Blender menus Name: 'Bevel Center' -Blender: 232 +Blender: 233 Group: 'Mesh' Tip: 'Bevel selected vertices.' """ +# $Id$ +# ###################################################################### # Bevel Center v1 for Blender # @@ -369,7 +371,7 @@ def draw(): Button("Bevel",EVENT_BEVEL,10,100,280,25) left=Number('', EVENT_NOEVENT,10,70,45, 20,left.val,0,right.val,'Set the minimum of the slider') right = Number("",EVENT_NOEVENT,245,70,45,20,right.val,left.val,200,"Set the maximum of the slider") - dist=Slider("Thickness ",EVENT_UPDATE,60,70,180,20,dist.val,left.val,right.val,0,"Thickness of the bevel") + dist=Slider("Thickness ",EVENT_UPDATE,60,70,180,20,dist.val,left.val,right.val,0,"Thickness of the bevel, can be changed even after bevelling") glRasterPos2d(8,40) Text('To finish, you can use recursive bevel to smooth it') num=Number('', EVENT_NOEVENT,10,10,40, 16,num.val,1,100,'Recursion level') @@ -377,7 +379,7 @@ def draw(): Button("Exit",EVENT_EXIT,210,10,80,20) def event(evt, val): - if (evt == QKEY and not val): + if ((evt == QKEY or evt == ESCKEY) and not val): Exit() def bevent(evt): @@ -403,12 +405,9 @@ def bevel(): """ The main function, which creates the bevel """ global me,NF,NV,NE,NC, old_dist # + is_editmode = Window.EditMode() + if is_editmode: Window.EditMode(0) objects = Blender.Object.GetSelected() - if objects[0].getType() != "Mesh": - PupMenu("Error|Active object for bevelling must be a mesh.") - return - editmode = Window.EditMode() - if editmode: Window.EditMode(0) me = NMesh.GetRaw(objects[0].data.name) # NF = [] @@ -425,12 +424,14 @@ def bevel(): old_dist = dist.val # me.update(1) - if editmode: Window.EditMode(1) + if is_editmode: Window.EditMode(1) Blender.Redraw() def bevel_update(): """ Use NV to update the bevel """ global dist, old_dist + is_editmode = Window.EditMode() + if is_editmode: Window.EditMode(0) fac = dist.val - old_dist old_dist = dist.val # @@ -440,6 +441,7 @@ def bevel_update(): NV[old_v][dir].co[i] += fac*dir.co[i] # me.update(1) + if is_editmode: Window.EditMode(1) Blender.Redraw() def recursive(): diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index 1c3c1f4bf91..b2112e1f44c 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -51,14 +51,16 @@ source_files = ['BPY_interface.c', 'api2_2x/rgbTuple.c', 'api2_2x/gen_utils.c', 'api2_2x/sceneRender.c', + 'api2_2x/sceneRadio.c', 'api2_2x/EXPP_interface.c', - 'api2_2x/Noise.c'] + 'api2_2x/Noise.c'] python_env.Append (CPPPATH = ['api2_2x', '../blenkernel', '../blenlib', '../blenloader', '../render/extern/include', + '../radiosity/extern/include', '../makesdna', '#/intern/guardedalloc', '#/intern/bmfont', diff --git a/source/blender/python/api2_2x/Ipo.c b/source/blender/python/api2_2x/Ipo.c index 9033219e764..90f42e0fe61 100644 --- a/source/blender/python/api2_2x/Ipo.c +++ b/source/blender/python/api2_2x/Ipo.c @@ -48,6 +48,7 @@ void getname_mat_ei (int nr, char *str); void getname_world_ei (int nr, char *str); void getname_cam_ei (int nr, char *str); void getname_ob_ei (int nr, char *str); +void getname_ac_ei (int nr, char *str); /*****************************************************************************/ /* Python API function prototypes for the Ipo module. */ @@ -664,6 +665,11 @@ GetIpoCurveName (IpoCurve * icu, char *s) getname_ob_ei (icu->adrcode, s); break; } + case ID_AC: + { + getname_ac_ei (icu->adrcode, s); + break; + } } } diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c index 59a1118398b..97667ed9eed 100644 --- a/source/blender/python/api2_2x/Scene.c +++ b/source/blender/python/api2_2x/Scene.c @@ -49,6 +49,7 @@ #include "constant.h" #include "gen_utils.h" #include "sceneRender.h" +#include "sceneRadio.h" #include "Scene.h" @@ -101,6 +102,7 @@ static PyObject *Scene_getChildren(BPy_Scene *self); static PyObject *Scene_getCurrentCamera(BPy_Scene *self); static PyObject *Scene_setCurrentCamera(BPy_Scene *self, PyObject *args); static PyObject *Scene_getRenderingContext(BPy_Scene *self); +static PyObject *Scene_getRadiosityContext(BPy_Scene *self); static PyObject *Scene_getScriptLinks(BPy_Scene *self, PyObject *args); static PyObject *Scene_addScriptLink(BPy_Scene *self, PyObject *args); static PyObject *Scene_clearScriptLinks(BPy_Scene *self); @@ -181,6 +183,8 @@ static PyMethodDef BPy_Scene_methods[] = { "() - Return location of the backbuffer image"}, {"getRenderingContext", (PyCFunction)Scene_getRenderingContext, METH_NOARGS, "() - Get the rendering context for the scene and return it as a BPy_RenderData"}, + {"getRadiosityContext", (PyCFunction)Scene_getRadiosityContext, METH_NOARGS, + "() - Get the radiosity context for this scene."}, {"currentFrame", (PyCFunction)Scene_currentFrame, METH_VARARGS, "(frame) - If frame is given, the current frame is set and" "\nreturned in any case"}, @@ -234,7 +238,8 @@ PyObject *Scene_Init (void) submodule = Py_InitModule3("Blender.Scene", M_Scene_methods, M_Scene_doc); dict = PyModule_GetDict (submodule); - PyDict_SetItemString (dict, "Render", Render_Init ()); + PyDict_SetItemString (dict, "Render", Render_Init ()); + PyDict_SetItemString (dict, "Radio", Radio_Init ()); return submodule; } @@ -757,6 +762,15 @@ static PyObject *Scene_getRenderingContext (BPy_Scene *self) return RenderData_CreatePyObject(self->scene); } +static PyObject *Scene_getRadiosityContext (BPy_Scene *self) +{ + if (!self->scene) + return EXPP_ReturnPyObjError (PyExc_RuntimeError, + "Blender Scene was deleted!"); + + return Radio_CreatePyObject(self->scene); +} + /* scene.addScriptLink */ static PyObject *Scene_addScriptLink (BPy_Scene *self, PyObject *args) { diff --git a/source/blender/python/api2_2x/Window.c b/source/blender/python/api2_2x/Window.c index 73ae020acbf..754831e89a8 100644 --- a/source/blender/python/api2_2x/Window.c +++ b/source/blender/python/api2_2x/Window.c @@ -75,6 +75,7 @@ static PyObject *M_Window_QRedrawAll (PyObject *self, PyObject *args); static PyObject *M_Window_DrawProgressBar (PyObject *self, PyObject *args); static PyObject *M_Window_GetCursorPos (PyObject *self); static PyObject *M_Window_SetCursorPos (PyObject *self, PyObject *args); +static PyObject *M_Window_WaitCursor (PyObject *self, PyObject *args); static PyObject *M_Window_GetViewVector (PyObject *self); static PyObject *M_Window_GetViewQuat (PyObject *self); static PyObject *M_Window_SetViewQuat (PyObject *self, PyObject *args); @@ -91,11 +92,13 @@ static PyObject *M_Window_QRead (PyObject *self); static PyObject *M_Window_QAdd (PyObject *self, PyObject *args); static PyObject *M_Window_QHandle (PyObject *self, PyObject *args); static PyObject *M_Window_GetMouseCoords (PyObject *self); +static PyObject *M_Window_SetMouseCoords (PyObject *self, PyObject *args); static PyObject *M_Window_GetMouseButtons (PyObject *self); static PyObject *M_Window_GetKeyQualifiers (PyObject *self); static PyObject *M_Window_SetKeyQualifiers (PyObject *self, PyObject *args); static PyObject *M_Window_GetAreaSize (PyObject *self); static PyObject *M_Window_GetAreaID (PyObject *self); +static PyObject *M_Window_GetScreenSize (PyObject *self); static PyObject *M_Window_GetScreens (PyObject *self); static PyObject *M_Window_SetScreen (PyObject *self, PyObject *args); static PyObject *M_Window_GetScreenInfo (PyObject *self, PyObject *args, @@ -151,6 +154,9 @@ static char M_Window_GetCursorPos_doc[] = static char M_Window_SetCursorPos_doc[] = "([f,f,f]) - Set the current 3d cursor position from a list of three floats."; +static char M_Window_WaitCursor_doc[] = +"(bool) - Set cursor to wait mode (nonzero bool) or normal mode (0)."; + static char M_Window_GetViewVector_doc[] = "() - Get the current 3d view vector as a list of three floats [x,y,z]."; @@ -214,7 +220,11 @@ static char M_Window_QHandle_doc[] = See Blender.Window.QAdd() for how to send events to a particular window."; static char M_Window_GetMouseCoords_doc[] = -"() - Get the current mouse screen coordinates."; +"() - Get mouse pointer's current screen coordinates."; + +static char M_Window_SetMouseCoords_doc[] = +"(x, y) - Set mouse pointer's current screen coordinates.\n\ +(x,y) - ints ([x, y] also accepted): the new x, y coordinates."; static char M_Window_GetMouseButtons_doc[] = "() - Get the current mouse button state (see Blender.Draw.LEFTMOUSE, etc)."; @@ -232,7 +242,10 @@ static char M_Window_GetAreaID_doc[] = "() - Get the current window's (area) ID."; static char M_Window_GetAreaSize_doc[] = -"() - Get the current window's (area) size as [x,y]."; +"() - Get the current window's (area) size as [width, height]."; + +static char M_Window_GetScreenSize_doc[] = +"() - Get the screen's size as [width, height]."; static char M_Window_GetScreens_doc[] = "() - Get a list with the names of all available screens."; @@ -276,6 +289,8 @@ struct PyMethodDef M_Window_methods[] = { M_Window_GetCursorPos_doc}, {"SetCursorPos", M_Window_SetCursorPos, METH_VARARGS, M_Window_SetCursorPos_doc}, + {"WaitCursor", M_Window_WaitCursor, METH_VARARGS, + M_Window_WaitCursor_doc}, {"GetViewVector", (PyCFunction)M_Window_GetViewVector, METH_NOARGS, M_Window_GetViewVector_doc}, {"GetViewQuat", (PyCFunction)M_Window_GetViewQuat, METH_NOARGS, @@ -304,6 +319,8 @@ struct PyMethodDef M_Window_methods[] = { M_Window_QHandle_doc}, {"GetMouseCoords", (PyCFunction)M_Window_GetMouseCoords, METH_NOARGS, M_Window_GetMouseCoords_doc}, + {"SetMouseCoords", (PyCFunction)M_Window_SetMouseCoords, METH_VARARGS, + M_Window_SetMouseCoords_doc}, {"GetMouseButtons", (PyCFunction)M_Window_GetMouseButtons, METH_NOARGS, M_Window_GetMouseButtons_doc}, {"GetKeyQualifiers", (PyCFunction)M_Window_GetKeyQualifiers, METH_NOARGS, @@ -314,6 +331,8 @@ struct PyMethodDef M_Window_methods[] = { M_Window_GetAreaSize_doc}, {"GetAreaID", (PyCFunction)M_Window_GetAreaID, METH_NOARGS, M_Window_GetAreaID_doc}, + {"GetScreenSize", (PyCFunction)M_Window_GetScreenSize, METH_NOARGS, + M_Window_GetScreenSize_doc}, {"GetScreens", (PyCFunction)M_Window_GetScreens, METH_NOARGS, M_Window_GetScreens_doc}, {"SetScreen", (PyCFunction)M_Window_SetScreen, METH_VARARGS, @@ -584,6 +603,19 @@ static PyObject *M_Window_SetCursorPos(PyObject *self, PyObject *args) return Py_None; } +static PyObject *M_Window_WaitCursor(PyObject *self, PyObject *args) +{ + int bool; + + if (!PyArg_ParseTuple(args, "i", &bool)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected bool (0 or 1) or nothing as argument"); + + waitcursor(bool); /* nonzero bool sets, zero unsets */ + + return EXPP_incr_ret(Py_None); +} + /*****************************************************************************/ /* Function: M_Window_GetViewVector */ /* Python equivalent: Blender.Window.GetViewVector */ @@ -923,6 +955,31 @@ static PyObject *M_Window_GetMouseCoords(PyObject *self) return Py_BuildValue("hh", mval[0], mval[1]); } +static PyObject *M_Window_SetMouseCoords(PyObject *self, PyObject *args) +{ + int ok, x, y; + + if (!G.curscreen) + return EXPP_ReturnPyObjError (PyExc_RuntimeError, + "no current screen to retrieve info from!"); + + x = G.curscreen->sizex / 2; + y = G.curscreen->sizey / 2; + + if (PyObject_Length(args) == 2) + ok = PyArg_ParseTuple(args, "hh", &x, &y); + else + ok = PyArg_ParseTuple(args, "|(hh)", &x, &y); + + if (!ok) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected [i, i] or i,i as arguments (or nothing)."); + + warp_pointer(x, y); + + return EXPP_incr_ret(Py_None); +} + static PyObject *M_Window_GetMouseButtons(PyObject *self) { short mbut = get_mbut(); @@ -972,6 +1029,16 @@ static PyObject *M_Window_GetAreaID(PyObject *self) return Py_BuildValue("h", sa->win); } +static PyObject *M_Window_GetScreenSize(PyObject *self) +{ + bScreen *scr = G.curscreen; + + if (!scr) return EXPP_incr_ret(Py_None); + + return Py_BuildValue("hh", scr->sizex, scr->sizey); +} + + static PyObject *M_Window_SetScreen(PyObject *self, PyObject *args) { bScreen *scr = G.main->screen.first; diff --git a/source/blender/python/api2_2x/doc/API_intro.py b/source/blender/python/api2_2x/doc/API_intro.py new file mode 100644 index 00000000000..ab9074a488e --- /dev/null +++ b/source/blender/python/api2_2x/doc/API_intro.py @@ -0,0 +1,198 @@ +# This is not a real module, it's simply an introductory text. + +""" +The Blender Python API Reference +================================ + + Top Module: + ----------- + + - L{Blender} (*) + + Submodules: + ----------- + - L{Armature} + - L{Bone} + - L{NLA} + - L{BGL} + - L{Camera} (*) + - L{Curve} + - L{Draw} (*) + - L{Effect} + - L{Image} (*) + - L{Ipo} + - L{Lamp} (*) + - L{Lattice} + - L{Library} + - L{Material} (*) + - L{Mathutils} + - L{Metaball} (*) + - L{NMesh} + - L{Noise} + - L{Object} (*) + - L{Registry} + - L{Scene} (*) + - L{Radio} (new) + - L{Render} + - L{Text} + - L{Texture} + - L{Types} + - L{Window} (* important: L{Window.EditMode}) + - L{World} (*) + - L{sys<Sys>} (*) + + (*) - marks updated. + +Introduction: +============= + + This reference documents the Blender Python API, a growing collection of + Python modules (libraries) that give access to part of the program's internal + data and functions. + + Through scripting Blender can be extended in realtime via + U{Python <www.python.org>}, an impressive high level, multi-paradigm, open + source language. Newcomers are recommended to start with the tutorial that + comes with it. + + This opens many interesting possibilities, ranging from automating repetitive + tasks to adding new functionality to the program: procedural models, + importers and exporters, even complex applications and so on. Blender itself + comes with some scripts, but many others can be found in the Scripts & Plugins + sections and forum posts at the Blender-related sites listed below. + +Scripting and Blender: +====================== + +There are four basic ways to execute scripts in Blender: + + 1. They can be loaded or typed as text files in the Text Editor window, then + executed with ALT+P. + 2. Via command line: 'blender -P <scriptname>' will start Blender and executed + the given script. <scriptname> can be a filename in the user's file system or + the name of a text saved in a .blend Blender file: + 'blender myfile.blend -P textname'. + 3. Properly registered scripts can be selected directly from the program's + menus. + 4. Scriptlinks: these are also loaded or typed in the Text Editor window and + can be linked to objects, materials or scenes using the Scriptlink buttons + tab. Script links get executed automatically when their events (ONLOAD, + REDRAW, FRAMECHANGED) are triggered. Normal scripts can create (L{Text}) and + link other scripts to objects and events, see L{Object.Object.addScriptLink}, + for example. + +Registering scripts: +-------------------- + To be registered a script needs two things: + - be either in the default scripts dir or in the user defined scripts path + (see Info window, paths tab); + - have a proper header. + + Try 'blender -d' to know where your default dir for scripts is, it will + inform either the dir or the file with that info already parsed, which is + in the same dir of the scripts folder. + + The header should be like this one (all double and single apostrophes below + are required):: + #!BPY + \"\"\" + Name: 'Script Name' + Blender: 233 + Group: 'Export' + Submenu: 'All' all + Submenu: 'Selected' sel + Submenu: 'Configure (gui)' gui + Tooltip: 'Export to some format.' + \"\"\" + + where: + - B{Name} is the string that will appear in the menu; + - B{Blender} is the minimum program version required to run the script; + - B{Group} defines where the script will be put, see all groups in the + Scripts Window's header, menu "Scripts"; + - B{Submenu} adds optional submenus for further control; + - B{Tooltip} is the (short) tooltip string for the menu entry. + + Submenu lines are not required, use them if you want to provide extra + options. To see which submenu the user chose, check the "__script__" + dictionary in your code: __script__['arg'] has the defined keyword (the word + after the submenu string name: all, sel or gui in the example above) of the + chosen submenu. For example, if the user clicked on submenu 'Selected' above, + __script__['arg'] will be "sel". + + If your script requires extra data or configuration files, there is a special + folder where they can be saved: see 'datadir' in L{Blender.Get}. + +Interaction with users: +----------------------- + + Scripts can: + - simply run and exit; + - grab the main input event queue and process (or pass to Blender) selected + keyboard, mouse, redraw events; + - pop messages, menus and small number and text input boxes; + - draw graphical user interfaces (guis) with OpenGL calls and native + program buttons, which stay there accepting user input like any other + Blender window until the user closes them; + - make changes to the 3D View (set visible layer(s), view point, etc); + - use external Python libraries, if available. + + You can read the documentation for the L{Window}, L{Draw} and L{BGL} modules + for more information and also check Python's site for external modules that + might be useful to you. Note though that any imported module will become a + requirement of your script, since Blender itself does not bundle external + modules. + +Command line mode: +------------------ + + Python was embedded in Blender, so to access bpython modules you need to + run scripts from the program itself: you can't import the Blender module + into an external Python interpreter. But with "OnLoad" script links, the + "-b" background mode and additions like the "-P" command line switch, + L{Blender.Save}, L{Blender.Load}, L{Blender.Quit} and the L{Library} module, + it's possible to control Blender from outside via some automated process + using scripts. + +Demo mode: +---------- + + Blender has a demo mode, where once started it can work without user + intervention, "showing itself off". Demos can render stills and animations, + play rendered or realtime animations, calculate radiosity simulations and + do many other nifty things. If you want to turn a .blend file into a demo, + write a script to run the show and link it as a scene "OnLoad" scriptlink. + The demo will then be played automatically whenever this .blend file is + opened, B{unless Blender was started with the "-y" parameter}. + +The Game Engine API: +-------------------- + + Blender has a game engine for users to create and play 3d games. This + engine lets programmers add scripts to improve game AI, control, etc, making + more complex interaction and tricks possible. The game engine API is + separate from the Blender Python API this document references and you can + find its own ref doc in the docs section of the main sites below. + +A note to newbie script writers: +-------------------------------- + + Interpreted languages are known to be much slower than compiled code, but for + many applications the difference is negligible or acceptable. Also, with well + thought optimizations, it can be I{considerably} reduced in many cases. Try + some of the best bpython scripts to get an idea of what can be done, it may + surprise you. + +@author: The Blender Python Team +@requires: Blender 2.34 or newer. +@version: 2.34 +@see: U{www.blender3d.org<http://www.blender3d.org>}: main site +@see: U{www.blender.org<http://www.blender.org>}: documentation and forum +@see: U{www.elysiun.com<http://www.elysiun.com>}: user forum +@see: U{projects.blender.org<http://projects.blender.org>} +@see: U{www.python.org<http://www.python.org>} +@see: U{www.python.org/doc<http://www.python.org/doc>} +@note: this documentation was generated by epydoc, which can output html and + pdf (requires a working LaTeX environment) versions of this text. +""" + diff --git a/source/blender/python/api2_2x/doc/Blender.py b/source/blender/python/api2_2x/doc/Blender.py index 38a3cbc67bc..5fab895bb15 100644 --- a/source/blender/python/api2_2x/doc/Blender.py +++ b/source/blender/python/api2_2x/doc/Blender.py @@ -11,66 +11,10 @@ # Draw.py Image.py Text.py Lattice.py Texture.py Registry.py Sys.py Mathutils.py """ -The main Blender module (*). +The main Blender module. -The Blender Python API Reference -================================ - - Submodules: - ----------- - - - L{Armature} - - L{Bone} - - L{NLA} - - L{BGL} - - L{Camera} (*) - - L{Curve} - - L{Draw} (*) - - L{Effect} - - L{Image} (*) - - L{Ipo} - - L{Lamp} (*) - - L{Lattice} - - L{Library} - - L{Material} (*) - - L{Mathutils} - - L{Metaball} (*) - - L{NMesh} - - L{Noise} - - L{Object} (*) - - L{Registry} - - L{Scene} (*) - - L{Render} - - L{Text} - - L{Texture} - - L{Types} - - L{Window} (* important: L{Window.EditMode}) - - L{World} (*) - - L{sys<Sys>} (*) - - (*) - marks updated. - - Introduction: - ------------- - - This reference documents the Blender Python API, a growing collection of - Python modules (libraries) that give access to part of the program's internal - data and functions. - - Through scripting Blender can be extended in realtime. Possibilities range - from simple functionality to importers / exporters and even more complex - "applications". Blender scripts are written in - U{Python <www.python.org>}, an impressive high level, multi-paradigm, - open-source language. - -@author: The Blender Python Team -@requires: Blender 2.34 or newer. -@version: 2.34 -@see: U{www.blender.org<http://www.blender.org>}: documentation and forum -@see: U{www.elysiun.com<http://www.elysiun.com>}: user forum -@see: U{projects.blender.org<http://projects.blender.org>} -@see: U{www.python.org<http://www.python.org>} -@see: U{www.python.org/doc<http://www.python.org/doc>} +Blender +======= """ def Set (request, data): diff --git a/source/blender/python/api2_2x/doc/NMesh.py b/source/blender/python/api2_2x/doc/NMesh.py index 992ed27a4bf..322323ca733 100644 --- a/source/blender/python/api2_2x/doc/NMesh.py +++ b/source/blender/python/api2_2x/doc/NMesh.py @@ -392,10 +392,13 @@ class NMesh: """ Update the mesh in Blender. The changes made are put back to the mesh in Blender, if available, or put in a newly created mesh object if this NMesh - wasn't linked to one, yet. + wasn't already linked to one. @type recalc_normals: int @param recalc_normals: If given and equal to 1, the vertex normals are recalculated. + @note: if your mesh disappears after it's updated, try + L{Object.Object.makeDisplayList}. 'Subsurf' meshes (see L{getMode}, + L{setMode}) need their display lists updated, too. """ def getMode(): diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py index 2cea8d90f75..29b6cd79200 100644 --- a/source/blender/python/api2_2x/doc/Object.py +++ b/source/blender/python/api2_2x/doc/Object.py @@ -526,13 +526,14 @@ class Object: isn't modified, there's no need to recalculate this data. This method is here for the *few cases* where a script may need it, like when toggling the "SubSurf" mode for a mesh: + Example:: - object = Blender.Object.Get("Sphere") - nmesh = object.getData() - nmesh.setMode("SubSurf") - nmesh.update() # don't forget to update! - object.makeDisplayList() - Blender.Window.RedrawAll() # and don't forget to redraw + object = Blender.Object.Get("Sphere") + nmesh = object.getData() + nmesh.setMode("SubSurf") + nmesh.update() # don't forget to update! + object.makeDisplayList() + Blender.Window.Redraw() If you try this example without the line to update the display list, the object will disappear from the screen until you press "SubSurf". diff --git a/source/blender/python/api2_2x/doc/Radio.py b/source/blender/python/api2_2x/doc/Radio.py new file mode 100644 index 00000000000..380cb298104 --- /dev/null +++ b/source/blender/python/api2_2x/doc/Radio.py @@ -0,0 +1,66 @@ +# Blender.Scene.Radio module and the Radiosity PyType object + +""" +The Blender.Scene.Radio submodule. + +Radio +===== + +This module gives access to B{Scene Radiosity Contexts} in Blender. + +Example:: + import Blender + from Blender import Scene + + # Only the current scene has a radiosity context. + # Naturally, any scene can be made the current one + # with scene.makeCurrent() + + scn = Scene.GetCurrent() + + # this is the only way to access the radiosity object: + + radio = scn.getRadiosityContext() + + radio.setDrawType('Gouraud') + radio.setMode('ShowLimits', 'Z') + + radio.collectMeshes() # prepare patches + radio.go() # calculate radiosity + Blender.Redraw(-1) + + +@type Modes: readonly dictionary +@var Modes: + - ShowLimits + - Z + +@type DrawTypes: readonly dictionary +@var DrawTypes: + - Wire + - Solid + - Gouraud +""" + +class Radio: + """ + The Radiosity object + ==================== + This object wraps the current Scene's radiosity context in Blender. + """ + + def go(): + """ + Start the radiosity simulation. Remember to call L{collectMeshes} first. + """ + + def collectMeshes(): + """ + Convert selected visible meshes to patches for radiosity calculation. + """ + + def freeData(): + """ + Release all memory used by radiosity. + """ + diff --git a/source/blender/python/api2_2x/doc/Scene.py b/source/blender/python/api2_2x/doc/Scene.py index 1d84b95a229..35d709c02d8 100644 --- a/source/blender/python/api2_2x/doc/Scene.py +++ b/source/blender/python/api2_2x/doc/Scene.py @@ -3,7 +3,8 @@ """ The Blender.Scene submodule. -B{New}: L{Scene.play}, scriptLink methods: L{Scene.getScriptLinks}, ... +B{New}: L{Scene.play}; scriptLink methods: L{Scene.getScriptLinks}, etc; +L{Scene.getRadiosityContext} Scene ===== @@ -91,16 +92,6 @@ class Scene: @param name: The new name. """ - def getWinSize(): - """ - @warn: B{Deprecated}: use RenderData.imageSizeX() and RenderData.imageSizeY() - """ - - def setWinSize(dimensions): - """ - @warn: B{Deprecated}: use RenderData.imageSizeX() and RenderData.imageSizeY - """ - def copy(duplicate_objects = 1): """ Make a copy of this Scene. @@ -113,26 +104,6 @@ class Scene: @return: The copied Blender Scene. """ - def startFrame(frame = None): - """ - @warn: B{Deprecated}: use RenderData.startFrame() - """ - - def endFrame(frame = None): - """ - @warn: B{Deprecated}: use RenderData.endFrame() - """ - - def currentFrame(frame = None): - """ - @warn: B{Deprecated}: use RenderData.currentFrame - """ - - def frameSettings(start = None, end = None, current = None): - """ - @warn: B{Deprecated}: use RenderData.startFrame(), RenderData.endFrame, RenderData.currentFrame - """ - def makeCurrent(): """ Make this Scene the currently active one in Blender. @@ -149,14 +120,19 @@ class Scene: The "full" update is a recent addition to this method. """ - def getRenderdir(): + def getRenderingContext(): """ - @warn: B{Deprecated}: use RenderData.getRenderPath() + Get the rendering context for this scene, see L{Render}. + @rtype: RenderData + @return: the render data object for this scene. """ - def getBackbufdir(): + def getRadiosityContext(): """ - @warn: B{Deprecated}: use RenderData.getBackbufPath() + Get the radiosity context for this scene, see L{Radio}. + @rtype: Blender Radiosity + @return: the radiosity object for this scene. + @note: only the current scene can return a radiosity context. """ def getChildren(): diff --git a/source/blender/python/api2_2x/doc/Sys.py b/source/blender/python/api2_2x/doc/Sys.py index 7908e6df0b8..7536296d0ff 100644 --- a/source/blender/python/api2_2x/doc/Sys.py +++ b/source/blender/python/api2_2x/doc/Sys.py @@ -6,7 +6,7 @@ The Blender.sys submodule. sys === -B{New}: L{exists}, L{makename}, L{join}. +B{New}: L{exists}, L{makename}, L{join}, L{sleep}. 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', @@ -129,3 +129,11 @@ def time (): @rtype: float @return: the elapsed time in seconds. """ + +def sleep (millisecs = 10): + """ + Sleep for the specified amount of time. + @type millisecs: int + @param millisecs: the amount of time in milliseconds to sleep. The default + is 10 which is 0.1 seconds. + """ diff --git a/source/blender/python/api2_2x/doc/Window.py b/source/blender/python/api2_2x/doc/Window.py index 3626e38bc09..6ad4971ff86 100644 --- a/source/blender/python/api2_2x/doc/Window.py +++ b/source/blender/python/api2_2x/doc/Window.py @@ -83,9 +83,12 @@ DrawProgressBar:: - SHIFT """ -def Redraw (): +def Redraw (spacetype = '<Types.VIEW3D>'): """ - Force a redraw of a specific Window Type (see L{Types}). + Force a redraw of a specific space type. + @type spacetype: int + @param spacetype: the space type, see L{Types}. By default the 3d Views are + redrawn. If spacetype < 0, all currently visible spaces are redrawn. """ def RedrawAll (): @@ -161,11 +164,27 @@ def GetCursorPos (): def SetCursorPos (coords): """ - Change the 3d cursor position. Note: if visible, the 3d window must be - redrawn to display the change. This can be done with - L{Redraw}(L{Types}['VIEW3D']), for example. + Change the 3d cursor position. @type coords: 3 floats or a list of 3 floats @param coords: The new x, y, z coordinates. + @note: if visible, the 3d View must be redrawn to display the change. This + can be done with L{Redraw}. + """ + +def WaitCursor (bool): + """ + Set cursor to wait or back to normal mode. + + Example:: + Blender.Window.WaitCursor(1) + Blender.sys.sleep(2000) # do something that takes some time + Blender.Window.WaitCursor(0) # back + + @type bool: int (bool) + @param bool: if nonzero the cursor is set to wait mode, otherwise to normal + mode. + @note: when the script finishes execution, the cursor is set to normal by + Blender itself. """ def GetViewVector (): @@ -187,11 +206,14 @@ def EditMode(enable = -1): Get and optionally set the current edit mode status: in or out. Example:: - Window.EditMode(0) # MUST leave edit mode before changing an active mesh + in_editmode = Window.EditMode() + # MUST leave edit mode before changing an active mesh: + if in_editmode: Window.EditMode(0) # ... # make changes to the mesh # ... - Window.EditMode(1) # be nice to the user and return things to how they were + # be nice to the user and return things to how they were: + if in_editmode: Window.EditMode(1) @type enable: int @param enable: get/set current status: - -1: just return current status (default); @@ -315,11 +337,20 @@ def QHandle (winId): def GetMouseCoords (): """ - Get the current mouse screen coordinates. + Get mouse's current screen coordinates. @rtype: list with two ints @return: a [x, y] list with the coordinates. """ +def SetMouseCoords (coords): + """ + Set mouse's current screen coordinates. + @type coords: (list of) two ints + @param coords: can be passed as x, y or [x, y] and are clamped to stay inside + the screen. If not given they default to the coordinates of the middle + of the screen. + """ + def GetMouseButtons (): """ Get the current mouse button state (compare with events from L{Draw}). @@ -360,6 +391,13 @@ def GetAreaSize (): returns for the 'vertices' of the same area. """ +def GetScreenSize (): + """ + Get Blender's screen size. + @rtype: list with two ints + @return: a [width, height] list. + """ + def GetScreens (): """ Get the names of all available screens. diff --git a/source/blender/python/api2_2x/doc/epy_docgen.sh b/source/blender/python/api2_2x/doc/epy_docgen.sh index b87f015232b..27d82c9d373 100644 --- a/source/blender/python/api2_2x/doc/epy_docgen.sh +++ b/source/blender/python/api2_2x/doc/epy_docgen.sh @@ -4,6 +4,6 @@ # run from the doc directory containing the .py files # usage: sh epy_docgen.sh -epydoc -o BPY_API_233 --url "http://www.blender.org" -t Blender.py \ +epydoc -o BPY_API_234 --url "http://www.blender.org" -t API_intro.py \ -n "Blender" --no-private --no-frames \ $( ls [A-Z]*.py ) diff --git a/source/blender/python/api2_2x/sceneRadio.c b/source/blender/python/api2_2x/sceneRadio.c new file mode 100644 index 00000000000..7b631bb1292 --- /dev/null +++ b/source/blender/python/api2_2x/sceneRadio.c @@ -0,0 +1,638 @@ +/* + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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, + * 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. + * + * This is a new part of Blender. + * + * Contributor(s): Willian P. Germano + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + +#include "sceneRadio.h" /* includes Python.h */ +#include <radio.h> +#include <BKE_object.h> /* disable_where_script() */ + +#include "constant.h" +#include "gen_utils.h" + +/* bitflags */ +#define EXPP_RADIO_flag_SHOWLIM 1 +#define EXPP_RADIO_flag_Z 2 +/* shorts */ +#define EXPP_RADIO_hemires_MIN 100 +#define EXPP_RADIO_hemires_MAX 1000 +#define EXPP_RADIO_maxiter_MIN 0 +#define EXPP_RADIO_maxiter_MAX 10000 +#define EXPP_RADIO_subshootp_MIN 0 +#define EXPP_RADIO_subshootp_MAX 10 +#define EXPP_RADIO_subshoote_MIN 0 +#define EXPP_RADIO_subshoote_MAX 10 +#define EXPP_RADIO_nodelim_MIN 0 +#define EXPP_RADIO_nodelim_MAX 50 +#define EXPP_RADIO_maxsublamp_MIN 1 +#define EXPP_RADIO_maxsublamp_MAX 250 +#define EXPP_RADIO_pama_MIN 10 +#define EXPP_RADIO_pama_MAX 1000 +#define EXPP_RADIO_pami_MIN 10 +#define EXPP_RADIO_pami_MAX 1000 +#define EXPP_RADIO_elma_MIN 1 +#define EXPP_RADIO_elma_MAX 500 +#define EXPP_RADIO_elmi_MIN 1 +#define EXPP_RADIO_elmi_MAX 500 +/* ints */ +#define EXPP_RADIO_maxnode_MIN 1 +#define EXPP_RADIO_maxnode_MAX 250000 +/* floats */ +#define EXPP_RADIO_convergence_MIN 0.0 +#define EXPP_RADIO_convergence_MAX 0.1 +#define EXPP_RADIO_radfac_MIN 0.001 +#define EXPP_RADIO_radfac_MAX 250.0 +#define EXPP_RADIO_gamma_MIN 0.2 +#define EXPP_RADIO_gamma_MAX 10.0 +/* drawtypes */ +#define EXPP_RADIO_drawtype_WIRE 0 +#define EXPP_RADIO_drawtype_SOLID 1 +#define EXPP_RADIO_drawtype_GOURAUD 2 + +static int EXPP_check_scene(Scene *scene) +{ + if (scene != G.scene) { + PyErr_SetString(PyExc_EnvironmentError, + "\nradiosity only works on the current scene, check scene.makeCurrent()."); + return 0; + } + else if (!scene->radio) { + PyErr_SetString(PyExc_EnvironmentError, + "\nradiosity data was deleted from scene!"); + return 0; + } + + return 1; +} + +static PyObject *Radio_collectMeshes(BPy_Radio *self); +static PyObject *Radio_go(BPy_Radio *self); +static PyObject *Radio_freeData(BPy_Radio *self); + +static void Radio_dealloc (BPy_Radio *self); +static PyObject *Radio_repr (BPy_Radio *self); + +static PyObject *EXPP_create_ret_PyInt(int value) +{ + PyObject *pyval = PyInt_FromLong(value); + + if (!pyval) + PyErr_SetString(PyExc_MemoryError, "couldn't create py int!"); + + return pyval; +} + +static PyObject *EXPP_create_ret_PyFloat(float value) +{ + PyObject *pyval = PyFloat_FromDouble((double)value); + + if (!pyval) + PyErr_SetString(PyExc_MemoryError, "couldn't create py int!"); + + return pyval; +} + +static PyObject *Radio_get_hemires(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyInt((int)self->scene->radio->hemires); +} + +static PyObject *Radio_get_maxiter(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyInt((int)self->scene->radio->maxiter); +} + +static PyObject *Radio_get_subshootp(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyInt((int)self->scene->radio->subshootp); +} + +static PyObject *Radio_get_subshoote(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyInt((int)self->scene->radio->subshoote); +} + +static PyObject *Radio_get_nodelim(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyInt((int)self->scene->radio->nodelim); +} + +static PyObject *Radio_get_maxsublamp(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyInt((int)self->scene->radio->maxsublamp); +} + +static PyObject *Radio_get_pama(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyInt((int)self->scene->radio->pama); +} + +static PyObject *Radio_get_pami(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyInt((int)self->scene->radio->pami); +} + +static PyObject *Radio_get_elma(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyInt((int)self->scene->radio->elma); +} + +static PyObject *Radio_get_elmi(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyInt((int)self->scene->radio->elmi); +} + +static PyObject *Radio_get_drawtype(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyInt((int)self->scene->radio->drawtype); +} + +static PyObject *Radio_get_flag(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyInt((int)self->scene->radio->flag); +} + +static PyObject *Radio_get_maxnode(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyInt((int)self->scene->radio->maxnode); +} + +static PyObject *Radio_get_convergence(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyFloat(self->scene->radio->convergence); +} + +static PyObject *Radio_get_radfac(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyFloat(self->scene->radio->radfac); +} + +static PyObject *Radio_get_gamma(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_create_ret_PyFloat(self->scene->radio->gamma); +} + +static PyObject *EXPP_unpack_set_int(PyObject *args, int *ptr, + int min, int max) +{ + int value; + + if (!PyArg_ParseTuple(args, "i", &value)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected int argument"); + + *ptr = EXPP_ClampInt(value, min, max); + + return EXPP_incr_ret (Py_None); +} + +/* could merge with set_int, but is cleaner this way */ +static PyObject *EXPP_unpack_set_short(PyObject *args, short *ptr, + short min, short max) +{ + int value; + + if (!PyArg_ParseTuple(args, "i", &value)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected int argument"); + + *ptr = (short)EXPP_ClampInt(value, min, max); + + return EXPP_incr_ret (Py_None); +} + +static PyObject *EXPP_unpack_set_float(PyObject *args, float *ptr, + float min, float max) +{ + float value; + + if (!PyArg_ParseTuple(args, "f", &value)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected float argument"); + + *ptr = EXPP_ClampFloat(value, min, max); + + return EXPP_incr_ret (Py_None); +} + +static PyObject *Radio_set_hemires(BPy_Radio *self, PyObject *args) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_unpack_set_short(args, &self->scene->radio->hemires, + EXPP_RADIO_hemires_MIN, EXPP_RADIO_hemires_MAX); +} + +static PyObject *Radio_set_maxiter(BPy_Radio *self, PyObject *args) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_unpack_set_short(args, &self->scene->radio->maxiter, + EXPP_RADIO_maxiter_MIN, EXPP_RADIO_maxiter_MAX); +} + +static PyObject *Radio_set_subshootp(BPy_Radio *self, PyObject *args) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_unpack_set_short(args, &self->scene->radio->subshootp, + EXPP_RADIO_subshootp_MIN, EXPP_RADIO_subshootp_MAX); +} + +static PyObject *Radio_set_subshoote(BPy_Radio *self, PyObject *args) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_unpack_set_short(args, &self->scene->radio->subshoote, + EXPP_RADIO_subshoote_MIN, EXPP_RADIO_subshoote_MAX); +} + +static PyObject *Radio_set_nodelim(BPy_Radio *self, PyObject *args) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_unpack_set_short(args, &self->scene->radio->nodelim, + EXPP_RADIO_nodelim_MIN, EXPP_RADIO_nodelim_MAX); +} + +static PyObject *Radio_set_maxsublamp(BPy_Radio *self, PyObject *args) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_unpack_set_short(args, &self->scene->radio->maxsublamp, + EXPP_RADIO_maxsublamp_MIN, EXPP_RADIO_maxsublamp_MAX); +} + +static PyObject *Radio_set_pama(BPy_Radio *self, PyObject *args) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_unpack_set_short(args, &self->scene->radio->pama, + EXPP_RADIO_pama_MIN, EXPP_RADIO_pama_MAX); +} + +static PyObject *Radio_set_pami(BPy_Radio *self, PyObject *args) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_unpack_set_short(args, &self->scene->radio->pami, + EXPP_RADIO_pami_MIN, EXPP_RADIO_pami_MAX); +} + +static PyObject *Radio_set_elma(BPy_Radio *self, PyObject *args) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_unpack_set_short(args, &self->scene->radio->elma, + EXPP_RADIO_elma_MIN, EXPP_RADIO_elma_MAX); +} + +static PyObject *Radio_set_elmi(BPy_Radio *self, PyObject *args) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_unpack_set_short(args, &self->scene->radio->elmi, + EXPP_RADIO_elmi_MIN, EXPP_RADIO_elmi_MAX); +} + +static PyObject *Radio_set_drawtype(BPy_Radio *self, PyObject *args) +{ + PyObject *pyob = NULL; + char *str = NULL; + short dt = EXPP_RADIO_drawtype_WIRE; + + if (!EXPP_check_scene(self->scene)) return NULL; + + if (!PyArg_ParseTuple (args, "O", &pyob)) + return EXPP_ReturnPyObjError(PyExc_TypeError, + "expected int or string as argument"); + + if (PyString_Check(pyob)) { + str = PyString_AsString(pyob); + if (!str) + return EXPP_ReturnPyObjError (PyExc_MemoryError, + "couldn't create py string!"); + else if (!strcmp(str, "Wire")) dt = EXPP_RADIO_drawtype_WIRE; + else if (!strcmp(str, "Solid")) dt = EXPP_RADIO_drawtype_SOLID; + else if (!strcmp(str, "Gouraud")) dt = EXPP_RADIO_drawtype_GOURAUD; + else + return EXPP_ReturnPyObjError (PyExc_AttributeError, + "unknown drawtype string"); + } + else if (PyInt_Check(pyob)) { + dt = (short)EXPP_ClampInt(PyInt_AsLong(pyob), + EXPP_RADIO_drawtype_WIRE, EXPP_RADIO_drawtype_GOURAUD); + } + else + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected int or string as argument"); + + self->scene->radio->drawtype = dt; + + return EXPP_incr_ret (Py_None); +} + +static PyObject *Radio_set_flag(BPy_Radio *self, PyObject *args) +{ + int i, imode = 0; + char *mode[2] = {NULL, NULL}; + + if (!EXPP_check_scene(self->scene)) return NULL; + + if (!PyArg_ParseTuple(args, "|ss", &mode[0], &mode[1])) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected string arguments (or nothing)"); + + for (i = 0; i < 2; i++) { + if (!mode[i]) break; + else if (!strcmp(mode[i], "ShowLimits")) imode |= EXPP_RADIO_flag_SHOWLIM; + else if (!strcmp(mode[i], "Z")) imode |= EXPP_RADIO_flag_Z; + } + + self->scene->radio->flag = (short)EXPP_ClampInt(imode, 0, 3); + + return EXPP_incr_ret(Py_None); +} + +static PyObject *Radio_set_maxnode(BPy_Radio *self, PyObject *args) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_unpack_set_int(args, &self->scene->radio->maxnode, + EXPP_RADIO_maxnode_MIN, EXPP_RADIO_maxnode_MAX); +} + +static PyObject *Radio_set_convergence(BPy_Radio *self, PyObject *args) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_unpack_set_float(args, &self->scene->radio->convergence, + EXPP_RADIO_convergence_MIN, EXPP_RADIO_convergence_MAX); +} + +static PyObject *Radio_set_radfac(BPy_Radio *self, PyObject *args) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_unpack_set_float(args, &self->scene->radio->radfac, + EXPP_RADIO_radfac_MIN, EXPP_RADIO_radfac_MAX); +} + +static PyObject *Radio_set_gamma(BPy_Radio *self, PyObject *args) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + return EXPP_unpack_set_float(args, &self->scene->radio->gamma, + EXPP_RADIO_gamma_MIN, EXPP_RADIO_gamma_MAX); +} + +static PyMethodDef BPy_Radio_methods[] = { + {"collectMeshes", (PyCFunction) Radio_collectMeshes, METH_NOARGS, + "() - Convert selected meshes to patches."}, + {"go", (PyCFunction) Radio_go, METH_NOARGS, + "() - Start radiosity calculations."}, + {"freeData", (PyCFunction) Radio_freeData, METH_NOARGS, + "() - Free all memory used by radiosity."}, + {"getHemiRes", (PyCFunction) Radio_get_hemires, METH_NOARGS, + "() - Get hemicube size."}, + {"setHemiRes", (PyCFunction) Radio_set_hemires, METH_VARARGS, + "(int) - Set hemicube size, the range is [100, 1000]."}, + {"getMaxIter", (PyCFunction) Radio_get_maxiter, METH_NOARGS, + "() - Get maximum number of radiosity rounds."}, + {"setMaxIter", (PyCFunction) Radio_set_maxiter, METH_VARARGS, + "(i) - Set maximum number of radiosity rounds in [0, 10000]."}, + {"getSubShPatch", (PyCFunction) Radio_get_subshootp, METH_NOARGS, + "() - Get max number of times environment is tested to detect patches."}, + {"setSubShPatch", (PyCFunction) Radio_set_subshootp, METH_VARARGS, + "(i) - Set max number of times environment is tested to detect patches.\n\ + Range is [0, 10]."}, + {"getSubShElem", (PyCFunction) Radio_get_subshoote, METH_NOARGS, + "() - Get number of times environment is tested to detect elements."}, + {"setSubShElem", (PyCFunction) Radio_set_subshoote, METH_VARARGS, + "(i) - Set number of times environment is tested to detect elements.\n\ + Range is [0, 10]."}, + {"getNodeLimit", (PyCFunction) Radio_get_nodelim, METH_NOARGS, + "() - Get the range for removing doubles."}, + {"setNodeLimit", (PyCFunction) Radio_set_nodelim, METH_VARARGS, + "(i) - Set the range for removing doubles in [0, 50]."}, + {"getMaxSubDivSh", (PyCFunction) Radio_get_maxsublamp, METH_NOARGS, + "() - Get max number of initial shoot patches evaluated."}, + {"setMaxSubDivSh", (PyCFunction) Radio_set_maxsublamp, METH_VARARGS, + "(i) - Set max number of initial shoot patches evaluated in [1, 250]."}, + {"getPatchMax", (PyCFunction) Radio_get_pama, METH_NOARGS, + "() - Get max size of a patch."}, + {"setPatchMax", (PyCFunction) Radio_set_pama, METH_VARARGS, + "(i) - Set max size of a patch in [10, 1000]."}, + {"getPatchMin", (PyCFunction) Radio_get_pami, METH_NOARGS, + "() - Get minimum size of a patch."}, + {"setPatchMin", (PyCFunction) Radio_set_pami, METH_VARARGS, + "(i) - Set minimum size of a patch in [10, 1000]."}, + {"getElemMax", (PyCFunction) Radio_get_elma, METH_NOARGS, + "() - Get max size of an element."}, + {"setElemMax", (PyCFunction) Radio_set_elma, METH_VARARGS, + "(i) - Set max size of an element in [1, 100]."}, + {"getElemMin", (PyCFunction) Radio_get_elmi, METH_NOARGS, + "() - Get minimum size of an element."}, + {"setElemMin", (PyCFunction) Radio_set_elmi, METH_VARARGS, + "(i) - Set minimum size of an element in [1, 100]."}, + {"getMaxElems", (PyCFunction) Radio_get_maxnode, METH_NOARGS, + "() - Get maximum number of elements."}, + {"setMaxElems", (PyCFunction) Radio_set_maxnode, METH_VARARGS, + "(i) - Set maximum nunber of elements in [1, 250000]."}, + {"getConvergence", (PyCFunction) Radio_get_convergence, METH_NOARGS, + "() - Get lower threshold of unshot energy."}, + {"setConvergence", (PyCFunction) Radio_set_convergence, METH_VARARGS, + "(f) - Set lower threshold of unshot energy in [0.0, 1.0]."}, + {"getMult", (PyCFunction) Radio_get_radfac, METH_NOARGS, + "() - Get energy value multiplier."}, + {"setMult", (PyCFunction) Radio_set_radfac, METH_VARARGS, + "(f) - Set energy value multiplier in [0.001, 250.0]."}, + {"getGamma", (PyCFunction) Radio_get_gamma, METH_NOARGS, + "() - Get change in the contrast of energy values."}, + {"setGamma", (PyCFunction) Radio_set_gamma, METH_VARARGS, + "(f) - Set change in the contrast of energy values in [0.2, 10.0]."}, + {"getDrawType", (PyCFunction) Radio_get_drawtype, METH_NOARGS, + "() - Get the draw type: Wire, Solid or Gouraud as an int value."}, + {"setDrawType", (PyCFunction) Radio_set_drawtype, METH_VARARGS, + "(i or s) - Set the draw type: wire, solid (default) or gouraud."}, + {"getMode", (PyCFunction) Radio_get_flag, METH_NOARGS, + "() - Get mode as an or'ed bitmask, see Radio.Modes dict."}, + {"setMode", (PyCFunction) Radio_set_flag, METH_VARARGS, + "(|ss) - Set mode flags as strings: 'ShowLimits', 'Z'."}, + {NULL, NULL, 0, NULL} +}; + +static PyTypeObject Radio_Type = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "Blender Radiosity", /*tp_name*/ + sizeof(BPy_Radio), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)Radio_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + (reprfunc)Radio_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "Blender radiosity", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_Radio_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0,0,0,0,0,0,0,0, /* up to tp_del, so we don't get a warning */ +}; + +static void Radio_dealloc (BPy_Radio *self) +{ + PyObject_DEL (self); +} + +static PyObject *Radio_repr (BPy_Radio *self) +{ + if (self->radio) + return PyString_FromFormat ("[Radiosity \"%s\"]", self->scene->id.name + 2); + else + return PyString_FromString ("NULL"); +} + +PyObject *Radio_CreatePyObject (struct Scene *scene) +{ + BPy_Radio *py_radio; + + if (scene != G.scene) { + return EXPP_ReturnPyObjError (PyExc_EnvironmentError, + "\nradiosity only works on the current scene, check scene.makeCurrent()."); + } + + py_radio = (BPy_Radio *) PyObject_NEW (BPy_Radio, &Radio_Type); + + if (!py_radio) return NULL; + + if (!scene->radio) add_radio(); /* adds to G.scene */ + + py_radio->radio = scene->radio; + py_radio->scene = scene; + + return ((PyObject *) py_radio); +} + +int Radio_CheckPyObject (PyObject *pyob) +{ + return (pyob->ob_type == &Radio_Type); +} + +static PyObject *Radio_collectMeshes(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + + disable_where_script(1); /* used to avoid error popups */ + rad_collect_meshes(); + disable_where_script(0); + + return EXPP_incr_ret(Py_None); +} + +static PyObject *Radio_freeData(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + + delete_radio(); + + return EXPP_incr_ret(Py_None); +} + +static PyObject *Radio_go(BPy_Radio *self) +{ + if (!EXPP_check_scene(self->scene)) return NULL; + + rad_go(); + + return EXPP_incr_ret(Py_None); +} + +static PyMethodDef M_Radio_methods[] = {{NULL, NULL, 0, NULL}}; + +PyObject *Radio_Init (void) +{ + PyObject *submodule, *Modes, *DrawTypes; + + if (PyType_Ready(&Radio_Type) < 0) return NULL; + + submodule = Py_InitModule3 ("Blender.Scene.Radio", M_Radio_methods, + "The Blender Radiosity submodule"); + + Modes = M_constant_New(); + DrawTypes = M_constant_New(); + + if (Modes) { + BPy_constant *d = (BPy_constant *)Modes; + + constant_insert(d, "ShowLimits", PyInt_FromLong(EXPP_RADIO_flag_SHOWLIM)); + constant_insert(d, "Z", PyInt_FromLong(EXPP_RADIO_flag_Z)); + + PyModule_AddObject(submodule, "Modes", Modes); + } + + if (DrawTypes) { + BPy_constant *d = (BPy_constant *)DrawTypes; + + constant_insert(d, "Wire", PyInt_FromLong(EXPP_RADIO_drawtype_WIRE)); + constant_insert(d, "Solid", PyInt_FromLong(EXPP_RADIO_drawtype_SOLID)); + constant_insert(d, "Gouraud", PyInt_FromLong(EXPP_RADIO_drawtype_GOURAUD)); + + PyModule_AddObject(submodule, "DrawTypes", DrawTypes); + } + + return submodule; +} diff --git a/source/blender/python/api2_2x/sceneRadio.h b/source/blender/python/api2_2x/sceneRadio.h new file mode 100644 index 00000000000..a08d7d4327b --- /dev/null +++ b/source/blender/python/api2_2x/sceneRadio.h @@ -0,0 +1,52 @@ +/* + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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, + * 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. + * + * This is a new part of Blender. + * + * Contributor(s): Willian P. Germano + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + +#ifndef EXPP_SCENERADIO_H +#define EXPP_SCENERADIO_H + +#include <Python.h> +#include <DNA_radio_types.h> +#include <DNA_scene_types.h> + +/* BPy_Radio declaration */ +typedef struct +{ + PyObject_HEAD + struct Radio *radio; + struct Scene *scene; +}BPy_Radio; + +PyObject *Radio_Init (void); + +PyObject *Radio_CreatePyObject (struct Scene * scene); +int Radio_CheckPyObject (PyObject * py_obj); + +#endif /* EXPP_SCENERADIO_H */ diff --git a/source/blender/radiosity/intern/source/radpreprocess.c b/source/blender/radiosity/intern/source/radpreprocess.c index 1f2f8bc2a89..3c94bfc1a22 100644 --- a/source/blender/radiosity/intern/source/radpreprocess.c +++ b/source/blender/radiosity/intern/source/radpreprocess.c @@ -60,6 +60,7 @@ #include "BKE_global.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_object.h" /* during_script() */ #include "BIF_toolbox.h" @@ -300,7 +301,7 @@ void rad_collect_meshes() int a, b, offs, index, matindex; if(G.obedit) { - error("Unable to perform function in EditMode"); + if (!during_script()) error("Unable to perform function in EditMode"); return; } @@ -325,7 +326,7 @@ void rad_collect_meshes() base= base->next; } if(RG.totvert==0) { - error("No vertices"); + if (!during_script()) error("No vertices"); return; } vnc= RG.verts= MEM_callocN(RG.totvert*sizeof(VeNoCo), "readvideoscape1"); diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c index 2ef2908cf36..a4041dc6d4b 100644 --- a/source/blender/src/drawmesh.c +++ b/source/blender/src/drawmesh.c @@ -896,13 +896,12 @@ void draw_tface_mesh(Object *ob, Mesh *me, int dt) if(mesh_uses_displist(me) && editing==0) { DispList *dl= find_displist(&me->disp, DL_MESH); - DispListMesh *dlm= dl->mesh; - - totface= dlm->totface; - + DispListMesh *dlm= NULL; + if (!dl) totface= 0; else { + dlm = dl->mesh; totface= dlm->totface; mvert= dlm->mvert; mface= dlm->mface; |