New scripts:
authorWillian Padovani Germano <wpgermano@gmail.com>
Sat, 3 Jul 2004 05:17:04 +0000 (05:17 +0000)
committerWillian Padovani Germano <wpgermano@gmail.com>
Sat, 3 Jul 2004 05:17:04 +0000 (05:17 +0000)
- hotkeys, obdatacopier and renameobjectbyblock, all from Jean-Michel Soler (jms);
- bevel_center by Loic Berthe, suggested for inclusion by jms;
- doc_browser, by Daniel Dunbar (Zr)

  Thanks to them for the new contributions!

  (I included doc_browser at 'Misc' because only users interested in script writing would actually use it, but it could also be under 'Help'.  Opinions?)

BPython related:
- Added scriptlink methods to object, lamp, camera and world.
- Object: added object.makeTrack and object.clearTrack (old track method).
- sys: made sys.exists(path) return 0 for not found; 1 for file, 2 for dir and -1 for neither.
- doc updates and fixes.
- made ONLOAD event work.  G.f's SCENESCRIPT bit was being zeroed in set_app_data.
- Blender: updated functions Load and Save to support the builtin importers and exporters besides .blend (dxf, videoscape, vrml 1.0, stl, ...)
- Draw: added mouse wheel events.
- Scene: added scene.play to play back animations (like ALT+A and SHIFT+ALT+A).  Makes a good counter, too, when the 'win' attribute is set to a space that doesn't "animate".

The scene.play() addition and the fix to ONLOAD scriptlinks is part of the work for a Blender demo mode.  It already works, but I'll still add support for Radiosity calculations and fix a thing in main(): it executes onload scripts too early (BIF_Init), giving funny results in alt+a animations and renderings when firing up Blender.  Loading after the program is up has no such problems.  When I finish I'll post examples of demo mode scripts.

34 files changed:
release/scripts/ac3d_export.py
release/scripts/bevel_center.py [new file with mode: 0644]
release/scripts/doc_browser.py [new file with mode: 0644]
release/scripts/hotkeys.py [new file with mode: 0644]
release/scripts/obdatacopier.py [new file with mode: 0644]
release/scripts/renameobjectbyblock.py [new file with mode: 0644]
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/exotic.c
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/Draw.c
source/blender/python/api2_2x/Lamp.c
source/blender/python/api2_2x/Lamp.h
source/blender/python/api2_2x/Object.c
source/blender/python/api2_2x/Scene.c
source/blender/python/api2_2x/Sys.c
source/blender/python/api2_2x/World.c
source/blender/python/api2_2x/World.h
source/blender/python/api2_2x/doc/BGL.py
source/blender/python/api2_2x/doc/Blender.py
source/blender/python/api2_2x/doc/Camera.py
source/blender/python/api2_2x/doc/Draw.py
source/blender/python/api2_2x/doc/Image.py
source/blender/python/api2_2x/doc/Lamp.py
source/blender/python/api2_2x/doc/Mathutils.py
source/blender/python/api2_2x/doc/Object.py
source/blender/python/api2_2x/doc/Scene.py
source/blender/python/api2_2x/doc/Sys.py
source/blender/python/api2_2x/doc/Window.py
source/blender/python/api2_2x/doc/World.py
source/blender/src/drawtext.c
source/blender/src/drawview.c
source/creator/creator.c

index e1ec989963fac0a065b5f9860b859fe8461efa7b..3ee140e9a2cf67f6cf9f9c2036deb3d8914764e7 100644 (file)
@@ -100,13 +100,11 @@ def matrix_mul(m, n = acmatrix):
 
 # ---
 
-errmsg = ''
-
 class AC3DExport:
 
     def __init__(self, scene, filename):
 
-        global ARG, SKIP_DATA, ADD_DEFAULT_MAT, DEFAULT_MAT, errmsg
+        global ARG, SKIP_DATA, ADD_DEFAULT_MAT, DEFAULT_MAT
 
         print 'Trying AC3DExport...'
 
@@ -179,7 +177,9 @@ class AC3DExport:
         try:
             file = open(filename, 'w')
         except IOError, (errno, strerror):
-            errmsg = "IOError #%s: %s" % (errno, strerror)
+            errmsg = "IOError #%s" % errno
+            errmsg = errmsg + "%t|" + strerror
+            Blender.Draw.PupMenu(errmsg)
             return None
         file.write(buf)
         file.close()
@@ -333,30 +333,43 @@ def gui():
     BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
     BGL.glColor3f(1,1,1)
     BGL.glRasterPos2i(18, 150)
-    Draw.Text("AC3D is a simple, affordable commercial 3d modeller that can be found at www.ac3d.org .")
+    Draw.Text("AC3D is a simple, affordable commercial 3d modeller that can "
+      "be found at www.ac3d.org .")
     BGL.glRasterPos2i(18, 130)
-    Draw.Text("It uses a nice text file format (extension .ac) which supports uv-textured meshes")
+    Draw.Text("It uses a nice text file format (extension .ac) which supports "
+      "uv-textured meshes")
     BGL.glRasterPos2i(18, 110)
     Draw.Text("with parenting (grouping) information.")
     BGL.glRasterPos2i(18, 90)
-    Draw.Text("Notes: AC3D has a 'data' token that assigns a string to each mesh, useful for games,")
+    Draw.Text("Notes: AC3D has a 'data' token that assigns a string to each "
+      "mesh, useful for games,")
     BGL.glRasterPos2i(55, 70)
-    Draw.Text("for example. You can use Blender's mesh datablock name for that.")
+    Draw.Text("for example. You can use Blender's mesh 'ME:' field for that.")
     BGL.glRasterPos2i(55, 50)
     Draw.Text("The .ac format is well supported by the PLib 3d gaming library.")
-    Draw.Button("Ok", 21, 285, 10, 45, 20, "Click to return to previous screen.")
+    Draw.Button("Ok", 21, 285, 10, 45, 20,
+      "Click to return to previous screen.")
   else:
     BGL.glClearColor(0,0,1,1)
     BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
     BGL.glColor3f(1,1,1)
     BGL.glRasterPos2i(20, 150)
     Draw.Text("AC3D Exporter")
-    Draw.Toggle("Default mat", 1, 15, 100, 90, 20, ADD_DEFAULT_MAT, "Objects without materials assigned get a default (white) one automatically.")
-    Draw.Toggle("Skip data", 2, 15, 80, 90, 20, SKIP_DATA, "Don't export mesh names as 'data' info.")
-    Draw.Toggle("Mir2Amb", 3, 15, 50, 90, 20, MIRCOL_AS_AMB, "Get AC3D's ambient RGB color for each object from its mirror color in Blender.")
-    Draw.Toggle("Mir2Emis", 4, 15, 30, 90, 20, MIRCOL_AS_EMIS, "Get AC3D's emissive RGB color for each object from its mirror color in Blender.")
-    Draw.Button("Export All...", 10, 140, 80, 110, 30, "Export all meshes to an AC3D file.")
-    Draw.Button("Export Selected...", 11, 140, 40, 110, 30, "Export selected meshes to an AC3D file.")
+    Draw.Toggle("Default mat", 1, 15, 100, 90, 20, ADD_DEFAULT_MAT,
+      "Objects without materials assigned get a default (white) one"
+      " automatically.")
+    Draw.Toggle("Skip data", 2, 15, 80, 90, 20, SKIP_DATA,
+      "Don't export mesh names as 'data' info.")
+    Draw.Toggle("Mir2Amb", 3, 15, 50, 90, 20, MIRCOL_AS_AMB,
+      "Get AC3D's ambient RGB color for each object from its mirror color "
+      "in Blender.")
+    Draw.Toggle("Mir2Emis", 4, 15, 30, 90, 20, MIRCOL_AS_EMIS,
+      "Get AC3D's emissive RGB color for each object from its mirror color "
+      "in Blender.")
+    Draw.Button("Export All...", 10, 140, 80, 110, 30,
+      "Export all meshes to an AC3D file.")
+    Draw.Button("Export Selected...", 11, 140, 40, 110, 30,
+      "Export selected meshes to an AC3D file.")
     Draw.Button("HELP", 20, 285, 80, 100, 40, "Click for additional info.")
     Draw.Button("EXIT", 22, 285, 30, 100, 40, "Click to leave.")
 
