BPython:
authorWillian Padovani Germano <wpgermano@gmail.com>
Sun, 25 Jul 2004 16:55:45 +0000 (16:55 +0000)
committerWillian Padovani Germano <wpgermano@gmail.com>
Sun, 25 Jul 2004 16:55:45 +0000 (16:55 +0000)
- 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.

18 files changed:
release/scripts/bevel_center.py
source/blender/python/SConscript
source/blender/python/api2_2x/Ipo.c
source/blender/python/api2_2x/Scene.c
source/blender/python/api2_2x/Window.c
source/blender/python/api2_2x/doc/API_intro.py [new file with mode: 0644]
source/blender/python/api2_2x/doc/Blender.py
source/blender/python/api2_2x/doc/NMesh.py
source/blender/python/api2_2x/doc/Object.py
source/blender/python/api2_2x/doc/Radio.py [new file with mode: 0644]
source/blender/python/api2_2x/doc/Scene.py
source/blender/python/api2_2x/doc/Sys.py
source/blender/python/api2_2x/doc/Window.py
source/blender/python/api2_2x/doc/epy_docgen.sh
source/blender/python/api2_2x/sceneRadio.c [new file with mode: 0644]
source/blender/python/api2_2x/sceneRadio.h [new file with mode: 0644]
source/blender/radiosity/intern/source/radpreprocess.c
source/blender/src/drawmesh.c

index e40c25b3ec12c6b0dbca881cd11554e3ad712ed7..37c7b64c12a2d91b82c617437179bace430e2f62 100644 (file)
@@ -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():
index 1c3c1f4bf9178b5a05bf22889e6f369e26854d68..b2112e1f44cb10b8b2ba7b3a9bb4271e2b8e0013 100644 (file)
@@ -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',
index 9033219e7648bf0ba70c2a964c814174d4e092c5..90f42e0fe618544509e6f6293cbdae30f12afc33 100644 (file)
@@ -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;
+                       }
     }
 }
 
index 59a1118398bb6a107275e93c635bc4c70bb3582d..97667ed9eedf36f835be01a6d9f779bf4096c13a 100644 (file)
@@ -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)
 {
index 73ae020acbffe1fc07b14e4175eabd4a55183b43..754831e89a8704a41e41d9f6798082222be0db16 100644 (file)
@@ -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 (file)
index 0000000..ab9074a
--- /dev/null
@@ -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.
+"""
+
index 38a3cbc67bca94423608ddacd3596a9c4a25614b..5fab895bb155af0ee7c3f16523300b81d58d1a36 100644 (file)
 # 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):
index 992ed27a4bfaf553c42b6fb652bff28d62cb5f9f..322323ca733d61b2fba015e2c0c880c530f3384d 100644 (file)
@@ -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():
index 2cea8d90f751373f29e94f735258e651977e1cde..29b6cd79200ae00b4afc52daab286f27d96e037b 100644 (file)
@@ -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 (file)
index 0000000..380cb29
--- /dev/null
@@ -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.
+    """
+
index 1d84b95a2291bce3846f06cd5c80ce2af49b874c..35d709c02d8923886bbab6181b29fe830152a904 100644 (file)
@@ -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():
index 7908e6df0b8c3cfe5187c56fa75ca9b15c2f332a..7536296d0ff6e22ff0c58550361ffd48654a20e8 100644 (file)
@@ -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.
+  """
index 3626e38bc09af9c67d206b37f8afe56372e25897..6ad4971ff86df593cef8f7b46b8ca510a7fc7882 100644 (file)
@@ -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.
index b87f015232b8c72f9dcb327d9125a579a3468d5b..27d82c9d373aca1d6824b072f29d04bba6de4c15 100644 (file)
@@ -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 (file)
index 0000000..7b631bb
--- /dev/null
@@ -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 (file)
index 0000000..a08d7d4
--- /dev/null
@@ -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 */
index 1f2f8bc2a8945c90a7113d5ba99a6bb4ae954309..3c94bfc1a22cf103def444cc45a13d19b6d7ec5b 100644 (file)
@@ -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");
index 2ef2908cf36c6ecc76cc11b626f6ff950455a014..a4041dc6d4bbb10f946dee4481167e9349a8fcaa 100644 (file)
@@ -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;