The following updates have been contributed by Willian P. Germano:
authorMichel Selten <michel@mselten.demon.nl>
Tue, 8 Apr 2003 19:54:14 +0000 (19:54 +0000)
committerMichel Selten <michel@mselten.demon.nl>
Tue, 8 Apr 2003 19:54:14 +0000 (19:54 +0000)
* Implemented BPY_end_python function.
* Implemented error handling. This results in rerunning a script after an
  error has occurred. No need to restart blender anymore.
* Camera module supports dir()
* variable assignment now calls the Python equivalent function - this has
  type checking and should be safer now.
* Implemented the Lamp module. Used the Camera module as a template.
* Implemented the Image module.
* Added EXPP_ClampFloat and EXPP_intError functions to gen_utils.[ch]
* Implemented 'constant' object.

13 files changed:
source/blender/python/BPY_interface.c
source/blender/python/api2_2x/Blender.c
source/blender/python/api2_2x/Camera.c
source/blender/python/api2_2x/Camera.h [new file with mode: 0644]
source/blender/python/api2_2x/Image.c [new file with mode: 0644]
source/blender/python/api2_2x/Image.h [new file with mode: 0644]
source/blender/python/api2_2x/Lamp.c [new file with mode: 0644]
source/blender/python/api2_2x/Lamp.h [new file with mode: 0644]
source/blender/python/api2_2x/constant.c [new file with mode: 0644]
source/blender/python/api2_2x/constant.h [new file with mode: 0644]
source/blender/python/api2_2x/gen_utils.c
source/blender/python/api2_2x/gen_utils.h
source/blender/python/api2_2x/modules.h

index d205f790f90a7c8d15cdf8517482b08cdcbb9b54..3ee3178b07d6b6c8c51a59bc32c3a03e9c9feaf7 100644 (file)
@@ -24,7 +24,7 @@
  *
  * This is a new part of Blender.
  *
- * Contributor(s): Michel Selten
+ * Contributor(s): Michel Selten, Willian P. Germano
  *
  * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */
@@ -96,12 +96,12 @@ void BPY_start_python(void)
 }
 
 /*****************************************************************************/
-/* Description:                                                              */
-/* Notes:       Not implemented yet                                          */
+/* Description: This function will terminate the Python interpreter          */
 /*****************************************************************************/
 void BPY_end_python(void)
 {
        printf ("In BPY_end_python\n");
+       Py_Finalize();
        return;
 }
 
@@ -145,6 +145,15 @@ struct _object *BPY_txt_do_python(struct SpaceText* st)
        /* dict = newGlobalDictionary(); */
        ret = RunPython (st->text, dict);
 
+       /* If errors have occurred, set the error filename to the name of the
+          script.
+       */
+       if (!ret)
+       {
+               sprintf(g_script_error.filename, "%s", st->text->id.name+2);
+               return NULL;
+       }
+
        return dict;
 }
 
@@ -307,6 +316,17 @@ PyObject * RunPython(Text *text, PyObject *globaldict)
        buf = txt_to_buf(text);
        ret = PyRun_String (buf, Py_file_input, globaldict, globaldict);
 
+       if (!ret)
+       {
+               /* an exception was raised, handle it here */
+               PyErr_Print(); /* this function also clears the error
+                                 indicator */
+       }
+       else
+       {
+               PyErr_Clear(); /* seems necessary, at least now */
+       }
+
        MEM_freeN (buf);
        return ret;
 }
index a258e31be2b1415641e0eaca44659c59bb5abe61..2af50256de738e18193b25db8d8d74a97937f2a3 100644 (file)
@@ -241,6 +241,8 @@ void initBlender (void)
        dict = PyModule_GetDict (module);
        g_blenderdict = dict;
        PyDict_SetItemString (dict, "Object", initObject());
-       PyDict_SetItemString (dict, "Camera", initCamera());
+       PyDict_SetItemString (dict, "Camera", M_Camera_Init());
+       PyDict_SetItemString (dict, "Lamp", M_Lamp_Init());
+       PyDict_SetItemString (dict, "Image", M_Image_Init());
 }
 
index 20d74ea3c1827e78c255c73ad041d01f9d1db7fc..f3f7ba6d4a8b5c7e87ab227c3141544a863d5124 100644 (file)
-/* TODO: 'print dir(CameraObject)' doesn't work, attribs are not recognized;
- *   how to assign methods to objects? PyMethod_New() ? Maybe separate
- *   CameraModule and Camera; found: check Extending ... section 2.2.3
- *   correctly handle references;
- *   Make all functions but module init's static ?
- *   'print Blender.Camera.__doc__' doesn't work (still gives 'None')*/
+/* 
+ *
+ * ***** 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 "Camera.h"
 
-#include <Python.h>
-#include <stdio.h>
+/*****************************************************************************/
+/* Function:              M_Camera_New                                       */
+/* Python equivalent:     Blender.Camera.New                                 */
+/*****************************************************************************/
+static PyObject *M_Camera_New(PyObject *self, PyObject *args, PyObject *keywords)
+{
+  char        *type_str = "persp"; /* "persp" is type 0, "ortho" is type 1 */
+  char        *name_str = "Data";
+  static char *kwlist[] = {"type_str", "name_str", NULL};
+  C_Camera    *cam;
+  PyObject    *type, *name;
+  int         type_int;
+  char        buf[21];
 
-#include <BKE_main.h>
-#include <BKE_global.h>
-#include <BKE_object.h>
-#include <DNA_camera_types.h>
+  printf ("In Camera_New()\n");
 
-#include "gen_utils.h"
-#include "modules.h"
+  if (!PyArg_ParseTupleAndKeywords(args, keywords, "|ss", kwlist,
+                                   &type_str, &name_str))
+  {
+  /* We expected string(s) (or nothing) as argument, but we didn't get it. */
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected zero, one or two strings as arguments"));
+  }
 
-/*****************************************************************************/
-/* Python API function prototypes for the Camera module.                    */
-/******************************************************************************/
-PyObject *Camera_New (PyObject *self, PyObject *args, PyObject *keywords);
-PyObject *Camera_Get (PyObject *self, PyObject *args);
+  if (strcmp (type_str, "persp") == 0)
+    type_int = EXPP_CAM_TYPE_PERSP;
+  else
+  {
+    if (strcmp (type_str, "ortho") == 0)
+    {
+      type_int = EXPP_CAM_TYPE_ORTHO;
+    }
+    else
+    {
+      return (PythonReturnErrorObject (PyExc_AttributeError,
+              "unknown camera type"));
+    }
+  }
 
-/*****************************************************************************/
-/* The following string definitions are used for documentation strings.      */
-/* In Python these will be written to the console when doing a               */
-/* Blender.Camera.__doc__                                                     */
-/*****************************************************************************/
-char CameraModule_doc[] =
-"The Blender Camera module\n\n\
-This module provides access to **Camera** objects in Blender\n\n\
-Example::\n\n\
-  from Blender import Camera, Object, Scene\n\
-  c = Camera.New('ortho')      # create new ortho camera data\n\
-  c.lens = 35.0                # set lens value\n\
-  cur = Scene.getCurrent()     # get current Scene\n\
-  ob = Object.New('Camera')    # make camera object\n\
-  ob.link(c)                   # link camera data with this object\n\
-  cur.link(ob)                 # link object into scene\n\
-  cur.setCurrentCamera(ob)     # make this camera the active\n";
-
-char Camera_New_doc[] =
-"(type) - returns a new Camera object of type 'type', \
-which can be 'persp' or 'ortho'.\n\
-() - returns a new Camera object of type 'persp'.";
-
-char Camera_Get_doc[] =
-"(name) - return the camera with the name 'name', \
-returns None if not found.\n If 'name' is not specified, \
-it returns a list of all cameras in the\ncurrent scene.";
+  cam = (C_Camera *)CameraCreatePyObject(NULL);
 
-/*****************************************************************************/
-/* Python BlenderCamera structure definition.                                */
-/*****************************************************************************/
-typedef struct {
-  PyObject_HEAD
-  struct Camera    *camera;
-} BlenCamera;
+  if (cam == NULL)
+  {
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+                                     "couldn't create Camera Data object"));
+  }
+  cam->linked = 0; /* only Camera Data, not linked */
 
-/*****************************************************************************/
-/* PythonTypeCamera callback function prototypes                             */
-/*****************************************************************************/
-void CameraDeAlloc (BlenCamera *cam);
-PyObject* CameraGetAttr (BlenCamera *cam, char *name);
-int CameraSetAttr (BlenCamera *cam, char *name, PyObject *v);
-PyObject* CameraRepr (BlenCamera *cam);
+  type = PyInt_FromLong(type_int);
+  if (type)
+  {
+    CameraSetAttr(cam, "type", type);
+  }
+  else
+  {
+    Py_DECREF((PyObject *)cam);
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+                                     "couldn't create PyString"));
+  }
+
+  if (strcmp(name_str, "Data") == 0)
+  {
+    return (PyObject *)cam;
+  }
+
+  PyOS_snprintf(buf, sizeof(buf), "%s", name_str);
+  name = PyString_FromString(buf);
+  if (name)
+  {
+    CameraSetAttr(cam, "name", name);
+  }
+  else
+  {
+    Py_DECREF((PyObject *)cam);
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+                                     "couldn't create PyString"));
+  }
+
+  return (PyObject *)cam;
+}
 
 /*****************************************************************************/
-/* Python TypeCamera structure definition.                                   */
+/* Function:              M_Camera_Get                                       */
+/* Python equivalent:     Blender.Camera.Get                                 */
 /*****************************************************************************/
-static PyTypeObject camera_type =
+static PyObject *M_Camera_Get(PyObject *self, PyObject *args)
 {
-  PyObject_HEAD_INIT(&PyType_Type)
-  0,                                                           /* ob_size */
-  "Camera",                                            /* tp_name */
-  sizeof (BlenCamera),                 /* tp_basicsize */
-  0,                                                           /* tp_itemsize */
-  /* methods */
-  (destructor)CameraDeAlloc,           /* tp_dealloc */
-  0,                                                           /* tp_print */
-  (getattrfunc)CameraGetAttr,          /* tp_getattr */
-  (setattrfunc)CameraSetAttr,          /* tp_setattr */
-  0,                                                           /* tp_compare */
-  (reprfunc)CameraRepr,                                        /* tp_repr */
-  0,                                                           /* tp_as_number */
-  0,                                                           /* tp_as_sequence */
-  0,                                                           /* tp_as_mapping */
-  0,                                                           /* tp_as_hash */
-  0,
-  0,
-  0,
-  0,
-  0,
-  0,
-  CameraModule_doc,  /* tp_doc Isn't working for some reason */ 
-  0,
-};
+  char     *name;
+  Camera   *cam_iter;
+  C_Camera *wanted_cam;
+
+  printf ("In Camera_Get()\n");
+  if (!PyArg_ParseTuple(args, "s", &name))
+  {
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected string argument"));
+  }
+
+  /* Use the name to search for the camera requested. */
+  wanted_cam = NULL;
+  cam_iter = G.main->camera.first;
+
+  while ((cam_iter) && (wanted_cam == NULL))
+  {
+    if (strcmp (name, GetIdName (&(cam_iter->id))) == 0)
+    {
+      wanted_cam = (C_Camera *)CameraCreatePyObject(cam_iter);
+      cam_iter = cam_iter->id.next;
+    }
+  }
+
+  if (wanted_cam == NULL)
+  {
+    /* No camera exists with the name specified in the argument name. */
+    char error_msg[64];
+    PyOS_snprintf(error_msg, sizeof(error_msg),
+                    "Camera \"%s\" not found", name);
+    return (PythonReturnErrorObject (PyExc_NameError, error_msg));
+  }
+
+  wanted_cam->linked = 1; /* TRUE: linked to a Blender Camera Object */
+  return ((PyObject*)wanted_cam);
+}
 
 /*****************************************************************************/
-/* Python method structure definition.                                       */
+/* Function:              M_Camera_Init                                      */
 /*****************************************************************************/
-struct PyMethodDef Camera_methods[] = {
-  {"New",(PyCFunction)Camera_New, METH_VARARGS|METH_KEYWORDS, Camera_New_doc},
-  {"Get",         Camera_Get,         METH_VARARGS, Camera_Get_doc},
-  {"get",         Camera_Get,         METH_VARARGS, Camera_Get_doc},
-  {NULL, NULL, 0, NULL}
-};
+PyObject *M_Camera_Init (void)
+{
+  PyObject  *module;
+
+  printf ("In M_Camera_Init()\n");
+
+  module = Py_InitModule3("Camera", M_Camera_methods, M_Camera_doc);
+
+  return (module);
+}
 
 /*****************************************************************************/
-/* Function:              Camera_New                                         */
-/* Python equivalent:     Blender.Camera.New                                 */
+/* Python C_Camera methods:                                                  */
 /*****************************************************************************/
-PyObject *Camera_New(PyObject *self, PyObject *args, PyObject *keywords)
+static PyObject *Camera_getName(C_Camera *self)
 {
-  char          *type_str = "persp"; /* "persp" is type 0, "ortho" is type 1 */
-  static char   *kwlist[] = {"type_str", NULL};
-  Camera             * cam;
-  BlenCamera     * blen_camera;
+  PyObject *attr;
+  attr = PyDict_GetItemString(self->dict, "name");
+  if (attr)
+  {
+    Py_INCREF(attr);
+    return attr;
+  }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                   "couldn't get Camera.name attribute"));
+}
 
-  printf ("In Camera_New()\n");
+static PyObject *Camera_getType(C_Camera *self)
+{ 
+  PyObject *attr;
+
+  attr = PyDict_GetItemString(self->dict, "type");
+  if (attr)
+  {
+    Py_INCREF(attr);
+    return attr;
+  }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                   "couldn't get Camera.type attribute"));
+}
 
-  if (!PyArg_ParseTupleAndKeywords(args, keywords, "|s", kwlist, &type_str))
-  /* We expected a string (or nothing) as an argument, but we didn't get one. */
+static PyObject *Camera_getMode(C_Camera *self)
+{
+  PyObject *attr;
+
+  attr = PyDict_GetItemString(self->dict, "mode");
+  if (attr)
+  {
+    Py_INCREF(attr);
+    return attr;
+  }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                   "couldn't get Camera.Mode attribute"));
+}
+
+static PyObject *Camera_getLens(C_Camera *self)
+{
+  PyObject *attr;
+
+  attr = PyDict_GetItemString(self->dict, "lens");
+  if (attr)
+  {
+    Py_INCREF(attr);
+    return attr;
+  }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                   "couldn't get Camera.lens attribute"));
+}
+
+static PyObject *Camera_getClipStart(C_Camera *self)
+{
+  PyObject *attr;
+
+  attr = PyDict_GetItemString(self->dict, "clipStart");
+  if (attr)
+  {
+    Py_INCREF(attr);
+    return attr;
+  }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                   "couldn't get Camera.clipStart attribute"));
+}
+
+static PyObject *Camera_getClipEnd(C_Camera *self)
+{
+  PyObject *attr;
+
+  attr = PyDict_GetItemString(self->dict, "clipEnd");
+  if (attr)
+  {
+    Py_INCREF(attr);
+    return attr;
+  }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                   "couldn't get Camera.clipEnd attribute"));
+}
+
+static PyObject *Camera_getDrawSize(C_Camera *self)
+{
+  PyObject *attr;
+
+  attr = PyDict_GetItemString(self->dict, "drawSize");
+  if (attr)
+  {
+    Py_INCREF(attr);
+    return attr;
+  }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                   "couldn't get Camera.drawSize attribute"));
+}
+
+static PyObject *Camera_rename(C_Camera *self, PyObject *args)
+{
+  char      *name_str;
+  char       buf[21];
+  PyObject  *name;
+
+  if (!PyArg_ParseTuple(args, "s", &name_str))
+  {
     return (PythonReturnErrorObject (PyExc_AttributeError,
-            "expected string (or empty) argument"));
+                                     "expected string argument"));
+  }
+  
+  PyOS_snprintf(buf, sizeof(buf), "%s", name_str);
+  
+  if (self->linked)
+  {
+    /* update the Blender Camera, too */
+    ID *tmp_id = &self->camera->id;
+    rename_id(tmp_id, buf);
+    PyOS_snprintf(buf, sizeof(buf), "%s", tmp_id->name+2);/* may have changed */
+  }
+
+  name = PyString_FromString(buf);
+
+  if (!name)
+  {
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+            "couldn't create PyString Object"));
+  }
 
-  cam = add_camera();
-  cam->id.us = 0; /* new camera: no user yet */
+  if (PyDict_SetItemString(self->dict, "name", name) != 0)
+  {
+    Py_DECREF(name);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                     "couldn't set Camera.name attribute"));
+  }
 