diff --git a/release/scripts/bevel_center.py b/release/scripts/bevel_center.py
new file mode 100644 (file)
index 0000000..eef2f63
--- /dev/null
@@ -0,0 +1,462 @@
+#!BPY
+
+""" Registration info for Blender menus
+Name: 'Bevel Center'
+Blender: 232
+Group: 'Mesh'
+Tip: 'Bevel selected vertices.'
+"""
+
+######################################################################
+# Bevel Center v1 for Blender
+#
+# This script lets you bevel the selected vertices and control the
+# thickness of the bevel
+#
+# (c) 2004 Loïc Berthe (loic.berthe@lilotux.net)
+# released under Blender Artistic License
+#
+######################################################################
+
+import Blender
+from Blender import NMesh
+from Blender.Draw import *
+from Blender.BGL import *
+
+from math import pi, sin, sqrt
+
+######################################################################
+# Functions to handle the global structures of the script NV, NE and NC
+# which contain informations about the vertices, faces and corners to be
+# created
+
+class Dir:
+       def __init__(self, co):
+               self.co = co
+
+def add_to_NV(old,co,new):
+       dir = Dir(co)
+       #
+       if old in NV.keys():
+               NV[old][dir] = new
+       else:
+               NV[old] = {dir:new}
+
+def is_in_NV(old,co):
+       if old in NV.keys():
+               for dir in NV[old]:
+                       if dir.co == co : return NV[old][dir]
+       #
+       return False
+
+def add_to_NE(old, new):
+       ind1 = old[0].index
+       ind2 = old[1].index
+       if ind1 > ind2:
+               new.reverse()
+               ind1,ind2 = ind2,ind1
+       id = str(ind1)+"_"+str(ind2)
+       if id in NE.keys():
+               [NE[id].append(v) for v in new]
+       else:
+               NE[id] = new
+
+def add_to_NC(old,edge):
+       if old in NC.keys():
+               NC[old].append(edge)
+       else:
+               NC[old] = [edge]
+               
+######################################################################
+# Geometric functions
+               
+def norm(vec):
+       n = sqrt(vec[0]**2+vec[1]**2+vec[2]**2)
+       return [vec[0]/n,vec[1]/n,vec[2]/n]
+
+def parall_coord(old, dir):
+       co = old.co
+       vec = [0.0,0.0,0.0]
+       nco = [0.0,0.0,0.0]
+       #
+       if len(dir) == 1:
+               for i in range(3): vec[i] = dir[0].co[i] - co[i] 
+               vec = norm(vec)
+       #
+       elif len(dir) == 2:
+               vec1 = [0.0,0.0,0.0]
+               vec2 = [0.0,0.0,0.0]
+               for i in range(3):
+                       vec1[i] = dir[0].co[i] - co[i] 
+                       vec2[i] = dir[1].co[i] - co[i] 
+               vec1 = norm(vec1)
+               vec2 = norm(vec2)
+               for i in range(3) : vec[i] = vec1[i]+vec2[i]
+       #
+       for i in range(3): nco[i] = co[i] + dist.val*vec[i]
+       return (nco,vec)
+
+def get_vert(old, dir):
+       """ Look in NV if a vertice corresponding to the vertex old and the
+       direction dir already exists, and create one otherwise""" 
+       (nco, vec) = parall_coord(old, dir)
+       v = is_in_NV(old,vec)
+       if v: return v
+       #
+       v = NMesh.Vert(nco[0],nco[1],nco[2])
+       v.sel = 1
+       me.verts.append(v)
+       add_to_NV(old,vec,v)
+       return v
+                       
+######################################################################
+# Functions to create the differents faces
+       
+def make_NF():
+       """ Analyse the mesh, sort the faces containing selected vertices and
+       create a liste NF : NF = [[flag, vertlist, old_face]]. Flag describes the
+       topology of the face.""" 
+       #
+       for f in me.faces:
+               V = f.v
+               v_sel = [x.sel for x in V]
+               nb_sel = sum(v_sel)
+               if nb_sel == 0 :
+                       pass
+               else:
+                       nb_v = len(V)
+                       #
+                       if nb_v == 4:
+                               #
+                               if nb_sel == 4:
+                                       NF.append([1,V,f])
+                               #
+                               elif nb_sel == 3:
+                                       if v_sel == [0,1,1,1]: V = [V[1],V[2],V[3],V[0]]
+                                       elif v_sel == [1,0,1,1]: V = [V[2],V[3],V[0],V[1]]
+                                       elif v_sel == [1,1,0,1]: V = [V[3],V[0],V[1],V[2]]
+                                       NF.append([2,V,f])
+                               #               
+                               elif nb_sel == 2:
+                                       if v_sel == [1,0,1,0] or v_sel == [0,1,0,1]:
+                                               if      v_sel == [0,1,0,1]: V = [V[1],V[2],V[3],V[0]]
+                                               NF.append([5,[V[0],V[1],V[3]],f])
+                                               NF.append([5,[V[2],V[1],V[3]]])
+                                       else:
+                                               if v_sel == [0,1,1,0]: V = [V[1],V[2],V[3],V[0]]
+                                               elif v_sel == [0,0,1,1]: V = [V[2],V[3],V[0],V[1]]
+                                               elif v_sel == [1,0,0,1]: V = [V[3],V[0],V[1],V[2]]
+                                               NF.append([3,V,f])
+                               #
+                               else:
+                                       if v_sel == [0,1,0,0]: V = [V[1],V[2],V[3],V[0]]
+                                       elif v_sel == [0,0,1,0]: V = [V[2],V[3],V[0],V[1]]
+                                       elif v_sel == [0,0,0,1]: V = [V[3],V[0],V[1],V[2]]
+                                       NF.append([4,V,f])
+                       #
+                       elif nb_v == 3:
+                               #
+                               if nb_sel == 3:
+                                       NF.append([6,V,f])
+                               #
+                               elif nb_sel == 2:
+                                       if v_sel == [0,1,1]: V = [V[1],V[2],V[0]]
+                                       elif v_sel == [1,0,1]: V = [V[2],V[0],V[1]]
+                                       NF.append([7,V,f])
+                               #
+                               else:
+                                       if v_sel == [0,1,0]: V = [V[1],V[2],V[0]]
+                                       elif v_sel == [0,0,1]: V = [V[2],V[0],V[1]]
+                                       NF.append([5,V,f])
+
+def make_faces():
+       """ Make the new faces according to NF """
+       #
+       for N in NF:
+               cas = N[0]
+               V = N[1]
+               #
+               if cas < 6:
+                       new_v = [0,0,0,0]
+                       if cas == 1:                            # v_sel = [1,1,1,1]
+                               for i in range(-1,3):
+                                       new_v[i] = get_vert(V[i],[V[i-1],V[i+1]])
+                               new_f = NMesh.Face(new_v)
+                               me.faces.append(new_f)
+                               for i in range(-1,3):
+                                       add_to_NE([V[i],V[i+1]],[new_v[i],new_v[i+1]])
+                       #
+                       elif cas == 2:                          # v_sel = [1,1,1,0]
+                               new_v[0] = get_vert(V[0],[V[3]])
+                               new_v[1] = get_vert(V[1],[V[0],V[2]])
+                               new_v[2] = get_vert(V[2],[V[3]])
+                               new_v[3] = V[3]
+                               #
+                               new_f = NMesh.Face(new_v)
+                               me.faces.append(new_f)
+                               #
+                               add_to_NE([V[0],V[1]],[new_v[0],new_v[1]])
+                               add_to_NE([V[1],V[2]],[new_v[1],new_v[2]])
+                       #               
+                       elif cas == 3:                          # v_sel = [1,1,0,0]
+                               new_v[0] = get_vert(V[0],[V[3]])
+                               new_v[1] = get_vert(V[1],[V[2]])
+                               new_v[2] = V[2]
+                               new_v[3] = V[3]
+                               #
+                               new_f = NMesh.Face(new_v)
+                               me.faces.append(new_f)
+                               #
+                               add_to_NE([V[0],V[1]],[new_v[0],new_v[1]])
+                       #
+                       elif cas == 4:                          # v_sel = [1,0,0,0]
+                               new_v[0] = get_vert(V[0],[V[3]])
+                               new_v[1] = get_vert(V[0],[V[1]])
+                               new_v[2] = V[1]
+                               new_v[3] = V[3]
+                               #
+                               new_f = NMesh.Face(new_v)
+                               me.faces.append(new_f)
+                               #
+                               add_to_NC(V[0], new_v[0:2])
+                               #
+                               new_v[0] = V[1]
+                               new_v[1] = V[2]
+                               new_v[2] = V[3]
+                               #
+                               new_f = NMesh.Face(new_v[:3])
+                               me.faces.append(new_f)
+                       #
+                       else:                           # v_sel = [1,0,0]
+                               new_v[0] = get_vert(V[0],[V[2]])
+                               new_v[1] = get_vert(V[0],[V[1]])
+                               new_v[2] = V[1]
+                               new_v[3] = V[2]
+                               #
+                               new_f = NMesh.Face(new_v)
+                               me.faces.append(new_f)
+                               #
+                               add_to_NC(V[0], new_v[0:2])
+               #
+               else:
+                       new_v = [0,0,0]
+                       #
+                       if cas == 6:                            # v_sel = [1,1,1]
+                               for i in range(-1,2):
+                                       new_v[i] = get_vert(V[i],[V[i-1],V[i+1]])
+                               new_f = NMesh.Face(new_v)
+                               me.faces.append(new_f)
+                               for i in range(-1,2):
+                                       add_to_NE([V[i],V[i+1]],[new_v[i],new_v[i+1]])
+                       #
+                       elif cas == 7:                          # v_sel = [1,1,0]
+                               new_v[0] = get_vert(V[0],[V[2]])
+                               new_v[1] = get_vert(V[1],[V[2]])
+                               new_v[2] = V[2]
+                               #
+                               new_f = NMesh.Face(new_v)
+                               me.faces.append(new_f)
+                               add_to_NE([V[0],V[1]],[new_v[0],new_v[1]])
+
+def make_edges():
+       """ Make the faces corresponding to selected edges """
+       #
+       for l in NE.values():
+               if len(l) == 4:
+                       f = NMesh.Face([l[0],l[1],l[3],l[2]])
+                       me.faces.append(f)
+
+def make_corners():
+       """ Make the faces corresponding to selected corners """
+       #
+       for v in NV.keys():
+               V = NV[v].values()
+               nb_v = len(V)
+               #
+               if nb_v < 3:
+                       pass
+               #
+               elif nb_v == 3:
+                       new_f = NMesh.Face(V)
+                       me.faces.append(new_f)
+               #
+               else:
+                       # We need to know which are the edges around the corner.
+                       # First, we look for the quads surrounding the corner.
+                       q = [NE[id] for id in NE.keys() if str(v.index) in id.split('_')]
+                       #
+                       # We will put the associated edges in the list eed
+                       is_in_v = lambda x:x in V
+                       eed =  [filter(is_in_v, l) for l in q]
+                       #
+                       # We will add the edges coming from faces where only one vertice is selected.
+                       # They are stocked in NC.
+                       if v in NC.keys():
+                               eed = eed+NC[v]
+                       b = eed.pop()
+                       # b will contain the sorted list of vertices
+                       #
+                       while  eed:
+                               for l in eed:
+                                       if l[0] == b[-1]:
+                                               b.append(l[1])
+                                               eed.remove(l)
+                                               break
+                                       elif l[1] == b[-1]:
+                                               b.append(l[0])
+                                               eed.remove(l)
+                                               break
+                       # Now we can create the faces
+                       if nb_v == 4:
+                               new_f = NMesh.Face(b[:4])
+                               me.faces.append(new_f)
+                       #
+                       else:
+                               co = [0.0, 0.0,0.0]
+                               vec = [0.0, 0.0,0.0]
+                               for x in V:
+                                       co[0] += x[0]
+                                       co[1] += x[1]
+                                       co[2] += x[2]
+                               #
+                               for dir in NV[v]:
+                                       vec[0] += dir.co[0]
+                                       vec[1] += dir.co[1]
+                                       vec[2] += dir.co[2]
+                               #
+                               co = [x/nb_v for x in co]
+                               vec = [x/nb_v for x in vec]
+                               center = NMesh.Vert(co[0],co[1],co[2])
+                               center.sel = 1
+                               me.verts.append(center)
+                               add_to_NV(v,vec,center)
+                               #
+                               for k in range(nb_v):
+                                       new_f = NMesh.Face([center, b[k], b[k+1]])
+                                       me.faces.append(new_f)
+               #
+
+def clear_old():
+       """ Erase old faces and vertices """
+       for F in NF:
+               if len(F) == 3:
+                       me.faces.remove(F[2])
+       #
+       for v in NV.keys():
+               me.verts.remove(v)
+
+######################################################################
+# Interface
+#
+global dist
+dist = Create(0.2)
+left = Create(0.0)
+right = Create(1.0)
+num = Create(2)
+
+# Events
+EVENT_NOEVENT = 1
+EVENT_BEVEL = 2
+EVENT_UPDATE = 3
+EVENT_RECURS = 4
+EVENT_EXIT = 5
+
+def draw():
+       global dist, left, right, num
+       global EVENT_NOEVENT, EVENT_BEVEL, EVENT_UPDATE, EVENT_RECURS, EVENT_EXIT
+
+       glClear(GL_COLOR_BUFFER_BIT)
+       Button("Bevel",EVENT_BEVEL,10,100,280,25)
+       left=Number('',  EVENT_NOEVENT,10,70,45, 20,left.val,0,right.val,'Set the minimum of the slider')
+       right = Number("",EVENT_NOEVENT,245,70,45,20,right.val,left.val,200,"Set the maximum of the slider")
+       dist=Slider("Thickness  ",EVENT_UPDATE,60,70,180,20,dist.val,left.val,right.val,0,"Thickness of the bevel")
+       glRasterPos2d(8,40)
+       Text('To finish, you can use recursive bevel to smooth it')
+       num=Number('',  EVENT_NOEVENT,10,10,40, 16,num.val,1,100,'Recursion level')
+       Button("Recursive",EVENT_RECURS,55,10,100,16)
+       Button("Exit",EVENT_EXIT,210,10,80,20)
+
+def event(evt, val):
+       if (evt == QKEY and not val):
+               Exit()
+
+def bevent(evt):
+       if evt == EVENT_EXIT :
+               Exit()
+       #
+       elif evt == EVENT_BEVEL:
+               bevel()
+       #
+       elif evt == EVENT_UPDATE:
+               try:
+                       bevel_update()
+               except NameError:
+                       pass
+       #
+       elif evt == EVENT_RECURS:
+               recursive()
+
+Register(draw, event, bevent)
+
+######################################################################
+def bevel():
+       """ The main function, which creates the bevel """
+       global me,NF,NV,NE,NC, old_dist
+       #
+       objects = Blender.Object.GetSelected() 
+       me = NMesh.GetRaw(objects[0].data.name)
+       #
+       NF = []
+       NV = {}
+       NE = {}
+       NC = {}
+       #
+       make_NF()
+       make_faces()
+       make_edges()
+       make_corners()
+       clear_old()
+       #
+       old_dist = dist.val
+       #
+       me.update(1)
+       Blender.Redraw()
+
+def bevel_update():
+       """ Use NV to update the bevel """
+       global dist, old_dist
+       fac = dist.val - old_dist
+       old_dist = dist.val
+       #
+       for old_v in NV.keys():
+               for dir in NV[old_v].keys():
+                       for i in range(3):
+                               NV[old_v][dir].co[i] += fac*dir.co[i]
+       #
+       me.update(1)
+       Blender.Redraw()
+
+def recursive():
+       """ Make a recursive bevel... still experimental """
+       global dist
+       #
+       if num.val > 1:
+               a = pi/4
+               ang = []
+               for k in range(num.val):
+                       ang.append(a)
+                       a = (pi+2*a)/4
+               #
+               l = [2*(1-sin(x))/sin(2*x) for x in ang]
+               R = dist.val/sum(l)
+               l = [x*R for x in l]
+               #
+               dist.val = l[0]
+               bevel_update()
+               #
+               for x in l[1:]:
+                       dist.val = x
+                       bevel()
+       
+# vim:set ts=4 sw=4:
+
diff --git a/release/scripts/doc_browser.py b/release/scripts/doc_browser.py
new file mode 100644 (file)
index 0000000..e9c63b3
--- /dev/null
@@ -0,0 +1,425 @@
+#!BPY
+
+"""
+Name: 'BPy Doc Browser'
+Blender: 232
+Group: 'Misc'
+Tip: 'Browse BPython (scripting API) modules doc strings.'
+"""
+
+# $Id$
+#
+# --------------------------------------------------------------------------
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# Copyright (C) 2004:  Daniel Dunbar, ddunbar _at_ diads.com
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+
+#####
+# Blender help browser
+# By Daniel Dunbar, 
+#
+# This should function as a self-explanatory (interface, not code)
+# (mostly) help browser. The code is wacky and nasty and or fun,
+# but mainly bad, just cause it works doesn't mean its readable! 
+# 
+# TEEHEE!
+#
+# The row_draw function could easily be made into a more generic
+# and usefull table drawing function... 
+#
+
+import Blender
+from types import ListType, IntType, FloatType, StringType, ModuleType
+from Blender.Draw import *
+from Blender.BGL import *
+
+# Simple version check, since I use the
+# buffer calls... DONT use this code,
+# assume everyone has 1.73+, and force
+# them to upgrade if they dont
+try:
+       a= BufList
+       version= 172
+except:
+       version= 173
+       
+# I could have used the split from the string module,
+# but some people might not have it
+def split(str, on):
+       out= [""]
+       for s in str:
+               if s in on: out.append("")
+               else: out[-1]= out[-1]+s
+
+       if out[-1]=="": del(out[-1])
+
+       return out
+
+last_sort= 1; direction= 1
+def sort_browselist(type):
+       global browselist
+       global last_sort, direction
+
+       if (type==last_sort): direction= -direction
+       else: direction= 1
+
+       last_sort= type
+
+       if (direction==1):
+               def byname(x, y): return cmp(x[0],y[0]);
+               def bytype(x, y): return cmp(x[1],y[1])
+               def bydata(x, y): return cmp(x[2],y[2])
+       else:
+               def byname(x, y): return cmp(y[0],x[0]);
+               def bytype(x, y): return cmp(y[1],x[1])
+               def bydata(x, y): return cmp(y[2],x[2])
+
+       if (type==1): browselist.sort(byname)
+       elif (type==2): browselist.sort(bytype)
+       elif (type==3): browselist.sort(bydata)
+
+selected= -1
+def view_doc(num):
+       global selected, selected_page
+
+       if (selected==num): selected= -1
+       else: selected= num
+
+       selected_page= 0
+
+function_filter= 0
+def toggle_function_filter():
+       global function_filter
+
+       function_filter= not function_filter
+       make_browselist()
+
+def view_page(dir):
+       global selected_page
+
+       selected_page= selected_page + dir
+
+browse_scrollstart= 0
+def browse_module(num):
+       global browsing, selected, browse_scrollstart
+       
+       if (num>=0): newstr= browsing.val + "." + browselist[num][0]
+       else:
+               modules= split(browsing.val, ".")
+               newstr= ""
+               for m in modules[:-1]:
+                       newstr= newstr+m
+       try:
+               browsing= Create(newstr)
+               make_browselist()
+       except:
+               browsing= Create('Blender')
+               make_browselist()
+               
+       browse_scrollstart= 0
+       scrolling= 0
+       selected= -1
+
+def make_browselist():
+       global browselist
+
+       browselist= []
+
+       module= eval(browsing.val)
+       items= dir(module)
+
+       for item_name in items:
+               if (item_name[:2]=='__'): continue
+
+               data= [item_name, 'None', '', '']
+               item= eval(item_name,module.__dict__)
+               t= type(item)
+
+               if (t==IntType): data[1]= 'Int'; data[2]= `item`
+               elif (t==FloatType): data[1]= 'Float'; data[2]= `item`
+               elif (t==StringType): data[1]= 'String'
+               elif (t==ModuleType): data[1]= 'Module'
+               elif (callable(item)):
+                       data[1]= 'Function'
+                       doc= item.__doc__
+                       if (doc): data[3]= doc
+
+               if (function_filter and data[1]!='Function'): continue
+
+               browselist.append(data)
+
+browsing= Create('Blender')
+make_browselist()
+
+BROWSE_EVT= 1
+
+SORT_BYNAME= 2
+SORT_BYTYPE= 3
+SORT_BYDATA= 4
+
+DOC_PAGE_UP= 5
+DOC_PAGE_DOWN= 6
+
+BACK_MODULE= 7
+CLOSE_VIEW= 8
+FILTER_DISPLAY= 9
+
+SCROLLBAR= 10
+
+VIEW_DOC= 100
+BROWSE_MODULE= 20000
+
+scr= Create(0)
+browse_scrollstart= 0
+
+winrect= [0.0, 0.0, 0.0, 0.0]
+def draw():
+       global browsing, winrect, scr, browse_scrollstart
+
+       # Blender doesn't give us direct access to
+       # the window size yet, but it does set the
+       # GL scissor box for it, so we can get the 
+       # size from that.
+
+       if (version<173):
+               size= Buffer(GL_FLOAT, None, 4)
+               glGetFloat(GL_SCISSOR_BOX, size)
+               size= BufList(size)
+       else:
+               size= Buffer(GL_FLOAT, 4)
+               glGetFloatv(GL_SCISSOR_BOX, size)
+               size= size.list
+
+       winrect= size[:]
+
+       size[0]= size[1]= 0.0
+       
+       # Shrink the size to make a nice frame
+       # (also a good technique so you can be sure you are clipping things properly)
+       size[0], size[1]= int(size[0]+10), int(size[1]+10)
+       size[2], size[3]= int(size[2]-12), int(size[3]-10)
+
+       glClearColor(0.6, 0.5, 0.3, 0.0)
+       glClear(GL_COLOR_BUFFER_BIT)
+
+       # The frame
+       glColor3f(0.4, 0.5, 0.2)
+       glRectf(size[0], size[1], size[2], size[3])
+
+       # Window header 
+       glColor3f(0.2, 0.2, 0.4)
+       glRectf(size[0], size[3]-25, size[2], size[3])
+
+       glColor3f(0.6, 0.6, 0.6)
+       glRasterPos2f(size[0]+15, size[3]-17)
+       Text("Zr's Help Browser")
+
+       Button("Filter", FILTER_DISPLAY, size[2]-400, size[3]-22, 45, 18)
+       Button("Back", BACK_MODULE, size[2]-300, size[3]-22, 45, 18)
+       browsing= String("Browse: ", BROWSE_EVT, size[2]-250, size[3]-22, 245, 18, browsing.val, 30)
+
+       # The real table
+       def row_draw(rect, data, cols, cell_colors, text_colors):
+               if (len(data)!=len(cols)):
+                       print "Must have same length data and columns"
+                       return
+
+               if (type(cell_colors)!=ListType): cell_colors= [cell_colors]
+               if (type(text_colors)!=ListType): text_colors= [text_colors]
+
+               sx= rect[0]
+               for i in range(len(data)):
+                       d= data[i]
+                       c= cols[i]
+       
+                       c, align= c[0], c[1]
+
+                       if (type(c)==FloatType): c= c*(rect[2]-rect[0])
+                       ex= sx + c
+
+                       color= cell_colors[i%len(cell_colors)]
+                       apply(glColor3f, color)
+                       glRectf(sx, rect[1], ex, rect[3])
+
+                       color= text_colors[i%len(text_colors)]
+                       apply(glColor3f, color)
+
+                       if (type(d)==StringType):
+                               str_width= len(d)*8
+                               if (align=='left'): glRasterPos2f(sx+3, rect[1]+5)
+                               elif (align=='center'): glRasterPos2f((sx+ex)/2 - str_width/2 +3, rect[1]+5)
+                               elif (align=='right'): glRasterPos2f(ex - str_width -3, rect[1]+5)
+
+                               Text(d)
+                       else:
+                               d(map(int,[sx, rect[1], ex, rect[3]]))
+
+                       sx= ex
+       # Some colors
+       black= (0.0, 0.0, 0.0)
+       white= (1.0, 1.0, 1.0)
+       red= (0.8, 0.1, 0.1)
+
+       gray0= (0.17, 0.17, 0.17)
+       gray1= (0.25, 0.25, 0.25)
+       gray2= (0.33, 0.33, 0.33)
+       gray3= (0.41, 0.41, 0.41)
+       gray4= (0.49, 0.49, 0.49)
+       gray5= (0.57, 0.57, 0.57)
+       gray6= (0.65, 0.65, 0.65)
+
+       cols= [[.3, 'left'], [.2, 'left'], [.4, 'right'], [.1, 'center']]
+
+       header= [size[0]+20, size[3]-60, size[2]-40, size[3]-40]
+
+       def sort_byname(co): Button("Name",SORT_BYNAME, co[0]+3, co[1], co[2]-co[0]-4, 19)
+       def sort_bytype(co): Button("Type",SORT_BYTYPE, co[0]+3, co[1], co[2]-co[0]-4, 19)
+       def sort_bydata(co): Button("Data",SORT_BYDATA, co[0]+3, co[1], co[2]-co[0]-4, 19)
+
+       row_draw(header, [sort_byname, sort_bytype, sort_bydata,'Link'], cols, [gray0, gray1], gray6)
+
+       if (selected!=-1):
+               table= [size[0]+20, size[1]+220, size[2]-40, size[3]-60]
+       else:
+               table= [size[0]+20, size[1]+20, size[2]-40, size[3]-60]
+
+       row_height= 25
+       items= (table[3]-table[1])/row_height
+
+       items= 10
+       if (items>len(browselist)): items= len(browselist)
+
+       end= len(browselist)-items
+       if (end>0):
+               scr= Scrollbar(SCROLLBAR, table[2]+5, table[1], 20, table[3]-table[1], scr.val, 0.0, end, 0, "Page Up/Down scrolls list.")
+
+       row= table
+       row[1]= row[3]-row_height
+       start= browse_scrollstart
+       if (start+items>len(browselist)): items= len(browselist)-start
+       for i in range(items):
+               i= start+i
+               data= browselist[i][:]
+
+               if (i%2): colors= [gray1, gray2]
+               else: colors= [gray2, gray3]
+
+               # Strange pythonic code
+               def view_doc(co,num=i):
+                       Button("Doc",VIEW_DOC+num, co[0]+3, co[1]+2, co[2]-co[0]-4, 19)
+
+               def browse_module(co,num=i):
+                       Button("Browse",BROWSE_MODULE+num, co[0]+3, co[1]+2, co[2]-co[0]-4, 19)
+
+               if (data[1]=='Function'):
+                       if data[3]:
+                               data[3]= view_doc
+                               tcolor= black
+                       else:
+                               tcolor= red
+                               data[2]= 'NO DOC STRING'
+                               data[3]= ''
+               else:
+                       if (data[1]=='Module'): data[3]= browse_module
+                       else: data[3]= ''
+
+                       tcolor= black
+
+               row_draw(row, data, cols, colors, tcolor)
+
+               row[1]= row[1]-row_height
+               row[3]= row[3]-row_height
+
+       if (selected!=-1):
+               table= [size[0]+20, size[1]+20, size[2]-40, size[1]+180]
+
+               apply(glColor3f, gray5)
+               glRectf(table[0], table[3], table[2], table[3]+20)
+               apply(glColor3f, gray2)
+               glRectf(table[0], table[1], table[2], table[3])
+
+               apply(glColor3f, black)
+               glRasterPos2f(table[0]+3, table[3]+5)
+               Text("Function: " + browsing.val + "." + browselist[selected][0])
+
+               Button("Close", CLOSE_VIEW, table[2]-50, table[3], 45, 18)
+
+               row_height= 20
+               view_lines= int((table[3]-table[1])/row_height)-1
+
+               lines= split(browselist[selected][3], "\n")
+               doc_lines= len(lines)
+
+               sindex= view_lines*selected_page
+               eindex= view_lines*(selected_page+1)
+               if (sindex>0):
+                       sindex= sindex-1
+                       eindex= eindex-1
+
+               lines= lines[sindex:eindex]
+
+               y= table[3]-20
+               for line in lines:
+                       glRasterPos2f(table[0]+3, y)
+                       Text(line)
+
+                       y= y-20
+
+               if (sindex): Button("Page up", DOC_PAGE_UP, table[2]-100, table[3]-20, 90, 18)
+               if (eindex<doc_lines): Button("Page down", DOC_PAGE_DOWN, table[2]-100, table[1]+5, 90, 18)
+
+lmouse= [0, 0]
+def event(evt, val):
+       global browse_scrollstart
+
+       if (evt==QKEY or evt==ESCKEY): Exit()
+       elif (evt in [PAGEUPKEY, PAGEDOWNKEY] and val): 
+               if (evt==PAGEUPKEY): browse_scrollstart= browse_scrollstart-5
+               else: browse_scrollstart= browse_scrollstart+5
+               
+               if (browse_scrollstart<0): browse_scrollstart= 0
+               elif (browse_scrollstart>=len(browselist)): browse_scrollstart= len(browselist)-1
+
+               Redraw()
+
+def bevent(evt):
+       if (evt==BROWSE_EVT): make_browselist()
+
+       elif (evt==SORT_BYNAME): sort_browselist(1)
+       elif (evt==SORT_BYTYPE): sort_browselist(2)
+       elif (evt==SORT_BYDATA): sort_browselist(3)
+       
+       elif (evt==DOC_PAGE_UP): view_page(-1)
+       elif (evt==DOC_PAGE_DOWN): view_page(1)
+
+       elif (evt==BACK_MODULE): browse_module(-1)
+       elif (evt==CLOSE_VIEW): view_doc(-1)
+       elif (evt==FILTER_DISPLAY): toggle_function_filter()
+
+       elif (evt==SCROLLBAR):
+               global browse_scrollstart
+               browse_scrollstart= int(scr.val)
+
+       elif (evt>=BROWSE_MODULE): browse_module(evt-BROWSE_MODULE)
+       elif (evt>=VIEW_DOC): view_doc(evt-VIEW_DOC)    
+
+       Redraw()
+
+Register(draw, event, bevent)
diff --git a/release/scripts/hotkeys.py b/release/scripts/hotkeys.py
new file mode 100644 (file)
index 0000000..9f15a97
--- /dev/null
@@ -0,0 +1,438 @@
+#!BPY
+
+""" Registration info for Blender menus:
+Name: 'HotKeys'
+Blender: 232
+Group: 'Help'
+Tip: 'All the hotkeys.'
+""" 
+# $Id$
+#------------------------
+#  Hotkeys script
+#         jm soler (2003)
+# -----------------------
+# Page officielle :
+#   http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_hotkeyscript.htm
+# Communiquer les problemes et les erreurs sur:
+#   http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
+#--------------------------------------------- 
+# ce script est proposé sous licence GPL pour etre associe
+# a la distribution de Blender 2.33 et suivant
+# --------------------------------------------------------------------------
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# Copyright (C) 2003, 2004: Jean-Michel Soler
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+
+import Blender
+from Blender.Draw import *
+from Blender.BGL import *
+
+hotkeys={
+'Specials 1 ':[
+[',', 'Set Bounding Box rotation scaling pivot'],
+['.', 'Set 3D cursor as rotation scaling pivot'] ,
+['~', 'Display all layers'] ,
+['Shift-~', 'Display all/previous layers'] ,
+['TAB', 'Enter/exit edit mode'] ,
+['TAB', 'Edit Mode and Numerical Edit (see N key) : move to next input value'],
+['TAB', 'Sequencer: Edit meta strip'] ,
+['CTRL-TAB', 'Enter/exit pose mode']
+],
+
+'Specials 2 ':[
+['F1', 'Open File'],
+['F2', 'Save File'],
+['F3', 'Save image'],
+['F4', 'Logic window (may change)'],
+['F5', 'Material window'],
+['F6', 'Texture window'],
+['F7', 'Object window'],
+['F8', 'World window'],
+['F9', 'Edit Mode window'],
+['F10', 'Render Window'],
+['F11', 'Recall the last rendered image'],
+['F12', 'Render current Scene'],
+['Shift-F1', 'Library Data Select'],
+['Shift-F4', 'Data Select '],
+['Shift-F5', '3D window'],
+['Shift-F6', 'IPO window'],
+['Shift-F8', 'Video Sequencer window'],
+['Shift-F9', 'OOP window'],
+['Shift-F10', 'Image Window']
+] ,
+
+'Numbers  ':[
+['1..2..0-=', 'Show layer 1..2..12'] ,
+['ALT-1..2..0', 'Show layer 11..12..20'] ,
+['SHIFT-1..2..0-=', 'Toggle layer 1..2..12'] ,
+['SHIFT-ALT-...', 'Toggle layer 11..12..20'] ],
+
+'Numpad  ':[
+['Numpad DEL', 'Zoom on object'] ,
+['Numpad /', 'Local view on object (hide others)'] ,
+['Numpad *', "Rotate view to object's local axes"] ,
+['Numpad +', 'Zoom in (works everywhere)'] ,
+['Numpad +', 'Proportional vertex edit mode: Increase range of influence'] ,
+['Numpad -', 'Zoom out (works everywhere)'] ,
+['Numpad -', 'Proportional vertex edit mode: Decrease range of influence'] ,
+['Numpad INS', 'Set Camera view'] ,
+['CTRL-Numpad INS', 'Set active object as camera'] ,
+['ALT-Numbad INS', 'Restore old camera'] ,
+['Numpad 1', 'Front view'] ,
+['CTRL-Numpad 1', 'Back view'] ,
+['Numpad 3', 'Right-Side view'] ,
+['CTRL-Numpad 3', 'Left-Side view'] ,
+['Numpad 7', 'Top view'] ,
+['CTRL-Numpad 7', 'Bottom view '] ,
+['Numpad 5', 'Toggle orthogonal // perspective view'] ,
+['Numpad 9', 'Redraw view'] ,
+['Numpad 2', 'Rotate view left'] ,
+['Numpad 6', 'Rotate view right'] ,
+['Numpad 8', 'Rotate view up'] ,
+['Numpad 2', 'Rotate view down'] ],
+
+'Arrows ':[
+['PgUp', 'IPO: Select next keyframe'] ,
+['CTRL-PgUp', 'IPO: Select and jump to next keyframe'] ,
+['PgDn', 'IPO: Select previous keyframe'] ,
+['CTRL-PgDn', 'IPO: Select and jump to previous keyframe'] ,
+['LEFT', 'One frame backwards'] ,
+['RIGHT', 'One frame forwards'] ,
+['DOWN', '10 frames backwards'] ,
+['UP', '10 frames forwards'] ],
+
+'Letters ':[ {"A":[ 
+['A', 'Select all / Deselect all'] ,
+['ALT-A', 'Animate current window'] ,
+['CTRL-A', "Apply object's size/rotation to object data"] ,
+['SHIFT-A', 'Sequencer: ADD menu'] ,
+['SHIFT-ALT-A', 'Animate all windows'] ,
+['SHIFT-CTRL-A', 'Apply lattice / Make dupliverts real']] ,
+
+"B":[ 
+['B', 'Border select'] ,
+['BB', 'Circle select'] ,
+['SHIFT-B', 'Set render border'] ],
+
+"C":[ 
+['C', 'Center view on cursor'] ,
+['C', 'Sequencer: Change images'] ,
+['C', 'IPO: Snap current frame to selected key'] ,
+['ALT-C', 'Convert menu'] ,
+['CTRL-C', 'Copy menu (Copy properties of active to selected objects)'] ,
+['SHIFT-C', 'Center and zoom view on selected objects']] ,
+
+"D":[  
+['D', 'Set 3d draw mode'] ,
+['ALT-D', 'Create new instance of object'] ,
+['CTRL-D', 'Display alpha of image texture as wire'] ,
+['SHIFT-D', 'Create full copy of object'] ],
+
+"E":[ 
+['E', 'Extrude'],
+['EX', 'Extrude along X axis'],
+['EY', 'Extrude along Y axis'],
+['EZ', 'Extrude along Z axis'],
+['ALT-E', 'Edit mode: exit edit mode'],] ,
+
+"F":[ 
+['F', 'Edit mode: Make edge/face'] ,
+['F', 'Sequencer: Set Filter Y'] ,
+['F', 'Faceselect mode'] ,
+['ALT-F', 'Beautify fill'] ,
+['CTRL-F', 'Sort faces in Z direction'] ,
+['CTRL-F', 'Edit mode: Flip triangle edges'] ,
+['SHIFT-F', 'Edit mode: Fill with triangles']] ,
+
+"G":[ 
+['G', 'Grab (move)'] ,
+['ALT-G', 'Clear location'] ,
+['SHIFT-ALT-G', 'Remove selected objects from group'] ,
+['CTRL-G', 'Add selected objects to group'] ,
+['SHIFT-G', 'Group menu'] ],
+
+"H":[ 
+['H', 'Hide selected vertices/faces'] ,
+['H', 'Curves: Set handle type'] ,
+['ALT-H', 'Reveal vertices'] ,
+['CTRL-H', 'Curves: Automatic handle calculation'] ,
+['SHIFT-H', 'Hide deselected vertices'] ,
+['SHIFT-H', 'Curves: Set handle type']] ,
+
+"I":[ 
+['I', 'Keyframe menu'] ],
+
+"J":[ 
+['J', 'Mesh: Join all adjacent triangles to quads'] ,
+['J', 'Swap render page of render window'] ,
+['CTRL-J', 'Join selected objects'] ,
+['CTRL-J', 'Nurbs: Add segment'] ,
+['CTRL-J', 'IPO: Join keyframes menu'],
+['ALT-J', 'Edit Mode: convert quads to triangles']
+],
+
+"K":[  
+['K', '3d window: Show keyframe positions'] ,
+['K', 'IPO: Show keyframe positions'] ,
+['K', 'Nurbs: Print knots'] ,
+['CTRL-K', 'Make skeleton from armature'] ,
+['SHIFT-K', 'Show and select all keyframes for object'] ,
+['SHIFT-K', 'Edit: Knife Mode select'],
+['SHIFT-K', 'Faceselect: Clear vertexcolours'],
+] ,
+
+"L":[ 
+['L', 'Make local menu'] ,
+['L', 'Edit mode: Select linked vertices (near mouse pointer)'] ,
+['L', 'OOPS window: Select linked objects'] ,
+['CTRL-L', 'Make links menu'] ,
+['SHIFT-L', 'Select links menu'] ],
+
+"M":[ 
+['M', 'Move object to different layer'] ,
+['M', 'Sequencer: Make meta strip (group) from selected strips'],
+['ALT-M', 'Edit Mode: Merge vertices'] ],
+
+"N":[ 
+['N', 'Numeric input menu (Size/Rot/Loc)'] ,
+['N', 'OOPS window: Rename object/linked objects'] ,
+['CTRL-N', 'Armature: Recalculate bone roll angles'] ,
+['CTRL-N', 'Recalculate normals to outside'] ,
+['CTRL-ALT-N', 'Recalculate normals to inside'] ],
+
+"O":[ 
+['O', 'Edit mode: Toggle proportional vertex editing'] ,
+['ALT-O', 'Clear object origin'] ,
+['CTRL-O', 'Revert current file to last saved'] ,
+['SHIFT-O', 'Proportional vertex edit mode: Toggle smooth/steep falloff'] ],
+
+"P":[ 
+['P', 'Start realtime engine'] ,
+['P', 'Edit mode: Seperate vertices to new object'] ,
+['ALT-P', 'Clear parent relationship'] ,
+['CTRL-P', 'Make active object parent of selected object'] ,
+['CTRL-SHIFT-P', 'Make active object parent of selected object without inverse'] ,
+['CTRL-P', 'Edit mode: Make active vertex parent of selected object'] ],
+
+"Q":[['Q', 'Quit'] ],
+
+"R":[ 
+['R', 'Rotate'] ,
+['R', 'IPO: Record mouse movement as IPO curve'] ,
+['RX', 'Rotate around X axis'] ,
+['RXX', "Rotate around object's local X axis"] ,
+['RY', 'Rotate around Y axis'] ,
+['RYY', "Rotate around object's local Y axis"] ,
+['RZ', 'Rotate around Z axis'] ,
+['RZZ', "Rotate around object's local Z axis"] ,
+['ALT-R', 'Clear object rotation'] ,
+['SHIFT-R', 'Nurbs: Select row'], 
+['CTRL-R', 'Edit Mode: Knife, cut selected edges, accept left mouse/ cancel right mouse'],
+['SHIT-R', 'Edit Mode: loop Selection']],
+
+"S":[ 
+['S', 'Scale'] ,
+['SX', 'Flip around X axis'] ,
+['SY', 'Flip around Y axis'] ,
+['SZ', 'Flip around Z axis'] ,
+['SXX', 'Flip around X axis and show axis'] ,
+['SYY', 'Flip around Y axis and show axis'] ,
+['SZZ', 'Flip around Z axis and show axis'] ,
+['ALT-S', 'Edit mode: Shrink/fatten (Scale along vertex normals)'] ,
+['ALT-S', 'Clear object size'] ,
+['CTRL-S', 'Edit mode: Shear'] ,
+['SHIFT-S', 'Cursor/Grid snap menu'] ],
+
+"T":[ 
+['T', 'Sequencer: Touch and print selected movies'] ,
+['T', 'Adjust texture space'] ,
+['T', 'Edit mode: Flip 3d curve'] ,
+['T', 'IPO: Change IPO type'] ,
+['ALT-T', 'Clear tracking of object'] ,
+['CTRL-T', 'Make selected object track active object'] ,
+['CTRL-T', 'Mesh: Convert to triangles'] ,
+['CTRL-ALT-T', 'Blenchmark'] ],
+
+"U":[ 
+['U', 'Make single user menu'] ,
+['U', 'Edit mode: Reload object data from before entering edit mode'] ,
+['U', 'Faceselect mode: Automatic UV calculation menu'] ,
+['U', 'Vertex-/Weightpaint mode: Undo'] ,
+['CTRL-U', 'Save current state as user default'],
+['SHIFT-U', 'EditMode : Redo Menu'],
+['ALT-U', 'Edit Mode: Undo Menu']
+ ],
+
+"V":[ 
+['V', 'Curves/Nurbs: Vector handle'] ,
+['V', 'Vertexpaint mode'] ,
+['ALT-V', "Scale object to match image texture's aspect ratio"] ,
+['SHIFT-V', 'Edit mode: Align view to selected vertices'] ],
+
+"W":[ 
+['W', 'Boolean operations menu'] ,
+['W', 'Edit mode: Specials menu'] ,
+['CTRL-W', 'Save current file'] ,
+['CTRL-W', 'Nurbs: Switch direction'] ,
+['SHIFT-W', 'Warp/bend selected vertices around cursor'] ] ,
+
+"X":[ 
+['X', 'Delete menu'] ,
+['CTRL-X', 'Restore default state (Erase all)'] ],
+
+"Y":[ 
+['Y', 'Mesh: Split selected vertices/faces from the rest'] ],
+
+"Z":[ 
+['Z', 'Switch 3d draw type : solide/ wireframe (see also D)'],
+['Alt-Z', 'Switch 3d draw type : solid / textured (see also D)'],
+['Shift-Z', 'Switch 3d draw type : shaded / wireframe (see also D)'],
+
+]}]}
+
+
+for k in hotkeys.keys():
+   hotkeys[k].append(Create(0))
+
+for k in hotkeys['Letters '][0]:
+   hotkeys['Letters '][0][k].append(Create(0))
+
+hotL=hotkeys['Letters '][0].keys()
+hotL.sort()
+
+hot=hotkeys.keys()
+hot.sort()
+
+glCr=glRasterPos2d
+glCl3=glColor3f
+glCl4=glColor4f
+glRct=glRectf
+
+cf=[0.95,0.95,0.9,0.0]
+c1=[0.95,0.95,0.9,0.0]
+c=cf
+r=[0,0,0,0]
+
+def trace_rectangle4(r,c):
+    glCl4(c[0],c[1],c[2],c[3])
+    glRct(r[0],r[1],r[2],r[3])
+
+def trace_rectangle3(r,c,c1):
+    glCl3(c[0],c[1],c[2])
+    glRct(r[0],r[1],r[2],r[3])
+    glCl3(c1[0],c1[1],c1[2])
+
+def draw():
+    global r,c,c1,hotkeys, hot, hotL
+
+    size=Buffer(GL_FLOAT, 4)
+    glGetFloatv(GL_SCISSOR_BOX, size)
+    size= size.list
+
+    for s in [0,1,2,3]: size[s]=int(size[s])
+
+    c=[0.9,0.95,0.95,0.0]
+    c1=[0.95,0.95,0.9,0.0]
+
+    r=[0,size[3],size[2],0]
+    trace_rectangle4(r,c)
+
+    c=[0.7,0.7,0.9,0.0]
+    c1=[0.95,0.95,0.9,0.0]
+    
+    r=[0,size[3],size[2],size[3]-20]
+    trace_rectangle4(r,c)
+
+    c1=[0.7,0.7,0.9,0.0]
+    c=[0.2,0.2,0.4,0.0]
+    c2=[0.87,0.87,0.95,0.0]     
+
+    r=[0,size[3]-20,size[2],size[3]-44]
+    trace_rectangle4(r,c)
+
+    glColor3f(0.1, 0.1, 0.15)
+    glRasterPos2f(10, size[3]-16)
+
+    Text("HotKey")
+
+    l=0
+    listed=0
+    Llisted=0
+    for k in hot:             
+       hotkeys[k][-1]=Toggle(k, hot.index(k)+10, 4+(20*26)/6*hot.index(k), size[3]-(40), len(k)*8, 20, hotkeys[k][-1].val )
+       l+=len(k)
+       if hotkeys[k][-1].val==1.0:
+           listed=hot.index(k)
+           #print listed
+    l=0
+    if hot[listed]!='Letters ':
+       for n in  hotkeys[hot[listed]][:-1]:
+          if l%2==0:
+             r=[4,size[3]-(18*l+66),
+                     8+(21*26), size[3]-(46+18*l)]
+             trace_rectangle4(r,c2)
+          glColor3f(0.1, 0.1, 0.15)
+          glRasterPos2f(4+8, size[3]-(58+18*l))
+          Text(n[0])
+          glRasterPos2f(4+8*15, size[3]-(58+18*l))
+          Text('  : '+n[1]) 
+          l+=1
+    else:
+       for k in hotL:
+            pos=hotL.index(k)
+            hotkeys['Letters '][0][k][-1]=Toggle(k,pos+20,4+hotL.index(k)*21, size[3]-(52+18), 20, 20, hotkeys['Letters '][0][k][-1].val )
+            if hotkeys['Letters '][0][k][-1].val==1.0:
+               Llisted=pos
+       for n in hotkeys['Letters '][0][hotL[Llisted]][:-1]:
+          if l%2==0:
+             r=[4,size[3]-(18*l+92),
+                     8+(21*26), size[3]-(74+18*l)]
+             trace_rectangle4(r,c2)
+          glColor3f(0.1, 0.1, 0.15)  
+          glRasterPos2f(4+8, size[3]-(88+18*l))
+          Text(n[0])
+          glRasterPos2f(4+8*15, size[3]-(88+18*l))
+          Text('  : '+n[1]) 
+          l+=1
+
+def event(evt, val):
+    global hotkeys     
+    if (evt== QKEY and not val): Exit()
+
+def bevent(evt):
+    global hotkeysmhot, hotL
+    if   (evt== 1):
+        Exit()
+
+    elif (evt in range(10,20,1)):
+        for k in hot:
+           if hot.index(k)+10!=evt:
+                 hotkeys[k][-1].val=0
+                 
+        Blender.Window.Redraw()
+
+    elif (evt in range(20,46,1)):
+        for k in hotL:
+           if hotL.index(k)+20!=evt:
+                 hotkeys['Letters '][0][k][-1].val=0
+
+        Blender.Window.Redraw()
+
+Register(draw, event, bevent)
diff --git a/release/scripts/obdatacopier.py b/release/scripts/obdatacopier.py
new file mode 100644 (file)
index 0000000..82cabdb
--- /dev/null
@@ -0,0 +1,142 @@
+#!BPY
+
+""" Registration info for Blender menus: <- these words are ignored
+Name: 'Data Copier'
+Blender: 232
+Group: 'Object'
+Tip: 'Copy data from active object to other selected ones.'
+"""
+
+# ----------------------------------------------------------
+# Object DATA copier 0.1.1
+# (c) 2004 jean-michel soler
+# -----------------------------------------------------------
+#----------------------------------------------
+# Page officielle/official page du blender python Object DATA copier:
+#   http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_lampdatacopier.htm
+# Communiquer les problemes et erreurs sur:
+# To Communicate problems and errors on:
+#   http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
+#---------------------------------------------
+# Blender Artistic License
+# http://download.blender.org/documentation/html/x21254.html
+#---------------------------------------------
+
+import Blender
+from Blender import *
+from Blender.Draw import *
+from Blender.BGL import *
+
+
+O = Object.GetSelected()
+
+def renew():
+     global O
+     MAJ='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+     O = Object.GetSelected()
+     param= [ p for p in dir(O[0].getData()) if (p.find('set')!=0 and p.find('get')!=0 and (MAJ.find(p[0])==-1 or (p in ['R','G','B']))) ]  
+     PARAM={}
+     evt=4
+     doc='doc' 
+     for p in param:
+         try:
+           if p=='mode':
+              try:
+                 exec "doc=str(%s.Modes)+' ; value : %s'"%( O[0].getType(), str(O[0].getData().mode) )
+              except:
+                 exec """doc= '%s'+' value = '+ str(O[0].getData().%s)"""%(p,p) 
+           elif p=='type':
+               try:
+                 exec "doc=str(%s.Types)+' ; value : %s'"%( O[0].getType(), str(O[0].getData().type) )
+               except:
+                 exec """doc= '%s'+' value = '+ str(O[0].getData().%s)"""%(p,p) 
+           else:
+             exec """doc= '%s'+' value = '+ str(O[0].getData().%s)"""%(p,p)
+             if doc.find('built-in')!=-1:
+                exec """doc= 'This is a function ! Doc = '+ str(O[0].getData().%s.__doc__)"""%(p)
+         except:    
+             doc='Doc...' 
+         PARAM[p]=[Create(0),evt,doc]
+         evt+=1
+     return PARAM
+
+def copy():
+   global PARAM
+   OBJECT=None
+   TYPE=None
+
+   for O in Blender.Object.GetSelected():
+      if O.getType()!='Mesh' and O.getType()!='Empty' :
+          if OBJECT==None and TYPE==None:
+               OBJECT=O.getData()
+               TYPE= O.getType()
+
+          elif O.getType()==TYPE:
+            for p in PARAM.keys():
+               if  PARAM[p][0].val==1:
+                  try:
+                    exec "O.getData().%s=OBJECT.%s"%(p,p) 
+                  except:
+                    errormsg = "Type Error|It's not possible to copy %s to %s types." % (p,TYPE)
+                    Blender.Draw.PupMenu(errormsg)
+
+PARAM= renew()
+
+def EVENT(evt,val):
+   pass
+
+def BUTTON(evt):
+   global PARAM   
+   if (evt==1):
+         Exit()
+
+   if (evt==2):
+
+         copy()
+         Blender.Redraw()
+
+   if (evt==3):
+         PARAM= renew()
+         Blender.Redraw()
+
+def DRAW():
+  global PARAM, O
+  glColor3f(0.7, 0.7, 0.7)
+  glClear(GL_COLOR_BUFFER_BIT)
+  glColor3f(0.1, 0.1, 0.15)    
+
+  size=Buffer(GL_FLOAT, 4)
+  glGetFloatv(GL_SCISSOR_BOX, size)
+  size= size.list
+  for s in [0,1,2,3]: size[s]=int(size[s])
+  ligne=20
+
+  Button ("Exit",1,20,4,80,ligne)
+  Button ("Copy",2,102,4,80,ligne)
+  Button ("renew",3,184,4,80,ligne)
+
+  glRasterPos2f(20, ligne*2-8)
+  Text(O[0].getType()+" DATA copier")
+
+
+  max=size[3] / 22 -2
+  pos   = 1
+  decal = 20
+  key=PARAM.keys()
+  key.sort()
+  for p in key:
+     if  pos==max:
+         decal+=102
+         pos=1
+     else:
+         pos+=1       
+     PARAM[p][0]=Toggle(p,
+                      PARAM[p][1],
+                      decal,
+                      pos*22+22,
+                      100,
+                      20, 
+                      PARAM[p][0].val,str(PARAM[p][2]))
+
+  
+Register(DRAW,EVENT,BUTTON)
diff --git a/release/scripts/renameobjectbyblock.py b/release/scripts/renameobjectbyblock.py
new file mode 100644 (file)
index 0000000..f2ce46e
--- /dev/null
@@ -0,0 +1,173 @@
+#!BPY
+
+""" Registration info for Blender menus: <- these words are ignored
+Name: 'Name OBJECT changer'
+Blender: 232
+Group: 'Object'
+Tip: 'GUI to select then rename objects.'
+"""
+
+# ----------------------------------------------------------
+# Name OBJECT changer
+# (c) 2004 jean-michel soler
+# -----------------------------------------------------------
+#----------------------------------------------
+# Page officielle/offcial page du blender python Name OBJECT changer:
+#   http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_renameobjectgui.htm
+# Communiquer les problemes et erreurs sur:
+# To Communicate problems and errors on:
+#   http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
+#--------------------------------------------- 
+# Blender Artistic License
+# http://download.blender.org/documentation/html/x21254.html
+#---------------------------------------------
+
+CVS=0
+
+import Blender
+from Blender import *
+from Blender.Draw import *
+from Blender.BGL import *
+
+
+O = Object.Get()
+taglist=[]
+stringlist=[[],[]]
+
+
+def renew(taglist):
+     global O
+     MAJ='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+     O = Object.Get()
+     if CVS==0:
+        param= [ [p.getName(),O.index(p),str(p.getType())] for p in O ]
+     else:
+        param= [ [p.getName(),O.index(p),str(p.getType()),O[O.index(p)].isSelected()] for p in O ]
+     PARAM={}
+     evt=9
+     stringlist=[[],[],[]]
+     for p in param:
+         if p[0] in taglist or len(p)>3:
+            if CVS==0:
+               PARAM[p[0]]=[Create(1),evt,p[1],p[2],Create(p[0]),evt+1]
+            elif p[3]==1:
+               PARAM[p[0]]=[Create(1),evt,p[1],p[2],Create(p[0]),evt+1]
+            elif p[3]==0:
+               PARAM[p[0]]=[Create(0),evt,p[1],p[2],Create(p[0]),evt+1]
+            stringlist[0].append(evt+1)
+            stringlist[1].append(p[0])
+            stringlist[2].append(evt)
+         else:   
+            PARAM[p[0]]=[Create(0),evt,p[1],p[2],Create(p[0]),evt+1]
+            stringlist[0].append(evt+1)
+            stringlist[1].append(p[0])
+            stringlist[2].append(evt) 
+         evt+=2
+     return PARAM,stringlist
+
+NEWNAME=Create('Name')
+
+alignment={'BEGIN' : [Create(1),5],
+           'END'   : [Create(0),6],
+           'POINT' : [Create(0),7],
+           'FULL'  : [Create(0),8]}
+
+def rename():
+     global NEWNAME, alignment, O, taglist, PARAM, stringlist
+     taglist=[]
+     for p in PARAM.keys():
+        if PARAM[p][0].val==1:
+           if alignment['END'][0].val:  
+             O[PARAM[p][2]].setName(p+NEWNAME.val) 
+             taglist.append(p+NEWNAME.val)
+           elif alignment['BEGIN'][0].val:
+             O[PARAM[p][2]].setName(NEWNAME.val+p) 
+             taglist.append(NEWNAME.val+p)
+           elif alignment['FULL'][0].val:
+             O[PARAM[p][2]].setName(NEWNAME.val) 
+             taglist.append(O[PARAM[p][2]].getName())
+     PARAM, stringlist =renew(taglist)
+    
+PARAM, stringlist = renew(taglist)
+
+def EVENT(evt,val):
+   pass
+
+def BUTTON(evt):
+   global PARAM  , alignment, O, stringlist, CVS
+   if (evt==1):
+         Exit()
+   elif (evt==2):
+         rename()
+   elif (evt==3):
+         PARAM, stringlist = renew(taglist)
+
+   elif (evt in [5,6,7,8]):    
+         for k in alignment.keys():
+             if alignment[k][1]!=evt:
+                alignment[k][0].val=0
+
+
+   elif (evt in stringlist[0]):
+         O[PARAM[stringlist[1][(evt-9)/2]][2]].setName(PARAM[stringlist[1][(evt-9)/2]][4].val)
+         PARAM, stringlist = renew(taglist)
+
+   elif (evt in stringlist[2]):
+       try:
+         O[PARAM[stringlist[1][(evt-9)/2]][2]].select(PARAM[stringlist[1][(evt-9)/2]][0].val)
+       except:
+        pass
+
+   Blender.Redraw()
+
+def DRAW():
+  global PARAM, O, NEWNAME, alignment
+  
+
+  #glColor3f(0.7, 0.7, 0.7)
+  glClear(GL_COLOR_BUFFER_BIT)
+  glColor3f(0.1, 0.1, 0.15)    
+
+  size=Buffer(GL_FLOAT, 4)
+  glGetFloatv(GL_SCISSOR_BOX, size)
+  size= size.list
+  for s in [0,1,2,3]: size[s]=int(size[s])
+  ligne=20
+
+  Button ("Exit",1,20,1,80,ligne)
+  Button ("Rename",2,102,1,80,ligne)
+  Button ("renew",3,184,1,80,ligne)
+
+  glRasterPos2f(20, ligne*2-10)
+  Text(" Poly-RENAME tool")
+  NEWNAME=String('Add string : ', 4, 150, ligne*2-16, 150, 18, NEWNAME.val,120 )
+
+  key=alignment.keys()
+  key.sort()
+  n=150+150+4
+  for k in key:
+      alignment[k][0]=Toggle(k,alignment[k][1],n,ligne*2-16, 40, 18, alignment[k][0].val)
+      n+=40+4
+
+  max=size[3] / 22 -2
+  pos   = 1
+  decal = 20
+
+  keys=[[PARAM[k][1],k] for k in PARAM.keys()]
+  keys.sort()
+
+  
+  for p_ in keys:
+     p=p_[1] 
+     if  pos==max:
+         decal+=152
+         pos=1
+     else:
+         pos+=1       
+     PARAM[p][0]=Toggle('S',PARAM[p][1],decal,pos*22+22,20,20, PARAM[p][0].val,"Select this one for a group renaming")
+     PARAM[p][4]=String('> ',PARAM[p][5],decal+20,pos*22+22,90,20, PARAM[p][4].val,200, "string button to rename immediately but only this object")
+
+     glRasterPos2f(decal+115,pos*22+22)
+     Text(PARAM[p][3][:4])
+Register(DRAW,EVENT,BUTTON)
+
index 9bbe9d3726f2eb6a06450b5be2332ba4e7554fe8..964b252c8443f54155cd761075c42c65b97fe9f2 100644 (file)
@@ -290,7 +290,8 @@ static void setup_app_data(BlendFileData *bfd, char *filename) {
        R.displaymode= bfd->displaymode;
        G.curscreen= bfd->curscreen;
        G.fileflags= bfd->fileflags;
-       if (G.f & G_DEBUG) bfd->globalf |=G_DEBUG;
+       if (G.f & G_DEBUG) bfd->globalf |= G_DEBUG;
+       if (G.f & G_SCENESCRIPT) bfd->globalf |= G_SCENESCRIPT;
        G.f= bfd->globalf;
        G.scene= G.curscreen->scene;
        
index b7a52e6bf4cf83836baff1f1e21a06f2a9869081..57c8a56f2bed8f193b8ac19968fd8a9ea67176d3 100644 (file)
@@ -2611,14 +2611,16 @@ void write_stl(char *str)
        if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
        if(BLI_testextensie(str,".stl")==0) strcat(str, ".stl");
 
-       if (BLI_exists(str))
-               if(saveover(str)==0)
-                       return;
-       
+       if (!during_script()) {
+               if (BLI_exists(str))
+                       if(saveover(str)==0)
+                               return;
+       }
+
        fpSTL= fopen(str, "wb");
        
        if(fpSTL==NULL) {
-               error("Can't write file");
+               if (!during_script()) error("Can't write file");
                return;
        }
        strcpy(videosc_dir, str);
@@ -2791,7 +2793,7 @@ void write_videoscape(char *str)
 
        file= open(str,O_BINARY|O_RDONLY);
        close(file);
-       if(file>-1) if(saveover(str)==0) return;
+       if(file>-1) if(!during_script() && saveover(str)==0) return;
 
        strcpy(videosc_dir, str);
 
@@ -3114,11 +3116,11 @@ void write_vrml(char *str)
        if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
        if(BLI_testextensie(str,".wrl")==0) strcat(str, ".wrl");
 
-       if(saveover(str)==0) return;
+       if(!during_script() && saveover(str)==0) return;
        
        fp= fopen(str, "w");
        
-       if(fp==NULL) {
+       if(fp==NULL && !during_script()) {
                error("Can't write file");
                return;
        }
@@ -3420,13 +3422,15 @@ void write_dxf(char *str)
        if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
        if(BLI_testextensie(str,".dxf")==0) strcat(str, ".dxf");
 
-       if (BLI_exists(str))
-               if(saveover(str)==0)
-                       return;
-       
+       if (!during_script()) {
+               if (BLI_exists(str))
+                       if(saveover(str)==0)
+                               return;
+       }
+
        fp= fopen(str, "w");
        
-       if(fp==NULL) {
+       if(fp==NULL && !during_script()) {
                error("Can't write file");
                return;
        }
index 63e416d86d55165a28e34be8c82a45ca55f60b14..fecff8e02e811613048be06ddb678184b583f803 100644 (file)
@@ -417,6 +417,7 @@ int BPY_txt_do_python_Text(struct Text* text)
 {
        PyObject *py_dict, *py_result;
        BPy_constant *info;
+       char textname[24];
        Script *script = G.main->script.first;
 
        if (!text) return 0;
@@ -442,6 +443,11 @@ int BPY_txt_do_python_Text(struct Text* text)
                return 0;
        }
 
+       /* if in the script Blender.Load(blendfile) is not the last command,
+        * an error after it will call BPY_Err_Handle below, but the text struct
+        * will have been deallocated already, so we need to copy its name here. */
+       BLI_strncpy(textname, GetName(text), strlen(GetName(text))+1);
+
        /* if in it, leave editmode, since changes a script makes to meshdata
         * can be lost otherwise. */
        if (G.obedit) exit_editmode(1);
@@ -468,12 +474,10 @@ int BPY_txt_do_python_Text(struct Text* text)
 
        if (!py_result) { /* Failed execution of the script */
 
-               BPY_Err_Handle(GetName(text));
+               BPY_Err_Handle(textname);
                ReleaseGlobalDictionary(py_dict);
                script->py_globaldict = NULL;
-               free_libblock(&G.main->script, script);
-               //BPY_end_python();
-               //BPY_start_python();
+               if (G.main->script.first) free_libblock(&G.main->script, script);
 
                return 0;
        }
@@ -507,28 +511,38 @@ int BPY_txt_do_python(struct SpaceText* st)
 /*****************************************************************************/
 void BPY_run_python_script(char *fn)
 {
-       Text    *text;
+       Text    *text = NULL;
+       int is_blenText = 0;
+
+       if ( !BLI_exists(fn) ) { /* if there's no such filename ...*/
+               text = G.main->text.first; /* try an already existing Blender Text */
+               while (text) {
+                       if (!strcmp(fn, text->id.name+2)) break;
+                       text = text->id.next;
+               }
 
-       if ( !BLI_exists(fn) ) {
-               printf("\nError: no such file -- %s.\n", fn);
-               return;
+               if (!text) {
+                       printf("\nError: no such file or Blender text -- %s.\n", fn);
+                       return;
+               }
+               else is_blenText = 1; /* fn is already a Blender Text */
        }
 
-       text = add_text(fn);
+       if (!is_blenText) text = add_text(fn);
        if (text == NULL) {
                printf("Error in BPY_run_python_script: couldn't create Blender text "
                        "from %s\n", fn);
-               // On Windows if I continue I just get a segmentation
+               // Chris: On Windows if I continue I just get a segmentation
                // violation.  To get a baseline file I exit here.
                exit(2);
        }
 
        if (BPY_txt_do_python_Text(text) != 1) {
-               printf( "\nError executing Python script:\n"
-                       "%s (at line %d)\n", fn, BPY_Err_getLinenumber());
+               printf( "\nError executing Python script from command-line:\n"
+                       "%s (at line %d).\n", fn, BPY_Err_getLinenumber());
        }
 
-       free_libblock(&G.main->text, text);
+       if (!is_blenText) free_libblock(&G.main->text, text);
 }
 
 /*****************************************************************************/
@@ -708,9 +722,7 @@ int BPY_menu_do_python(short menutype, int event)
                BPY_Err_Handle(script->id.name+2);
                PyErr_Print();
                ReleaseGlobalDictionary(py_dict);
-               free_libblock(&G.main->script, script);
-       //      BPY_end_python();
-       //      BPY_start_python();
+               if (G.main->script.first) free_libblock(&G.main->script, script);
                error ("Python script error: check console");
 
                return 0;
index f9629cf1d1e3f30fee470ee33badc95fc6e5ba7a..ecb9764217623240616f9beb2e0b1c22f7107f6d 100644 (file)
 #include <Python.h>
 #include <stdio.h>
 
+/* for open, close in Blender_Load */
+#include <fcntl.h>
+#ifndef WIN32 
+#include <unistd.h>
+#else
+#include "BLI_winstuff.h"
+#include <io.h>
+#endif
+
 #include <BIF_usiblender.h>
 #include <BLI_blenlib.h>
 #include <BLO_writefile.h>
+#include <BKE_exotic.h>
 #include <BKE_global.h>
 #include <BKE_packedFile.h>
+#include <BKE_object.h>
 #include <BPI_script.h>
 #include <BSE_headerbuttons.h>
 #include <DNA_ID.h>
@@ -46,6 +57,7 @@
 #include <DNA_space_types.h> /* for SPACE_VIEW3D */
 #include <DNA_userdef_types.h>
 #include <BKE_ipo.h>
+#include <blendef.h>
 
 #include "gen_utils.h"
 #include "modules.h"
@@ -97,19 +109,28 @@ static char Blender_Quit_doc[] =
 "() - Quit Blender.  The current data is saved as 'quit.blend' before leaving.";
 
 static char Blender_Load_doc[] =
-"(filename) - Load the given .blend file.  If successful, the script is ended\n\
-immediately.\n\
+"(filename) - Load the given file.\n\
+Supported formats:\n\
+Blender, DXF, Inventor 1.0 ASCII, VRML 1.0 asc, STL, Videoscape, radiogour.\n\
+\n\
 Notes:\n\
 1 - () - an empty argument loads the default .B.blend file;\n\
 2 - if the substring '.B.blend' occurs inside 'filename', the default\n\
 .B.blend file is loaded;\n\
-3 - The current data is always preserved as an autosave file, for safety;\n\
-4 - This function only works if the script where it's executed is the\n\
-only one running.";
+3 - If a Blender file is loaded the script ends immediately.\n\
+4 - The current data is always preserved as an autosave file, for safety;\n\
+5 - This function only works if the script where it's executed is the\n\
+only one running at the moment.";
 
 static char Blender_Save_doc[] =
-"(filename) - Save a .blend file with the given filename.\n\
-(filename) - A file pathname that should not contain \".B.blend\" in it.";
+"(filename) - Save data to a file based on the filename's extension.\n\
+Supported are: Blender's .blend and the builtin exporters:\n\
+VRML 1.0 (.wrl), Videoscape (.obj), DXF (.dxf) and STL (.stl)\n\
+(filename) - A filename with one of the supported extensions.\n\
+Note 1: 'filename' should not contain the substring \".B.blend\" in it.\n\
+Note 2: only .blend raises an error if file wasn't saved.\n\
+\tYou can use Blender.sys.exists(filename) to make sure the file was saved\n\
+\twhen writing to one of the other formats.";
 
 /*****************************************************************************/
 /* Python method structure definition.                                                                                                                                                  */
@@ -295,10 +316,17 @@ static PyObject *Blender_Quit(PyObject *self)
        return Py_None;
 }
 
+/**
+ * Blender.Load
+ * loads Blender's .blend, DXF, radiogour(?), STL, Videoscape,
+ * Inventor 1.0 ASCII, VRML 1.0 asc.
+ */
 static PyObject *Blender_Load(PyObject *self, PyObject *args)
 {
        char *fname = NULL;
        Script *script = NULL;
+       char str[32];
+       int file, is_blend_file = 0;
 
        if (!PyArg_ParseTuple(args, "|s", &fname))
                return EXPP_ReturnPyObjError(PyExc_TypeError,
@@ -315,12 +343,30 @@ static PyObject *Blender_Load(PyObject *self, PyObject *args)
                return EXPP_ReturnPyObjError(PyExc_RuntimeError,
                        "there are other scripts running at the Scripts win, close them first!");
 
-       /* trick: mark the script so that its script struct won't be freed after
-        * the script is executed (to avoid a double free warning on exit): */
-       script = G.main->script.first;
-       script->flags |= SCRIPT_GUI;
+       if (fname) {
+               file = open(fname, O_BINARY|O_RDONLY);
 
-       BIF_write_autosave(); /* for safety let's preserve the current data */
+               if (file <= 0) {
+                       return EXPP_ReturnPyObjError(PyExc_RuntimeError,
+                               "cannot open file!");
+               }
+               else {
+                       read(file, str, 31);
+                       close(file);
+
+                       if (strncmp(str, "BLEN", 4) == 0) is_blend_file = 1;
+               }
+       }
+       else is_blend_file = 1; /* .B.blend */
+
+       if (is_blend_file) {
+               /* trick: mark the script so that its script struct won't be freed after
+                * the script is executed (to avoid a double free warning on exit): */
+               script = G.main->script.first;
+               script->flags |= SCRIPT_GUI;
+
+               BIF_write_autosave(); /* for safety let's preserve the current data */
+       }
 
        /* for safety, any filename with .B.blend is considered the default one.
         * It doesn't seem necessary to compare file attributes (like st_ino and
@@ -329,7 +375,7 @@ static PyObject *Blender_Load(PyObject *self, PyObject *args)
         * default one for sure.  Taking any .B.blend file as the default is good
         * enough here.  Note: the default file requires extra clean-up done by
         * BIF_read_homefile: freeing the user theme data. */
-       if (!fname || strstr(fname, ".B.blend"))
+       if (!fname || (strstr(fname, ".B.blend") && is_blend_file))
                BIF_read_homefile();
        else
                BIF_read_file(fname);
@@ -341,7 +387,6 @@ static PyObject *Blender_Load(PyObject *self, PyObject *args)
 static PyObject *Blender_Save(PyObject *self, PyObject *args)
 {
        char *fname = NULL;
-       char savefname[FILE_MAXFILE];
        int overwrite = 0, len = 0;
        char *error = NULL;
        Library *li;
@@ -365,23 +410,37 @@ static PyObject *Blender_Save(PyObject *self, PyObject *args)
 
        len = strlen(fname);
 
-       if (len > FILE_MAXFILE - 7) /* 6+1 for eventual .blend added below */
+       if (len > FILE_MAXFILE)
                return EXPP_ReturnPyObjError(PyExc_AttributeError,
                        "filename is too long!");
-       else
-               BLI_strncpy(savefname, fname, len + 1);
-
-       if (!strstr(fname, ".blend"))
-               BLI_strncpy(savefname + len, ".blend", 7); /* 7: BLI_strncpy adds '\0'*/
-
-       if (BLI_exists(savefname) && !overwrite)
+       else if (BLI_exists(fname) && !overwrite)
                return EXPP_ReturnPyObjError(PyExc_AttributeError,
                        "file already exists and overwrite flag was not given.");
 
-       if (G.fileflags & G_AUTOPACK) packAll();
+       disable_where_script(1); /* to avoid error popups in the write_* functions */
+
+       if (BLI_testextensie(fname, ".blend")) {
+               if (G.fileflags & G_AUTOPACK) packAll();
+               if (!BLO_write_file(fname, G.fileflags, &error)) {
+                       disable_where_script(0);
+                       return EXPP_ReturnPyObjError(PyExc_SystemError, error);
+               }
+       }
+       else if (BLI_testextensie(fname, ".dxf"))
+               write_dxf(fname);
+       else if (BLI_testextensie(fname, ".stl"))
+               write_stl(fname);
+       else if (BLI_testextensie(fname, ".wrl"))
+               write_vrml(fname);
+       else if (BLI_testextensie(fname, ".obj"))
+               write_videoscape(fname);
+       else {
+               disable_where_script(0);
+               return EXPP_ReturnPyObjError(PyExc_AttributeError,
+                       "unknown file extension.");
+       }
 
-       if (!BLO_write_file(savefname, G.fileflags, &error))
-               return EXPP_ReturnPyObjError(PyExc_SystemError, error);
+       disable_where_script(0);
 
        Py_INCREF(Py_None);
        return Py_None;
index efa1300359caaccffdfa62ea5a150ba6cc3bd03a..66ccee15d006c6ae8bb426f17a0bed16b8a1bc75 100644 (file)
@@ -113,6 +113,9 @@ static PyObject *Camera_setLens (BPy_Camera * self, PyObject * args);
 static PyObject *Camera_setClipStart (BPy_Camera * self, PyObject * args);
 static PyObject *Camera_setClipEnd (BPy_Camera * self, PyObject * args);
 static PyObject *Camera_setDrawSize (BPy_Camera * self, PyObject * args);
+static PyObject *Camera_getScriptLinks(BPy_Camera *self, PyObject *args);
+static PyObject *Camera_addScriptLink(BPy_Camera *self, PyObject *args);
+static PyObject *Camera_clearScriptLinks(BPy_Camera *self);
 
 /*****************************************************************************/
 /* Python BPy_Camera methods table:                                          */
@@ -154,6 +157,16 @@ static PyMethodDef BPy_Camera_methods[] = {
    "(f) - Set Camera clip end value"},
   {"setDrawSize", (PyCFunction) Camera_setDrawSize, METH_VARARGS,
    "(f) - Set Camera draw size value"},
+       {"getScriptLinks", (PyCFunction)Camera_getScriptLinks, METH_VARARGS,
+                       "(eventname) - Get a list of this camera's scriptlinks (Text names) "
+                       "of the given type\n"
+       "(eventname) - string: FrameChanged or Redraw."},
+       {"addScriptLink", (PyCFunction)Camera_addScriptLink, METH_VARARGS,
+                       "(text, evt) - Add a new camera scriptlink.\n"
+       "(text) - string: an existing Blender Text name;\n"
+       "(evt) string: FrameChanged or Redraw."},
+       {"clearScriptLinks", (PyCFunction)Camera_clearScriptLinks, METH_NOARGS,
+                       "() - Delete all scriptlinks from this camera."},
   {NULL, NULL, 0, NULL}
 };
 
@@ -739,6 +752,44 @@ Camera_setDrawSize (BPy_Camera * self, PyObject * args)
   Py_INCREF (Py_None);
   return Py_None;
 }
+/* cam.addScriptLink */
+static PyObject *Camera_addScriptLink (BPy_Camera *self, PyObject *args)
+{
+       Camera *cam = self->camera;
+       ScriptLink *slink = NULL;
+
+       slink = &(cam)->scriptlink;
+
+       if (!EXPP_addScriptLink(slink, args, 0))
+               return EXPP_incr_ret (Py_None);
+       else return NULL;
+}
+
+/* cam.clearScriptLinks */
+static PyObject *Camera_clearScriptLinks (BPy_Camera *self)
+{
+       Camera *cam = self->camera;
+       ScriptLink *slink = NULL;
+
+       slink = &(cam)->scriptlink;
+
+       return EXPP_incr_ret(Py_BuildValue("i", EXPP_clearScriptLinks (slink)));
+}
+
+/* cam.getScriptLinks */
+static PyObject *Camera_getScriptLinks (BPy_Camera *self, PyObject *args)
+{
+       Camera *cam = self->camera;
+       ScriptLink *slink = NULL;
+       PyObject *ret = NULL;
+
+       slink = &(cam)->scriptlink;
+
+       ret = EXPP_getScriptLinks(slink, args, 0);
+
+       if (ret) return ret;
+       else return NULL;
+}
 
 static void
 Camera_dealloc (BPy_Camera * self)
index 02e0ed028d0c5da974c0739b3cd3208f0fca843b..707323b9955fa7e227cb08584b96cdcc8dbec1a4 100644 (file)
@@ -325,12 +325,13 @@ PyTypeObject Button_Type = {
        (reprfunc) Button_repr, /*tp_repr */
 };
 
-
 static void Button_dealloc (PyObject *self)
 {
        Button *but = (Button *) self;
 
-       if (but->type == 3) MEM_freeN (but->val.asstr);
+       if (but->type == 3) {
+               if (but->val.asstr) MEM_freeN (but->val.asstr);
+       }
 
        PyObject_DEL (self);
 }
@@ -1008,7 +1009,7 @@ static PyObject *Method_String (PyObject *self, PyObject *args)
        but->val.asstr = MEM_mallocN (len + 1, "button string");
 
        strncpy (but->val.asstr, newstr, len);
-       but->val.asstr[len] = 0;
+       but->val.asstr[len] = '\0';
 
        block = Get_uiBlock ();
        if (block)
@@ -1189,6 +1190,8 @@ PyObject *Draw_Init (void)
        EXPP_ADDCONST (LEFTMOUSE);
        EXPP_ADDCONST (MIDDLEMOUSE);
        EXPP_ADDCONST (RIGHTMOUSE);
+       EXPP_ADDCONST (WHEELUPMOUSE);
+       EXPP_ADDCONST (WHEELDOWNMOUSE);
        EXPP_ADDCONST (MOUSEX);
        EXPP_ADDCONST (MOUSEY);
        EXPP_ADDCONST (TIMER0);
index c09113ab3fa8b431028729f1d207a400e6cb1acf..74f2718a5fab12baecaaee556cca1877f318f77d 100644 (file)
  * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */
 
-#include "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 <BLI_blenlib.h>
+#include <DNA_lamp_types.h>
+
+#include "constant.h"
+#include "rgbTuple.h"
+#include "gen_utils.h"
+#include "modules.h"
+#include "bpy_types.h" /* for the BPy_Lamp declaration */
+
+/*****************************************************************************/
+/* Python BPy_Lamp defaults:                                                 */
+/*****************************************************************************/
+
+/* 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
+#define EXPP_LAMP_MODE_NODIFFUSE  2048
+#define EXPP_LAMP_MODE_NOSPECULAR 4096
+/* Lamp MIN, MAX values */
+
+#define EXPP_LAMP_SAMPLES_MIN 1
+#define EXPP_LAMP_SAMPLES_MAX 16
+#define EXPP_LAMP_BUFFERSIZE_MIN 512
+#define EXPP_LAMP_BUFFERSIZE_MAX 5120
+#define EXPP_LAMP_ENERGY_MIN  0.0
+#define EXPP_LAMP_ENERGY_MAX 10.0
+#define EXPP_LAMP_DIST_MIN    0.1
+#define EXPP_LAMP_DIST_MAX 5000.0
+#define EXPP_LAMP_SPOTSIZE_MIN   1.0
+#define EXPP_LAMP_SPOTSIZE_MAX 180.0
+#define EXPP_LAMP_SPOTBLEND_MIN 0.00
+#define EXPP_LAMP_SPOTBLEND_MAX 1.00
+#define EXPP_LAMP_CLIPSTART_MIN    0.1
+#define EXPP_LAMP_CLIPSTART_MAX 1000.0
+#define EXPP_LAMP_CLIPEND_MIN    1.0
+#define EXPP_LAMP_CLIPEND_MAX 5000.0
+#define EXPP_LAMP_BIAS_MIN 0.01
+#define EXPP_LAMP_BIAS_MAX 5.00
+#define EXPP_LAMP_SOFTNESS_MIN   1.0
+#define EXPP_LAMP_SOFTNESS_MAX 100.0
+#define EXPP_LAMP_HALOINT_MIN 0.0
+#define EXPP_LAMP_HALOINT_MAX 5.0
+#define EXPP_LAMP_HALOSTEP_MIN  0
+#define EXPP_LAMP_HALOSTEP_MAX 12
+#define EXPP_LAMP_QUAD1_MIN 0.0
+#define EXPP_LAMP_QUAD1_MAX 1.0
+#define EXPP_LAMP_QUAD2_MIN 0.0
+#define EXPP_LAMP_QUAD2_MAX 1.0
+#define EXPP_LAMP_COL_MIN 0.0
+#define EXPP_LAMP_COL_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__                                                      */
+/*****************************************************************************/
+static 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')            # create new 'Spot' lamp data\n\
+  l.setMode('square', 'shadow')   # set these two lamp mode flags\n\
+  ob = Object.New('Lamp')         # create new lamp object\n\
+  ob.link(l)                      # link lamp obj with lamp data\n";
+
+static char M_Lamp_New_doc[] =
+"Lamp.New (type = 'Lamp', name = 'LampData'):\n\
+        Return a new Lamp Data object with the given type and name.";
+
+static char M_Lamp_Get_doc[] =
+"Lamp.Get (name = None):\n\
+        Return the Lamp Data with the given name, None if not found, or\n\
+        Return a list with all Lamp Data objects in the current scene,\n\
+        if no argument was given.";
+
+/*****************************************************************************/
+/* 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 BPy_Lamp methods declarations:                                     */
+/*****************************************************************************/
+static PyObject *Lamp_getName(BPy_Lamp *self);
+static PyObject *Lamp_getType(BPy_Lamp *self);
+static PyObject *Lamp_getMode(BPy_Lamp *self);
+static PyObject *Lamp_getSamples(BPy_Lamp *self);
+static PyObject *Lamp_getBufferSize(BPy_Lamp *self);
+static PyObject *Lamp_getHaloStep(BPy_Lamp *self);
+static PyObject *Lamp_getEnergy(BPy_Lamp *self);
+static PyObject *Lamp_getDist(BPy_Lamp *self);
+static PyObject *Lamp_getSpotSize(BPy_Lamp *self);
+static PyObject *Lamp_getSpotBlend(BPy_Lamp *self);
+static PyObject *Lamp_getClipStart(BPy_Lamp *self);
+static PyObject *Lamp_getClipEnd(BPy_Lamp *self);
+static PyObject *Lamp_getBias(BPy_Lamp *self);
+static PyObject *Lamp_getSoftness(BPy_Lamp *self);
+static PyObject *Lamp_getHaloInt(BPy_Lamp *self);
+static PyObject *Lamp_getQuad1(BPy_Lamp *self);
+static PyObject *Lamp_getQuad2(BPy_Lamp *self);
+static PyObject *Lamp_getCol(BPy_Lamp *self);
+static PyObject *Lamp_setName(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setType(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setIntType(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setMode(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setIntMode(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setSamples(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setBufferSize(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setHaloStep(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setEnergy(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setDist(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setSpotSize(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setSpotBlend(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setClipStart(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setClipEnd(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setBias(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setSoftness(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setHaloInt(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setQuad1(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setQuad2(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setCol(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_setColorComponent(BPy_Lamp *self, char *key,
+  PyObject *args);
+static PyObject *Lamp_getScriptLinks(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_addScriptLink(BPy_Lamp *self, PyObject *args);
+static PyObject *Lamp_clearScriptLinks(BPy_Lamp *self);
+
+/*****************************************************************************/
+/* Python BPy_Lamp methods table:                                            */
+/*****************************************************************************/
+static PyMethodDef BPy_Lamp_methods[] = {
+ /* name, method, flags, doc */
+  {"getName", (PyCFunction)Lamp_getName, METH_NOARGS,
+          "() - return Lamp name"},
+  {"getType", (PyCFunction)Lamp_getType, METH_NOARGS,
+          "() - return Lamp type - '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"},
+  {"getQuad1", (PyCFunction)Lamp_getQuad1, METH_NOARGS,
+          "() - return light intensity value #1 for a Quad Lamp"},
+  {"getQuad2", (PyCFunction)Lamp_getQuad2, METH_NOARGS,
+          "() - return light intensity value #2 for a Quad Lamp"},
+  {"getCol", (PyCFunction)Lamp_getCol, METH_NOARGS,
+          "() - return light rgb color triplet"},
+  {"setName", (PyCFunction)Lamp_setName, 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"},
+  {"setDist", (PyCFunction)Lamp_setDist, METH_VARARGS,
+          "(float) - change Lamp clipping distance value"},
+  {"setSpotSize", (PyCFunction)Lamp_setSpotSize, METH_VARARGS,
+          "(float) - change Lamp spot size value"},
+  {"setSpotBlend", (PyCFunction)Lamp_setSpotBlend, 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"},
+  {"setQuad1", (PyCFunction)Lamp_setQuad1, METH_VARARGS,
+          "(float) - change light intensity value #1 for a Quad Lamp"},
+  {"setQuad2", (PyCFunction)Lamp_setQuad2, METH_VARARGS,
+          "(float) - change light intensity value #2 for a Quad Lamp"},
+  {"setCol", (PyCFunction)Lamp_setCol, METH_VARARGS,
+          "(f,f,f) or ([f,f,f]) - change light's rgb color triplet"},
+       {"getScriptLinks", (PyCFunction)Lamp_getScriptLinks, METH_VARARGS,
+                       "(eventname) - Get a list of this lamp's scriptlinks (Text names) "
+                       "of the given type\n"
+       "(eventname) - string: FrameChanged or Redraw."},
+       {"addScriptLink", (PyCFunction)Lamp_addScriptLink, METH_VARARGS,
+                       "(text, evt) - Add a new lamp scriptlink.\n"
+       "(text) - string: an existing Blender Text name;\n"
+       "(evt) string: FrameChanged or Redraw."},
+       {"clearScriptLinks", (PyCFunction)Lamp_clearScriptLinks, METH_NOARGS,
+                       "() - Delete all scriptlinks from this lamp."},
+  {NULL, NULL, 0, NULL}
+};
+
+/*****************************************************************************/
+/* Python TypeLamp callback function prototypes:                             */
+/*****************************************************************************/
+static void Lamp_dealloc (BPy_Lamp *lamp);
+static PyObject *Lamp_getAttr (BPy_Lamp *lamp, char *name);
+static int Lamp_setAttr (BPy_Lamp *lamp, char *name, PyObject *v);
+static int Lamp_compare (BPy_Lamp *a, BPy_Lamp *b);
+static PyObject *Lamp_repr (BPy_Lamp *lamp);
+
 
 /*****************************************************************************/
 /* Python TypeLamp structure definition:                                     */
@@ -859,6 +1121,45 @@ static PyObject *Lamp_setCol(BPy_Lamp *self, PyObject *args)
   return rgbTuple_setCol(self->color, args);
 }
 
+/* lamp.addScriptLink */
+static PyObject *Lamp_addScriptLink (BPy_Lamp *self, PyObject *args)
+{
+       Lamp *lamp = self->lamp;
+       ScriptLink *slink = NULL;
+
+       slink = &(lamp)->scriptlink;
+
+       if (!EXPP_addScriptLink(slink, args, 0))
+               return EXPP_incr_ret (Py_None);
+       else return NULL;
+}
+
+/* lamp.clearScriptLinks */
+static PyObject *Lamp_clearScriptLinks (BPy_Lamp *self)
+{
+       Lamp *lamp = self->lamp;
+       ScriptLink *slink = NULL;
+
+       slink = &(lamp)->scriptlink;
+
+       return EXPP_incr_ret(Py_BuildValue("i", EXPP_clearScriptLinks (slink)));
+}
+
+/* mat.getScriptLinks */
+static PyObject *Lamp_getScriptLinks (BPy_Lamp *self, PyObject *args)
+{
+       Lamp *lamp = self->lamp;
+       ScriptLink *slink = NULL;
+       PyObject *ret = NULL;
+
+       slink = &(lamp)->scriptlink;
+
+       ret = EXPP_getScriptLinks(slink, args, 0);
+
+       if (ret) return ret;
+       else return NULL;
+}
+
 /*****************************************************************************/
 /* Function:    Lamp_dealloc                                                 */
 /* Description: This is a callback function for the BPy_Lamp type. It is     */
index f3e2f92eda0808c985a54aea1779036a9a791c5f..1ba8a8a5d3575b6e13dd63edbbbcc75bebc45cec 100644 (file)
 #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 <BLI_blenlib.h>
-#include <DNA_lamp_types.h>
-
-#include "constant.h"
-#include "rgbTuple.h"
-#include "gen_utils.h"
-#include "modules.h"
-#include "bpy_types.h" /* for the BPy_Lamp declaration */
-
-/*****************************************************************************/
-/* Python BPy_Lamp defaults:                                                 */
-/*****************************************************************************/
-
-/* 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
-#define EXPP_LAMP_MODE_NODIFFUSE  2048
-#define EXPP_LAMP_MODE_NOSPECULAR 4096
-/* Lamp MIN, MAX values */
-
-#define EXPP_LAMP_SAMPLES_MIN 1
-#define EXPP_LAMP_SAMPLES_MAX 16
-#define EXPP_LAMP_BUFFERSIZE_MIN 512
-#define EXPP_LAMP_BUFFERSIZE_MAX 5120
-#define EXPP_LAMP_ENERGY_MIN  0.0
-#define EXPP_LAMP_ENERGY_MAX 10.0
-#define EXPP_LAMP_DIST_MIN    0.1
-#define EXPP_LAMP_DIST_MAX 5000.0
-#define EXPP_LAMP_SPOTSIZE_MIN   1.0
-#define EXPP_LAMP_SPOTSIZE_MAX 180.0
-#define EXPP_LAMP_SPOTBLEND_MIN 0.00
-#define EXPP_LAMP_SPOTBLEND_MAX 1.00
-#define EXPP_LAMP_CLIPSTART_MIN    0.1
-#define EXPP_LAMP_CLIPSTART_MAX 1000.0
-#define EXPP_LAMP_CLIPEND_MIN    1.0
-#define EXPP_LAMP_CLIPEND_MAX 5000.0
-#define EXPP_LAMP_BIAS_MIN 0.01
-#define EXPP_LAMP_BIAS_MAX 5.00
-#define EXPP_LAMP_SOFTNESS_MIN   1.0
-#define EXPP_LAMP_SOFTNESS_MAX 100.0
-#define EXPP_LAMP_HALOINT_MIN 0.0
-#define EXPP_LAMP_HALOINT_MAX 5.0
-#define EXPP_LAMP_HALOSTEP_MIN  0
-#define EXPP_LAMP_HALOSTEP_MAX 12
-#define EXPP_LAMP_QUAD1_MIN 0.0
-#define EXPP_LAMP_QUAD1_MAX 1.0
-#define EXPP_LAMP_QUAD2_MIN 0.0
-#define EXPP_LAMP_QUAD2_MAX 1.0
-#define EXPP_LAMP_COL_MIN 0.0
-#define EXPP_LAMP_COL_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')            # create new 'Spot' lamp data\n\
-  l.setMode('square', 'shadow')   # set these two lamp mode flags\n\
-  ob = Object.New('Lamp')         # create new lamp object\n\
-  ob.link(l)                      # link lamp obj with lamp data\n";
-
-char M_Lamp_New_doc[] =
-"Lamp.New (type = 'Lamp', name = 'LampData'):\n\
-        Return a new Lamp Data object with the given type and name.";
-
-char M_Lamp_Get_doc[] =
-"Lamp.Get (name = None):\n\
-        Return the Lamp Data with the given name, None if not found, or\n\
-        Return a list with all Lamp Data objects in the current scene,\n\
-        if no argument was given.";
-
-/*****************************************************************************/
-/* 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 BPy_Lamp methods declarations:                                     */
-/*****************************************************************************/
-static PyObject *Lamp_getName(BPy_Lamp *self);
-static PyObject *Lamp_getType(BPy_Lamp *self);
-static PyObject *Lamp_getMode(BPy_Lamp *self);
-static PyObject *Lamp_getSamples(BPy_Lamp *self);
-static PyObject *Lamp_getBufferSize(BPy_Lamp *self);
-static PyObject *Lamp_getHaloStep(BPy_Lamp *self);
-static PyObject *Lamp_getEnergy(BPy_Lamp *self);
-static PyObject *Lamp_getDist(BPy_Lamp *self);
-static PyObject *Lamp_getSpotSize(BPy_Lamp *self);
-static PyObject *Lamp_getSpotBlend(BPy_Lamp *self);
-static PyObject *Lamp_getClipStart(BPy_Lamp *self);
-static PyObject *Lamp_getClipEnd(BPy_Lamp *self);
-static PyObject *Lamp_getBias(BPy_Lamp *self);
-static PyObject *Lamp_getSoftness(BPy_Lamp *self);
-static PyObject *Lamp_getHaloInt(BPy_Lamp *self);
-static PyObject *Lamp_getQuad1(BPy_Lamp *self);
-static PyObject *Lamp_getQuad2(BPy_Lamp *self);
-static PyObject *Lamp_getCol(BPy_Lamp *self);
-static PyObject *Lamp_setName(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setType(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setIntType(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setMode(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setIntMode(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setSamples(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setBufferSize(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setHaloStep(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setEnergy(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setDist(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setSpotSize(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setSpotBlend(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setClipStart(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setClipEnd(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setBias(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setSoftness(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setHaloInt(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setQuad1(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setQuad2(BPy_Lamp *self, PyObject *args);
-static PyObject *Lamp_setCol(BPy_Lamp *self, PyObject *args);
-
-static PyObject *Lamp_setColorComponent(BPy_Lamp *self, char *key,
-                PyObject *args);
-
-/*****************************************************************************/
-/* Python BPy_Lamp methods table:                                            */
-/*****************************************************************************/
-static PyMethodDef BPy_Lamp_methods[] = {
- /* name, method, flags, doc */
-  {"getName", (PyCFunction)Lamp_getName, METH_NOARGS,
-          "() - return Lamp name"},
-  {"getType", (PyCFunction)Lamp_getType, METH_NOARGS,
-          "() - return Lamp type - '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"},
-  {"getQuad1", (PyCFunction)Lamp_getQuad1, METH_NOARGS,
-          "() - return light intensity value #1 for a Quad Lamp"},
-  {"getQuad2", (PyCFunction)Lamp_getQuad2, METH_NOARGS,
-          "() - return light intensity value #2 for a Quad Lamp"},
-  {"getCol", (PyCFunction)Lamp_getCol, METH_NOARGS,
-          "() - return light rgb color triplet"},
-  {"setName", (PyCFunction)Lamp_setName, 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"},
-  {"setDist", (PyCFunction)Lamp_setDist, METH_VARARGS,
-          "(float) - change Lamp clipping distance value"},
-  {"setSpotSize", (PyCFunction)Lamp_setSpotSize, METH_VARARGS,
-          "(float) - change Lamp spot size value"},
-  {"setSpotBlend", (PyCFunction)Lamp_setSpotBlend, 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"},
-  {"setQuad1", (PyCFunction)Lamp_setQuad1, METH_VARARGS,
-          "(float) - change light intensity value #1 for a Quad Lamp"},
-  {"setQuad2", (PyCFunction)Lamp_setQuad2, METH_VARARGS,
-          "(float) - change light intensity value #2 for a Quad Lamp"},
-  {"setCol", (PyCFunction)Lamp_setCol, METH_VARARGS,
-          "(f,f,f) or ([f,f,f]) - change light's rgb color triplet"},
-  {NULL, NULL, 0, NULL}
-};
-
-/*****************************************************************************/
-/* Python TypeLamp callback function prototypes:                             */
-/*****************************************************************************/
-static void Lamp_dealloc (BPy_Lamp *lamp);
-static PyObject *Lamp_getAttr (BPy_Lamp *lamp, char *name);
-static int Lamp_setAttr (BPy_Lamp *lamp, char *name, PyObject *v);
-static int Lamp_compare (BPy_Lamp *a, BPy_Lamp *b);
-static PyObject *Lamp_repr (BPy_Lamp *lamp);
-
-
 #endif /* EXPP_LAMP_H */
index 508bc47a0a49c2909ba72400a88f7a31c4767763..0830184d9410f83a1b1a266ef15e6848a9245c35 100644 (file)
@@ -99,6 +99,7 @@ struct PyMethodDef M_Object_methods[] = {
 static PyObject *Object_buildParts (BPy_Object *self);
 static PyObject *Object_clearIpo (BPy_Object *self);
 static PyObject *Object_clrParent (BPy_Object *self, PyObject *args);
+static PyObject *Object_clearTrack (BPy_Object *self, PyObject *args);
 static PyObject *Object_getData (BPy_Object *self);
 static PyObject *Object_getDeltaLocation (BPy_Object *self);
 static PyObject *Object_getDrawMode (BPy_Object *self);
@@ -133,6 +134,7 @@ static PyObject *Object_setMaterials (BPy_Object *self, PyObject *args);
 static PyObject *Object_setName (BPy_Object *self, PyObject *args);
 static PyObject *Object_setSize (BPy_Object *self, PyObject *args);
 static PyObject *Object_setTimeOffset (BPy_Object *self, PyObject *args);
+static PyObject *Object_makeTrack (BPy_Object *self, PyObject *args);
 static PyObject *Object_shareFrom (BPy_Object *self, PyObject *args);
 static PyObject *Object_Select (BPy_Object *self, PyObject *args);
 static PyObject *Object_getAllProperties (BPy_Object *self);
@@ -141,6 +143,9 @@ static PyObject *Object_removeProperty(BPy_Object *self, PyObject *args);
 static PyObject *Object_getProperty(BPy_Object *self, PyObject *args);
 static PyObject *Object_removeAllProperties(BPy_Object *self);
 static PyObject *Object_copyAllPropertiesTo(BPy_Object *self, PyObject *args);
+static PyObject *Object_getScriptLinks(BPy_Object *self, PyObject *args);
+static PyObject *Object_addScriptLink(BPy_Object *self, PyObject *args);
+static PyObject *Object_clearScriptLinks(BPy_Object *self);
 
 /*****************************************************************************/
 /* Python BPy_Object methods table:                                                                                       */
@@ -153,6 +158,10 @@ static PyMethodDef BPy_Object_methods[] = {
                "Returns the ipo of this object (if any) "},   
   {"clrParent", (PyCFunction)Object_clrParent, METH_VARARGS,
        "Clears parent object. Optionally specify:\n\
+mode\n\tnonzero: Keep object transform\nfast\n\t>0: Don't update scene \
+hierarchy (faster)"},
+  {"clearTrack", (PyCFunction)Object_clearTrack, METH_VARARGS,
+       "Make this object not track another anymore. Optionally specify:\n\
 mode\n\t2: Keep object transform\nfast\n\t>0: Don't update scene \
 hierarchy (faster)"},
   {"getData", (PyCFunction)Object_getData, METH_NOARGS,
@@ -203,7 +212,7 @@ match the Object's type, so you cannot link a Lamp to a Mesh type object."},
        "Makes the object the parent of the objects provided in the \n\
 argument which must be a list of valid Objects. Optional extra arguments:\n\
 mode:\n\t0: make parent with inverse\n\t1: without inverse\n\
-fase:\n\t0: update scene hierarchy automatically\n\t\
+fast:\n\t0: update scene hierarchy automatically\n\t\
 don't update scene hierarchy (faster). In this case, you must\n\t\
 explicitely update the Scene hierarchy."},
   {"materialUsage", (PyCFunction)Object_materialUsage, METH_VARARGS,
@@ -237,6 +246,12 @@ objects."},
 triple."},
   {"setTimeOffset", (PyCFunction)Object_setTimeOffset, METH_VARARGS,
        "Set the object's time offset."},
+  {"makeTrack", (PyCFunction)Object_makeTrack, METH_VARARGS,
+       "(trackedobj, fast = 0) - Make this object track another.\n\
+        (trackedobj) - the object that will be tracked.\n\
+        (fast = 0) - if 0: update the scene hierarchy automatically.  If you\n\
+        set 'fast' to a nonzero value, don't forget to update the scene yourself\n\
+        (see scene.update())."},
   {"shareFrom", (PyCFunction)Object_shareFrom, METH_VARARGS,
        "Link data of self with object specified in the argument. This\n\
 works only if self and the object specified are of the same type."},
@@ -259,6 +274,16 @@ works only if self and the object specified are of the same type."},
   "() - removeAll a properties from this object"},
    {"copyAllPropertiesTo", (PyCFunction)Object_copyAllPropertiesTo, METH_VARARGS,
   "() - copy all properties from this object to another object"},
+       {"getScriptLinks", (PyCFunction)Object_getScriptLinks, METH_VARARGS,
+                       "(eventname) - Get a list of this object's scriptlinks (Text names) "
+                       "of the given type\n"
+       "(eventname) - string: FrameChanged or Redraw."},
+       {"addScriptLink", (PyCFunction)Object_addScriptLink, METH_VARARGS,
+                       "(text, evt) - Add a new object scriptlink.\n"
+       "(text) - string: an existing Blender Text name;\n"
+       "(evt) string: FrameChanged or Redraw."},
+       {"clearScriptLinks", (PyCFunction)Object_clearScriptLinks, METH_NOARGS,
+                       "() - Delete all scriptlinks from this object."},
   {NULL, NULL, 0, NULL}
 };
 
@@ -620,6 +645,35 @@ static PyObject *Object_clrParent (BPy_Object *self, PyObject *args)
   return (Py_None);
 }
 
+static PyObject *Object_clearTrack (BPy_Object *self, PyObject *args)
+{
+  int mode=0;
+  int fast=0;
+
+  if (!PyArg_ParseTuple (args, "|ii", &mode, &fast))
+  {
+               return (EXPP_ReturnPyObjError (PyExc_AttributeError,
+                 "expected one or two integers as arguments"));
+  }
+
+  /* Remove the link only, the object is still in the scene. */
+  self->object->track = NULL;
+
+  if (mode)
+  {
+               /* Keep transform */
+               apply_obmat (self->object);
+  }
+
+  if (!fast)
+  {
+               sort_baselist (G.scene);
+  }
+
+  Py_INCREF (Py_None);
+  return (Py_None);
+}
+
 /* adds object data to a Blender object, if object->data = NULL */
 int EXPP_add_obdata(struct Object *object)
 {
@@ -1600,6 +1654,23 @@ static PyObject *Object_setTimeOffset (BPy_Object *self, PyObject *args)
        return (Py_None);
 }
 
+static PyObject *Object_makeTrack (BPy_Object *self, PyObject *args)
+{
+  BPy_Object *tracked = NULL;
+       Object *ob = self->object;
+       int fast = 0;
+       
+       if (!PyArg_ParseTuple (args, "O!|i", &Object_Type, &tracked, &fast))
+               return EXPP_ReturnPyObjError (PyExc_TypeError,
+                       "expected an object and optionally also an int as arguments.");
+
+       ob->track = tracked->object;
+
+       if (!fast) sort_baselist(G.scene);
+
+       return EXPP_incr_ret(Py_None);
+}
+
 static PyObject *Object_shareFrom (BPy_Object *self, PyObject *args)
 {
        BPy_Object              * object;
@@ -1608,22 +1679,19 @@ static PyObject *Object_shareFrom (BPy_Object *self, PyObject *args)
 
        if (!PyArg_ParseTuple (args, "O", &object))
        {
-               EXPP_ReturnPyObjError (PyExc_AttributeError,
+               return EXPP_ReturnPyObjError (PyExc_AttributeError,
                                "expected an object argument");
-               return (NULL);
        }
        if (!Object_CheckPyObject ((PyObject*)object))
        {
-               EXPP_ReturnPyObjError (PyExc_TypeError,
+               return EXPP_ReturnPyObjError (PyExc_TypeError,
                                "argument 1 is not of type 'Object'");
-               return (NULL);
        }
 
        if (self->object->type != object->object->type)
        {
-               EXPP_ReturnPyObjError (PyExc_TypeError,
+               return EXPP_ReturnPyObjError (PyExc_TypeError,
                                "objects are not of same data type");
-               return (NULL);
        }
        switch (self->object->type)
        {
@@ -1659,9 +1727,8 @@ static PyObject *Object_shareFrom (BPy_Object *self, PyObject *args)
                        Py_INCREF (Py_None);
                        return (Py_None);
                default:
-                       EXPP_ReturnPyObjError (PyExc_TypeError,
+                       return EXPP_ReturnPyObjError (PyExc_TypeError,
                                        "type not supported");
-                       return (NULL);
        }
 
        Py_INCREF (Py_None);
@@ -1871,6 +1938,45 @@ static PyObject *Object_copyAllPropertiesTo(BPy_Object *self, PyObject *args)
        return EXPP_incr_ret  (Py_None);
 }
 
+/* obj.addScriptLink */
+static PyObject *Object_addScriptLink (BPy_Object *self, PyObject *args)
+{
+       Object *obj = self->object;
+       ScriptLink *slink = NULL;
+
+       slink = &(obj)->scriptlink;
+
+       if (!EXPP_addScriptLink(slink, args, 0))
+               return EXPP_incr_ret (Py_None);
+       else return NULL;
+}
+
+/* obj.clearScriptLinks */
+static PyObject *Object_clearScriptLinks (BPy_Object *self)
+{
+       Object *obj = self->object;
+       ScriptLink *slink = NULL;
+
+       slink = &(obj)->scriptlink;
+
+       return EXPP_incr_ret(Py_BuildValue("i", EXPP_clearScriptLinks (slink)));
+}
+
+/* obj.getScriptLinks */
+static PyObject *Object_getScriptLinks (BPy_Object *self, PyObject *args)
+{
+       Object *obj = self->object;
+       ScriptLink *slink = NULL;
+       PyObject *ret = NULL;
+
+       slink = &(obj)->scriptlink;
+
+       ret = EXPP_getScriptLinks(slink, args, 0);
+
+       if (ret) return ret;
+       else return NULL;
+}
+
 /*****************************************************************************/
 /* Function:   Object_CreatePyObject                                                                            */
 /* Description: This function will create a new BlenObject from an existing  */
@@ -2231,10 +2337,10 @@ static int Object_setAttr (BPy_Object *obj, char *name, PyObject *value)
        }
        if (StringEqual (name, "track"))
        {
-               /* This is not allowed. */
-               EXPP_ReturnPyObjError (PyExc_AttributeError,
-                                       "Setting the track is not allowed.");
-               return (0);
+               if (Object_makeTrack (obj, valtuple) != Py_None)
+                       return (-1);
+               else
+                       return (0);
        }
        if (StringEqual (name, "data"))
        {
index eb1536f2d1b8479a8458d626b04548e985eb6d71..59a1118398bb6a107275e93c635bc4c70bb3582d 100644 (file)
 #include <BKE_scene.h>
 #include <BKE_library.h>
 #include <BLI_blenlib.h>
+#include <BSE_drawview.h> /* for play_anim */
 #include <BSE_headerbuttons.h> /* for copy_scene */
 #include <BIF_drawscene.h>              /* for set_scene */
 #include <BIF_space.h>                          /* for copy_view3d_lock() */
+#include <BIF_screen.h> /* curarea */
+#include <DNA_screen_types.h> /* SPACE_VIEW3D, SPACE_SEQ */
 #include <DNA_scriptlink_types.h>
 #include <MEM_guardedalloc.h>  /* for MEM_callocN */
 #include <mydevice.h>                                   /* for #define REDRAW */
@@ -101,6 +104,7 @@ static PyObject *Scene_getRenderingContext(BPy_Scene *self);
 static PyObject *Scene_getScriptLinks(BPy_Scene *self, PyObject *args);
 static PyObject *Scene_addScriptLink(BPy_Scene *self, PyObject *args);
 static PyObject *Scene_clearScriptLinks(BPy_Scene *self);
+static PyObject *Scene_play(BPy_Scene *self, PyObject *args);
 
 //deprecated methods
 static PyObject *Scene_currentFrame(BPy_Scene *self, PyObject *args);
@@ -180,6 +184,19 @@ static PyMethodDef BPy_Scene_methods[] = {
        {"currentFrame", (PyCFunction)Scene_currentFrame, METH_VARARGS,
                        "(frame) - If frame is given, the current frame is set and"
                        "\nreturned in any case"},
+       {"play", (PyCFunction)Scene_play, METH_VARARGS,
+                       "(mode = 0, win = VIEW3D) - Play realtime animation in Blender"
+                       " (not rendered).\n"
+                       "(mode) - int:\n"
+                       "\t0 - keep playing in biggest given 'win';\n"
+                       "\t1 - keep playing in all 'win', VIEW3D and SEQ windows;\n"
+                       "\t2 - play once in biggest given 'win';\n"
+                       "\t3 - play once in all 'win', VIEW3D and SEQ windows.\n"
+                       "(win) - int: see Blender.Window.Types. Only these are meaningful here:"
+                       "VIEW3D, SEQ,   IPO, ACTION, NLA, SOUND.  But others are also accepted, "
+                       "since they can be used just as an interruptible timer.  If 'win' is not"
+                       "available or invalid, VIEW3D is tried, then any bigger window."
+                       "Returns 0 for normal exit or 1 when canceled by user input."},
        {NULL, NULL, 0, NULL}
 };
 //-----------------------BPy_Scene method def-------------------------------------------------------------------------
@@ -791,6 +808,62 @@ static PyObject *Scene_getScriptLinks (BPy_Scene *self, PyObject *args)
        else return NULL;
 }
 
+static PyObject *Scene_play (BPy_Scene *self, PyObject *args)
+{
+       Scene *scene = self->scene;
+       int mode = 0, win = SPACE_VIEW3D;
+       PyObject *ret = NULL;
+       ScrArea *sa = NULL, *oldsa = curarea;
+
+       if (!scene)
+               return EXPP_ReturnPyObjError (PyExc_RuntimeError,
+                       "Blender Scene was deleted!");
+
+       if (!PyArg_ParseTuple(args, "|ii", &mode, &win))
+               return EXPP_ReturnPyObjError (PyExc_TypeError,
+                       "expected nothing, or or two ints as arguments.");
+
+       if (mode < 0 || mode > 3)
+               return EXPP_ReturnPyObjError (PyExc_TypeError,
+                       "mode should be in range [0, 3].");
+
+       switch (win) {
+               case SPACE_VIEW3D:
+               case SPACE_SEQ:
+               case SPACE_IPO:
+               case SPACE_ACTION:
+               case SPACE_NLA:
+               case SPACE_SOUND:
+               case SPACE_BUTS: /* from here they don't 'play', but ...*/
+               case SPACE_TEXT: /* ... might be used as a timer. */
+               case SPACE_SCRIPT:
+               case SPACE_OOPS:
+               case SPACE_IMAGE:
+               case SPACE_IMASEL:
+               case SPACE_INFO:
+               case SPACE_FILE:
+                       break;
+               default:
+                       win = SPACE_VIEW3D;
+       }
+
+       /* we have to move to a proper win */
+       sa = find_biggest_area_of_type(win);
+       if (!sa && win != SPACE_VIEW3D)
+               sa = find_biggest_area_of_type(SPACE_VIEW3D);
+
+       if (!sa) sa = find_biggest_area();
+
+       if (sa) areawinset(sa->win);
+
+       /* play_anim returns 0 for normal exit or 1 if user canceled it */
+       ret =  Py_BuildValue("i", play_anim(mode));
+
+       if (sa) areawinset(oldsa->win);
+
+       return ret;
+}
+
 /*****************************************************************************/
 // DEPRECATED  
 /*****************************************************************************/
index de6da24496f041d31560913d804b79f9ad9652e6..39412fada16f2c19998f5a71e94b3d5f359ad24d 100644 (file)
@@ -33,6 +33,7 @@
 #include <BLI_blenlib.h>
 #include <PIL_time.h>
 #include <Python.h>
+#include <sys/stat.h>
 #include "gen_utils.h"
 #include "modules.h"
 
@@ -92,7 +93,12 @@ Each successive call is garanteed to return values greater than or\n\
 equal to the previous call.";
 
 static char M_sys_exists_doc[] =
-"(path) - Return 1 if given pathname (file or dir) exists, 0 otherwise.";
+"(path) - Check if the given pathname exists.\n\
+The return value is as follows:\n\
+\t 0: path doesn't exist;\n\
+\t 1: path is an existing filename;\n\
+\t 2: path is an existing dirname;\n\
+\t-1: path exists but is neither a regular file nor a dir.";
 
 /*****************************************************************************/
 /* Python method structure definition for Blender.sys module:                */
@@ -337,16 +343,20 @@ static PyObject *M_sys_time (PyObject *self)
 
 static PyObject *M_sys_exists (PyObject *self, PyObject *args)
 {
+       struct stat st;
        char *fname = NULL;
-       int i = 0;
+       int res = 0, i = -1;
 
        if (!PyArg_ParseTuple(args, "s", &fname))
                return EXPP_ReturnPyObjError (PyExc_TypeError,
-                                                       "expected string (file path) argument");
+                                                       "expected string (pathname) argument");
 
-       i = BLI_exists(fname);
+       res = stat(fname, &st);
 
-       if (i) return Py_BuildValue("i", 1); /* path was found */
+       if (res == -1) i = 0;
+       else if (S_ISREG(st.st_mode)) i = 1;
+       else if (S_ISDIR(st.st_mode)) i = 2;
+       /* i stays as -1 if path exists but is neither a regular file nor a dir */
 
-       return Py_BuildValue("i", 0); /* path doesn't exist */
+       return Py_BuildValue("i", i);
 }
index 056fdcc9281e1cc29b066d543dbd075c5900decd..ef0ade60c4833b5837926ae48034ac6d34836d62 100644 (file)
@@ -639,7 +639,44 @@ static PyObject *World_setMist(BPy_World *self, PyObject *args )
        return Py_None;
 }
 
+/* world.addScriptLink */
+static PyObject *World_addScriptLink (BPy_World *self, PyObject *args)
+{
+       World *world = self->world;
+       ScriptLink *slink = NULL;
+
+       slink = &(world)->scriptlink;
+
+       if (!EXPP_addScriptLink(slink, args, 0))
+               return EXPP_incr_ret (Py_None);
+       else return NULL;
+}
+
+/* world.clearScriptLinks */
+static PyObject *World_clearScriptLinks (BPy_World *self)
+{
+       World *world = self->world;
+       ScriptLink *slink = NULL;
+
+       slink = &(world)->scriptlink;
 
+       return EXPP_incr_ret(Py_BuildValue("i", EXPP_clearScriptLinks (slink)));
+}
+
+/* world.getScriptLinks */
+static PyObject *World_getScriptLinks (BPy_World *self, PyObject *args)
+{
+       World *world = self->world;
+       ScriptLink *slink = NULL;
+       PyObject *ret = NULL;
+
+       slink = &(world)->scriptlink;
+
+       ret = EXPP_getScriptLinks(slink, args, 0);
+
+       if (ret) return ret;
+       else return NULL;
+}
 
 
 /*@{*/
index 2f83cd0fb9fdea47109f3be112a145d579f25f97..d7c99ac923139ec593759ce790ff7f6f7ce1c667 100644 (file)
@@ -105,6 +105,9 @@ static PyObject *World_getStar(BPy_World *self);
 static PyObject *World_setStar(BPy_World *self, PyObject *args );
 static PyObject *World_getMist(BPy_World *self);
 static PyObject *World_setMist(BPy_World *self, PyObject *args );
+static PyObject *World_getScriptLinks(BPy_World *self, PyObject *args);
+static PyObject *World_addScriptLink(BPy_World *self, PyObject *args);
+static PyObject *World_clearScriptLinks(BPy_World *self);
 
 /*****************************************************************************/
 /* Python BPy_World methods table:                                          */
@@ -152,6 +155,16 @@ static PyMethodDef BPy_World_methods[] = {
       "() - Return World Data mist"},
   {"setMist", (PyCFunction)World_setMist, METH_VARARGS,
       "() - Return World Data mist"},
+       {"getScriptLinks", (PyCFunction)World_getScriptLinks, METH_VARARGS,
+                       "(eventname) - Get a list of this world's scriptlinks (Text names) "
+                       "of the given type\n"
+       "(eventname) - string: FrameChanged or Redraw."},
+       {"addScriptLink", (PyCFunction)World_addScriptLink, METH_VARARGS,
+                       "(text, evt) - Add a new world scriptlink.\n"
+       "(text) - string: an existing Blender Text name;\n"
+       "(evt) string: FrameChanged or Redraw."},
+       {"clearScriptLinks", (PyCFunction)World_clearScriptLinks, METH_NOARGS,
+                       "() - Delete all scriptlinks from this world :)."},
   {NULL, NULL, 0, NULL}
 };
 
@@ -160,7 +173,7 @@ static PyMethodDef BPy_World_methods[] = {
 /* and Object modules.                                                       */
 /*****************************************************************************/
 PyObject *World_Init (void);
-PyObject *World_CreatePyObject (World *cam);
+PyObject *World_CreatePyObject (World *world);
 World   *World_FromPyObject (PyObject *pyobj);
 int       World_CheckPyObject (PyObject *pyobj);
 
index dff399318efafaf164dcfa1169ff65d3bc71f627..b9155b4cb7ecae3ff8cf66cbb327aa5298939c0d 100644 (file)
@@ -23,16 +23,27 @@ Example::
   from Blender import Draw
   R = G = B = 0
   A = 1
-  instructions = "Hold mouse buttons to change the background color."
+  title = "Testing BGL  + Draw"
+  instructions = "Use mouse buttons or wheel to change the background color."
   quitting = " Press ESC or q to quit."
+  len1 = Draw.GetStringWidth(title)
+  len2 = Draw.GetStringWidth(instructions + quitting)
   #
   def show_win():
     glClearColor(R,G,B,A)                # define color used to clear buffers 
     glClear(GL_COLOR_BUFFER_BIT)         # use it to clear the color buffer
-    glColor3f(1,1,1)                     # change default color
+    glColor3f(0.35,0.18,0.92)            # define default color
+    glBegin(GL_POLYGON)                  # begin a vertex data list
+    glVertex2i(165, 158)
+    glVertex2i(252, 55)
+    glVertex2i(104, 128)
+    glEnd()
+    glColor3f(0.4,0.4,0.4)               # change default color
+    glRecti(40, 96, 60+len1, 113)
+    glColor3f(1,1,1)
     glRasterPos2i(50,100)                # move cursor to x = 50, y = 100
-    Draw.Text("Testing BGL  + Draw")     # draw this text there
-    glRasterPos2i(350,20)                # move cursor again
+    Draw.Text(title)                     # draw this text there
+    glRasterPos2i(350,40)                # move cursor again
     Draw.Text(instructions + quitting)   # draw another msg
     glBegin(GL_LINE_LOOP)                # begin a vertex-data list
     glVertex2i(46,92)
@@ -40,29 +51,29 @@ Example::
     glVertex2i(120,115)
     glVertex2i(46,115)
     glEnd()                              # close this list
-    glColor3f(0.35,0.18,0.92)            # change default color again
-    glBegin(GL_POLYGON)                  # another list, for a polygon
-    glVertex2i(315, 292)
-    glVertex2i(412, 200)
-    glVertex2i(264, 256)
-    glEnd()
-    Draw.Redraw(1)                       # make changes visible.
   #
-  def ev(evt, val):                     # this is a callback for Draw.Register()
+  def ev(evt, val):                      # event callback for Draw.Register()
     global R,G,B,A                       # ... it handles input events
     if evt == Draw.ESCKEY or evt == Draw.QKEY:
       Draw.Exit()                        # this quits the script
+    elif not val: return
     elif evt == Draw.LEFTMOUSE: R = 1 - R
     elif evt == Draw.MIDDLEMOUSE: G = 1 - G
     elif evt == Draw.RIGHTMOUSE: B = 1 - B
+    elif evt == Draw.WHEELUPMOUSE:
+      R += 0.1
+      if R > 1: R = 1
+    elif evt == Draw.WHEELDOWNMOUSE:
+      R -= 0.1
+      if R < 0: R = 0
     else:
-      Draw.Register(show_win, ev, None)
+      return                             # don't redraw if nothing changed
+    Draw.Redraw(1)                       # make changes visible.
   #
-    Draw.Register(show_win, ev, None)     # start the main loop
+  Draw.Register(show_win, ev, None)      # start the main loop
 
 @see: U{www.opengl.org}
 @see: U{nehe.gamedev.net}
-
 """
 
 def glAccum(op, value):
index b595bfb9e4913e69989cf904981b08aaa96740d8..eb048b65e313196c459a6d7347c6721e698a65f7 100644 (file)
@@ -4,14 +4,14 @@
 # Doc system used: epydoc - http://epydoc.sf.net
 # command line:
 
-# epydoc -o BPY_API_230 --url "http://www.blender.org" -t Blender.py \
+# epydoc -o BPY_API_23x --url "http://www.blender.org" -t Blender.py \
 # -n "Blender" --no-private --no-frames Blender.py \
 # Types.py Scene.py Object.py NMesh.py Material.py Camera.py Lamp.py \
 # Armature.py Metaball.py Effect.py Curve.py Ipo.py World.py BGL.py Window.py \
 # Draw.py Image.py Text.py Lattice.py Texture.py Registry.py Sys.py Mathutils.py
 
 """
-The main Blender module.
+The main Blender module (*).
 
 The Blender Python API Reference
 ================================
@@ -23,30 +23,32 @@ The Blender Python API Reference
      - L{Bone}
      - L{NLA}
   - L{BGL}
-  - L{Camera}
+  - L{Camera} (*)
   - L{Curve}
-  - L{Draw}
+  - L{Draw} (*)
   - L{Effect}
-  - L{Image}
+  - L{Image} (*)
   - L{Ipo}
-  - L{Lamp}
+  - L{Lamp} (*)
   - L{Lattice}
   - L{Library}
-  - L{Material}
+  - L{Material} (*)
   - L{Mathutils}
-  - L{Metaball}
+  - L{Metaball} (*)
   - L{NMesh}
   - L{Noise}
-  - L{Object}
+  - L{Object} (*)
   - L{Registry}
-  - L{Scene}
+  - L{Scene} (*)
      - L{Render}
   - L{Text}
   - L{Texture}
   - L{Types}
   - L{Window}
-  - L{World}
-  - L{sys<Sys>}
+  - L{World} (*)
+  - L{sys<Sys>} (*)
+
+ (*) - marks updated.
 
  Introduction:
  -------------
@@ -104,29 +106,54 @@ def Redraw ():
 
 def Load (filename = None):
   """
-  Load a Blender .blend file.
+  Load a Blender .blend file or any of the other supported file formats.
+
+  Supported formats:
+    - Blender's .blend;
+    - DXF;
+    - Open Inventor 1.0 ASCII;
+    - Radiogour;
+    - STL;
+    - Videoscape;
+    - VRML 1.0 asc.
+
   @type filename: string
-  @param filename: the pathname to the desired .blend file.  If 'filename'
+  @param filename: the pathname to the desired file.  If 'filename'
       isn't given or if it contains the substring '.B.blend', the default
       .B.blend file is loaded.
 
   @warn: loading a new .blend file removes the current data in Blender.  For
      safety, this function saves the current data as an autosave file in
-     the temporary dir used by Blender before loading the new file.
+     the temporary dir used by Blender before loading a new Blender file.
+  @warn: after a call to Load(blendfile), current data in Blender is lost,
+     including the Python dictionaries.  Any posterior references in the
+     script to previously defined data will generate a NameError.  So it's
+     better to put Blender.Load as the last executed command in the script,
+     when this function is used to open .blend files.
   """
 
 def Save (filename, overwrite = 0):
   """
-  Save a Blender .blend file with the current program data.
+  Save a Blender .blend file with the current program data or export to
+  one of the builtin file formats.
+  
+  Supported formats:
+    - Blender (.blend);
+    - DXF (.dxf);
+    - STL (.stl);
+    - Videoscape (.obj);
+    - VRML 1.0 (.wrl).
+
   @type filename: string
-  @param filename: the pathname for the desired .blend file.  If it doesn't
-      contain ".blend", this extension is automatically appended.
+  @param filename: the filename for the file to be written.  It must have one
+      of the supported extensions or an error will be returned.
   @type overwrite: int (bool)
   @param overwrite: if non-zero, file 'filename' will be overwritten if it
       already exists.  By default existing files are not overwritten (an error
       is returned).
 
-  @note: the substring ".B.blend" is not accepted inside 'filename'.
+  @note: The substring ".B.blend" is not accepted inside 'filename'.
+  @note: DXF, STL and Videoscape export only B{selected} meshes.
   """
 
 def Quit ():
index 77e2cf3830f635cd8d4e0b7f1ccc706fe581885f..803d8ad025dfff1ffe23cf6edf714e9c89b95a5a 100644 (file)
@@ -3,6 +3,8 @@
 """
 The Blender.Camera submodule.
 
+B{New}: scriptLink methods: L{Camera.getScriptLinks}, ...
+
 Camera Data
 ===========
 
@@ -178,3 +180,29 @@ class Camera:
     @type drawsize: float
     @param drawsize: The new draw size value.
     """
+
+  def getScriptLinks (event):
+    """
+    Get a list with this Camera's script links of type 'event'.
+    @type event: string
+    @param event: "FrameChanged" or "Redraw".
+    @rtype: list
+    @return: a list with Blender L{Text} names (the script links of the given
+        'event' type) or None if there are no script links at all.
+    """
+
+  def clearScriptLinks ():
+    """
+    Delete all this Camera's script links.
+    @rtype: bool
+    @return: 0 if some internal problem occurred or 1 if successful.
+    """
+
+  def addScriptLink (text, event):
+    """
+    Add a new script link to this Camera.
+    @type text: string
+    @param text: the name of an existing Blender L{Text}.
+    @type event: string
+    @param event: "FrameChanged" or "Redraw".
+    """
index aa95dbb2337fc8b6720412b145247ea86970d1b6..2efb40b4339c9883d61e3036c2d451039e5c9a7b 100644 (file)
@@ -6,7 +6,7 @@ The Blender.Draw submodule.
 Draw
 ====
 
-B{New}: L{PupIntInput}, L{PupFloatInput}, L{PupStrInput}.
+B{New}: L{PupIntInput}, L{PupFloatInput}, L{PupStrInput}, mouse wheel events.
 
 This module provides access to a B{windowing interface} in Blender.  Its widgets
 include many kinds of buttons: push, toggle, menu, number, string, slider,
index 4c8a525d513c01910f99a1b20b41323a3d5d6574..bf4c25607b8dfcb4b06f112ed708b1c69e077d06 100644 (file)
@@ -6,6 +6,8 @@ The Blender.Image submodule.
 Image
 =====
 
+B{New}: L{Image.reload}.
+
 This module provides access to B{Image} objects in Blender.
 
 Example::
index 95f1d61a1eb1330a2b0c8567e87c6c12edb3ed0d..a120605117d4ed486a3c8c26e1756391e806c9d5 100644 (file)
@@ -3,6 +3,8 @@
 """
 The Blender.Lamp submodule.
 
+B{New}: scriptLink methods: L{Lamp.getScriptLinks}, ...
+
 Lamp Data
 =========
 
@@ -320,3 +322,29 @@ class Lamp:
     @param quad2: The new quad 2 value.
     @warning: this only applies to Lamps with the 'Quad' flag on.
     """ 
+
+  def getScriptLinks (event):
+    """
+    Get a list with this Lamp's script links of type 'event'.
+    @type event: string
+    @param event: "FrameChanged" or "Redraw".
+    @rtype: list
+    @return: a list with Blender L{Text} names (the script links of the given
+        'event' type) or None if there are no script links at all.
+    """
+
+  def clearScriptLinks ():
+    """
+    Delete all this Lamp's script links.
+    @rtype: bool
+    @return: 0 if some internal problem occurred or 1 if successful.
+    """
+
+  def addScriptLink (text, event):
+    """
+    Add a new script link to this Lamp.
+    @type text: string
+    @param text: the name of an existing Blender L{Text}.
+    @type event: string
+    @param event: "FrameChanged" or "Redraw".
+    """
index 238c4def84c5b6f760d05d68da9a3753c82de4cf..74f320639c52e64e932ab4b0a11f5c1b45fcc1e2 100644 (file)
@@ -39,18 +39,6 @@ def Rand (high = 1, low = 0):
   @param low: The lower range.
   """
 
-def Vector (list = None):
-  """
-  Create a new Vector object from a list.
-  @type list: PyList of float or int
-  @param list: The list of values for the Vector object.
-  Must be 2, 3, or 4 values.
-  @rtype: Vector object.
-  @return: It depends wheter a parameter was passed:
-      - (list): Vector object initialized with the given values;
-      - ():     An empty 3 dimensional vector.
-  """
-
 def CopyVec(vector):
   """
   Create a copy of the Vector object.
@@ -128,23 +116,6 @@ def ProjectVecs(vec1, vec2):
   @return: The parallel projection vector.
   """
 
-def Matrix(list1 = None, list2 = None, list3 = None, list4 = None):
-  """  
-  Create a new matrix object from intialized values.
-  @type list1: PyList of int/float
-  @param list1: A 2d,3d or 4d list.
-  @type list2: PyList of int/float
-  @param list2: A 2d,3d or 4d list.
-  @type list3: PyList of int/float
-  @param list3: A 2d,3d or 4d list.
-  @type list4: PyList of int/float
-  @param list4: A 2d,3d or 4d list.
-  @rtype: New matrix object.
-  @return: It depends wheter a parameter was passed:
-      - (list1, etc.): Matrix object initialized with the given values;
-      - ():     An empty 3 dimensional matrix.
-  """
-
 def RotationMatrix(angle, matSize, axisFlag, axis):
   """  
   Create a matrix representing a rotation.
@@ -248,21 +219,6 @@ def MatMultVec(mat, vec):
   @return: The column vector that results from the muliplication.
   """
 
-def Quaternion(list = None, angle = None):
-  """  
-  Create a new matrix object from intialized values.
-  @type list: PyList of int/float
-  @param list: A 3d or 4d list to intialize quaternion.
-  4d if intializing, 3d if will be used as an axis of rotation.
-  @type angle: float (optional)
-  @param angle: An arbitrary rotation amount around 'list'.
-  List is used as an axis of rotation in this case.
-  @rtype: New quaternion object.
-  @return: It depends wheter a parameter was passed:
-      - (list/angle): Quaternion object initialized with the given values;
-      - ():     An identity 4 dimensional quaternion.
-  """
-
 def CopyQuat(quaternion):
   """
   Create a copy of the Quaternion object.
@@ -320,16 +276,6 @@ def Slerp(quat1, quat2, factor):
   @return: The interpolated rotation.
   """
 
-def Euler(list = None):
-  """
-  Create a new euler object.
-  @type list: PyList of float/int
-  @param list: 3d list to initalize euler
-  @rtype: Euler object
-  @return: Euler representing heading, pitch, bank.
-  Values are in degrees.
-  """
-
 def CopyEuler(euler):
   """
   Create a new euler object.
@@ -365,6 +311,21 @@ class Vector:
   @cvar length: The magnitude of the vector.
   """
 
+  def __init__(list = None):
+    """
+    Create a new Vector object from a list.
+
+    Example::
+      v = Blender.Mathutils.Vector([1,0,0])
+    @type list: PyList of float or int
+    @param list: The list of values for the Vector object.
+    Must be 2, 3, or 4 values.
+    @rtype: Vector object.
+    @return: It depends wheter a parameter was passed:
+        - (list): Vector object initialized with the given values;
+        - ():     An empty 3 dimensional vector.
+    """
+
   def zero():
     """
     Set all values to zero.
@@ -405,6 +366,19 @@ class Euler:
   @cvar z: The roll value in degrees.
   """
 
+  def __init__(list = None):
+    """
+    Create a new euler object.
+
+    Example::
+      euler = Euler([45,0,0])
+    @type list: PyList of float/int
+    @param list: 3d list to initialize euler
+    @rtype: Euler object
+    @return: Euler representing heading, pitch, bank.
+    @note: Values are in degrees.
+    """
+
   def zero():
     """
     Set all values to zero.
@@ -446,6 +420,25 @@ class Quaternion:
   in degrees.
   """
 
+  def __init__(list = None, angle = None):
+    """  
+    Create a new quaternion object from initialized values.
+
+    Example::
+      quat = Mathutils.Quaternion()
+
+    @type list: PyList of int/float
+    @param list: A 3d or 4d list to initialize quaternion.
+        4d if intializing, 3d if will be used as an axis of rotation.
+    @type angle: float (optional)
+    @param angle: An arbitrary rotation amount around 'list'.
+        List is used as an axis of rotation in this case.
+    @rtype: New quaternion object.
+    @return: It depends wheter a parameter was passed:
+        - (list/angle): Quaternion object initialized with the given values;
+        - ():     An identity 4 dimensional quaternion.
+    """
+
   def identity():
     """
     Set the quaternion to the identity quaternion.
@@ -496,6 +489,27 @@ class Matrix:
   @cvar colsize: The column size of the matrix.
   """
 
+  def __init__(list1 = None, list2 = None, list3 = None, list4 = None):
+    """  
+    Create a new matrix object from initialized values.
+
+    Example::
+      matrix = Mathutils.Matrix([1,1,1],[0,1,0],[1,0,0])
+
+    @type list1: PyList of int/float
+    @param list1: A 2d,3d or 4d list.
+    @type list2: PyList of int/float
+    @param list2: A 2d,3d or 4d list.
+    @type list3: PyList of int/float
+    @param list3: A 2d,3d or 4d list.
+    @type list4: PyList of int/float
+    @param list4: A 2d,3d or 4d list.
+    @rtype: New matrix object.
+    @return: It depends wheter a parameter was passed:
+        - (list1, etc.): Matrix object initialized with the given values;
+        - ():     An empty 3 dimensional matrix.
+    """
+
   def zero():
     """
     Set all matrix values to 0.
index a2a1ac824a0d9ff0a7b21953bfed9f47dfcad733..8f1165d2f9635ab279d76b0f6d5342ec7e5e429f 100644 (file)
@@ -3,7 +3,12 @@
 """
 The Blender.Object submodule
 
-This module provides access to the B{Object Data} in Blender.
+B{New}: L{Object.makeTrack}, scriptLink methods: L{Object.getScriptLinks}, ...
+
+Object
+======
+
+This module provides access to the B{Objects} in Blender.
 
 Example::
 
@@ -522,3 +527,53 @@ class Object:
        are not displayed correctly, try this method function.  But if the script
        works properly without it, there's no reason to use it.
     """
+
+  def getScriptLinks (event):
+    """
+    Get a list with this Object's script links of type 'event'.
+    @type event: string
+    @param event: "FrameChanged" or "Redraw".
+    @rtype: list
+    @return: a list with Blender L{Text} names (the script links of the given
+        'event' type) or None if there are no script links at all.
+    """
+
+  def clearScriptLinks ():
+    """
+    Delete all this Object's script links.
+    @rtype: bool
+    @return: 0 if some internal problem occurred or 1 if successful.
+    """
+
+  def addScriptLink (text, event):
+    """
+    Add a new script link to this Object.
+    @type text: string
+    @param text: the name of an existing Blender L{Text}.
+    @type event: string
+    @param event: "FrameChanged" or "Redraw".
+    """
+
+  def makeTrack (tracked, fast = 0):
+    """
+    Make this Object track another.
+    @type tracked: Blender Object
+    @param tracked: the object to be tracked.
+    @type fast: int (bool)
+    @param fast: if zero, the scene hierarchy is updated automatically.  If
+        you set 'fast' to a nonzero value, don't forget to update the scene
+        yourself (see L{Scene.Scene.update}).
+    @note: you also need to clear the rotation (L{setEuler}) of this object
+       if it was not (0,0,0) already.
+    """
+
+  def clearTrack (mode = 0, fast = 0):
+    """
+    Make this Object not track another anymore.
+    @type mode: int (bool)
+    @param mode: if nonzero the matrix transformation used for tracking is kept.
+    @type fast: int (bool)
+    @param fast: if zero, the scene hierarchy is updated automatically.  If
+        you set 'fast' to a nonzero value, don't forget to update the scene
+        yourself (see L{Scene.Scene.update}).
+    """
index 232ce33d5670f07ed1172a1cc1ae08a7c1fe5a1a..1d84b95a2291bce3846f06cd5c80ce2af49b874c 100644 (file)
@@ -3,7 +3,7 @@
 """
 The Blender.Scene submodule.
 
-B{New}: scriptLink methods: L{Scene.getScriptLinks}, ...
+B{New}: L{Scene.play}, scriptLink methods: L{Scene.getScriptLinks}, ...
 
 Scene
 =====
@@ -219,3 +219,24 @@ class Scene:
     @type event: string
     @param event: "FrameChanged", "OnLoad" or "Redraw".
     """
+
+  def play (mode = 0, win = '<VIEW3D>'):
+    """
+    Play a realtime animation.  This is the "Play Back Animation" function in
+    Blender, different from playing a sequence of rendered images (for that
+    check L{Render.RenderData.play}).
+    @type mode: int
+    @param mode: controls playing:
+        - 0: keep playing in the biggest 'win' window;
+        - 1: keep playing in all 'win', VIEW3D and SEQ windows;
+        - 2: play once in the biggest VIEW3D;
+        - 3: play once in all 'win', VIEW3D and SEQ windows.
+    @type win: int
+    @param win: window type, see L{Window.Types}.  Only some of them are
+        meaningful here: VIEW3D, SEQ, IPO, ACTION, NLA, SOUND.  But the others
+        are also accepted, since this function can be used simply as an
+        interruptible timer.  If 'win' is not visible or invalid, VIEW3D is
+        tried, then any bigger visible window.
+    @rtype: bool
+    @return: 0 on normal exit or 1 when play back is canceled by user input.
+    """
index 47367d86c187e14a0b493a7b19c8fb1e9a8dee6a..7908e6df0b8c3cfe5187c56fa75ca9b15c2f332a 100644 (file)
@@ -114,14 +114,18 @@ def makename (path = "Blender.Get('filename')", ext = "", strip = 0):
 def exists(path):
   """
   Tell if the given pathname (file or dir) exists.
-  @rtype: bool
-  @return: 1 if 'path' exists, 0 otherwise.
+  @rtype: int
+  @return:
+      -  0: path does not exist;
+      -  1: path is an existing filename;
+      -  2: path is an existing dirname;
+      - -1: path exists but is neither a regular file nor a dir.
   """
 
 def time ():
   """
   Get the current time in seconds since a fixed value.  Successive calls to
-  this function are garanteed to return values greater than the previous call.
+  this function are guaranteed to return values greater than the previous call.
   @rtype: float
   @return: the elapsed time in seconds.
   """
index 8c87f83b48cec3dd53f7ac82a1ac49b526d2caff..a4bbab9e4102b5cb1c04647a76f92e21a207f992 100644 (file)
@@ -55,19 +55,20 @@ DrawProgressBar::
 
 @type Types: readonly dictionary
 @var Types: The available Window Types.
-    - VIEW3D
-    - IPO
-    - OOPS
+    - ACTION
     - BUTS
     - FILE
     - IMAGE
+    - IMASEL
     - INFO
+    - IPO
+    - NLA
+    - OOPS
+    - SCRIPT
     - SEQ
-    - IMASEL
     - SOUND
-    - ACTION
     - TEXT
-    - NLA
+    - VIEW3D
 """
 
 def Redraw ():
index 625f0432212298892527a370dffc5ea5f50076be..3b133deec5d69c8c0e2164cda7e5f985d43b5891 100644 (file)
@@ -3,7 +3,10 @@
 """
 The Blender.World submodule
 
+B{New}: scriptLink methods: L{World.getScriptLinks}, ...
+
 INTRODUCTION
+============
 
 The module world allows you to access all the data of a Blender World.
 
@@ -80,7 +83,7 @@ class World:
 
   def getName():
     """
-    Retreives the name of an world object
+    Retrieves the name of an world object
     @rtype: string
     @return:  the name of the world object.
     """
@@ -116,7 +119,7 @@ class World:
 
   def getSkytype():
     """
-    Retreives the skytype of a world object.
+    Retrieves the skytype of a world object.
     The skytype is a combination of 3 bits : Bit 0 : Blend; Bit 1 : Real; Bit 2 : paper.
     @rtype: int
     @return:  the skytype of the world object.
@@ -135,7 +138,7 @@ class World:
 
   def getMode():
     """
-    Retreives the mode of a world object.
+    Retrieves the mode of a world object.
     The mode is a combination of 3 bits : Bit 0 : Blend; Bit 1 : Real; Bit 2 : paper.
     @rtype: int
     @return:  the mode of the world object.
@@ -154,7 +157,7 @@ class World:
 
   def getMistype():
     """
-    Retreives the mist type of a world object.
+    Retrieves the mist type of a world object.
     The mist type is an integer 0 : quadratic;  1 : linear;  2 : square.
     @rtype: int
     @return:  the mistype of the world object.
@@ -173,7 +176,7 @@ class World:
 
   def getHor():
     """
-    Retreives the horizon color  of a world object.
+    Retrieves the horizon color  of a world object.
     This color is a list of 3 floats.
     @rtype: list of three floats
     @return:  the horizon color of the world object.
@@ -191,7 +194,7 @@ class World:
 
   def getZen():
     """
-    Retreives the zenith color  of a world object.
+    Retrieves the zenith color  of a world object.
     This color is a list of 3 floats.
     @rtype: list of three floats
     @return:  the zenith color of the world object.
@@ -209,7 +212,7 @@ class World:
 
   def getAmb():
     """
-    Retreives the ambient color  of a world object.
+    Retrieves the ambient color  of a world object.
     This color is a list of 3 floats.
     @rtype: list of three floats
     @return:  the ambient color of the world object.
@@ -227,7 +230,7 @@ class World:
 
   def getStar():
     """
-    Retreives the star parameters  of a world object.
+    Retrieves the star parameters  of a world object.
     It is a list of nine floats :
     red component of the color
     green component of the color
@@ -253,7 +256,7 @@ class World:
 
   def getMist():
     """
-    Retreives the mist parameters  of a world object.
+    Retrieves the mist parameters  of a world object.
     It is a list of four floats :
     intensity of the mist
     start of the mist
@@ -273,3 +276,29 @@ class World:
     @rtype: PyNone
     @return:  PyNone
     """
+
+  def getScriptLinks (event):
+    """
+    Get a list with this World's script links of type 'event'.
+    @type event: string
+    @param event: "FrameChanged" or "Redraw".
+    @rtype: list
+    @return: a list with Blender L{Text} names (the script links of the given
+        'event' type) or None if there are no script links at all.
+    """
+
+  def clearScriptLinks ():
+    """
+    Delete all this World's script links!
+    @rtype: bool
+    @return: 0 if some internal problem occurred or 1 if successful.
+    """
+
+  def addScriptLink (text, event):
+    """
+    Add a new script link to this World.
+    @type text: string
+    @param text: the name of an existing Blender L{Text}.
+    @type event: string
+    @param event: "FrameChanged" or "Redraw".
+    """
index 1806732e919f60eddc2370aaf19b42b3de9fe930..13b2798825ad3780581b7be5da1f0e3098b86795 100644 (file)
@@ -951,21 +951,27 @@ void run_python_script(SpaceText *st)
 {
        char *py_filename;
        Text *text=st->text;
+
        if (!BPY_txt_do_python(st)) {
                int lineno = BPY_Err_getLinenumber();
                // jump to error if happened in current text:
                py_filename = (char*) BPY_Err_getFilename();
+
+               /* st->text can become NULL: user called Blender.Load(blendfile)
+                * before the end of the script. */
+               if (!st->text) return;
+
                if (!strcmp(py_filename, st->text->id.name+2)) {
                        error("Python script error, check console");
-               if (lineno >= 0) {
-                       txt_move_toline(text, lineno-1, 0);
-                       txt_sel_line(text);
-                       pop_space_text(st);
+                       if (lineno >= 0) {
+                               txt_move_toline(text, lineno-1, 0);
+                               txt_sel_line(text);
+                               pop_space_text(st);
+                       }       
+               } else {
+                       error("Error in other (possibly external) file, "\
+                               "check console");
                }       
-       } else {
-               error("Error in other (possibly external) file, "\
-               "check console");
-       }       
        }
 }
 
index dab5c5ff2bfacd994b0bba3f13c487a234f40dc3..5f5d4afb41c4153a209635490f4be5f9b71ecff7 100644 (file)
@@ -2428,7 +2428,7 @@ void inner_play_anim_loop(int init, int mode)
                if(sa==oldsa) {
                        scrarea_do_windraw(sa);
                }
-               else if(curmode) {
+               else if(curmode & 1) { /* catch modes 1 and 3 */
                        if ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ) {
                                scrarea_do_windraw(sa);
                        }
@@ -2453,6 +2453,11 @@ void inner_play_anim_loop(int init, int mode)
        }
 }
 
+/* play_anim: 'mode' defines where to play and if repeat is on:
+ * - 0: current area
+ * - 1: all view3d and seq areas
+ * - 2: current area, no replay
+ * - 3: all view3d and seq areas, no replay */
 int play_anim(int mode)
 {
        ScrArea *sa, *oldsa;
@@ -2507,7 +2512,7 @@ int play_anim(int mode)
                }
                if(event==ESCKEY || event==SPACEKEY) break;
                                
-               if(mode==2 && CFRA==EFRA) break;        
+               if((mode > 1) && CFRA==EFRA) break; /* no replay */     
        }
 
        if(event==SPACEKEY);
index 67c05422ed26d73b2bc500fce079d7c75d4ad32c..f95653f772526c701d85a3887ce604a283fd2595 100644 (file)
@@ -182,7 +182,7 @@ static void print_help(void)
        printf ("  -noaudio\tDisable audio on systems that support audio\n");
        printf ("  -h\t\tPrint this help text\n");
        printf ("  -y\t\tDisable OnLoad scene scripts, use -Y to find out why its -y\n");
-       printf ("  -P <filename>\tRun the given Python script\n");
+       printf ("  -P <filename>\tRun the given Python script (filename or Blender Text)\n");
 #ifdef WIN32
        printf ("  -R\t\tRegister .blend extension\n");
 #endif
@@ -424,16 +424,6 @@ int main(int argc, char **argv)
 
                BIF_init();
 
-               /**
-                * NOTE: the U.pythondir string is NULL until BIF_init() is executed,
-                * so we provide the BPY_ function below to append the user defined
-                * pythondir to Python's sys.path at this point.  Simply putting
-                * BIF_init() before BPY_start_python() crashes Blender at startup.
-                * Update: now this function also inits the bpymenus, which also depend
-                * on U.pythondir.
-                */
-
-               BPY_post_start_python();
        }
        else {
                BPY_start_python();
@@ -445,6 +435,16 @@ int main(int argc, char **argv)
         // if (G.f & G_DEBUG) printf("setting audio to: %d\n", audio);
        }
 
+       /**
+        * NOTE: the U.pythondir string is NULL until BIF_init() is executed,
+        * so we provide the BPY_ function below to append the user defined
+        * pythondir to Python's sys.path at this point.  Simply putting
+        * BIF_init() before BPY_start_python() crashes Blender at startup.
+        * Update: now this function also inits the bpymenus, which also depend
+        * on U.pythondir.
+        */
+       BPY_post_start_python();
+
        RE_init_filt_mask();
 
 #ifdef WITH_QUICKTIME