Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWillian Padovani Germano <wpgermano@gmail.com>2004-07-03 09:17:04 +0400
committerWillian Padovani Germano <wpgermano@gmail.com>2004-07-03 09:17:04 +0400
commit928282772051eadd29b26a43b4c217ebf06d0ba9 (patch)
tree36e2a9906ed924e962554df716d30f0ad1bce798 /release
parent90d4f7a3c1f6f789df61f348f974813a260014f5 (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.
Diffstat (limited to 'release')
-rw-r--r--release/scripts/ac3d_export.py43
-rw-r--r--release/scripts/bevel_center.py462
-rw-r--r--release/scripts/doc_browser.py425
-rw-r--r--release/scripts/hotkeys.py438
-rw-r--r--release/scripts/obdatacopier.py142
-rw-r--r--release/scripts/renameobjectbyblock.py173
6 files changed, 1668 insertions, 15 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)
+