-  if (StringEqual (type_str, "persp"))
-    cam->type = 0;
-  else if (StringEqual (type_str, "ortho"))
-    cam->type = 1;
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+static PyObject *Camera_setType(C_Camera *self, PyObject *args)
+{
+  short value;
+  char *type_str;
+  PyObject *type;
+
+  if (!PyArg_ParseTuple(args, "s", &type_str))
+  {
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+                                     "expected string argument"));
+  }
+
+  if (strcmp (type_str, "persp") == 0)
+    value = EXPP_CAM_TYPE_PERSP;
+  else if (strcmp (type_str, "ortho") == 0)
+    value = EXPP_CAM_TYPE_ORTHO;  
   else
+  {
     return (PythonReturnErrorObject (PyExc_AttributeError,
-            "unknown camera type"));
+                                     "unknown camera type"));
+  }
+
+  type = PyInt_FromLong(value);
+  if (!type)
+  {
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+                                     "couldn't create PyInt Object"));
+  }
+
+  if (PyDict_SetItemString(self->dict, "type", type) != 0)
+  {
+    Py_DECREF(type);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                     "couldn't set Camera.type attribute"));
+  }
 
-  blen_camera = (BlenCamera*)PyObject_NEW(BlenCamera, &camera_type);
-  blen_camera->camera = cam;
+  if (self->linked)
+  {
+    /* update the Blender Camera, too */
+    self->camera->type = value;
+  }
 
-  return ((PyObject*)blen_camera);
+  Py_INCREF(Py_None);
+  return Py_None;
 }
 
-/*****************************************************************************/
-/* Function:              Camera_Get                                         */
-/* Python equivalent:     Blender.Camera.Get                                 */
-/*****************************************************************************/
-PyObject *Camera_Get(PyObject *self, PyObject *args)
+/* This one is 'private'. It is not really a method, just a helper function for
+ * when script writers use Camera.type = t instead of Camera.setType(t), since in
+ * the first case t should be an int and in the second a string. So while the
+ * method setType expects a string ('persp' or 'ortho') or an empty argument,
+ * this function should receive an int (0 or 1). */
+static PyObject *Camera_setIntType(C_Camera *self, PyObject *args)
 {
-  char            * name;
-  struct Camera          * cam_iter;
-  BlenCamera      * blen_camera;
+  short value;
+  PyObject *type;
 
-  printf ("In Camera_Get()\n");
-  if (!PyArg_ParseTuple(args, "s", &name))
+  if (!PyArg_ParseTuple(args, "i", &value))
   {
     return (PythonReturnErrorObject (PyExc_AttributeError,
-            "expected string argument"));
+                                     "expected int argument: 0 or 1"));
   }
 
-  /* Use the name to search for the camera requested. */
-  blen_camera = NULL;
-  cam_iter = G.main->camera.first;
-  while ((cam_iter) && (blen_camera == NULL))
+  if (value == 0 || value == 1)
+  {
+    type = PyInt_FromLong(value);
+  }
+  else
+  {
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+                                     "expected int argument: 0 or 1"));
+  }
+
+  if (!type)
+  {
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+                                     "couldn't create PyInt Object"));
+  }
+
+  if (PyDict_SetItemString(self->dict, "type", type) != 0)
+  {
+    Py_DECREF(type);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                     "could not set Camera.type attribute"));
+  }
+
+  if (self->linked)
+  {
+    /* update the Blender Camera, too */
+    self->camera->type = value;
+  }
+
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+static PyObject *Camera_setMode(C_Camera *self, PyObject *args)
+{
+  char *mode_str1 = NULL, *mode_str2 = NULL;
+  short flag = 0;
+  PyObject *mode;
+
+  if (!PyArg_ParseTuple(args, "|ss", &mode_str1, &mode_str2))
+  {
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected one or two strings as arguments"));
+  } 
+  
+  if (mode_str1 != NULL)
   {
-    if (StringEqual (name, GetIdName (&(cam_iter->id))))
+    if (strcmp(mode_str1, "showLimits") == 0)
+      flag |= EXPP_CAM_MODE_SHOWLIMITS;
+    else if (strcmp(mode_str1, "showMist") == 0)
+      flag |= EXPP_CAM_MODE_SHOWMIST;
+    else
+    {
+      return (PythonReturnErrorObject (PyExc_AttributeError,
+                              "first argument is an unknown camera flag"));
+    }
+
+    if (mode_str2 != NULL)
     {
-      blen_camera = (BlenCamera*)PyObject_NEW(BlenCamera, &camera_type);
-      blen_camera->camera = cam_iter;
+      if (strcmp(mode_str2, "showLimits") == 0)
+        flag |= EXPP_CAM_MODE_SHOWLIMITS;
+      else if (strcmp(mode_str2, "showMist") == 0)
+        flag |= EXPP_CAM_MODE_SHOWMIST;
+      else
+      {
+        return (PythonReturnErrorObject (PyExc_AttributeError,
+                              "second argument is an unknown camera flag"));
+      }
     }
-    cam_iter = cam_iter->id.next;
+  }
+  
+  mode = PyInt_FromLong(flag);
+  if (!mode)
+  {
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+                                     "couldn't create PyInt Object"));
   }
 
-  if (blen_camera == NULL)
+  if (PyDict_SetItemString(self->dict, "mode", mode) != 0)
   {
-    /* No camera exists with the name specified in the argument name. */
-    char error_msg[256];
-    sprintf(error_msg, "camera \"%s\" not found", name);
-    return (PythonReturnErrorObject (PyExc_AttributeError, error_msg));
+    Py_DECREF(mode);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                     "couldn't set Camera.mode attribute"));
   }
 
-  return ((PyObject*)blen_camera);
+  if (self->linked) /* update the Blender Camera, too */
+    self->camera->flag = flag;
+
+  Py_INCREF(Py_None);
+  return Py_None;
 }
 
-/*****************************************************************************/
-/* Function:              initCamera                                         */
-/*****************************************************************************/
-PyObject *initCamera (void)
+/* Another helper function, for the same reason.
+ * (See comment before Camera_setIntType above). */
+static PyObject *Camera_setIntMode(C_Camera *self, PyObject *args)
 {
-  PyObject     * module;
+  short value;
+  PyObject *mode;
+
+  if (!PyArg_ParseTuple(args, "h", &value))
+  {
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+                                     "expected int argument in [0,3]"));
+  }
 
-  printf ("In initCamera()\n");
+  if (value >= 0 && value <= 3)
+  {
+    mode = PyInt_FromLong(value);
+  }
+  else
+  {
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+                                     "expected int argument in [0,3]"));
+  }
 
-  module = Py_InitModule("Camera", Camera_methods);
+  if (!mode)
+  {
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+                                     "couldn't create PyInt object"));
+  }
 
-  return (module);
+  if (PyDict_SetItemString(self->dict, "mode", mode) != 0)
+  {
+    Py_DECREF(mode);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                     "could not set Camera.mode attribute"));
+  }
+
+  if (self->linked)
+  {
+    /* update the Blender Camera, too */
+    self->camera->flag = value;
+  }
+
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+static PyObject *Camera_setLens(C_Camera *self, PyObject *args)
+{
+  float value;
+  PyObject *lens;
+  
+  if (!PyArg_ParseTuple(args, "f", &value))
+  {
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+                                     "expected float argument"));
+  }
+  
+  value = EXPP_ClampFloat (value, EXPP_CAM_LENS_MIN, EXPP_CAM_LENS_MAX);
+  lens = PyFloat_FromDouble(value);
+  if (!lens)
+  {
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+                                     "couldn't create PyFloat Object"));
+  }
+
+  if (PyDict_SetItemString(self->dict, "lens", lens) != 0)
+  {
+    Py_DECREF(lens);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                     "couldn't set Camera.lens attribute"));
+  }
+  
+  if (self->linked)
+  {
+    /* update the Blender Camera, too */
+    self->camera->lens = value;
+  }
+
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+static PyObject *Camera_setClipStart(C_Camera *self, PyObject *args)
+{
+  float value;
+  PyObject *clipStart;
+  
+  if (!PyArg_ParseTuple(args, "f", &value))
+  {
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+                                     "expected a float number as argument"));
+  }
+  
+  value = EXPP_ClampFloat (value, EXPP_CAM_CLIPSTART_MIN,
+                           EXPP_CAM_CLIPSTART_MAX);
+  
+  clipStart = PyFloat_FromDouble(value);
+  if (!clipStart)
+  {
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+                                     "couldn't create PyFloat Object"));
+  }
+
+  if (PyDict_SetItemString(self->dict, "clipStart", clipStart) != 0)
+  {
+    Py_DECREF(clipStart);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                  "couldn't set Camera.clipStart attribute"));
+  }
+  
+  if (self->linked)
+  {
+    /* update the Blender Camera, too */
+    self->camera->clipsta = value;
+  }
+
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+static PyObject *Camera_setClipEnd(C_Camera *self, PyObject *args)
+{
+  float value;
+  PyObject *clipEnd;
+  
+  if (!PyArg_ParseTuple(args, "f", &value))
+  {
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+                                     "expected a float number as argument"));
+  }
+
+  value = EXPP_ClampFloat (value, EXPP_CAM_CLIPEND_MIN, EXPP_CAM_CLIPEND_MAX);
+
+  clipEnd = PyFloat_FromDouble(value);
+  if (!clipEnd)
+  {
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+                                     "couldn't create PyFloat Object"));
+  }
+
+  if (PyDict_SetItemString(self->dict, "clipEnd", clipEnd) != 0)
+  {
+    Py_DECREF(clipEnd);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                    "couldn't set Camera.clipEnd attribute"));
+  }
+  
+  if (self->linked)
+  {
+    /* update the Blender Camera, too */
+    self->camera->clipend = value;
+  }
+
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+static PyObject *Camera_setDrawSize(C_Camera *self, PyObject *args)
+{
+  float value;
+  PyObject *drawSize;
+  
+  if (!PyArg_ParseTuple(args, "f", &value))
+  {
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+                                     "expected a float number as argument"));
+  }
+
+  value = EXPP_ClampFloat (value, EXPP_CAM_DRAWSIZE_MIN,
+                           EXPP_CAM_DRAWSIZE_MAX);
+
+  drawSize = PyFloat_FromDouble(value);
+  if (!drawSize)
+  {
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+                                     "couldn't create PyFloat Object"));
+  }
+
+  if (PyDict_SetItemString(self->dict, "drawSize", drawSize) != 0)
+  {
+    Py_DECREF(drawSize);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                   "couldn't set Camera.drawSize attribute"));
+  }
+  
+  if (self->linked)
+  {
+    /* update the Blender Camera, too */
+    self->camera->drawsize = value;
+  }
+
+  Py_INCREF(Py_None);
+  return Py_None;
 }
 
 /*****************************************************************************/
 /* Function:    CameraCreatePyObject                                         */
-/* Description: This function will create a new BlenCamera from an existing  */
-/*              Camera structure.                                            */
+/* Description: This function will create a new C_Camera.  If the Camera     */
+/*              struct passed to it is not NULL, it'll use its attributes.   */
 /*****************************************************************************/
-PyObject* CameraCreatePyObject (struct Camera *cam)
+PyObject *CameraCreatePyObject (Camera *blenderCam)
 {
-  BlenCamera      * blen_camera;
+  PyObject *name, *type, *mode;
+  PyObject *lens, *clipStart, *clipEnd, *drawSize; 
+  PyObject *Types, *persp, *ortho;
+  PyObject *Modes, *showLimits, *showMist;
+  C_Camera *cam;
 
   printf ("In CameraCreatePyObject\n");
 
-  blen_camera = (BlenCamera*)PyObject_NEW(BlenCamera, &camera_type);
+  cam = (C_Camera *)PyObject_NEW(C_Camera, &Camera_Type);
+  
+  if (cam == NULL)
+  {
+    return NULL;
+  }
+
+  cam->dict = PyDict_New();
+
+  if (cam->dict == NULL)
+  {
+    Py_DECREF((PyObject *)cam);
+    return NULL;
+  }
+
+  if (blenderCam == NULL)
+  {
+    /* Not linked to a Camera Object yet */
+    name = PyString_FromString("Data");
+    type = PyInt_FromLong(EXPP_CAM_TYPE);
+    mode = PyInt_FromLong(EXPP_CAM_MODE);
+    lens = PyFloat_FromDouble(EXPP_CAM_LENS);
+    clipStart = PyFloat_FromDouble(EXPP_CAM_CLIPSTART);
+    clipEnd = PyFloat_FromDouble(EXPP_CAM_CLIPEND);
+    drawSize = PyFloat_FromDouble(EXPP_CAM_DRAWSIZE);
+  }
+  else
+  {
+    /* Camera Object available, get its attributes directly */
+    name = PyString_FromString(blenderCam->id.name+2);
+    type = PyInt_FromLong(blenderCam->type);
+    mode = PyInt_FromLong(blenderCam->flag);
+    lens = PyFloat_FromDouble(blenderCam->lens);
+    clipStart = PyFloat_FromDouble(blenderCam->clipsta);
+    clipEnd = PyFloat_FromDouble(blenderCam->clipend);
+    drawSize = PyFloat_FromDouble(blenderCam->drawsize);
+  }
+
+  Types = constant_New();
+  persp = PyInt_FromLong(EXPP_CAM_TYPE_PERSP);
+  ortho = PyInt_FromLong(EXPP_CAM_TYPE_ORTHO);
+  
+  Modes = constant_New();
+  showLimits = PyInt_FromLong(EXPP_CAM_MODE_SHOWLIMITS);
+  showMist = PyInt_FromLong(EXPP_CAM_MODE_SHOWMIST);
+
+  if (name == NULL || type == NULL || mode == NULL|| lens == NULL ||
+      clipStart == NULL || clipEnd == NULL || drawSize == NULL ||
+      Types == NULL || persp == NULL || ortho == NULL ||
+      Modes == NULL || showLimits == NULL || showMist == NULL)
+  {
+    /* Some object creation has gone wrong. Clean up. */
+    goto fail;
+  }
+
+  if ((PyDict_SetItemString(cam->dict, "name", name) != 0) ||
+      (PyDict_SetItemString(cam->dict, "type", type) != 0) ||
+      (PyDict_SetItemString(cam->dict, "mode", mode) != 0) ||
+      (PyDict_SetItemString(cam->dict, "lens", lens) != 0) ||
+      (PyDict_SetItemString(cam->dict, "clipStart", clipStart) != 0) ||
+      (PyDict_SetItemString(cam->dict, "clipEnd", clipEnd) != 0) ||
+      (PyDict_SetItemString(cam->dict, "drawSize", drawSize) != 0) ||
+      (PyDict_SetItemString(cam->dict, "Types", Types) != 0) ||
+      (PyDict_SetItemString(cam->dict, "Modes", Modes) != 0) ||
+      (PyDict_SetItemString(cam->dict, "__members__",
+                            PyDict_Keys(cam->dict)) != 0))
+  {
+    /* One or more value setting actions has gone wwrong. Clean up. */
+    goto fail;
+  }
+
+  if ((PyDict_SetItemString(((C_constant *)Types)->dict,
+                            "persp", persp) != 0) ||
+      (PyDict_SetItemString(((C_constant *)Types)->dict,
+                            "ortho", ortho) != 0) ||
+      (PyDict_SetItemString(((C_constant *)Modes)->dict,
+                            "showLimits", showLimits) != 0) ||
+      (PyDict_SetItemString(((C_constant *)Modes)->dict,
+                             "showMist", showMist) != 0))
+  {
+    /* One or more value setting actions has gone wwrong. Clean up. */
+    goto fail;
+  }
 
-  blen_camera->camera = cam;
-  return ((PyObject*)blen_camera);
+  cam->camera = blenderCam; /* it's NULL when creating only camera "data" */
+  return ((PyObject*)cam);
+
+fail:
+  Py_XDECREF(name);
+  Py_XDECREF(type);
+  Py_XDECREF(mode);
+  Py_XDECREF(lens);
+  Py_XDECREF(clipStart);
+  Py_XDECREF(clipEnd);
+  Py_XDECREF(drawSize);
+  Py_XDECREF(Types);
+  Py_XDECREF(persp);
+  Py_XDECREF(ortho);
+  Py_XDECREF(Modes);
+  Py_XDECREF(showLimits);
+  Py_XDECREF(showMist);
+  Py_DECREF(cam->dict);
+  Py_DECREF((PyObject *)cam);
+  return NULL;
 }
 
 /*****************************************************************************/
 /* Function:    CameraDeAlloc                                                */
-/* Description: This is a callback function for the BlenCamera type. It is   */
+/* Description: This is a callback function for the C_Camera type. It is     */
 /*              the destructor function.                                     */
 /*****************************************************************************/
