diff options
author | Willian Padovani Germano <wpgermano@gmail.com> | 2004-07-03 09:17:04 +0400 |
---|---|---|
committer | Willian Padovani Germano <wpgermano@gmail.com> | 2004-07-03 09:17:04 +0400 |
commit | 928282772051eadd29b26a43b4c217ebf06d0ba9 (patch) | |
tree | 36e2a9906ed924e962554df716d30f0ad1bce798 | |
parent | 90d4f7a3c1f6f789df61f348f974813a260014f5 (diff) |
New scripts:
- 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, 2778 insertions, 476 deletions
diff --git a/release/scripts/ac3d_export.py b/release/scripts/ac3d_export.py index e1ec989963f..3ee140e9a2c 100644 --- a/release/scripts/ac3d_export.py +++ b/release/scripts/ac3d_export.py @@ -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 index 00000000000..eef2f630cea --- /dev/null +++ b/release/scripts/bevel_center.py @@ -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 index 00000000000..e9c63b3d319 --- /dev/null +++ b/release/scripts/doc_browser.py @@ -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 index 00000000000..9f15a97852b --- /dev/null +++ b/release/scripts/hotkeys.py @@ -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 index 00000000000..82cabdb8b36 --- /dev/null +++ b/release/scripts/obdatacopier.py @@ -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 index 00000000000..f2ce46e57fa --- /dev/null +++ b/release/scripts/renameobjectbyblock.py @@ -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) + diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 9bbe9d3726f..964b252c844 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -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; diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c index b7a52e6bf4c..57c8a56f2be 100644 --- a/source/blender/blenkernel/intern/exotic.c +++ b/source/blender/blenkernel/intern/exotic.c @@ -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; } diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index 63e416d86d5..fecff8e02e8 100644 --- a/source/blender/python/BPY_interface.c +++ b/source/blender/python/BPY_interface.c @@ -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; diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c index f9629cf1d1e..ecb97642176 100644 --- a/source/blender/python/api2_2x/Blender.c +++ b/source/blender/python/api2_2x/Blender.c @@ -32,11 +32,22 @@ #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; diff --git a/source/blender/python/api2_2x/Camera.c b/source/blender/python/api2_2x/Camera.c index efa1300359c..66ccee15d00 100644 --- a/source/blender/python/api2_2x/Camera.c +++ b/source/blender/python/api2_2x/Camera.c @@ -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) diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c index 02e0ed028d0..707323b9955 100644 --- a/source/blender/python/api2_2x/Draw.c +++ b/source/blender/python/api2_2x/Draw.c @@ -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); diff --git a/source/blender/python/api2_2x/Lamp.c b/source/blender/python/api2_2x/Lamp.c index c09113ab3fa..74f2718a5fa 100644 --- a/source/blender/python/api2_2x/Lamp.c +++ b/source/blender/python/api2_2x/Lamp.c @@ -29,7 +29,269 @@ * ***** 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 */ diff --git a/source/blender/python/api2_2x/Lamp.h b/source/blender/python/api2_2x/Lamp.h index f3e2f92eda0..1ba8a8a5d35 100644 --- a/source/blender/python/api2_2x/Lamp.h +++ b/source/blender/python/api2_2x/Lamp.h @@ -32,256 +32,4 @@ #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 */ diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index 508bc47a0a4..0830184d941 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -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")) { diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c index eb1536f2d1b..59a1118398b 100644 --- a/source/blender/python/api2_2x/Scene.c +++ b/source/blender/python/api2_2x/Scene.c @@ -34,9 +34,12 @@ #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 /*****************************************************************************/ diff --git a/source/blender/python/api2_2x/Sys.c b/source/blender/python/api2_2x/Sys.c index de6da24496f..39412fada16 100644 --- a/source/blender/python/api2_2x/Sys.c +++ b/source/blender/python/api2_2x/Sys.c @@ -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); } diff --git a/source/blender/python/api2_2x/World.c b/source/blender/python/api2_2x/World.c index 056fdcc9281..ef0ade60c48 100644 --- a/source/blender/python/api2_2x/World.c +++ b/source/blender/python/api2_2x/World.c @@ -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; +} /*@{*/ diff --git a/source/blender/python/api2_2x/World.h b/source/blender/python/api2_2x/World.h index 2f83cd0fb9f..d7c99ac9231 100644 --- a/source/blender/python/api2_2x/World.h +++ b/source/blender/python/api2_2x/World.h @@ -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); diff --git a/source/blender/python/api2_2x/doc/BGL.py b/source/blender/python/api2_2x/doc/BGL.py index dff399318ef..b9155b4cb7e 100644 --- a/source/blender/python/api2_2x/doc/BGL.py +++ b/source/blender/python/api2_2x/doc/BGL.py @@ -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): diff --git a/source/blender/python/api2_2x/doc/Blender.py b/source/blender/python/api2_2x/doc/Blender.py index b595bfb9e49..eb048b65e31 100644 --- a/source/blender/python/api2_2x/doc/Blender.py +++ b/source/blender/python/api2_2x/doc/Blender.py @@ -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 (): diff --git a/source/blender/python/api2_2x/doc/Camera.py b/source/blender/python/api2_2x/doc/Camera.py index 77e2cf3830f..803d8ad025d 100644 --- a/source/blender/python/api2_2x/doc/Camera.py +++ b/source/blender/python/api2_2x/doc/Camera.py @@ -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". + """ diff --git a/source/blender/python/api2_2x/doc/Draw.py b/source/blender/python/api2_2x/doc/Draw.py index aa95dbb2337..2efb40b4339 100644 --- a/source/blender/python/api2_2x/doc/Draw.py +++ b/source/blender/python/api2_2x/doc/Draw.py @@ -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, diff --git a/source/blender/python/api2_2x/doc/Image.py b/source/blender/python/api2_2x/doc/Image.py index 4c8a525d513..bf4c25607b8 100644 --- a/source/blender/python/api2_2x/doc/Image.py +++ b/source/blender/python/api2_2x/doc/Image.py @@ -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:: diff --git a/source/blender/python/api2_2x/doc/Lamp.py b/source/blender/python/api2_2x/doc/Lamp.py index 95f1d61a1eb..a120605117d 100644 --- a/source/blender/python/api2_2x/doc/Lamp.py +++ b/source/blender/python/api2_2x/doc/Lamp.py @@ -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". + """ diff --git a/source/blender/python/api2_2x/doc/Mathutils.py b/source/blender/python/api2_2x/doc/Mathutils.py index 238c4def84c..74f320639c5 100644 --- a/source/blender/python/api2_2x/doc/Mathutils.py +++ b/source/blender/python/api2_2x/doc/Mathutils.py @@ -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. diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py index a2a1ac824a0..8f1165d2f96 100644 --- a/source/blender/python/api2_2x/doc/Object.py +++ b/source/blender/python/api2_2x/doc/Object.py @@ -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}). + """ diff --git a/source/blender/python/api2_2x/doc/Scene.py b/source/blender/python/api2_2x/doc/Scene.py index 232ce33d567..1d84b95a229 100644 --- a/source/blender/python/api2_2x/doc/Scene.py +++ b/source/blender/python/api2_2x/doc/Scene.py @@ -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. + """ diff --git a/source/blender/python/api2_2x/doc/Sys.py b/source/blender/python/api2_2x/doc/Sys.py index 47367d86c18..7908e6df0b8 100644 --- a/source/blender/python/api2_2x/doc/Sys.py +++ b/source/blender/python/api2_2x/doc/Sys.py @@ -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. """ diff --git a/source/blender/python/api2_2x/doc/Window.py b/source/blender/python/api2_2x/doc/Window.py index 8c87f83b48c..a4bbab9e410 100644 --- a/source/blender/python/api2_2x/doc/Window.py +++ b/source/blender/python/api2_2x/doc/Window.py @@ -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 (): diff --git a/source/blender/python/api2_2x/doc/World.py b/source/blender/python/api2_2x/doc/World.py index 625f0432212..3b133deec5d 100644 --- a/source/blender/python/api2_2x/doc/World.py +++ b/source/blender/python/api2_2x/doc/World.py @@ -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". + """ diff --git a/source/blender/src/drawtext.c b/source/blender/src/drawtext.c index 1806732e919..13b2798825a 100644 --- a/source/blender/src/drawtext.c +++ b/source/blender/src/drawtext.c @@ -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"); - } } } diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index dab5c5ff2bf..5f5d4afb41c 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -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); diff --git a/source/creator/creator.c b/source/creator/creator.c index 67c05422ed2..f95653f7725 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -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 |