-void CameraDeAlloc (BlenCamera *cam)
+static void CameraDeAlloc (C_Camera *self)
 {
-  PyObject_DEL (cam);
+  Py_DECREF(self->dict);
+  PyObject_DEL (self);
 }
 
 /*****************************************************************************/
 /* Function:    CameraGetAttr                                                */
-/* Description: This is a callback function for the BlenCamera type. It is   */
-/*              the function that retrieves any value from Blender and       */
-/*              passes it to Python.                                         */
+/* Description: This is a callback function for the C_Camera type. It is     */
+/*              the function that accesses C_Camera member variables and     */
+/*              methods.                                                     */
 /*****************************************************************************/
-PyObject* CameraGetAttr (BlenCamera *cam, char *name)
+static PyObject* CameraGetAttr (C_Camera *cam, char *name)
 {
-  struct Camera   * camera;
-
-  camera = cam->camera;
-  if (StringEqual (name, "lens"))
-    return (PyFloat_FromDouble(camera->lens));
-  if (StringEqual (name, "clipStart"))
-    return (PyFloat_FromDouble(camera->clipsta));
-  if (StringEqual (name, "clipEnd"))
-    return (PyFloat_FromDouble(camera->clipend));
-  if (StringEqual (name, "type"))
-    return (PyInt_FromLong(camera->type));
-  if (StringEqual (name, "mode"))
-    return (PyInt_FromLong(camera->flag));
-
-  printf ("Unknown variable.\n");
-  Py_INCREF (Py_None); 
-  return (Py_None);
+  /* first try the attributes dictionary */
+  if (cam->dict)
+  {
+    PyObject *v = PyDict_GetItemString(cam->dict, name);
+    if (v)
+    {
+      Py_INCREF(v); /* was a borrowed ref */
+      return v;
+    }
+  }
+
+  /* not an attribute, search the methods table */
+  return Py_FindMethod(C_Camera_methods, (PyObject *)cam, name);
 }
 
 /*****************************************************************************/
 /* Function:    CameraSetAttr                                                */
-/* Description: This is a callback function for the BlenCamera type. It is   */
-/*              the function that retrieves any value from Python and sets   */
-/*              it accordingly in Blender.                                   */
+/* Description: This is a callback function for the C_Camera type. It is the */
+/*              function that changes Camera Data members values. If this    */
+/*              data is linked to a Blender Camera, it also gets updated.    */
 /*****************************************************************************/
-int CameraSetAttr (BlenCamera *cam, char *name, PyObject *value)
+static int CameraSetAttr (C_Camera *self, char *name, PyObject *value)
 {
-  struct Camera        * camera;
-
-  camera = cam->camera;
-  if (StringEqual (name, "lens"))
-    return (!PyArg_Parse (value, "f", &(camera->lens)));
-  if (StringEqual (name, "clipStart"))
-    return (!PyArg_Parse (value, "f", &(camera->clipsta)));
-  if (StringEqual (name, "clipEnd"))
-    return (!PyArg_Parse (value, "f", &(camera->clipend)));
-  if (StringEqual (name, "type"))
-    return (!PyArg_Parse (value, "i", &(camera->type)));
-  if (StringEqual (name, "mode"))
-    return (!PyArg_Parse (value, "i", &(camera->flag)));
-
-  printf ("Unknown variable.\n");
-  return (0);
+  PyObject *valtuple; 
+  PyObject *error = NULL;
+
+  if (self->dict == NULL)
+  {
+    return -1;
+  }
+
+/* We're playing a trick on the Python API users here.  Even if they use
+ * Camera.member = val instead of Camera.setMember(value), we end up using the
+ * function anyway, since it already has error checking, clamps to the right
+ * interval and updates the Blender Camera structure when necessary. */
+
+  valtuple = PyTuple_New(1); /* the set* functions expect a tuple */
+
+  if (!valtuple)
+  {
+    return EXPP_intError(PyExc_MemoryError,
+                         "CameraSetAttr: couldn't create PyTuple");
+  }
+
+  if (PyTuple_SetItem(valtuple, 0, value) != 0)
+  {
+    Py_DECREF(value); /* PyTuple_SetItem incref's value even when it fails */
+    Py_DECREF(valtuple);
+    return EXPP_intError(PyExc_RuntimeError,
+                        "CameraSetAttr: couldn't fill tuple");
+  }
+
+  if (strcmp (name, "name") == 0)
+    error = Camera_rename (self, valtuple);
+  else if (strcmp (name, "type") == 0)
+    error = Camera_setIntType (self, valtuple); /* special case */
+  else if (strcmp (name, "mode") == 0)
+    error = Camera_setIntMode (self, valtuple); /* special case */
+  else if (strcmp (name, "lens") == 0)
+    error = Camera_setLens (self, valtuple);
+  else if (strcmp (name, "clipStart") == 0)
+    error = Camera_setClipStart (self, valtuple);
+  else if (strcmp (name, "clipEnd") == 0)
+    error = Camera_setClipEnd (self, valtuple);
+  else if (strcmp (name, "drawSize") == 0)
+    error = Camera_setDrawSize (self, valtuple);
+  else
+  {
+    /* Error: no such member in the Camera Data structure */
+    Py_DECREF(value);
+    Py_DECREF(valtuple);
+    return (EXPP_intError (PyExc_KeyError,
+                           "attribute not found"));
+  }
+
+  if (error == Py_None)
+  {
+    return 0; /* normal exit */
+  }
+
+  Py_DECREF(value);
+  Py_DECREF(valtuple);
+
+  return -1;
 }
+
+/*****************************************************************************/
+/* Function:    CameraPrint                                                  */
+/* Description: This is a callback function for the C_Camera type. It        */
+/*              builds a meaninful string to 'print' camera objects.         */
+/*****************************************************************************/
+static int CameraPrint(C_Camera *self, FILE *fp, int flags)
+{ 
+  char *lstate = "unlinked";
+  char *name;
+
+  if (self->linked)
+  {
+    lstate = "linked";
+  }
+
+  name = PyString_AsString(Camera_getName(self));
+
+  fprintf(fp, "[Camera \"%s\" (%s)]", name, lstate);
+
+  return 0;
+}
+
 /*****************************************************************************/
 /* Function:    CameraRepr                                                   */
-/* Description: This is a callback function for the BlenCamera type. It      */
+/* Description: This is a callback function for the C_Camera type. It        */
 /*              builds a meaninful string to represent camera objects.       */
 /*****************************************************************************/
-PyObject* CameraRepr (BlenCamera *self)
+static PyObject *CameraRepr (C_Camera *self)
 {
-  static char s[256];
-  sprintf (s, "[Camera \"%s\"]", self->camera->id.name+2);
-  return Py_BuildValue("s", s);
+  char buf[64];
+  char *lstate = "unlinked";
+  char *name;
+
+  if (self->linked)
+  {
+    lstate = "linked";
+  }
+
+  name = PyString_AsString(Camera_getName(self));
+
+  PyOS_snprintf(buf, sizeof(buf), "[Camera \"%s\" (%s)]", name, lstate);
+
+  return PyString_FromString(buf);
 }
diff --git a/source/blender/python/api2_2x/Camera.h b/source/blender/python/api2_2x/Camera.h
new file mode 100644 (file)
index 0000000..4f8d1a3
--- /dev/null
@@ -0,0 +1,228 @@
+/* 
+ *
+ * ***** 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_CAMERA_H
+#define EXPP_CAMERA_H
+
+#include <Python.h>
+#include <stdio.h>
+
+#include <BKE_main.h>
+#include <BKE_global.h>
+#include <BKE_object.h>
+#include <BKE_library.h>
+#include <DNA_camera_types.h>
+
+#include "constant.h"
+#include "gen_utils.h"
+#include "modules.h"
+
+/*****************************************************************************/
+/* Python C_Camera defaults:                                                 */
+/*****************************************************************************/
+/* Camera types */
+
+#define EXPP_CAM_TYPE_PERSP 0
+#define EXPP_CAM_TYPE_ORTHO 1
+
+/* Camera mode flags */
+
+#define EXPP_CAM_MODE_SHOWLIMITS 1
+#define EXPP_CAM_MODE_SHOWMIST   2
+
+/* Camera default and MIN, MAX values */
+
+#define EXPP_CAM_TYPE           EXPP_CAM_TYPE_PERSP
+#define EXPP_CAM_MODE           0
+#define EXPP_CAM_LENS           35.0
+#define EXPP_CAM_LENS_MIN       1.0
+#define EXPP_CAM_LENS_MAX       250.0
+#define EXPP_CAM_CLIPSTART      0.10
+#define EXPP_CAM_CLIPSTART_MIN  0.00
+#define EXPP_CAM_CLIPSTART_MAX  100.00
+#define EXPP_CAM_CLIPEND        100.0
+#define EXPP_CAM_CLIPEND_MIN    1.0
+#define EXPP_CAM_CLIPEND_MAX    5000.0
+#define EXPP_CAM_DRAWSIZE       0.5
+#define EXPP_CAM_DRAWSIZE_MIN   0.1
+#define EXPP_CAM_DRAWSIZE_MAX   10.0
+
+/*****************************************************************************/
+/* Python API function prototypes for the Camera module.                     */
+/*****************************************************************************/
+static PyObject *M_Camera_New (PyObject *self, PyObject *args,
+                               PyObject *keywords);
+static PyObject *M_Camera_Get (PyObject *self, PyObject *args);
+
+/*****************************************************************************/
+/* The following string definitions are used for documentation strings.      */
+/* In Python these will be written to the console when doing a               */
+/* Blender.Camera.__doc__                                                    */
+/*****************************************************************************/
+char M_Camera_doc[] =
+"The Blender Camera module\n\n\
+This module provides access to **Camera Data** objects in Blender\n\n\
+Example::\n\n\
+  from Blender import Camera, Object, Scene\n\
+  c = Camera.New('ortho')      # create new ortho camera data\n\
+  c.lens = 35.0                # set lens value\n\
+  cur = Scene.getCurrent()     # get current Scene\n\
+  ob = Object.New('Camera')    # make camera object\n\
+  ob.link(c)                   # link camera data with this object\n\
+  cur.link(ob)                 # link object into scene\n\
+  cur.setCurrentCamera(ob)     # make this camera the active\n";
+
+char M_Camera_New_doc[] =
+"(type) - return a new Camera object of type \"type\", \
+which can be 'persp' or 'ortho'.\n\
+() - return a new Camera object of type 'persp'.";
+
+char M_Camera_Get_doc[] =
+"(name) - return the camera with the name 'name', \
+returns None if not found.\n If 'name' is not specified, \
+it returns a list of all cameras in the\ncurrent scene.";
+
+/*****************************************************************************/
+/* Python method structure definition for Blender.Camera module:             */
+/*****************************************************************************/
+struct PyMethodDef M_Camera_methods[] = {
+  {"New",(PyCFunction)M_Camera_New, METH_VARARGS|METH_KEYWORDS,
+          M_Camera_New_doc},
+  {"Get",         M_Camera_Get,         METH_VARARGS, M_Camera_Get_doc},
+  {"get",         M_Camera_Get,         METH_VARARGS, M_Camera_Get_doc},
+  {NULL, NULL, 0, NULL}
+};
+
+/*****************************************************************************/
+/* Python C_Camera structure definition:                                     */
+/*****************************************************************************/
+typedef struct {
+  PyObject_HEAD
+  PyObject *dict;
+  Camera   *camera;
+  int      linked;
+} C_Camera;
+
+/*****************************************************************************/
+/* Python C_Camera methods declarations:                                     */
+/*****************************************************************************/
+static PyObject *Camera_getName(C_Camera *self);
+static PyObject *Camera_getType(C_Camera *self);
+static PyObject *Camera_getMode(C_Camera *self);
+static PyObject *Camera_getLens(C_Camera *self);
+static PyObject *Camera_getClipStart(C_Camera *self);
+static PyObject *Camera_getClipEnd(C_Camera *self);
+static PyObject *Camera_getDrawSize(C_Camera *self);
+static PyObject *Camera_rename(C_Camera *self, PyObject *args);
+static PyObject *Camera_setType(C_Camera *self, PyObject *args);
+static PyObject *Camera_setIntType(C_Camera *self, PyObject *args);
+static PyObject *Camera_setMode(C_Camera *self, PyObject *args);
+static PyObject *Camera_setIntMode(C_Camera *self, PyObject *args);
+static PyObject *Camera_setLens(C_Camera *self, PyObject *args);
+static PyObject *Camera_setClipStart(C_Camera *self, PyObject *args);
+static PyObject *Camera_setClipEnd(C_Camera *self, PyObject *args);
+static PyObject *Camera_setDrawSize(C_Camera *self, PyObject *args);
+
+/*****************************************************************************/
+/* Python C_Camera methods table:                                            */
+/*****************************************************************************/
+static PyMethodDef C_Camera_methods[] = {
+ /* name, method, flags, doc */
+  {"getName", (PyCFunction)Camera_getName, METH_NOARGS,
+      "() - Return Camera Data name"},
+  {"getType", (PyCFunction)Camera_getType, METH_NOARGS,
+      "() - Return Camera type - 'persp':0, 'ortho':1"},
+  {"getMode", (PyCFunction)Camera_getMode, METH_NOARGS,
+      "() - Return Camera mode flags (or'ed value) -\n\t\
+'showLimits':1, 'showMist':2"},
+  {"getLens", (PyCFunction)Camera_getLens, METH_NOARGS,
+      "() - Return Camera lens value"},
+  {"getClipStart", (PyCFunction)Camera_getClipStart, METH_NOARGS,
+      "() - Return Camera clip start value"},
+  {"getClipEnd", (PyCFunction)Camera_getClipEnd, METH_NOARGS,
+      "() - Return Camera clip end value"},
+  {"getDrawSize", (PyCFunction)Camera_getDrawSize, METH_NOARGS,
+      "() - Return Camera draw size value"},
+  {"rename", (PyCFunction)Camera_rename, METH_VARARGS,
+      "(str) - Change Camera Data name"},
+  {"setType", (PyCFunction)Camera_setType, METH_VARARGS,
+      "(str) - Change Camera type, which can be 'persp' or 'ortho'"},
+  {"setMode", (PyCFunction)Camera_setMode, METH_VARARGS,
+      "([str[,str]]) - Set Camera mode flag(s): 'showLimits' and 'showMist'"},
+  {"setLens", (PyCFunction)Camera_setLens, METH_VARARGS,
+      "(float) - Change Camera lens value"},
+  {"setClipStart", (PyCFunction)Camera_setClipStart, METH_VARARGS,
+      "(float) - Change Camera clip start value"},
+  {"setClipEnd", (PyCFunction)Camera_setClipEnd, METH_VARARGS,
+      "(float) - Change Camera clip end value"},
+  {"setDrawSize", (PyCFunction)Camera_setDrawSize, METH_VARARGS,
+      "(float) - Change Camera draw size value"},
+  {0}
+};
+
+/*****************************************************************************/
+/* Python Camera_Type callback function prototypes:                          */
+/*****************************************************************************/
+static void CameraDeAlloc (C_Camera *cam);
+static int CameraPrint (C_Camera *cam, FILE *fp, int flags);
+static int CameraSetAttr (C_Camera *cam, char *name, PyObject *v);
+static PyObject *CameraGetAttr (C_Camera *cam, char *name);
+static PyObject *CameraRepr (C_Camera *cam);
+
+/*****************************************************************************/
+/* Python Camera_Type structure definition:                                  */
+/*****************************************************************************/
+static PyTypeObject Camera_Type =
+{
+  PyObject_HEAD_INIT(&PyType_Type)
+  0,                                      /* ob_size */
+  "Camera",                               /* tp_name */
+  sizeof (C_Camera),                      /* tp_basicsize */
+  0,                                      /* tp_itemsize */
+  /* methods */
+  (destructor)CameraDeAlloc,              /* tp_dealloc */
+  (printfunc)CameraPrint,                 /* tp_print */
+  (getattrfunc)CameraGetAttr,             /* tp_getattr */
+  (setattrfunc)CameraSetAttr,             /* tp_setattr */
+  0,                                      /* tp_compare */
+  (reprfunc)CameraRepr,                   /* tp_repr */
+  0,                                      /* tp_as_number */
+  0,                                      /* tp_as_sequence */
+  0,                                      /* tp_as_mapping */
+  0,                                      /* tp_as_hash */
+  0,0,0,0,0,0,
+  0,                                      /* tp_doc */ 
+  0,0,0,0,0,0,
+  C_Camera_methods,                       /* tp_methods */
+  0,                                      /* tp_members */
+};
+
+#endif /* EXPP_CAMERA_H */
diff --git a/source/blender/python/api2_2x/Image.c b/source/blender/python/api2_2x/Image.c
new file mode 100644 (file)
index 0000000..4d8ae74
--- /dev/null
@@ -0,0 +1,425 @@
+/* 
+ *
+ * ***** 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 "Image.h"
+
+/*****************************************************************************/
+/* Function:              M_Image_New                                       */
+/* Python equivalent:     Blender.Image.New                                 */
+/*****************************************************************************/
+static PyObject *M_Image_New(PyObject *self, PyObject *args, PyObject *keywords)
+{
+  printf ("In Image_New() - unimplemented in 2.25\n");
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+/*****************************************************************************/
+/* Function:              M_Image_Get                                       */
+/* Python equivalent:     Blender.Image.Get                                 */
+/*****************************************************************************/
+static PyObject *M_Image_Get(PyObject *self, PyObject *args)
+{
+  char     *name;
+  Image   *img_iter;
+       C_Image *wanted_img;
+
+  printf ("In Image_Get()\n");
+  if (!PyArg_ParseTuple(args, "s", &name))
+  {
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected string argument"));
+  }
+
+  /* Use the name to search for the image requested. */
+  wanted_img = NULL;
+  img_iter = G.main->image.first;
+
+  while ((img_iter) && (wanted_img == NULL)) {
+
+         if (strcmp (name, GetIdName (&(img_iter->id))) == 0)
+      wanted_img = (C_Image *)ImageCreatePyObject(img_iter);
+
+               img_iter = img_iter->id.next;
+  }
+
+  if (wanted_img == NULL) {
+  /* No image exists with the name specified in the argument name. */
+    char error_msg[64];
+    PyOS_snprintf(error_msg, sizeof(error_msg),
+                    "Image \"%s\" not found", name);
+    return (PythonReturnErrorObject (PyExc_NameError, error_msg));
+  }
+
+  return ((PyObject*)wanted_img);
+}
+
+static PyObject *M_Image_Load(PyObject *self, PyObject *args)
+{
+       char *fname;
+       Image *img_ptr;
+       C_Image *img;
+
+  printf ("In Image_Load()\n");
+       
+  if (!PyArg_ParseTuple(args, "s", &fname))
+  {
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected string argument"));
+  }
+       
+       img_ptr = add_image(fname);
+       if (!img_ptr)
+               return (PythonReturnErrorObject (PyExc_IOError,
+                                               "couldn't load image"));
+
+       img = (C_Image *)ImageCreatePyObject(img_ptr);
+
+       return (PyObject *)img;
+}
+
+/*****************************************************************************/
+/* Function:              M_Image_Init                                      */
+/*****************************************************************************/
+PyObject *M_Image_Init (void)
+{
+  PyObject  *module;
+
+  printf ("In M_Image_Init()\n");
+
+  module = Py_InitModule3("Image", M_Image_methods, M_Image_doc);
+
+  return (module);
+}
+
+/*****************************************************************************/
+/* Python C_Image methods:                                                  */
+/*****************************************************************************/
+static PyObject *Image_getName(C_Image *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "name");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+       return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                       "couldn't get Image.name attribute"));
+}
+
+static PyObject *Image_getFilename(C_Image *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "filename");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+       return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                       "couldn't get Image.filename attribute"));
+}
+
+static PyObject *Image_rename(C_Image *self, PyObject *args)
+{
+       char *name_str;
+       char buf[21];
+       ID *tmp_id;
+       PyObject *name;
+
+       if (!PyArg_ParseTuple(args, "s", &name_str))
+               return (PythonReturnErrorObject (PyExc_AttributeError,
+                                               "expected string argument"));
+       
+       PyOS_snprintf(buf, sizeof(buf), "%s", name_str);
+       
+       /* update the Blender Image, too */
+       tmp_id = &self->image->id;
+       rename_id(tmp_id, buf);
+       PyOS_snprintf(buf, sizeof(buf), "%s", tmp_id->name+2);/* may have changed */
+
+       name = PyString_FromString(buf);
+
+       if (!name)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyString Object"));
+
+       if (PyDict_SetItemString(self->dict, "name", name) != 0) {
+               Py_DECREF(name);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+            "couldn't set Image.name attribute"));
+       }
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Image_setXRep(C_Image *self, PyObject *args)
+{
+       short value;
+       PyObject *rep;
+
+       if (!PyArg_ParseTuple(args, "h", &value))
+               return (PythonReturnErrorObject (PyExc_AttributeError,
+                                               "expected int argument in [1,16]"));
+
+       if (value >= EXPP_IMAGE_REP_MIN || value <= EXPP_IMAGE_REP_MAX)
+               rep = PyInt_FromLong(value);
+       else
+               return (PythonReturnErrorObject (PyExc_AttributeError,
+                                               "expected int argument in [1,16]"));
+
+       if (!rep)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyInt Object"));
+
+       if (PyDict_SetItemString(self->dict, "xrep", rep) != 0) {
+               Py_DECREF(rep);
+               return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                               "could not set Image.xrep attribute"));
+       }
+
+       /* update the Blender Image, too */
+  self->image->xrep = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Image_setYRep(C_Image *self, PyObject *args)
+{
+       short value;
+       PyObject *rep;
+
+       if (!PyArg_ParseTuple(args, "h", &value))
+               return (PythonReturnErrorObject (PyExc_AttributeError,
+                                               "expected int argument in [1,16]"));
+
+       if (value >= EXPP_IMAGE_REP_MIN || value <= EXPP_IMAGE_REP_MAX)
+               rep = PyInt_FromLong(value);
+       else
+               return (PythonReturnErrorObject (PyExc_AttributeError,
+                                               "expected int argument in [1,16]"));
+
+       if (!rep)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyInt Object"));
+
+       if (PyDict_SetItemString(self->dict, "yrep", rep) != 0) {
+               Py_DECREF(rep);
+               return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                               "could not set Image.yrep attribute"));
+       }
+
+       /* update the Blender Image, too */
+  self->image->yrep = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+/*****************************************************************************/
+/* Function:    ImageCreatePyObject                                         */
+/* Description: This function will create a new C_Image.  If the Image     */
+/*              struct passed to it is not NULL, it'll use its attributes.   */
+/*****************************************************************************/
+PyObject *ImageCreatePyObject (Image *blenderImage)
+{
+       PyObject *name, *filename, *xrep, *yrep;
+  C_Image  *img;
+
+  printf ("In ImageCreatePyObject\n");
+
+       img = (C_Image *)PyObject_NEW(C_Image, &Image_Type);
+       
+       if (img == NULL)
+               return NULL;
+
+       img->dict = PyDict_New();
+
+       if (img->dict == NULL) {
+               Py_DECREF((PyObject *)img);
+               return NULL;
+       }
+            /*branch currently unused*/
+       if (blenderImage == NULL) { /* Not linked to an Image Object yet */
+               name = PyString_FromString("DATA");
+               filename = PyString_FromString("");
+               xrep = PyInt_FromLong(EXPP_IMAGE_REP); /* rep default is 1, of course */
+               yrep = PyInt_FromLong(EXPP_IMAGE_REP);
+       }
+       else { /* Image Object available, get its attributes directly */
+               name = PyString_FromString(blenderImage->id.name+2);
+               filename = PyString_FromString(blenderImage->name);
+               xrep = PyInt_FromLong(blenderImage->xrep);
+               yrep = PyInt_FromLong(blenderImage->yrep);
+       }
+
+       if (name == NULL || filename == NULL ||
+                       xrep == NULL || yrep == NULL)
+               goto fail;
+
+       if ((PyDict_SetItemString(img->dict, "name", name) != 0) ||
+           (PyDict_SetItemString(img->dict, "filename", filename) != 0) ||
+           (PyDict_SetItemString(img->dict, "xrep", xrep) != 0) ||
+           (PyDict_SetItemString(img->dict, "yrep", yrep) != 0) ||
+                       (PyDict_SetItemString(img->dict, "__members__",
+                                                                                                               PyDict_Keys(img->dict)) != 0))
+               goto fail;
+
+  img->image = blenderImage; /* it's NULL when creating only image "data" */
+  return ((PyObject*)img);
+
+fail:
+       Py_XDECREF(name);
+       Py_XDECREF(filename);
+       Py_XDECREF(xrep);
+       Py_XDECREF(yrep);
+  Py_DECREF(img->dict);
+       Py_DECREF((PyObject *)img);
+       return NULL;
+}
+
+/*****************************************************************************/
+/* Function:    ImageDeAlloc                                                */
+/* Description: This is a callback function for the C_Image type. It is     */
+/*              the destructor function.                                     */
+/*****************************************************************************/
+static void ImageDeAlloc (C_Image *self)
+{
+       Py_DECREF(self->dict);
+  PyObject_DEL (self);
+}
+
+/*****************************************************************************/
+/* Function:    ImageGetAttr                                                */
+/* Description: This is a callback function for the C_Image type. It is     */
+/*              the function that accesses C_Image member variables and     */
+/*              methods.                                                     */
+/*****************************************************************************/
+static PyObject* ImageGetAttr (C_Image *img, char *name)
+{/* first try the attributes dictionary */
+       if (img->dict) {
+               PyObject *v = PyDict_GetItemString(img->dict, name);
+               if (v) {
+                       Py_INCREF(v); /* was a borrowed ref */
+                       return v;
+               }
+       }
+
+/* not an attribute, search the methods table */
+       return Py_FindMethod(C_Image_methods, (PyObject *)img, name);
+}
+
+/*****************************************************************************/
+/* Function:    ImageSetAttr                                                */
+/* Description: This is a callback function for the C_Image type. It is the */
+/*              function that changes Image Data members values. If this    */
+/*              data is linked to a Blender Image, it also gets updated.    */
+/*****************************************************************************/
+static int ImageSetAttr (C_Image *self, char *name, PyObject *value)
+{
+       PyObject *valtuple; 
+       PyObject *error = NULL;
+
+       if (self->dict == NULL) return -1;
+
+/* We're playing a trick on the Python API users here.  Even if they use
+ * Image.member = val instead of Image.setMember(value), we end up using the
+ * function anyway, since it already has error checking, clamps to the right
+ * interval and updates the Blender Image structure when necessary. */
+
+       valtuple = PyTuple_New(1); /* the set* functions expect a tuple */
+
+       if (!valtuple)
+               return EXPP_intError(PyExc_MemoryError,
+                                                                       "ImageSetAttr: couldn't create PyTuple");
+
+       if (PyTuple_SetItem(valtuple, 0, value) != 0) {
+               Py_DECREF(value); /* PyTuple_SetItem incref's value even when it fails */
+               Py_DECREF(valtuple);
+               return EXPP_intError(PyExc_RuntimeError,
+                                                                        "ImageSetAttr: couldn't fill tuple");
+       }
+
+       if (strcmp (name, "name") == 0)
+    error = Image_rename (self, valtuple);
+       else if (strcmp (name, "xrep") == 0)
+               error = Image_setXRep (self, valtuple);
+       else if (strcmp (name, "yrep") == 0)
+               error = Image_setYRep (self, valtuple);
+       else { /* Error: no such member in the Image Data structure */
+               Py_DECREF(value);
+               Py_DECREF(valtuple);
+       return (EXPP_intError (PyExc_KeyError,
+             "attribute not found or immutable"));
+       }
+
+       if (error == Py_None) return 0; /* normal exit */
+
+       Py_DECREF(value);
+       Py_DECREF(valtuple);
+
+       return -1;
+}
+
+/*****************************************************************************/
+/* Function:    ImagePrint                                                  */
+/* Description: This is a callback function for the C_Image type. It        */
+/*              builds a meaninful string to 'print' image objects.         */
+/*****************************************************************************/
+static int ImagePrint(C_Image *self, FILE *fp, int flags)
+{ 
+       char *name;
+
+       name = PyString_AsString(Image_getName(self));
+
+       fprintf(fp, "[Image \"%s\"]", name);
+
+  return 0;
+}
+
+/*****************************************************************************/
+/* Function:    ImageRepr                                                   */
+/* Description: This is a callback function for the C_Image type. It        */
+/*              builds a meaninful string to represent image objects.       */
+/*****************************************************************************/
+static PyObject *ImageRepr (C_Image *self)
+{
+       char buf[64];
+       char *name;
+
+       name = PyString_AsString(Image_getName(self));
+
+       PyOS_snprintf(buf, sizeof(buf), "[Image \"%s\"]", name);
+
+  return PyString_FromString(buf);
+}
diff --git a/source/blender/python/api2_2x/Image.h b/source/blender/python/api2_2x/Image.h
new file mode 100644 (file)
index 0000000..e783a32
--- /dev/null
@@ -0,0 +1,167 @@
+/* 
+ *
+ * ***** 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_IMAGE_H
+#define EXPP_IMAGE_H
+
+#include <Python.h>
+#include <stdio.h>
+
+#include <BKE_main.h>
+#include <BKE_global.h>
+#include <BKE_library.h>
+#include <BKE_image.h>
+#include <DNA_image_types.h>
+
+#include "gen_utils.h"
+#include "modules.h"
+
+/*****************************************************************************/
+/* Python C_Image defaults:                                                 */
+/*****************************************************************************/
+#define EXPP_IMAGE_REP      1
+#define EXPP_IMAGE_REP_MIN  1
+#define EXPP_IMAGE_REP_MAX 16
+
+/*****************************************************************************/
+/* Python API function prototypes for the Image module.                     */
+/*****************************************************************************/
+static PyObject *M_Image_New (PyObject *self, PyObject *args,
+                                                               PyObject *keywords);
+static PyObject *M_Image_Get (PyObject *self, PyObject *args);
+static PyObject *M_Image_Load (PyObject *self, PyObject *args);
+
+/*****************************************************************************/
+/* The following string definitions are used for documentation strings.      */
+/* In Python these will be written to the console when doing a               */
+/* Blender.Image.__doc__                                                    */
+/*****************************************************************************/
+char M_Image_doc[] =
+"The Blender Image module\n\n";
+
+char M_Image_New_doc[] =
+"() - return a new Image object -- unimplemented";
+
+char M_Image_Get_doc[] =
+"(name) - return the camera with the name 'name', \
+returns None if not found.\n If 'name' is not specified, \
+it returns a list of all cameras in the\ncurrent scene.";
+
+char M_Image_Load_doc[] =
+"(filename) - return image from file filename as Image Object, \
+returns None if not found.\n";
+
+/*****************************************************************************/
+/* Python method structure definition for Blender.Image module:             */
+/*****************************************************************************/
+struct PyMethodDef M_Image_methods[] = {
+  {"New",(PyCFunction)M_Image_New, METH_VARARGS|METH_KEYWORDS,
+          M_Image_New_doc},
+  {"Get",         M_Image_Get,         METH_VARARGS, M_Image_Get_doc},
+  {"get",         M_Image_Get,         METH_VARARGS, M_Image_Get_doc},
+  {"Load",        M_Image_Load,        METH_VARARGS, M_Image_Load_doc},
+  {NULL, NULL, 0, NULL}
+};
+
+/*****************************************************************************/
+/* Python C_Image structure definition:                                     */
+/*****************************************************************************/
+typedef struct {
+  PyObject_HEAD
+  PyObject *dict;
+  Image    *image;
+} C_Image;
+
+/*****************************************************************************/
+/* Python C_Image methods declarations:                                     */
+/*****************************************************************************/
+static PyObject *Image_getName(C_Image *self);
+static PyObject *Image_getFilename(C_Image *self);
+static PyObject *Image_rename(C_Image *self, PyObject *args);
+static PyObject *Image_setXRep(C_Image *self, PyObject *args);
+static PyObject *Image_setYRep(C_Image *self, PyObject *args);
+
+/*****************************************************************************/
+/* Python C_Image methods table:                                            */
+/*****************************************************************************/
+static PyMethodDef C_Image_methods[] = {
+ /* name, method, flags, doc */
+  {"getName", (PyCFunction)Image_getName, METH_NOARGS,
+                                       "() - Return Image Data name"},
+  {"getFilename", (PyCFunction)Image_getFilename, METH_VARARGS,
+                                       "() - Return Image Data filename"},
+  {"rename", (PyCFunction)Image_rename, METH_VARARGS,
+                                       "(str) - Change Image Data name"},
+  {"setXRep", (PyCFunction)Image_setXRep, METH_VARARGS,
+                                       "(int) - Change Image Data x repetition value"},
+  {"setYRep", (PyCFunction)Image_setYRep, METH_VARARGS,
+                                       "(int) - Change Image Data y repetition value"},
+  {0}
+};
+
+/*****************************************************************************/
+/* Python Image_Type callback function prototypes:                          */
+/*****************************************************************************/
+static void ImageDeAlloc (C_Image *cam);
+static int ImagePrint (C_Image *cam, FILE *fp, int flags);
+static int ImageSetAttr (C_Image *cam, char *name, PyObject *v);
+static PyObject *ImageGetAttr (C_Image *cam, char *name);
+static PyObject *ImageRepr (C_Image *cam);
+
+/*****************************************************************************/
+/* Python Image_Type structure definition:                                  */
+/*****************************************************************************/
+static PyTypeObject Image_Type =
+{
+  PyObject_HEAD_INIT(&PyType_Type)
+  0,                                      /* ob_size */
+  "Image",                               /* tp_name */
+  sizeof (C_Image),                     /* tp_basicsize */
+  0,                                      /* tp_itemsize */
+  /* methods */
+  (destructor)ImageDeAlloc,              /* tp_dealloc */
+  (printfunc)ImagePrint,                 /* tp_print */
+  (getattrfunc)ImageGetAttr,             /* tp_getattr */
+  (setattrfunc)ImageSetAttr,             /* tp_setattr */
+  0,                                      /* tp_compare */
+  (reprfunc)ImageRepr,                   /* tp_repr */
+  0,                                      /* tp_as_number */
+  0,                                      /* tp_as_sequence */
+  0,                                      /* tp_as_mapping */
+  0,                                      /* tp_as_hash */
+  0,0,0,0,0,0,
+  0,                                      /* tp_doc */ 
+  0,0,0,0,0,0,
+  C_Image_methods,                      /* tp_methods */
+  0,                                      /* tp_members */
+};
+
+#endif /* EXPP_IMAGE_H */
diff --git a/source/blender/python/api2_2x/Lamp.c b/source/blender/python/api2_2x/Lamp.c
new file mode 100644 (file)
index 0000000..7247b41
--- /dev/null
@@ -0,0 +1,1281 @@
+/* 
+ *
+ * ***** 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 "Lamp.h"
+
+/*****************************************************************************/
+/* Function:              M_Lamp_New                                         */
+/* Python equivalent:     Blender.Lamp.New                                   */
+/*****************************************************************************/
+static PyObject *M_Lamp_New(PyObject *self, PyObject *args, PyObject *keywords)
+{
+  char        *type_str = "Lamp";
+       char        *name_str = "Data";
+  static char *kwlist[] = {"type_str", "name_str", NULL};
+  C_Lamp      *lamp;
+       PyObject    *type, *name;
+       int         type_int;
+       char        buf[21];
+
+  printf ("In Lamp_New()\n");
+
+  if (!PyArg_ParseTupleAndKeywords(args, keywords, "|ss", kwlist,
+                                                                                                       &type_str, &name_str))
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected string(s) or empty argument"));
+
+       if (!strcmp (type_str, "Lamp"))
+               type_int = EXPP_LAMP_TYPE_LAMP;
+       else if (!strcmp (type_str, "Sun"))
+               type_int = EXPP_LAMP_TYPE_SUN;
+       else if (!strcmp (type_str, "Spot"))
+               type_int = EXPP_LAMP_TYPE_SPOT;
+       else if (!strcmp (type_str, "Hemi"))
+               type_int = EXPP_LAMP_TYPE_HEMI;
+       else
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "unknown lamp type"));
+
+       lamp = (C_Lamp *)LampCreatePyObject(NULL);
+
+  if (lamp == NULL)
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+                                                                                                               "couldn't create Lamp Data object"));
+
+       type = PyInt_FromLong(type_int);
+       if (type)       LampSetAttr(lamp, "type", type);
+       else {
+               Py_DECREF((PyObject *)lamp);
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                                                                                               "couldn't create Python string"));
+       }
+
+       if (strcmp(name_str, "Data") == 0)
+               return (PyObject *)lamp;
+
+       PyOS_snprintf(buf, sizeof(buf), "%s", name_str);
+       name = PyString_FromString(buf);
+       if (name) LampSetAttr(lamp, "name", name);
+       else {
+               Py_DECREF((PyObject *)lamp);
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                                                                                               "couldn't create Python string"));
+       }
+
+       return (PyObject *)lamp;
+}
+
+/*****************************************************************************/
+/* Function:              M_Lamp_Get                                         */
+/* Python equivalent:     Blender.Lamp.Get                                   */
+/*****************************************************************************/
+static PyObject *M_Lamp_Get(PyObject *self, PyObject *args)
+{
+  char     *name;
+  Lamp   *lamp_iter;
+       C_Lamp *wanted_lamp;
+
+  printf ("In Lamp_Get()\n");
+  if (!PyArg_ParseTuple(args, "s", &name))
+  {
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected string argument"));
+  }
+
+  /* Use the name to search for the lamp requested. */
+  wanted_lamp = NULL;
+  lamp_iter = G.main->lamp.first;
+
+  while ((lamp_iter) && (wanted_lamp == NULL)) {
+
+         if (strcmp (name, GetIdName (&(lamp_iter->id))) == 0)
+      wanted_lamp = (C_Lamp *)LampCreatePyObject(lamp_iter);
+
+               lamp_iter = lamp_iter->id.next;
+  }
+
+  if (wanted_lamp == NULL) {
+  /* No lamp exists with the name specified in the argument name. */
+    char error_msg[64];
+    PyOS_snprintf(error_msg, sizeof(error_msg),
+                    "Lamp \"%s\" not found", name);
+    return (PythonReturnErrorObject (PyExc_NameError, error_msg));
+  }
+       wanted_lamp->linked = 1; /* TRUE: linked to a Blender Lamp Object */
+  return ((PyObject*)wanted_lamp);
+}
+
+/*****************************************************************************/
+/* Function:              M_Lamp_Init                                        */
+/*****************************************************************************/
+PyObject *M_Lamp_Init (void)
+{
+  PyObject  *module;
+
+  printf ("In M_Lamp_Init()\n");
+
+  module = Py_InitModule3("Lamp", M_Lamp_methods, M_Lamp_doc);
+
+  return (module);
+}
+
+/*****************************************************************************/
+/* Python C_Lamp methods:                                                    */
+/*****************************************************************************/
+static PyObject *Lamp_getName(C_Lamp *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "name");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+       return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                       "couldn't get Lamp.name attribute"));
+}
+
+static PyObject *Lamp_getType(C_Lamp *self)
+{ 
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "type");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+          "couldn't get Lamp.type attribute"));
+}
+
+static PyObject *Lamp_getMode(C_Lamp *self)
+{/* XXX improve this, add the constants to the Lamp dict */
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "mode");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+          "couldn't get Lamp.mode attribute"));
+}
+
+static PyObject *Lamp_getSamples(C_Lamp *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "samples");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+          "couldn't get Lamp.samples attribute"));
+}
+
+static PyObject *Lamp_getBufferSize(C_Lamp *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "bufferSize");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+          "couldn't get Lamp.bufferSize attribute"));
+}
+
+static PyObject *Lamp_getHaloStep(C_Lamp *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "haloStep");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+          "couldn't get Lamp.haloStep attribute"));
+}
+
+static PyObject *Lamp_getEnergy(C_Lamp *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "energy");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+          "couldn't get Lamp.energy attribute"));
+}
+
+static PyObject *Lamp_getDist(C_Lamp *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "dist");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+          "couldn't get Lamp.dist attribute"));
+}
+
+static PyObject *Lamp_getSpotSize(C_Lamp *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "spotSize");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+          "couldn't get Lamp.spotSize attribute"));
+}
+
+static PyObject *Lamp_getSpotBlend(C_Lamp *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "spotBlend");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+          "couldn't get Lamp.spotBlend attribute"));
+}
+
+static PyObject *Lamp_getClipStart(C_Lamp *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "clipStart");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+          "couldn't get Lamp.clipStart attribute"));
+}
+
+static PyObject *Lamp_getClipEnd(C_Lamp *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "clipEnd");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+          "couldn't get Lamp.clipEnd attribute"));
+}
+
+static PyObject *Lamp_getBias(C_Lamp *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "bias");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+          "couldn't get Lamp.bias attribute"));
+}
+
+static PyObject *Lamp_getSoftness(C_Lamp *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "softness");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+          "couldn't get Lamp.softness attribute"));
+}
+
+static PyObject *Lamp_getHaloInt(C_Lamp *self)
+{
+       PyObject *attr;
+       attr = PyDict_GetItemString(self->dict, "haloInt");
+       if (attr) {
+               Py_INCREF(attr);
+               return attr;
+       }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+          "couldn't get Lamp.haloInt attribute"));
+}
+                                                               
+static PyObject *Lamp_rename(C_Lamp *self, PyObject *args)
+{
+       char *name_str;
+       char buf[21];
+       PyObject *name;
+
+       if (!PyArg_ParseTuple(args, "s", &name_str))
+               return (PythonReturnErrorObject (PyExc_AttributeError,
+                                               "expected string argument"));
+       
+       PyOS_snprintf(buf, sizeof(buf), "%s", name_str);
+       
+       if (self->linked) { /* update the Blender Lamp, too */
+               ID *tmp_id = &self->lamp->id;
+               rename_id(tmp_id, buf);
+               PyOS_snprintf(buf, sizeof(buf), "%s", tmp_id->name+2);/* may have changed */
+       }
+
+       name = PyString_FromString(buf);
+
+       if (!name)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyString Object"));
+
+       if (PyDict_SetItemString(self->dict, "name", name) != 0) {
+               Py_DECREF(name);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+            "couldn't set Lamp.name attribute"));
+       }
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setType(C_Lamp *self, PyObject *args)
+{
+       short value;
+       char *type_str;
+       PyObject *type;
+
+       if (!PyArg_ParseTuple(args, "s", &type_str))
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected one string argument"));
+
+       if (strcmp (type_str, "Lamp") == 0)
+               value = EXPP_LAMP_TYPE_LAMP;
+       else if (strcmp (type_str, "Sun") == 0)
+               value = EXPP_LAMP_TYPE_SUN;     
+       else if (strcmp (type_str, "Spot") == 0)
+               value = EXPP_LAMP_TYPE_SPOT;    
+       else if (strcmp (type_str, "Hemi") == 0)
+               value = EXPP_LAMP_TYPE_HEMI;    
+  else
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "unknown lamp type"));
+
+       type = PyInt_FromLong(value);
+       if (!type)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyInt Object"));
+
+       if (PyDict_SetItemString(self->dict, "type", type) != 0) {
+               Py_DECREF(type);
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "couldn't set Lamp.type attribute"));
+       }
+
+       if (self->linked) /* update the Blender Lamp, too */
+    self->lamp->type = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+/* This one is 'private'. It is not really a method, just a helper function for
+ * when script writers use Lamp.type = t instead of Lamp.setType(t), since in
+ * the first case t shoud be an int and in the second it should be a string. So
+ * while the method setType expects a string ('persp' or 'ortho') or an empty
+ * argument, this function should receive an int (0 or 1). */
+static PyObject *Lamp_setIntType(C_Lamp *self, PyObject *args)
+{
+       short value;
+       PyObject *type;
+
+       if (!PyArg_ParseTuple(args, "h", &value))
+               return (PythonReturnErrorObject (PyExc_AttributeError,
+                                               "expected int argument in [0,3]"));
+
+       if (value >= 0 && value <= 3)
+               type = PyInt_FromLong(value);
+       else
+               return (PythonReturnErrorObject (PyExc_AttributeError,
+                                               "expected int argument in [0,3]"));
+
+       if (!type)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyInt Object"));
+
+       if (PyDict_SetItemString(self->dict, "type", type) != 0) {
+               Py_DECREF(type);
+               return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                               "could not set Lamp.type attribute"));
+       }
+
+       if (self->linked) /* update the Blender Lamp, too */
+    self->lamp->type = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setMode(C_Lamp *self, PyObject *args)
+{/* Quad, Sphere, Shadows, Halo, Layer, Negative, OnlyShadow, Square */
+       char *m[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+       short i, flag = 0;
+       PyObject *mode;
+
+       if (!PyArg_ParseTuple(args, "|ssssssss", &m[0], &m[1], &m[2],
+                                                                                               &m[3], &m[4], &m[5], &m[6], &m[7]))
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected string argument(s)"));
+
+       for (i = 0; i < 8; i++) {
+               if (m[i] == NULL) break;
+               if (strcmp(m[i], "Shadows") == 0)
+                       flag |= EXPP_LAMP_MODE_SHADOWS;
+               else if (strcmp(m[i], "Halo") == 0)
+                       flag |= EXPP_LAMP_MODE_HALO;
+               else if (strcmp(m[i], "Layer") == 0)
+                       flag |= EXPP_LAMP_MODE_LAYER;
+               else if (strcmp(m[i], "Quad") == 0)
+                       flag |= EXPP_LAMP_MODE_QUAD;
+               else if (strcmp(m[i], "Negative") == 0)
+                       flag |= EXPP_LAMP_MODE_NEGATIVE;
+               else if (strcmp(m[i], "OnlyShadow") == 0)
+                       flag |= EXPP_LAMP_MODE_ONLYSHADOW;
+               else if (strcmp(m[i], "Sphere") == 0)
+                       flag |= EXPP_LAMP_MODE_SPHERE;
+               else if (strcmp(m[i], "Square") == 0)
+                       flag |= EXPP_LAMP_MODE_SQUARE;
+       else
+       return (PythonReturnErrorObject (PyExc_AttributeError,
+             "unknown lamp flag argument"));
+       }
+
+       mode = PyInt_FromLong(flag);
+       if (!mode)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyInt Object"));
+       
+       if (PyDict_SetItemString(self->dict, "mode", mode) != 0) {
+               Py_DECREF(mode);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+            "couldn't set Lamp.mode attribute"));
+       }
+       
+       if (self->linked) /* update the Blender Lamp, too */
+    self->lamp->mode = flag;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+/* Another helper function, for the same reason.
+ * (See comment before Lamp_setIntType above). */
+static PyObject *Lamp_setIntMode(C_Lamp *self, PyObject *args)
+{
+       short value;
+       PyObject *mode;
+
+       if (!PyArg_ParseTuple(args, "h", &value))
+               return (PythonReturnErrorObject (PyExc_AttributeError,
+                                               "expected int argument"));
+
+/* well, with so many flag bits, we just accept any short int, no checking */
+       mode = PyInt_FromLong(value);
+
+       if (!mode)
+               return (PythonReturnErrorObject (PyExc_AttributeError,
+                                               "couldn't create PyInt object"));
+
+       if (PyDict_SetItemString(self->dict, "mode", mode) != 0) {
+               Py_DECREF(mode);
+               return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                               "could not set Lamp.mode attribute"));
+       }
+
+       if (self->linked) /* update the Blender Lamp, too */
+    self->lamp->mode = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setSamples(C_Lamp *self, PyObject *args)
+{
+       short value;
+       PyObject *samples;
+
+       if (!PyArg_ParseTuple(args, "h", &value))
+               return (PythonReturnErrorObject (PyExc_AttributeError,
+                                               "expected int argument in [1,16]"));
+
+       if (value >= EXPP_LAMP_SAMPLES_MIN &&
+                       value <= EXPP_LAMP_SAMPLES_MAX)
+               samples = PyInt_FromLong(value);
+       else
+               return (PythonReturnErrorObject (PyExc_AttributeError,
+                                               "expected int argument in [1,16]"));
+
+       if (!samples)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyInt Object"));
+
+       if (PyDict_SetItemString(self->dict, "samples", samples) != 0) {
+               Py_DECREF(samples);
+               return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                               "could not set Lamp.samples attribute"));
+       }
+
+       if (self->linked) /* update the Blender Lamp, too */
+    self->lamp->samp = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setBufferSize(C_Lamp *self, PyObject *args)
+{
+       short value;
+       PyObject *bufferSize;
+
+       if (!PyArg_ParseTuple(args, "h", &value))
+               return (PythonReturnErrorObject (PyExc_AttributeError,
+                                               "expected int argument, any of [512, 768, 1024, 1536, 2560]"));
+
+       switch (value) {
+               case  512:
+               case  768:
+               case 1024:
+               case 1536:
+               case 2560:
+                       bufferSize = PyInt_FromLong(value);
+                       break;
+               default:
+                       return (PythonReturnErrorObject (PyExc_AttributeError,
+                                                       "expected int argument, any of [512, 768, 1024, 1536, 2560]"));
+       }
+
+       if (!bufferSize)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyInt Object"));
+
+       if (PyDict_SetItemString(self->dict, "bufferSize", bufferSize) != 0) {
+               Py_DECREF(bufferSize);
+               return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                               "could not set Lamp.bufferSize attribute"));
+       }
+
+       if (self->linked) /* update the Blender Lamp, too */
+    self->lamp->bufsize = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setHaloStep(C_Lamp *self, PyObject *args)
+{
+       short value;
+       PyObject *haloStep;
+
+       if (!PyArg_ParseTuple(args, "h", &value))
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected int argument in [0,12]"));
+
+       if (value >= EXPP_LAMP_HALOSTEP_MIN &&
+                       value <= EXPP_LAMP_HALOSTEP_MAX)
+               haloStep = PyInt_FromLong(value);
+       else
+               return (PythonReturnErrorObject (PyExc_AttributeError,
+                                               "expected int argument in [0,12]"));
+       
+       if (!haloStep)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyInt Object"));
+
+       if (PyDict_SetItemString(self->dict, "haloStep", haloStep) != 0) {
+               Py_DECREF(haloStep);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+            "couldn't set Lamp.haloStep attribute"));
+       }
+
+       if (self->linked) /* update the Blender Lamp, too */
+    self->lamp->shadhalostep = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setColorComponent(C_Lamp *self, char *key, PyObject *args)
+{
+       float value;
+       PyObject *component;
+       
+       if (!PyArg_ParseTuple(args, "f", &value))
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected float argument in [0.0, 1.0]"));
+
+       value = EXPP_ClampFloat (value, 0.0, 1.0);
+       component = PyFloat_FromDouble(value);
+
+       if (!component)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyFloat Object"));
+
+       if (PyDict_SetItemString(self->dict, key, component) != 0) {
+               Py_DECREF(component);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+            "couldn't set Lamp color component attribute"));
+       }
+       
+       if (self->linked) { /* update the Blender Lamp, too */
+               if (!strcmp(key, "R"))
+                       self->lamp->r = value;
+               else if (!strcmp(key, "G"))
+                       self->lamp->g = value;
+               else if (!strcmp(key, "B"))
+                       self->lamp->b = value;
+       }
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setEnergy(C_Lamp *self, PyObject *args)
+{
+       float value;
+       PyObject *energy;
+       
+       if (!PyArg_ParseTuple(args, "f", &value))
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected float argument"));
+
+       value = EXPP_ClampFloat (value, EXPP_LAMP_ENERGY_MIN, EXPP_LAMP_ENERGY_MAX);
+       energy = PyFloat_FromDouble(value);
+
+       if (!energy)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyFloat Object"));
+
+       if (PyDict_SetItemString(self->dict, "energy", energy) != 0) {
+               Py_DECREF(energy);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+            "couldn't set Lamp.energy attribute"));
+       }
+       
+       if (self->linked) /* update the Blender Lamp, too */
+               self->lamp->energy = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setDist(C_Lamp *self, PyObject *args)
+{
+       float value;
+       PyObject *dist;
+       
+       if (!PyArg_ParseTuple(args, "f", &value))
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected float argument"));
+
+       value = EXPP_ClampFloat (value, EXPP_LAMP_DIST_MIN, EXPP_LAMP_DIST_MAX);
+       dist = PyFloat_FromDouble(value);
+       
+       if (!dist)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyFloat Object"));
+
+       if (PyDict_SetItemString(self->dict, "dist", dist) != 0) {
+               Py_DECREF(dist);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+            "couldn't set Lamp.dist attribute"));
+       }
+       
+       if (self->linked) /* update the Blender Lamp, too */
+               self->lamp->dist = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setSpotSize(C_Lamp *self, PyObject *args)
+{
+       float value;
+       PyObject *spotSize;
+       
+       if (!PyArg_ParseTuple(args, "f", &value))
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected float argument"));
+
+       value = EXPP_ClampFloat (value, EXPP_LAMP_SPOTSIZE_MIN, EXPP_LAMP_SPOTSIZE_MAX);
+       spotSize = PyFloat_FromDouble(value);
+       
+       if (!spotSize)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyFloat Object"));
+
+       if (PyDict_SetItemString(self->dict, "spotSize", spotSize) != 0) {
+               Py_DECREF(spotSize);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+            "couldn't set Lamp.spotSize attribute"));
+       }
+       
+       if (self->linked) /* update the Blender Lamp, too */
+               self->lamp->spotsize = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setSpotBlend(C_Lamp *self, PyObject *args)
+{
+       float value;
+       PyObject *spotBlend;
+       
+       if (!PyArg_ParseTuple(args, "f", &value))
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected float argument"));
+
+       value = EXPP_ClampFloat (value, EXPP_LAMP_SPOTBLEND_MIN,
+                                                                       EXPP_LAMP_SPOTBLEND_MAX);
+       spotBlend = PyFloat_FromDouble(value);
+       
+       if (!spotBlend)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyFloat Object"));
+
+       if (PyDict_SetItemString(self->dict, "spotBlend", spotBlend) != 0) {
+               Py_DECREF(spotBlend);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+            "couldn't set Lamp.spotBlend attribute"));
+       }
+       
+       if (self->linked) /* update the Blender Lamp, too */
+               self->lamp->spotblend = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setClipStart(C_Lamp *self, PyObject *args)
+{
+       float value;
+       PyObject *clipStart;
+       
+       if (!PyArg_ParseTuple(args, "f", &value))
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected a float number as argument"));
+       
+       value = EXPP_ClampFloat (value, EXPP_LAMP_CLIPSTART_MIN,
+                                                                       EXPP_LAMP_CLIPSTART_MAX);
+       
+       clipStart = PyFloat_FromDouble(value);
+       
+       if (!clipStart)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyFloat Object"));
+
+       if (PyDict_SetItemString(self->dict, "clipStart", clipStart) != 0) {
+               Py_DECREF(clipStart);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+            "couldn't set Lamp.clipStart attribute"));
+       }
+       
+       if (self->linked) /* update the Blender Lamp, too */
+    self->lamp->clipsta = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setClipEnd(C_Lamp *self, PyObject *args)
+{
+       float value;
+       PyObject *clipEnd;
+       
+       if (!PyArg_ParseTuple(args, "f", &value))
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected a float number as argument"));
+
+  value = EXPP_ClampFloat (value, EXPP_LAMP_CLIPEND_MIN,
+                                                                       EXPP_LAMP_CLIPEND_MAX);
+
+       clipEnd = PyFloat_FromDouble(value);
+       
+       if (!clipEnd)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyFloat Object"));
+
+       if (PyDict_SetItemString(self->dict, "clipEnd", clipEnd) != 0) {
+               Py_DECREF(clipEnd);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+            "couldn't set Lamp.clipEnd attribute"));
+       }
+       
+       if (self->linked) /* update the Blender Lamp, too */
+    self->lamp->clipend = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setBias(C_Lamp *self, PyObject *args)
+{
+       float value;
+       PyObject *bias;
+       
+       if (!PyArg_ParseTuple(args, "f", &value))
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected a float number as argument"));
+
+  value = EXPP_ClampFloat (value, EXPP_LAMP_BIAS_MIN, EXPP_LAMP_BIAS_MAX);
+
+       bias = PyFloat_FromDouble(value);
+       
+       if (!bias)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyFloat Object"));
+
+       if (PyDict_SetItemString(self->dict, "bias", bias) != 0) {
+               Py_DECREF(bias);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+            "couldn't set Lamp.bias attribute"));
+       }
+       
+       if (self->linked) /* update the Blender Lamp, too */
+    self->lamp->bias = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setSoftness(C_Lamp *self, PyObject *args)
+{
+       float value;
+       PyObject *softness;
+       
+       if (!PyArg_ParseTuple(args, "f", &value))
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected a float number as argument"));
+
+  value = EXPP_ClampFloat (value, EXPP_LAMP_SOFTNESS_MIN,
+                                                                       EXPP_LAMP_SOFTNESS_MAX);
+
+       softness = PyFloat_FromDouble(value);
+       
+       if (!softness)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyFloat Object"));
+
+       if (PyDict_SetItemString(self->dict, "softness", softness) != 0) {
+               Py_DECREF(softness);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+            "couldn't set Lamp.softness attribute"));
+       }
+       
+       if (self->linked) /* update the Blender Lamp, too */
+    self->lamp->soft = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static PyObject *Lamp_setHaloInt(C_Lamp *self, PyObject *args)
+{
+       float value;
+       PyObject *haloInt;
+       
+       if (!PyArg_ParseTuple(args, "f", &value))
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+            "expected a float number as argument"));
+
+  value = EXPP_ClampFloat (value, EXPP_LAMP_HALOINT_MIN,
+                                                                       EXPP_LAMP_HALOINT_MAX);
+
+       haloInt = PyFloat_FromDouble(value);
+       
+       if (!haloInt)
+               return (PythonReturnErrorObject (PyExc_MemoryError,
+                                               "couldn't create PyFloat Object"));
+
+       if (PyDict_SetItemString(self->dict, "haloInt", haloInt) != 0) {
+               Py_DECREF(haloInt);
+    return (PythonReturnErrorObject (PyExc_RuntimeError,
+            "couldn't set Lamp.haloInt attribute"));
+       }
+       
+       if (self->linked) /* update the Blender Lamp, too */
+    self->lamp->haint = value;
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+/*****************************************************************************/
+/* Function:    LampCreatePyObject                                           */
+/* Description: This function will create a new C_Lamp.  If the Lamp         */
+/*              struct passed to it is not NULL, it'll use its attributes.   */
+/*****************************************************************************/
+PyObject *LampCreatePyObject (Lamp *blenderLamp)
+{
+       PyObject *name, *type, *mode, *R, *G, *B, *energy, *dist;
+       PyObject *spotSize, *spotBlend, *clipStart, *clipEnd;
+       PyObject *bias, *softness, *samples, *bufferSize;
+       PyObject *haloInt, *haloStep;
+       PyObject *Types, *Lamp, *Sun, *Spot, *Hemi;
+       PyObject *Modes, *Shadows, *Halo, *Layer, *Quad;
+       PyObject *Negative, *OnlyShadow, *Sphere, *Square;
+  C_Lamp   *lamp;
+
+  printf ("In LampCreatePyObject\n");
+
+       lamp = (C_Lamp *)PyObject_NEW(C_Lamp, &Lamp_Type);
+       
+       if (lamp == NULL)
+               return NULL;
+
+       lamp->linked = 0;
+       lamp->dict = PyDict_New();
+
+       if (lamp->dict == NULL) {
+               Py_DECREF((PyObject *)lamp);
+               return NULL;
+       }
+
+       if (blenderLamp == NULL) { /* Not linked to a Lamp Object yet */
+               name = PyString_FromString("Data");
+               type = PyInt_FromLong(EXPP_LAMP_TYPE);
+               mode = PyInt_FromLong(EXPP_LAMP_MODE);
+               samples = PyInt_FromLong(EXPP_LAMP_SAMPLES);
+               bufferSize = PyInt_FromLong(EXPP_LAMP_BUFFERSIZE);
+               haloStep = PyInt_FromLong(EXPP_LAMP_HALOSTEP);
+         R = PyFloat_FromDouble(1.0);
+         G = PyFloat_FromDouble(1.0);
+         B = PyFloat_FromDouble(1.0);
+         energy = PyFloat_FromDouble(EXPP_LAMP_ENERGY);
+         dist = PyFloat_FromDouble(EXPP_LAMP_DIST);
+         spotSize = PyFloat_FromDouble(EXPP_LAMP_SPOTSIZE);
+         spotBlend = PyFloat_FromDouble(EXPP_LAMP_SPOTBLEND);
+               clipStart = PyFloat_FromDouble(EXPP_LAMP_CLIPSTART);
+               clipEnd = PyFloat_FromDouble(EXPP_LAMP_CLIPEND);
+         bias = PyFloat_FromDouble(EXPP_LAMP_BIAS);
+         softness = PyFloat_FromDouble(EXPP_LAMP_SOFTNESS);
+               haloInt = PyFloat_FromDouble(EXPP_LAMP_HALOINT);
+       }
+       else { /* Lamp Object available, get its attributes directly */
+               name = PyString_FromString(blenderLamp->id.name+2);
+               type = PyInt_FromLong(blenderLamp->type);
+               mode = PyInt_FromLong(blenderLamp->mode);
+               samples = PyInt_FromLong(blenderLamp->samp);
+               bufferSize = PyInt_FromLong(blenderLamp->bufsize);
+               haloStep = PyInt_FromLong(blenderLamp->shadhalostep);
+         R = PyFloat_FromDouble(blenderLamp->r);
+         G = PyFloat_FromDouble(blenderLamp->g);
+         B = PyFloat_FromDouble(blenderLamp->b);
+         energy = PyFloat_FromDouble(blenderLamp->energy);
+         dist = PyFloat_FromDouble(blenderLamp->dist);
+         spotSize = PyFloat_FromDouble(blenderLamp->spotsize);
+         spotBlend = PyFloat_FromDouble(blenderLamp->spotblend);
+               clipStart = PyFloat_FromDouble(blenderLamp->clipsta);
+               clipEnd = PyFloat_FromDouble(blenderLamp->clipend);
+         bias = PyFloat_FromDouble(blenderLamp->bias);
+         softness = PyFloat_FromDouble(blenderLamp->soft);
+               haloInt = PyFloat_FromDouble(blenderLamp->haint);
+               /*there's shadspotsize, too ... plus others, none in 2.25*/
+       }
+
+       Types = constant_New();
+       Lamp  = PyInt_FromLong(EXPP_LAMP_TYPE_LAMP);
+       Sun   = PyInt_FromLong(EXPP_LAMP_TYPE_SUN);
+       Spot  = PyInt_FromLong(EXPP_LAMP_TYPE_SPOT);
+       Hemi  = PyInt_FromLong(EXPP_LAMP_TYPE_HEMI);
+       
+       Modes = constant_New();
+       Shadows = PyInt_FromLong(EXPP_LAMP_MODE_SHADOWS);
+       Halo = PyInt_FromLong(EXPP_LAMP_MODE_HALO);
+       Layer = PyInt_FromLong(EXPP_LAMP_MODE_LAYER);
+       Quad = PyInt_FromLong(EXPP_LAMP_MODE_QUAD);
+       Negative = PyInt_FromLong(EXPP_LAMP_MODE_NEGATIVE);
+       OnlyShadow = PyInt_FromLong(EXPP_LAMP_MODE_ONLYSHADOW);
+       Sphere = PyInt_FromLong(EXPP_LAMP_MODE_SPHERE);
+       Square = PyInt_FromLong(EXPP_LAMP_MODE_SQUARE);
+
+       if (name == NULL || type == NULL || mode == NULL ||
+                       samples == NULL || bufferSize == NULL || haloStep == NULL ||
+                       R == NULL || G == NULL || B == NULL || energy == NULL ||
+                       dist == NULL || spotSize == NULL || spotBlend == NULL ||
+                       clipStart == NULL || clipEnd == NULL || bias == NULL ||
+                       softness == NULL || haloInt == NULL || Types == NULL ||
+                       Lamp == NULL || Sun == NULL || Spot == NULL || Hemi == NULL ||
+                       Modes == NULL || Shadows == NULL || Halo == NULL ||
+                       Layer == NULL || Quad == NULL || Negative == NULL ||
+                       OnlyShadow == NULL || Sphere == NULL || Square == NULL) /* ack! */
+               goto fail;
+
+       if ((PyDict_SetItemString(lamp->dict, "name", name) != 0) ||
+                       (PyDict_SetItemString(lamp->dict, "type", type) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "mode", mode) != 0) ||
+                       (PyDict_SetItemString(lamp->dict, "samples", samples) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "bufferSize", bufferSize) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "R", R) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "G", G) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "B", B) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "energy", energy) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "dist", dist) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "spotSize", spotSize) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "spotBlend", spotBlend) != 0) ||
+                       (PyDict_SetItemString(lamp->dict, "clipStart", clipStart) != 0) ||
+      (PyDict_SetItemString(lamp->dict, "clipEnd", clipEnd) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "bias", bias) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "softness", softness) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "haloInt", haloInt) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "haloStep", haloStep) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "Types", Types) != 0) ||
+                 (PyDict_SetItemString(lamp->dict, "Modes", Modes) != 0) ||
+                       (PyDict_SetItemString(lamp->dict, "__members__",
+                                                                                                               PyDict_Keys(lamp->dict)) != 0))
+               goto fail;
+
+       if ((PyDict_SetItemString(((C_constant *)Types)->dict,
+                                                                                                               "Lamp", Lamp) != 0) ||
+                       (PyDict_SetItemString(((C_constant *)Types)->dict,
+                                                                                                               "Sun", Sun) != 0) ||
+                       (PyDict_SetItemString(((C_constant *)Types)->dict,
+                                                                                                               "Spot", Spot) != 0) ||
+                       (PyDict_SetItemString(((C_constant *)Types)->dict,
+                                                                                                               "Hemi", Hemi) != 0) ||
+                       (PyDict_SetItemString(((C_constant *)Modes)->dict,
+                                                                                                               "Shadows", Shadows) != 0) ||
+                       (PyDict_SetItemString(((C_constant *)Modes)->dict,
+                                                                                                               "Halo", Halo) != 0) ||
+                       (PyDict_SetItemString(((C_constant *)Modes)->dict,
+                                                                                                               "Layer", Layer) != 0) ||
+                       (PyDict_SetItemString(((C_constant *)Modes)->dict,
+                                                                                                               "Quad", Quad) != 0) ||
+                       (PyDict_SetItemString(((C_constant *)Modes)->dict,
+                                                                                                               "Negative", Negative) != 0) ||
+                       (PyDict_SetItemString(((C_constant *)Modes)->dict,
+                                                                                                               "OnlyShadow", OnlyShadow) != 0) ||
+                       (PyDict_SetItemString(((C_constant *)Modes)->dict,
+                                                                                                               "Sphere", Sphere) != 0) ||
+                       (PyDict_SetItemString(((C_constant *)Modes)->dict,
+                                                                                                               "Square", Square) != 0))
+               goto fail;
+
+  lamp->lamp = blenderLamp; /* it's NULL when creating only lamp "data" */
+  return ((PyObject*)lamp);
+
+fail:
+       Py_XDECREF(name);
+       Py_XDECREF(type);
+       Py_XDECREF(mode);
+       Py_XDECREF(samples);
+       Py_XDECREF(bufferSize);
+       Py_XDECREF(R);
+       Py_XDECREF(G);
+       Py_XDECREF(B);
+       Py_XDECREF(energy);
+       Py_XDECREF(dist);
+       Py_XDECREF(spotSize);
+       Py_XDECREF(spotBlend);
+       Py_XDECREF(clipStart);
+       Py_XDECREF(clipEnd);
+       Py_XDECREF(bias);
+       Py_XDECREF(softness);
+       Py_XDECREF(haloInt);
+       Py_XDECREF(haloStep);
+       Py_XDECREF(Types);
+       Py_XDECREF(Lamp);
+       Py_XDECREF(Sun);
+       Py_XDECREF(Spot);
+       Py_XDECREF(Hemi);
+       Py_XDECREF(Modes);
+       Py_XDECREF(Shadows);
+       Py_XDECREF(Halo);
+       Py_XDECREF(Layer);
+       Py_XDECREF(Quad);
+       Py_XDECREF(Negative);
+       Py_XDECREF(OnlyShadow);
+       Py_XDECREF(Sphere);
+       Py_XDECREF(Square);
+  Py_DECREF(lamp->dict);
+       Py_DECREF((PyObject *)lamp);
+       return NULL;
+}
+
+/*****************************************************************************/
+/* Function:    LampDeAlloc                                                  */
+/* Description: This is a callback function for the C_Lamp type. It is       */
+/*              the destructor function.                                     */
+/*****************************************************************************/
+static void LampDeAlloc (C_Lamp *self)
+{
+       Py_DECREF(self->dict);
+  PyObject_DEL (self);
+}
+
+/*****************************************************************************/
+/* Function:    LampGetAttr                                                  */
+/* Description: This is a callback function for the C_Lamp type. It is       */
+/*              the function that accesses C_Lamp member variables and       */
+/*              methods.                                                     */
+/*****************************************************************************/
+static PyObject* LampGetAttr (C_Lamp *lamp, char *name)
+{/* first try the attributes dictionary */
+       if (lamp->dict) {
+               PyObject *v = PyDict_GetItemString(lamp->dict, name);
+               if (v) {
+                       Py_INCREF(v); /* was a borrowed ref */
+                       return v;
+               }
+       }
+/* not an attribute, search the methods table */
+       return Py_FindMethod(C_Lamp_methods, (PyObject *)lamp, name);
+}
+
+/*****************************************************************************/
+/* Function:    LampSetAttr                                                  */
+/* Description: This is a callback function for the C_Lamp type. It is the   */
+/*              function that changes Lamp Data members values. If this      */
+/*              data is linked to a Blender Lamp, it also gets updated.      */
+/*****************************************************************************/
+static int LampSetAttr (C_Lamp *self, char *name, PyObject *value)
+{
+       PyObject *valtuple; 
+       PyObject *error = NULL;
+
+       if (self->dict == NULL) return -1;
+
+/* We're playing a trick on the Python API users here.  Even if they use
+ * Lamp.member = val instead of Lamp.setMember(value), we end up using the
+ * function anyway, since it already has error checking, clamps to the right
+ * interval and updates the Blender Lamp structure when necessary. */
+
+       valtuple = PyTuple_New(1); /* the set* functions expect a tuple */
+
+       if (!valtuple)
+               return EXPP_intError(PyExc_MemoryError,
+                                                                       "LampSetAttr: couldn't create tuple");
+
+       if (PyTuple_SetItem(valtuple, 0, value) != 0) {
+               Py_DECREF(value); /* PyTuple_SetItem incref's value even when it fails */
+               Py_DECREF(valtuple);
+               return EXPP_intError(PyExc_MemoryError,
+                                                                        "LampSetAttr: couldn't fill tuple");
+       }
+
+       if (strcmp (name, "name") == 0)
+    error = Lamp_rename (self, valtuple);
+       else if (strcmp (name, "type") == 0)
+    error = Lamp_setIntType (self, valtuple); /* special case */
+       else if (strcmp (name, "mode") == 0)
+    error = Lamp_setIntMode (self, valtuple); /* special case */
+       else if (strcmp (name, "samples") == 0)
+    error = Lamp_setSamples (self, valtuple);
+       else if (strcmp (name, "bufferSize") == 0)
+    error = Lamp_setBufferSize (self, valtuple);
+       else if (strcmp (name, "haloStep") == 0)
+    error = Lamp_setHaloStep (self, valtuple);
+       else if (strcmp (name, "R") == 0)
+    error = Lamp_setColorComponent (self, "R", valtuple);
+       else if (strcmp (name, "G") == 0)
+    error = Lamp_setColorComponent (self, "G", valtuple);
+       else if (strcmp (name, "B") == 0)
+    error = Lamp_setColorComponent (self, "B", valtuple);
+       else if (strcmp (name, "energy") == 0)
+    error = Lamp_setEnergy (self, valtuple);
+       else if (strcmp (name, "dist") == 0)
+    error = Lamp_setDist (self, valtuple);
+       else if (strcmp (name, "spotSize") == 0)
+    error = Lamp_setSpotSize (self, valtuple);
+       else if (strcmp (name, "spotBlend") == 0)
+    error = Lamp_setSpotBlend (self, valtuple);
+       else if (strcmp (name, "clipStart") == 0)
+    error = Lamp_setClipStart (self, valtuple);
+       else if (strcmp (name, "clipEnd") == 0)
+    error = Lamp_setClipEnd (self, valtuple);
+       else if (strcmp (name, "bias") == 0)
+    error = Lamp_setBias (self, valtuple);
+       else if (strcmp (name, "softness") == 0)
+    error = Lamp_setSoftness (self, valtuple);
+       else if (strcmp (name, "haloInt") == 0)
+    error = Lamp_setHaloInt (self, valtuple);
+       else { /* Error: no such member in the Lamp Data structure */
+               Py_DECREF(value);
+               Py_DECREF(valtuple);
+       return (EXPP_intError (PyExc_AttributeError,
+             "attribute not found"));
+       }
+
+       if (error == Py_None) return 0; /* normal exit */
+
+       Py_DECREF(value);
+       Py_DECREF(valtuple);
+
+       return -1;
+}
+
+/*****************************************************************************/
+/* Function:    LampPrint                                                    */
+/* Description: This is a callback function for the C_Lamp type. It          */
+/*              builds a meaninful string to 'print' lamp objects.           */
+/*****************************************************************************/
+static int LampPrint(C_Lamp *self, FILE *fp, int flags)
+{ 
+       char *lstate = "unlinked";
+       char *name;
+
+       if (self->linked)
+               lstate = "linked";
+       
+       name = PyString_AsString(Lamp_getName(self));
+
+       fprintf(fp, "[Lamp \"%s\" (%s)]", name, lstate);
+
+  return 0;
+}
+
+/*****************************************************************************/
+/* Function:    LampRepr                                                     */
+/* Description: This is a callback function for the C_Lamp type. It          */
+/*              builds a meaninful string to represent lamp objects.         */
+/*****************************************************************************/
+static PyObject *LampRepr (C_Lamp *self)
+{
+       char buf[64];
+       char *lstate = "unlinked";
+       char *name;
+
+       if (self->linked)
+               lstate = "linked";
+
+       name = PyString_AsString(Lamp_getName(self));
+
+       PyOS_snprintf(buf, sizeof(buf), "[Lamp \"%s\" (%s)]", name, lstate);
+
+  return PyString_FromString(buf);
+}
diff --git a/source/blender/python/api2_2x/Lamp.h b/source/blender/python/api2_2x/Lamp.h
new file mode 100644 (file)
index 0000000..4139bea
--- /dev/null
@@ -0,0 +1,312 @@
+/* 
+ *
+ * ***** 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_LAMP_H
+#define EXPP_LAMP_H
+
+#include <Python.h>
+#include <stdio.h>
+
+#include <BKE_main.h>
+#include <BKE_global.h>
+#include <BKE_object.h>
+#include <BKE_library.h>
+#include <DNA_lamp_types.h>
+
+#include "constant.h"
+#include "gen_utils.h"
+#include "modules.h"
+
+/*****************************************************************************/
+/* Python C_Lamp defaults:                                                   */
+/*****************************************************************************/
+#define EXPP_LAMP_MAX 256
+
+/* Lamp types */
+
+#define EXPP_LAMP_TYPE_LAMP 0
+#define EXPP_LAMP_TYPE_SUN  1
+#define EXPP_LAMP_TYPE_SPOT 2
+#define EXPP_LAMP_TYPE_HEMI 3
+
+/* Lamp mode flags */
+
+#define EXPP_LAMP_MODE_SHADOWS       1
+#define EXPP_LAMP_MODE_HALO          2
+#define EXPP_LAMP_MODE_LAYER         4
+#define EXPP_LAMP_MODE_QUAD          8
+#define EXPP_LAMP_MODE_NEGATIVE     16
+#define EXPP_LAMP_MODE_ONLYSHADOW   32
+#define EXPP_LAMP_MODE_SPHERE       64
+#define EXPP_LAMP_MODE_SQUARE      128
+#define EXPP_LAMP_MODE_TEXTURE     256
+#define EXPP_LAMP_MODE_OSATEX      512
+#define EXPP_LAMP_MODE_DEEPSHADOW 1024
+
+/* Lamp default and MIN, MAX values */
+
+#define EXPP_LAMP_TYPE EXPP_LAMP_TYPE_LAMP
+#define EXPP_LAMP_MODE EXPP_LAMP_MODE_SHADOWS
+#define EXPP_LAMP_SAMPLES     3
+#define EXPP_LAMP_SAMPLES_MIN 1
+#define EXPP_LAMP_SAMPLES_MAX 16
+#define EXPP_LAMP_BUFFERSIZE 512
+#define EXPP_LAMP_ENERGY      1.0
+#define EXPP_LAMP_ENERGY_MIN  0.0
+#define EXPP_LAMP_ENERGY_MAX 10.0
+#define EXPP_LAMP_DIST       20.0
+#define EXPP_LAMP_DIST_MIN    0.1
+#define EXPP_LAMP_DIST_MAX 5000.0
+#define EXPP_LAMP_SPOTSIZE      45.0
+#define EXPP_LAMP_SPOTSIZE_MIN   1.0
+#define EXPP_LAMP_SPOTSIZE_MAX 180.0
+#define EXPP_LAMP_SPOTBLEND     0.15
+#define EXPP_LAMP_SPOTBLEND_MIN 0.00
+#define EXPP_LAMP_SPOTBLEND_MAX 1.00
+#define EXPP_LAMP_CLIPSTART        0.5
+#define EXPP_LAMP_CLIPSTART_MIN    0.1
+#define EXPP_LAMP_CLIPSTART_MAX 1000.0
+#define EXPP_LAMP_CLIPEND       40.0
+#define EXPP_LAMP_CLIPEND_MIN    1.0
+#define EXPP_LAMP_CLIPEND_MAX 5000.0
+#define EXPP_LAMP_BIAS     1.00
+#define EXPP_LAMP_BIAS_MIN 0.01
+#define EXPP_LAMP_BIAS_MAX 5.00
+#define EXPP_LAMP_SOFTNESS       3.0
+#define EXPP_LAMP_SOFTNESS_MIN   1.0
+#define EXPP_LAMP_SOFTNESS_MAX 100.0
+#define EXPP_LAMP_HALOINT     1.0
+#define EXPP_LAMP_HALOINT_MIN 0.0
+#define EXPP_LAMP_HALOINT_MAX 5.0
+#define EXPP_LAMP_HALOSTEP      0
+#define EXPP_LAMP_HALOSTEP_MIN  0
+#define EXPP_LAMP_HALOSTEP_MAX 12
+#define EXPP_LAMP_QUAD1     0.0 /* Not implemented yet ( and not in 2.25) */
+#define EXPP_LAMP_QUAD1_MIN 0.0
+#define EXPP_LAMP_QUAD1_MAX 1.0
+#define EXPP_LAMP_QUAD2     1.0
+#define EXPP_LAMP_QUAD2_MIN 0.0
+#define EXPP_LAMP_QUAD2_MAX 1.0
+
+/*****************************************************************************/
+/* Python API function prototypes for the Lamp module.                       */
+/*****************************************************************************/
+static PyObject *M_Lamp_New (PyObject *self, PyObject *args, PyObject *keywords);
+static PyObject *M_Lamp_Get (PyObject *self, PyObject *args);
+
+/*****************************************************************************/
+/* The following string definitions are used for documentation strings.      */
+/* In Python these will be written to the console when doing a               */
+/* Blender.Lamp.__doc__                                                      */
+/*****************************************************************************/
+char M_Lamp_doc[] =
+"The Blender Lamp module\n\n\
+This module provides control over **Lamp Data** objects in Blender.\n\n\
+Example::\n\n\
+  from Blender import Lamp\n\
+  l = Lamp.New('Spot')\n\
+  l.setMode('square', 'shadow')\n\
+  ob = Object.New('Lamp')\n\
+  ob.link(l)\n";
+
+char M_Lamp_New_doc[] =
+"(type, name) - return a new Lamp datablock of type 'type'\n\
+                and optional name 'name'.";
+
+char M_Lamp_Get_doc[] =
+"(name) - return the lamp with the name 'name', \
+returns None if not found.\n If 'name' is not specified, \
+it returns a list of all lamps in the\ncurrent scene.";
+
+/*****************************************************************************/
+/* Python method structure definition for Blender.Lamp module:               */
+/*****************************************************************************/
+struct PyMethodDef M_Lamp_methods[] = {
+  {"New",(PyCFunction)M_Lamp_New, METH_VARARGS|METH_KEYWORDS,
+          M_Lamp_New_doc},
+  {"Get",         M_Lamp_Get,         METH_VARARGS, M_Lamp_Get_doc},
+  {"get",         M_Lamp_Get,         METH_VARARGS, M_Lamp_Get_doc},
+  {NULL, NULL, 0, NULL}
+};
+
+/*****************************************************************************/
+/* Python C_Lamp structure definition:                                       */
+/*****************************************************************************/
+typedef struct {
+  PyObject_HEAD
+  PyObject *dict;
+  Lamp     *lamp;
+       int      linked;
+} C_Lamp;
+
+/*****************************************************************************/
+/* Python C_Lamp methods declarations:                                     */
+/*****************************************************************************/
+static PyObject *Lamp_getName(C_Lamp *self);
+static PyObject *Lamp_getType(C_Lamp *self);
+static PyObject *Lamp_getMode(C_Lamp *self);
+static PyObject *Lamp_getSamples(C_Lamp *self);
+static PyObject *Lamp_getBufferSize(C_Lamp *self);
+static PyObject *Lamp_getHaloStep(C_Lamp *self);
+static PyObject *Lamp_getEnergy(C_Lamp *self);
+static PyObject *Lamp_getDist(C_Lamp *self);
+static PyObject *Lamp_getSpotSize(C_Lamp *self);
+static PyObject *Lamp_getSpotBlend(C_Lamp *self);
+static PyObject *Lamp_getClipStart(C_Lamp *self);
+static PyObject *Lamp_getClipEnd(C_Lamp *self);
+static PyObject *Lamp_getBias(C_Lamp *self);
+static PyObject *Lamp_getSoftness(C_Lamp *self);
+static PyObject *Lamp_getHaloInt(C_Lamp *self);
+static PyObject *Lamp_rename(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setType(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setIntType(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setMode(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setIntMode(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setSamples(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setBufferSize(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setHaloStep(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setEnergy(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setDist(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setSpotSize(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setSpotBlend(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setClipStart(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setClipEnd(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setBias(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setSoftness(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setHaloInt(C_Lamp *self, PyObject *args);
+static PyObject *Lamp_setColorComponent(C_Lamp *self, char *key,
+                                                               PyObject *args);
+
+/*****************************************************************************/
+/* Python C_Lamp methods table:                                              */
+/*****************************************************************************/
+static PyMethodDef C_Lamp_methods[] = {
+ /* name, method, flags, doc */
+  {"getName", (PyCFunction)Lamp_getName, METH_NOARGS,
+                                       "() - return Lamp name"},
+  {"getType", (PyCFunction)Lamp_getType, METH_NOARGS,
+                                       "() - return Lamp type -\n\t\
+'Lamp':0, 'Sun':1, 'Spot':2, 'Hemi':3"},
+  {"getMode", (PyCFunction)Lamp_getMode, METH_NOARGS,
+                                       "() - return Lamp mode flags (or'ed value)"},
+  {"getSamples", (PyCFunction)Lamp_getSamples, METH_NOARGS,
+                                       "() - return Lamp samples value"},
+  {"getBufferSize", (PyCFunction)Lamp_getBufferSize, METH_NOARGS,
+                                       "() - return Lamp buffer size value"},
+  {"getHaloStep", (PyCFunction)Lamp_getHaloStep, METH_NOARGS,
+                                       "() - return Lamp halo step value"},
+  {"getEnergy", (PyCFunction)Lamp_getEnergy, METH_NOARGS,
+                                       "() - return Lamp energy value"},
+  {"getDist", (PyCFunction)Lamp_getDist, METH_NOARGS,
+                                       "() - return Lamp clipping distance value"},
+  {"getSpotSize", (PyCFunction)Lamp_getSpotSize, METH_NOARGS,
+                                       "() - return Lamp spot size value"},
+  {"getSpotBlend", (PyCFunction)Lamp_getSpotBlend, METH_NOARGS,
+                                       "() - return Lamp spot blend value"},
+  {"getClipStart", (PyCFunction)Lamp_getClipStart, METH_NOARGS,
+                                       "() - return Lamp clip start value"},
+  {"getClipEnd", (PyCFunction)Lamp_getClipEnd, METH_NOARGS,
+                                       "() - return Lamp clip end value"},
+  {"getBias", (PyCFunction)Lamp_getBias, METH_NOARGS,
+                                       "() - return Lamp bias value"},
+  {"getSoftness", (PyCFunction)Lamp_getSoftness, METH_NOARGS,
+                                       "() - return Lamp softness value"},
+  {"getHaloInt", (PyCFunction)Lamp_getHaloInt, METH_NOARGS,
+                                       "() - return Lamp halo intensity value"},
+  {"rename", (PyCFunction)Lamp_rename, METH_VARARGS,
+                                       "(str) - rename Lamp"},
+  {"setType", (PyCFunction)Lamp_setType, METH_VARARGS,
+                                       "(str) - change Lamp type, which can be 'persp' or 'ortho'"},
+  {"setMode", (PyCFunction)Lamp_setMode, METH_VARARGS,
+                                       "([up to eight str's]) - Set Lamp mode flag(s)"},
+  {"setSamples", (PyCFunction)Lamp_setSamples, METH_VARARGS,
+                                       "(int) - change Lamp samples value"},
+  {"setBufferSize", (PyCFunction)Lamp_setBufferSize, METH_VARARGS,
+                                       "(int) - change Lamp buffer size value"},
+  {"setHaloStep", (PyCFunction)Lamp_setHaloStep, METH_VARARGS,
+                                       "(int) - change Lamp halo step value"},
+  {"setEnergy", (PyCFunction)Lamp_setEnergy, METH_VARARGS,
+                                       "(float) - change Lamp energy value"},
+  {"setSpotSize", (PyCFunction)Lamp_setSpotSize, METH_VARARGS,
+                                       "(float) - change Lamp spot size value"},
+  {"setSpotBlend", (PyCFunction)Lamp_setHaloStep, METH_VARARGS,
+                                       "(float) - change Lamp spot blend value"},
+  {"setClipStart", (PyCFunction)Lamp_setClipStart, METH_VARARGS,
+                                       "(float) - change Lamp clip start value"},
+  {"setClipEnd", (PyCFunction)Lamp_setClipEnd, METH_VARARGS,
+                                       "(float) - change Lamp clip end value"},
+  {"setBias", (PyCFunction)Lamp_setBias, METH_VARARGS,
+                                       "(float) - change Lamp draw size value"},
+  {"setSoftness", (PyCFunction)Lamp_setSoftness, METH_VARARGS,
+                                       "(float) - change Lamp softness value"},
+  {"setHaloInt", (PyCFunction)Lamp_setHaloInt, METH_VARARGS,
+                                       "(float) - change Lamp halo intensity value"},
+  {0}
+};
+
+/*****************************************************************************/
+/* Python TypeLamp callback function prototypes:                             */
+/*****************************************************************************/
+static void LampDeAlloc (C_Lamp *lamp);
+static PyObject *LampGetAttr (C_Lamp *lamp, char *name);
+static int LampSetAttr (C_Lamp *lamp, char *name, PyObject *v);
+static PyObject *LampRepr (C_Lamp *lamp);
+static int LampPrint (C_Lamp *lamp, FILE *fp, int flags);
+
+/*****************************************************************************/
+/* Python TypeLamp structure definition:                                     */
+/*****************************************************************************/
+static PyTypeObject Lamp_Type =
+{
+  PyObject_HEAD_INIT(&PyType_Type)
+  0,                                      /* ob_size */
+  "Lamp",                               /* tp_name */
+  sizeof (C_Lamp),                     /* tp_basicsize */
+  0,                                      /* tp_itemsize */
+  /* methods */
+  (destructor)LampDeAlloc,              /* tp_dealloc */
+  (printfunc)LampPrint,                 /* tp_print */
+  (getattrfunc)LampGetAttr,             /* tp_getattr */
+  (setattrfunc)LampSetAttr,             /* tp_setattr */
+  0,                                      /* tp_compare */
+  (reprfunc)LampRepr,                   /* tp_repr */
+  0,                                      /* tp_as_number */
+  0,                                      /* tp_as_sequence */
+  0,                                      /* tp_as_mapping */
+  0,                                      /* tp_as_hash */
+  0,0,0,0,0,0,
+  0,                                      /* tp_doc */ 
+  0,0,0,0,0,0,
+  C_Lamp_methods,                      /* tp_methods */
+  0,                                      /* tp_members */
+};
+
+#endif /* EXPP_LAMP_H */
diff --git a/source/blender/python/api2_2x/constant.c b/source/blender/python/api2_2x/constant.c
new file mode 100644 (file)
index 0000000..2ab7a2e
--- /dev/null
@@ -0,0 +1,212 @@
+/* 
+ *
+ * ***** 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 "constant.h"
+
+/* This file is heavily based on the old bpython Constant object code in
+   Blender */
+
+/*****************************************************************************/
+/* Python constant_Type callback function prototypes:                        */
+/*****************************************************************************/
+static void constantDeAlloc (C_constant *cam);
+static PyObject *constantGetAttr (C_constant *cam, char *name);
+static PyObject *constantRepr (C_constant *cam);
+static int constantLength(C_constant *self);
+static PyObject *constantSubscript(C_constant *self, PyObject *key);
+static int constantAssSubscript(C_constant *self, PyObject *who,
+                                PyObject *cares);
+
+/*****************************************************************************/
+/* Python constant_Type Mapping Methods table:                               */
+/*****************************************************************************/
+static PyMappingMethods constantAsMapping =
+{
+  (inquiry)constantLength,             /* mp_length        */
+  (binaryfunc)constantSubscript,       /* mp_subscript     */
+  (objobjargproc)constantAssSubscript, /* mp_ass_subscript */
+};
+
+/*****************************************************************************/
+/* Python constant_Type structure definition:                                */
+/*****************************************************************************/
+PyTypeObject constant_Type =
+{
+  PyObject_HEAD_INIT(&PyType_Type)
+  0,                                      /* ob_size */
+  "constant",                             /* tp_name */
+  sizeof (C_constant),                    /* tp_basicsize */
+  0,                                      /* tp_itemsize */
+  /* methods */
+  (destructor)constantDeAlloc,            /* tp_dealloc */
+  0,                                      /* tp_print */
+  (getattrfunc)constantGetAttr,           /* tp_getattr */
+  0,                                      /* tp_setattr */
+  0,                                      /* tp_compare */
+  (reprfunc)constantRepr,                 /* tp_repr */
+  0,                                      /* tp_as_number */
+  0,                                      /* tp_as_sequence */
+  &constantAsMapping,                     /* tp_as_mapping */
+  0,                                      /* tp_as_hash */
+  0,0,0,0,0,0,
+  0,                                      /* tp_doc */ 
+  0,0,0,0,0,0,
+  0,                                      /* tp_methods */
+  0,                                      /* tp_members */
+};
+
+/*****************************************************************************/
+/* Function:              constant_New                                       */
+/*****************************************************************************/
+static PyObject *new_const(void);
+
+PyObject *constant_New(void) /* can't be static, we call it in other files */
+{
+  return new_const();
+}
+
+static PyObject *new_const(void)
+{ /* ... but this function needs to be static */
+  C_constant *constant;
+
+  printf ("In constant_New()\n");
+
+  constant = (C_constant *)PyObject_NEW(C_constant, &constant_Type);
+
+  if (constant == NULL)
+  {
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+                            "couldn't create constant object"));
+  }
+
+  if ((constant->dict = PyDict_New()) == NULL)
+  {
+    return (PythonReturnErrorObject (PyExc_MemoryError,
+                    "couldn't create constant object's dictionary"));
+  }
+  
+  return (PyObject *)constant;
+}
+
+/*****************************************************************************/
+/* Python C_constant methods:                                                */
+/*****************************************************************************/
+void constant_insert(C_constant *self, char *key, PyObject *value)
+{
+  if (self->dict)
+  {
+    PyDict_SetItemString(self->dict, key, value); 
+  }
+}
+
+/*****************************************************************************/
+/* Function:    constantDeAlloc                                              */
+/* Description: This is a callback function for the C_constant type. It is   */
+/*              the destructor function.                                     */
+/*****************************************************************************/
+static void constantDeAlloc (C_constant *self)
+{
+  Py_DECREF(self->dict);
+  PyObject_DEL (self);
+}
+
+/*****************************************************************************/
+/* Function:    constantGetAttr                                              */
+/* Description: This is a callback function for the C_constant type. It is   */
+/*              the function that accesses C_constant member variables and   */
+/*              methods.                                                     */
+/*****************************************************************************/
+static PyObject* constantGetAttr (C_constant *self, char *name)
+{
+  if (self->dict)
+  {
+    PyObject *v;
+
+    if (!strcmp(name, "__members__"))
+    {
+      return PyDict_Keys(self->dict);
+    }
+    v  = PyDict_GetItemString(self->dict, name);
+    if (v)
+    {
+      Py_INCREF(v); /* was a borrowed ref */
+      return v;
+    }
+    return (PythonReturnErrorObject (PyExc_AttributeError,
+                                     "attribute not found"));
+  }
+  return (PythonReturnErrorObject (PyExc_RuntimeError,
+                                   "constant object lacks a dictionary"));
+}
+
+/*****************************************************************************/
+/* Section:    Sequence Mapping                                              */
+/*             These functions provide code to access constant objects as    */
+/*             mappings.                                                     */
+/*****************************************************************************/
+static int constantLength(C_constant *self)
+{
+  return 0;
+}
+
+static PyObject *constantSubscript(C_constant *self, PyObject *key)
+{
+  if (self->dict)
+  {
+    PyObject *v = PyDict_GetItem(self->dict, key);
+    if (v)
+    {
+      Py_INCREF(v);
+      return v;
+    }
+  }
+
+  return NULL;
+}
+
+static int constantAssSubscript(C_constant *self, PyObject *who,
+                                PyObject *cares)
+{
+  /* no user assignments allowed */
+  return 0;
+}
+
+/*****************************************************************************/
+/* Function:    constantRepr                                                 */
+/* Description: This is a callback function for the C_constant type. It      */
+/*              builds a meaninful string to represent constant objects.     */
+/*****************************************************************************/
+static PyObject *constantRepr (C_constant *self)
+{
+  PyObject *repr = PyObject_Repr(self->dict);
+  return repr;
+}
diff --git a/source/blender/python/api2_2x/constant.h b/source/blender/python/api2_2x/constant.h
new file mode 100644 (file)
index 0000000..0eb6eae
--- /dev/null
@@ -0,0 +1,61 @@
+/* 
+ *
+ * ***** 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_constant_H
+#define EXPP_constant_H
+
+#include <Python.h>
+#include <stdio.h>
+
+#include "gen_utils.h"
+
+/* Objects of <type 'constant'> are instanced inside many other Blender Python
+ * objects, so this header file must contain only 'public' declarations */
+
+/*****************************************************************************/
+/* Python API function prototypes for the constant module.                   */
+/*****************************************************************************/
+PyObject *constant_New (void);
+
+/*****************************************************************************/
+/* Python C_constant structure definition:                                   */
+/*****************************************************************************/
+typedef struct {
+  PyObject_HEAD
+  PyObject *dict;
+} C_constant;
+
+/*****************************************************************************/
+/* Python C_constant methods declarations:                                   */
+/*****************************************************************************/
+void constant_insert(C_constant *self, char *name, PyObject *args);
+
+#endif /* EXPP_constant_H */
index f44bc7f95144baf9879484577993fa08d2ae87c0..a5ccb9cf6208a790109f19fabfaf299a1c66fa9a 100644 (file)
 #include <DNA_object_types.h>
 #include <DNA_scriptlink_types.h>
 
+/*****************************************************************************/
+/* Description: This function clamps a float to the given interval           */
+/*              [min, max].                                                  */
+/*****************************************************************************/
+float EXPP_ClampFloat (float value, float min, float max)
+{
+       if (value < min) return min;
+       else if (value > max) return max;
+       return value;
+}
+
 /*****************************************************************************/
 /* Description: This function returns true if both given strings are equal,  */
 /*              otherwise it returns false.                                  */
@@ -58,7 +69,7 @@ char * GetIdName (ID *id)
 }
 
 /*****************************************************************************/
-/* Description: This function sets an internal string with the given type    */
+/* Description: These functions set an internal string with the given type   */
 /*              and error_msg arguments.                                     */
 /*****************************************************************************/
 PyObject * PythonReturnErrorObject (PyObject * type, char * error_msg)
@@ -67,6 +78,12 @@ PyObject * PythonReturnErrorObject (PyObject * type, char * error_msg)
        return (NULL);
 }
 
+int EXPP_intError (PyObject *type, char *error_msg)
+{
+       PyErr_SetString (type, error_msg);
+       return -1;
+}
+
 /*****************************************************************************/
 /* Description: This function increments the reference count of the given    */
 /*              Python object.                                               */
index 038c7f814ad44d4f72a084596d46ca4d3e0c6362..c7ce089c07c9452303e3e15f21bb2fa1b7fdca66 100644 (file)
@@ -38,6 +38,8 @@ char * GetIdName (ID *id);
 PyObject * PythonReturnErrorObject (PyObject * type, char * error_msg);
 PyObject * PythonIncRef (PyObject *object);
 char * event_to_name(short event);
+float EXPP_ClampFloat(float value, float min, float max);
+int EXPP_intError(PyObject *type, char *error_msg);
 
 /* The following functions may need to be moved to the respective BKE or */
 /* DNA modules. */
index ce6c4be6bf321e0470033dad6e2a91cfad5f37a3..6d1fa51c993fa2c8db03f03d2a85264c2aa5b881 100644 (file)
@@ -31,6 +31,9 @@
 #include <Python.h>
 
 #include <DNA_object_types.h>
+#include <DNA_camera_types.h>
+#include <DNA_lamp_types.h>
+#include <DNA_image_types.h>
 
 /*****************************************************************************/
 /* Global variables                                                          */
@@ -40,5 +43,9 @@ PyObject *g_blenderdict;
 void initBlender (void);
 PyObject* initObject (void);
 PyObject* ObjectCreatePyObject (struct Object *obj);
-PyObject* initCamera (void);
+PyObject* M_Camera_Init (void);
 PyObject* CameraCreatePyObject (struct Camera *cam);
+PyObject* M_Lamp_Init (void);
+PyObject* LampCreatePyObject (struct Lamp *lamp);
+PyObject* M_Image_Init (void);
+PyObject* ImageCreatePyObject (struct Image *img);