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:
Diffstat (limited to 'intern/python/modules/Blender')
-rw-r--r--intern/python/modules/Blender/BGL.py1
-rw-r--r--intern/python/modules/Blender/Camera.py106
-rw-r--r--intern/python/modules/Blender/Draw.py1
-rw-r--r--intern/python/modules/Blender/Image.py52
-rw-r--r--intern/python/modules/Blender/Ipo.py279
-rw-r--r--intern/python/modules/Blender/Lamp.py168
-rw-r--r--intern/python/modules/Blender/Material.py251
-rw-r--r--intern/python/modules/Blender/Mesh.py250
-rw-r--r--intern/python/modules/Blender/NMesh.py192
-rw-r--r--intern/python/modules/Blender/Object.py391
-rw-r--r--intern/python/modules/Blender/Scene.py143
-rw-r--r--intern/python/modules/Blender/Text.py57
-rw-r--r--intern/python/modules/Blender/Types.py1
-rw-r--r--intern/python/modules/Blender/Window.py65
-rw-r--r--intern/python/modules/Blender/World.py157
-rw-r--r--intern/python/modules/Blender/__init__.py23
-rw-r--r--intern/python/modules/Blender/shadow.py195
-rw-r--r--intern/python/modules/Blender/sys.py20
18 files changed, 2352 insertions, 0 deletions
diff --git a/intern/python/modules/Blender/BGL.py b/intern/python/modules/Blender/BGL.py
new file mode 100644
index 00000000000..033b3560e4f
--- /dev/null
+++ b/intern/python/modules/Blender/BGL.py
@@ -0,0 +1 @@
+from _Blender.BGL import *
diff --git a/intern/python/modules/Blender/Camera.py b/intern/python/modules/Blender/Camera.py
new file mode 100644
index 00000000000..33f615fc0da
--- /dev/null
+++ b/intern/python/modules/Blender/Camera.py
@@ -0,0 +1,106 @@
+"""The Blender Camera module
+
+This module provides access to **Camera** objects in Blender
+
+Example::
+
+ from Blender import Camera, Object, Scene
+ c = Camera.New('ortho') # create new ortho camera data
+ c.lens = 35.0 # set lens value
+ cur = Scene.getCurrent() # get current Scene
+ ob = Object.New('Camera') # make camera object
+ ob.link(c) # link camera data with this object
+ cur.link(ob) # link object into scene
+ cur.setCurrentCamera(ob) # make this camera the active
+"""
+
+import shadow
+import _Blender.Camera as _Camera
+
+
+class Camera(shadow.hasIPO):
+ """Wrapper for Camera DataBlock
+
+ Attributes
+
+ lens -- The lens value
+
+ clipStart -- The clipping start of the view frustum
+
+ clipEnd -- The end clipping plane of the view frustum
+
+ type -- The camera type:
+ 0: perspective camera,
+ 1: orthogonal camera - (see Types)
+
+ mode -- Drawing mode; see Modes
+"""
+
+ _emulation = {'Lens' : "lens",
+ 'ClSta' : "clipStart",
+ 'ClEnd' : "clipEnd",
+ }
+
+ Types = {'persp' : 0,
+ 'ortho' : 1,
+ }
+
+ Modes = {'showLimits' : 1,
+ 'showMist' : 2,
+ }
+
+ def __init__(self, object):
+ self._object = object
+
+ def getType(self):
+ """Returns camera type: "ortho" or "persp" """
+ if self.type == self.Types['ortho']:
+ return 'ortho'
+ else:
+ return 'persp'
+
+ def setType(self, type):
+ """Sets Camera type to 'type' which must be one of ["persp", "ortho"]"""
+ self._object.type = self.Types[type]
+
+ def setMode(self, *modes):
+ """Sets Camera modes *the nice way*, instead of direct access
+of the 'mode' member.
+This function takes a variable number of string arguments of the types
+listed in self.Modes.
+
+
+Example::
+
+ c = Camera.New()
+ c.setMode('showMist', 'showLimits')
+"""
+ flags = 0
+ try:
+ for a in modes:
+ flags |= self.Modes[a]
+ except:
+ raise TypeError, "mode must be one of %s" % self.Modes.keys()
+ self.mode = flags
+
+ def __repr__(self):
+ return "[Camera \"%s\"]" % self.name
+
+def New(type = 'persp'):
+ """Creates new camera Object and returns it. 'type', if specified,
+must be one of Types"""
+ cam = Camera(_Camera.New())
+ cam.setType(type)
+ return cam
+
+def get(name = None):
+ """Returns the Camera with name 'name', if given. Otherwise, a list
+of all Cameras is returned"""
+ if name:
+ return Camera(_Camera.get(name))
+ else:
+ return shadow._List(_Camera.get(), Camera)
+
+Get = get # emulation
+
+
diff --git a/intern/python/modules/Blender/Draw.py b/intern/python/modules/Blender/Draw.py
new file mode 100644
index 00000000000..6c2cb8be09f
--- /dev/null
+++ b/intern/python/modules/Blender/Draw.py
@@ -0,0 +1 @@
+from _Blender.Draw import *
diff --git a/intern/python/modules/Blender/Image.py b/intern/python/modules/Blender/Image.py
new file mode 100644
index 00000000000..c1737e1bb0d
--- /dev/null
+++ b/intern/python/modules/Blender/Image.py
@@ -0,0 +1,52 @@
+"""The Blender Image module
+
+ This module provides (yet) basic support for Blender *Image* data blocks
+
+ Example::
+
+ from Blender import Image
+ im = Image.Load('dead-parrot.jpg')
+"""
+
+import _Blender.Image as _Image
+import shadow
+
+class Image(shadow.shadow):
+ """Image DataBlock object
+
+ See above example on how to create instances of Image objects.
+
+ Attributes
+
+ xrep -- Texture image tiling factor (subdivision) in X
+
+ yrep -- Texture image tiling factor (subdivision) in Y
+
+ LATER:
+
+ * Image buffer access
+
+ * better loading / saving of images
+"""
+ pass
+
+def get(name):
+ """If 'name' given, the Image 'name' is returned if existing, 'None' otherwise.
+If no name is given, a list of all Images is returned"""
+ pass
+
+def Load(filename):
+ """Returns image from file 'filename' as Image object if found, 'None' else."""
+ pass
+
+def New(name):
+ """This function is currently not implemented"""
+ pass
+
+# override all functions again, the above classes are just made
+# for documentation
+
+get = _Image.get
+Get = get
+Load = _Image.Load
+
diff --git a/intern/python/modules/Blender/Ipo.py b/intern/python/modules/Blender/Ipo.py
new file mode 100644
index 00000000000..110f95a5d07
--- /dev/null
+++ b/intern/python/modules/Blender/Ipo.py
@@ -0,0 +1,279 @@
+"""The Blender Ipo module
+
+This module provides access to **Ipo** objects in Blender.
+
+An Ipo object is a datablock of IpoCurves which control properties of
+an object in time.
+
+Note that IpoCurves assigned to rotation values (which must be specified
+in radians) appear scaled in the IpoWindow (which is in fact true, due
+to the fact that conversion to an internal unit of 10.0 angles happens).
+
+Example::
+
+ from Blender import Ipo, Object
+
+ ipo = Ipo.New('Object', 'ObIpo') # Create object ipo with name 'ObIpo'
+ curve = ipo.addCurve('LocY') # add IpoCurve for LocY
+ curve.setInterpolation('Bezier') # set interpolation type
+ curve.setExtrapolation('CyclicLinear') # set extrapolation type
+
+ curve.addBezier((0.0, 0.0)) # add automatic handle bezier point
+ curve.addBezier((20.0, 5.0), 'Free', (10.0, 4.0)) # specify left handle, right auto handle
+ curve.addBezier((30.0, 1.0), 'Vect') # automatic split handle
+ curve.addBezier((100.0, 1.0)) # auto handle
+
+ curve.update() # recalculate curve handles
+
+ curve.eval(35.0) # evaluate curve at 35.0
+
+ ob = Object.get('Plane')
+ ob.setIpo(ipo) # assign ipo to object
+"""
+
+import _Blender.Ipo as _Ipo
+
+import shadow
+
+_RotIpoCurves = ["RotX", "RotY", "RotZ", "dRotX", "dRotY", "dRotZ"]
+
+_radian_factor = 5.72957814 # 18.0 / 3.14159255
+
+def _convertBPoint(b):
+ f = _radian_factor
+ newb = BezierPoint()
+ p = b.pt
+ q = newb.pt
+ q[0], q[1] = (p[0], f * p[1])
+ p = b.h1
+ q = newb.h1
+ q[0], q[1] = (p[0], f * p[1])
+ p = b.h2
+ q = newb.h2
+ q[0], q[1] = (p[0], f * p[1])
+ return newb
+
+
+class IpoBlock(shadow.shadowEx):
+ """Wrapper for Blender Ipo DataBlock
+
+ Attributes
+
+ curves -- list of owned IpoCurves
+"""
+ def get(self, channel = None):
+ """Returns curve with channel identifier 'channel', which is one of the properties
+listed in the Ipo Window, 'None' if not found.
+If 'channel' is not specified, all curves are returned in a list"""
+ if channel:
+ for c in self._object.curves:
+ if c.name == channel:
+ return IpoCurve(c)
+ return None
+ else:
+ return map(lambda x: IpoCurve(x), self._object.curves)
+
+ def __getitem__(self, k):
+ """Emulates dictionary syntax, e.g. ipocurve = ipo['LocX']"""
+ curve = self.get(k)
+ if not curve:
+ raise KeyError, "Ipo does not have a curve for channel %s" % k
+ return curve
+
+ def __setitem__(self, k, val):
+ """Emulates dictionary syntax, e.g. ipo['LocX'] = ipocurve"""
+ c = self.addCurve(k, val)
+
+ has_key = get # dict emulation
+
+ items = get # dict emulation
+
+ def keys(self):
+ return map(lambda x: x.name, self.get())
+
+ def addCurve(self, channel, curve = None):
+ """Adds a curve of channel type 'channel' to the Ipo Block. 'channel' must be one of
+the object properties listed in the Ipo Window. If 'curve' is not specified,
+an empty curve is created, otherwise, the existing IpoCurve 'curve' is copied and
+added to the IpoBlock 'self'.
+In any case, the added curve is returned.
+"""
+ if curve:
+ if curve.__class__.__name__ != "IpoCurve":
+ raise TypeError, "IpoCurve expected"
+ c = self._object.addCurve(channel, curve._object)
+
+ ### RotIpo conversion hack
+ if channel in _RotIpoCurves:
+ print "addCurve, converting", curve.name
+ c.points = map(_convertBPoint, curve.bezierPoints)
+ else:
+ c.points = curve.bezierPoints
+ else:
+ c = self._object.addCurve(channel)
+ return IpoCurve(c)
+
+ _getters = { 'curves' : get }
+
+class BezierPoint:
+ """BezierPoint object
+
+ Attributes
+
+ pt -- Coordinates of the Bezier point
+
+ h1 -- Left handle coordinates
+
+ h2 -- Right handle coordinates
+
+ h1t -- Left handle type (see IpoCurve.addBezier(...) )
+
+ h2t -- Right handle type
+"""
+
+BezierPoint = _Ipo.BezTriple # override
+
+class IpoCurve(shadow.shadowEx):
+ """Wrapper for Blender IpoCurve
+
+ Attributes
+
+ bezierPoints -- A list of BezierPoints (see class BezierPoint),
+ defining the curve shape
+"""
+
+ InterpolationTypes = _Ipo.InterpolationTypes
+ ExtrapolationTypes = _Ipo.ExtrapolationTypes
+
+ def __init__(self, object):
+ self._object = object
+ self.__dict__['bezierPoints'] = self._object.points
+
+ def __getitem__(self, k):
+ """Emulate a sequence of BezierPoints"""
+ print k, type(k)
+ return self.bezierPoints[k]
+
+ def __repr__(self):
+ return "[IpoCurve %s]" % self.name
+
+ def __len__(self):
+ return len(self.bezierPoints)
+
+ def eval(self, time):
+ """Returns float value of curve 'self' evaluated at time 'time' which
+must be a float."""
+ return self._object.eval(time)
+
+ def addBezier(self, p, leftType = 'Auto', left = None, rightType = None, right = None):
+ """Adds a Bezier triple to the IpoCurve.
+
+The following values are float tuples (x,y), denoting position of a control vertex:
+
+p -- The position of the Bezier point
+
+left -- The position of the leftmost handle
+
+right -- The position of the rightmost handle
+
+'leftType', 'rightType' must be one of:
+
+"Auto" -- automatic handle calculation. In this case, 'left' and 'right' don't need to be specified
+
+"Vect" -- automatic split handle calculation. 'left' and 'right' are disregarded.
+
+"Align" -- Handles are aligned automatically. In this case, 'right' does not need to be specified.
+
+"Free" -- Handles can be set freely - this requires both arguments 'left' and 'right'.
+
+"""
+
+ b = _Ipo.BezTriple()
+ b.pt[0], b.pt[1] = (p[0], p[1])
+ b.h1t = leftType
+
+ if rightType:
+ b.h2t = rightType
+ else:
+ b.h2t = leftType
+
+ if left:
+ b.h1[0], b.h1[1] = (left[0], left[1])
+
+ if right:
+ b.h2[0], b.h2[1] = (right[0], right[1])
+
+ self.__dict__['bezierPoints'].append(b)
+ return b
+
+ def update(self, noconvert = 0):
+ # This is an ugly fix for the 'broken' storage of Rotation
+ # ipo values. The angles are stored in units of 10.0 degrees,
+ # which is totally inconsistent with anything I know :-)
+ # We can't (at the moment) change the internals, so we
+ # apply a conversion kludge..
+ if self._object.name in _RotIpoCurves and not noconvert:
+ points = map(_convertBPoint, self.bezierPoints)
+ else:
+ points = self.bezierPoints
+ self._object.points = points
+ self._object.update()
+
+ def getInterpolationType(self, ipotype):
+ "Returns the Interpolation type - see also IpoCurve.InterpolationTypes"
+ return self._object.getInterpolationType()
+
+ def setInterpolationType(self, ipotype):
+ """Sets the interpolation type which must be one of IpoCurve.InterpolationTypes"""
+ try:
+ self._object.setInterpolationType(ipotype)
+ except:
+ raise TypeError, "must be one of %s" % self.InterpolationTypes.keys()
+
+ def getExtrapolationType(self, ipotype):
+ "Returns the Extrapolation type - see also IpoCurve.ExtrapolationTypes"
+ return self._object.getExtrapolationType()
+
+ def setExtrapolationType(self, ipotype):
+ """Sets the interpolation type which must be one of IpoCurve.ExtrapolationTypes"""
+ try:
+ self._object.setInterpolationType(ipotype)
+ except:
+ raise TypeError, "must be one of %s" % self.ExtrapolationTypes.keys()
+
+
+def New(blocktype, name = None):
+ """Returns a new IPO block of type 'blocktype' which must be one of:
+["Object", "Camera", "World", "Material"]
+"""
+ if name:
+ i = _Ipo.New(blocktype, name)
+ else:
+ i = _Ipo.New(blocktype)
+ return IpoBlock(i)
+
+def Eval(ipocurve, time): # emulation code
+ """This function is just there for compatibility.
+Use IpoCurve.eval(time) instead"""
+ return ipocurve.eval(time)
+
+def Recalc(ipocurve): # emulation code
+ """This function is just there for compatibility. Note that Ipos
+assigned to rotation values will *not* get converted to the proper
+unit of radians.
+In the new style API, use IpoCurve.update() instead"""
+ return ipocurve.update(1)
+
+def get(name = None):
+ """If 'name' given, the Ipo 'name' is returned if existing, 'None' otherwise.
+If no name is given, a list of all Ipos is returned"""
+ if name:
+ ipo = _Ipo.get(name)
+ if ipo:
+ return IpoBlock(ipo)
+ else:
+ return None
+ else:
+ return shadow._List(_Ipo.get(), IpoBlock)
+
+Get = get # emulation
diff --git a/intern/python/modules/Blender/Lamp.py b/intern/python/modules/Blender/Lamp.py
new file mode 100644
index 00000000000..ab7ed63592a
--- /dev/null
+++ b/intern/python/modules/Blender/Lamp.py
@@ -0,0 +1,168 @@
+"""The Blender Lamp module
+
+This module provides control over **Lamp** objects in Blender.
+
+Example::
+
+ from Blender import Lamp
+ l = Lamp.New('Spot')
+ l.setMode('square', 'shadow')
+ ob = Object.New('Lamp')
+ ob.link(l)
+"""
+
+import _Blender.Lamp as _Lamp
+import shadow
+
+_validBufferSizes = [512, 768, 1024, 1536, 2560]
+
+def _setBufferSize(self, bufsize):
+ """Set the lamp's buffersize. This function makes sure that a valid
+bufferSize value is set (unlike setting lamp.bufferSize directly)"""
+ if bufsize not in _validBufferSizes:
+ print """Buffer size should be one of:
+%s
+Setting to default 512""" % _validBufferSizes
+ bufsize = 512
+ self._object.bufferSize = bufsize
+
+class Lamp(shadow.hasIPO, shadow.hasModes):
+ """Wrapper for Blender Lamp DataBlock
+
+ Attributes
+
+ mode -- Lamp mode value - see EditButtons. Do not access directly
+ See setMode()
+
+ type -- Lamp type value - see EditButtons. No direct access, please.
+ See setType()
+
+ col -- RGB vector (R, G, B) of lamp colour
+
+ energy -- Intensity (float)
+
+ dist -- clipping distance of a spot lamp or decay range
+
+ spotSize -- float angle (in degrees) of spot cone
+ (between 0.0 and 180.0)
+
+ spotBlend -- value defining the blurriness of the spot edge
+
+ haloInt -- Halo intensity
+
+ clipStart -- shadow buffer clipping start
+
+ clipStart -- shadow buffer clipping end
+
+ bias -- The bias value for the shadowbuffer routine
+
+ softness -- The filter value for the shadow blurring
+
+ samples -- Number of samples in shadow calculation - the
+ larger, the better
+
+ bufferSize -- Size of the shadow buffer which should be one of:
+ [512, 768, 1024, 1536, 2560]
+
+ haloStep -- Number of steps in halo calculation - the smaller, the
+ the better (and slower). A value of 0 disables shadow
+ halo calculation
+ """
+
+ _emulation = {'Energ' : "energy",
+ 'SpoSi' : "spotSize",
+ 'SpoBl' : "SpotBlend",
+ 'HaInt' : "haloInt",
+ 'Dist' : "dist",
+ 'Quad1' : "quad1",
+ 'Quad2' : "quad2",
+ }
+
+ _setters = {'bufferSize' : _setBufferSize}
+
+ t = _Lamp.Types
+
+ Types = {'Lamp' : t.LOCAL,
+ 'Spot' : t.SPOT,
+ 'Sun' : t.SUN,
+ 'Hemi' : t.HEMI,
+ }
+
+ t = _Lamp.Modes
+
+ Modes = {'quad' : t.QUAD,
+ 'sphere' : t.SPHERE,
+ 'shadow' : t.SHAD,
+ 'halo' : t.HALO,
+ 'layer' : t.LAYER,
+ 'negative' : t.NEG,
+ 'onlyShadow' : t.ONLYSHADOW,
+ 'square' : t.SQUARE,
+ }
+
+ del t
+
+ def __repr__(self):
+ return "[Lamp \"%s\"]" % self.name
+
+ def setType(self, name):
+ """Set the Lamp type of Lamp 'self'. 'name' must be a string of:
+
+* 'Lamp': A standard point light source
+
+* 'Spot': A spot light
+
+* 'Sun' : A unidirectional light source, very far away (like a Sun!)
+
+* 'Hemi': A diffuse hemispherical light source (daylight without sun)"""
+
+ try:
+ self._object.type = self.Types[name]
+ except:
+ raise TypeError, "type must be one of %s" % self.Types.keys()
+
+ def getType(self):
+ """Returns the lamp's type as string. See setType()"""
+ for k in self.Types.keys():
+ if self.Types[k] == self.type:
+ return k
+
+ def getMode(self):
+ """Returns the Lamp modes as a list of strings"""
+ return shadow._getModeBits(self.Modes, self._object.mode)
+
+ def setMode(self, *args):
+ """Set the Lamp mode of Lamp 'self'. This function takes a variable number
+of string arguments of the types listed in self.Modes.
+
+ Example::
+
+ l = Lamp.New()
+ l.setMode('quad', 'shadow')
+"""
+ print args
+ self._object.mode = shadow._setModeBits(self.Modes, args)
+
+ def getBufferSize(self):
+ return self.bufferSize
+
+def New(type = "Lamp", name = "Lamp"):
+ """Returns a new Lamp datablock of type 'type' and optional name 'name'
+"""
+ t = Lamp.Types[type]
+ rawlamp = _Lamp.New()
+ rawlamp.type = t
+ rawlamp.name = name
+ return Lamp(rawlamp)
+
+
+def get(name = None):
+ """If 'name' given, the Lamp 'name' is returned if existing, 'None' otherwise.
+If no name is given, a list of all Lamps is returned"""
+
+ if name:
+ return Lamp(_Lamp.get(name))
+ else:
+ return shadow._List(_Lamp.get(), Lamp)
+
+Types = _Lamp.Types
diff --git a/intern/python/modules/Blender/Material.py b/intern/python/modules/Blender/Material.py
new file mode 100644
index 00000000000..f24541f0f03
--- /dev/null
+++ b/intern/python/modules/Blender/Material.py
@@ -0,0 +1,251 @@
+"""The Blender Material module
+
+ This module provides access to *Material* datablocks
+
+ Example::
+
+ from Blender import Material, NMesh, Object, Scene
+ m = Material.New() # create free Material datablock
+ m.rgbCol = (1.0, 0.0, 0.3) # assign RGB values
+ mesh = NMesh.GetRaw() # get new mesh
+ mesh.addMaterial(m) # add material to mesh
+ object = Object.New('Mesh') # create new object
+ object.link(mesh) # link mesh data to object
+ Scene.getCurrent().link(ob) # link object to current scene
+"""
+
+import _Blender.Material as _Material
+import shadow
+#import Blender.Curve as Curve
+
+# These are getters and setters needed for emulation
+
+def _getRGB(obj):
+ return (obj.R, obj.G, obj.B)
+
+def _getSpec(obj):
+ return (obj.specR, obj.specG, obj.specB)
+
+def _getMir(obj):
+ return (obj.mirR, obj.mirG, obj.mirB)
+
+def _setRGB(obj, rgb):
+ obj.R, obj.G, obj.B = rgb
+
+def _setSpec(obj, rgb):
+ obj.specR, obj.specG, obj.specB = rgb
+
+def _setMir(obj, rgb):
+ obj.mirR, obj.mirG, obj.mirB = rgb
+
+
+
+class Material(shadow.hasIPO, shadow.hasModes):
+ """Material DataBlock object
+
+ See example in the Material module documentation on how to create
+ an instance of a Material object.
+
+ Attributes
+
+ The following attributes are colour vectors (r, g, b)
+
+ rgbCol -- The color vector (R, G, B).
+ The RGB values can be accessed individually as .R, .G and .B
+
+ specCol -- Specularity color vector (specR, specG, specG)
+
+ mirCol -- Mirror color vector (mirR, mirG, mirB)
+
+ The following are float values:
+
+ alpha -- The transparency
+
+ ref -- Reflectivity float value
+
+ emit -- Emit intensity value
+
+ amb -- Ambient intensity value
+
+ spec -- specularity value
+
+ specTransp -- Specular transpareny
+
+ haloSize -- Halo size
+
+ mode -- The material mode bit vector - see Material.ModeFlags
+
+ hard -- The hardness value
+
+"""
+
+ _emulation = {'Mode' : "mode",
+ 'Ref' : "ref",
+ 'HaSize' : "haloSize",
+ 'SpTra' : "specTransp",
+ 'Alpha' : "alpha",
+ 'Spec' : "spec",
+ 'Emit' : "emit",
+ 'Hard' : "hard",
+ 'Amb' : "amb",
+ }
+
+ _getters = {'rgbCol' : _getRGB,
+ 'specCol' : _getSpec,
+ 'mirCol' : _getMir,
+ }
+
+ _setters = {'rgbCol' : _setRGB,
+ 'specCol' : _setSpec,
+ 'mirCol' : _setMir,
+ }
+
+ t = _Material.Modes
+
+ Modes = {'traceable' : t.TRACEABLE,
+ 'shadow' : t.SHADOW,
+ 'shadeless' : t.SHADELESS,
+ 'wire' : t.WIRE,
+ 'vcolLight' : t.VCOL_LIGHT,
+ 'vcolPaint' : t.VCOL_PAINT,
+ 'zTransp' : t.ZTRANSP,
+ 'zInvert' : t.ZINVERT,
+ 'onlyShadow': t.ONLYSHADOW,
+ 'star' : t.STAR,
+ 'texFace' : t.TEXFACE,
+ 'noMist' : t.NOMIST,
+ }
+
+ t = _Material.HaloModes
+
+ HaloModes = { "rings" : t.RINGS,
+ "lines" : t.LINES,
+ "tex" : t.TEX,
+ "haloPuno": t.PUNO,
+ "shade" : t.SHADE,
+ "flare" : t.FLARE,
+ }
+
+
+ del t
+
+ def setMode(self, *args):
+ """Set the mode of 'self'. This function takes a variable number
+of string arguments of the types listed in self.Modes.
+
+ Example::
+
+ m = Material.New()
+ m.setMode('shadow', 'wire')
+"""
+ flags = 0
+ try:
+ for a in args:
+ flags |= self.Modes[a]
+ except:
+ raise TypeError, "mode must be one of" % self.Modes.keys()
+ self._object.mode = flags
+
+ def setHaloMode(self, *args):
+ """Sets the material to Halo mode.
+This function takes a variable number of string arguments of the types
+listed in self.HaloModes"""
+ flags = _Material.Modes.HALO
+
+ try:
+ for a in args:
+ flags |= self.HaloModes[a]
+ except:
+ raise TypeError, "mode must be one of" % self.HaloModes.keys()
+ self._object.mode = flags
+
+
+class ModeFlags:
+ """Readonly dictionary
+
+...containing Material mode bitvectors:
+
+|------------------------------------------|
+| Name | Description |
+|==========================================|
+| TRACEABLE | visible for shadow lamps |
+|------------------------------------------|
+| SHADOW | cast shadow |
+|------------------------------------------|
+| SHADELESS | do not shade |
+|------------------------------------------|
+| WIRE | draw in wireframe |
+|------------------------------------------|
+| VCOL_LIGHT | use vertex colors |
+| | with lighting |
+|------------------------------------------|
+| VCOL_PAINT | vertex colours |
+|------------------------------------------|
+| HALO | Halo material |
+|------------------------------------------|
+| ZTRANSP | Z transparency |
+|------------------------------------------|
+| ZINVERT | invert Z |
+|------------------------------------------|
+| ONLYSHADOW | only shadow, but |
+| | don't render |
+|------------------------------------------|
+| STAR | ? |
+|------------------------------------------|
+| TEXFACE | textured faces |
+|------------------------------------------|
+| NOMIST | disable mist |
+|------------------------------------------|
+
+These mode flags directly represent the buttons in the Material parameters
+window (EditButtons)
+
+Example::
+
+ # be 'm' a material
+ from Blender.Material.Modes import *
+ m.mode |= (TRACEABLE + WIRE) # Set 'wire' and 'traceable' flagsd
+ m.mode &= ~SHADELESS # clear 'shadeless' flag
+"""
+
+ t = _Material.Modes
+ TRACEABLE = t.TRACEABLE
+ SHADOW = t.SHADOW
+ SHADELESS = t.SHADELESS
+ WIRE = t.WIRE
+ VCOL_LIGHT = t.VCOL_LIGHT
+ VCOL_PAINT = t.VCOL_PAINT
+ HALO = t.HALO
+ ZTRANSP = t.ZTRANSP
+ ZINVERT = t.ZINVERT
+ ONLYSHADOW = t.ONLYSHADOW
+ STAR = t.STAR
+ TEXFACE = t.TEXFACE
+ NOMIST = t.NOMIST
+ del t
+
+# override:
+ModeFlags = _Material.Modes
+
+def get(name = None):
+ """If 'name' given, the Material 'name' is returned if existing, 'None' otherwise.
+If no name is given, a list of all Materials is returned"""
+ if name:
+ return Material(_Material.get(name))
+ else:
+ return shadow._List(_Material.get(), Material)
+
+Get = get # emulation
+
+def New(name = None):
+ """Creates a new, empty Material and returns it.
+
+Example::
+
+ from Blender import Material
+ mat = Material.New()
+"""
+ mat = Material(_Material.New())
+ if name:
+ mat.name = name
+ return mat
diff --git a/intern/python/modules/Blender/Mesh.py b/intern/python/modules/Blender/Mesh.py
new file mode 100644
index 00000000000..dd8103919f8
--- /dev/null
+++ b/intern/python/modules/Blender/Mesh.py
@@ -0,0 +1,250 @@
+"""The Blender Mesh module
+
+ This module provides routines for more extensive mesh manipulation.
+ Later, this Mesh type will also allow interactive access (like in
+ EditMode).
+ In the Publisher, Ngons will also be supported (and converted to
+ triangles on mesh.update(). The following code demonstrates
+ creation of an Ngon.
+
+ Example::
+
+ from Blender import Mesh, Object, Scene
+
+ m = Mesh.New() # new empty mesh
+ vlist = []
+ vlist.append(m.addVert((-0.0, -1.0, 0.0)))
+ vlist.append(m.addVert((1.0, 0.0, 0.0)))
+ vlist.append(m.addVert((1.0, 1.0, 0.0)))
+ vlist.append(m.addVert((0.0, 3.0, 0.0)))
+ vlist.append(m.addVert((-1.0, 2.0, 0.0)))
+ vlist.append(m.addVert((-3.0, 1.0, 0.0)))
+ vlist.append(m.addVert((-3.0, 3.0, 0.0)))
+ vlist.append(m.addVert((-4.0, 3.0, 0.0)))
+ vlist.append(m.addVert((-4.0, 0.0, 0.0)))
+
+ f = m.addFace(vlist)
+
+ # do some calculations: top project vertex coordinates to
+ # UV coordinates and normalize them to the square [0.0, 1.0]*[0.0, 1.0]
+
+ uvlist = map(lambda x: (x.co[0], x.co[1]), vlist)
+ maxx = max(map(lambda x: x[0], uvlist))
+ maxy = max(map(lambda x: x[1], uvlist))
+ minx = min(map(lambda x: x[0], uvlist))
+ miny = min(map(lambda x: x[1], uvlist))
+
+ len = max((maxx - minx), (maxy - miny))
+ offx = -minx / len
+ offy = -miny / len
+
+ f.uv = map(lambda x: (x[0]/len + offx, x[1]/len + offy), uvlist) # assign UV coordinates by 'top' projection
+
+ m.update() # update and triangulate mesh
+
+ ob = Object.New('Mesh') # create new Object
+ ob.link(m) # link mesh data
+ sc = Scene.getCurrent() # get current Scene
+ sc.link(ob) # link Object to scene
+"""
+
+from Blender.Types import NMFaceType
+import Blender.Material as Material
+
+from _Blender import NMesh as _NMesh
+
+FACEFLAGS = _NMesh.Const
+DEFAULTFLAGS = FACEFLAGS.LIGHT + FACEFLAGS.DYNAMIC
+
+import shadow
+
+def makeFace(f):
+ face = _NMesh.Face()
+ for v in f:
+ face.v.append(v)
+ face.uv.append((v.uvco[0], v.uvco[1]))
+ return face
+
+def toTriangles(ngon):
+ from utils import tesselation
+ # This should be a Publisher only feature...once the tesselation
+ # is improved. The GLU tesselator of Mesa < 4.0 is crappy...
+ if len(ngon.uv) == len(ngon.v):
+ i = 0
+ for v in ngon.v:
+ v.uvco = ngon.uv[i]
+ i += 1
+
+ return tesselation.NgonAsTriangles(ngon, makeFace) # return triangles
+
+def Color(r, g, b, a = 1.0):
+ return _NMesh.Col(255 * r, 255 * g, 255 * b, 255 * a)
+
+class Vert: #shadow NMVert class for the tesselator
+ """Vertex wrapper class
+This class emulates a float coordinate vector triple
+"""
+ def __init__(self):
+ self.vert = None
+ self.uv = []
+ def __len__(self):
+ return 3
+ def __setitem__(self, i, val):
+ self.vert[i] = val
+ def __getitem__(self, i):
+ return self.vert.co[i]
+
+class Face:
+ """Face wrapper class
+This class emulates a list of vertex references
+"""
+ def __init__(self, vlist):
+ self.v= vlist
+ self.uv = []
+
+ def __len__(self):
+ return len(self.v)
+
+ def __setitem__(self, i, val):
+ self.v[i] = val
+
+ def __getitem__(self, i):
+ return self.v[i]
+
+# override:
+
+Vert = _NMesh.Vert
+Face = _NMesh.Face
+
+class rawMesh:
+ """Wrapper for raw Mesh data"""
+ def __init__(self, object = None):
+ if object:
+ self._object = object
+ else:
+ self._object = _NMesh.GetRaw()
+
+ self.flags = DEFAULTFLAGS
+ self.smooth = 0
+ self.recalc_normals = 1
+ self.faces = self._object.faces[:]
+
+ def __getattr__(self, name):
+ if name == 'vertices':
+ return self._object.verts
+ elif name == 'has_col':
+ return self._object.hasVertexColours()
+ elif name == 'has_uv':
+ return self._object.hasFaceUV()
+ else:
+ return getattr(self._object, name)
+
+ def __repr__(self):
+ return "Mesh: %d faces, %d vertices" % (len(self.faces), len(self.verts))
+
+ def hasFaceUV(self, true = None):
+ """Sets the per-face UV texture flag, if 'true' specified (either
+ 0 or 1). Returns the texture flag in any case."""
+ if true == None:
+ return self._object.hasFaceUV()
+ return self._object.hasFaceUV(true)
+
+ def hasVertexUV(self, true = None):
+ """Sets the per-vertex UV texture flag, if 'true' specified (either
+ 0 or 1). Returns the texture flag in any case."""
+ if true == None:
+ return self._object.hasVertexUV()
+ return self._object.hasVertexUV(true)
+
+ def hasVertexColours(self, true = None):
+ """Sets the per-face UV texture flag, if 'true' specified (either
+ 0 or 1). Returns the texture flag in any case."""
+ if true == None:
+ return self._object.hasVertexColours()
+ return self._object.hasVertexColours(true)
+
+ def addVert(self, v):
+ """Adds a vertex to the mesh and returns a reference to it. 'v' can
+be a float triple or any data type emulating a sequence, containing the
+coordinates of the vertex. Note that the returned value references an
+*owned* vertex"""
+ vert = _NMesh.Vert(v[0], v[1], v[2])
+ self._object.verts.append(vert)
+ return vert
+
+ def addFace(self, vlist, flags = None, makedefaultUV = 0):
+ """Adds a face to the mesh and returns a reference to it. 'vlist'
+must be a list of vertex references returned by addVert().
+Note that the returned value references an *owned* face"""
+ if type(vlist) == NMFaceType:
+ face = vlist
+ else:
+ n = len(vlist)
+ face = _NMesh.Face(vlist)
+ if makedefaultUV:
+ face.uv = defaultUV[:n]
+
+ self.faces.append(face)
+ # turn on default flags:
+ if not flags:
+ face.mode = self.flags
+ else:
+ face.mode = flags
+ return face
+
+ def update(self):
+ """Updates the mesh datablock in Blender"""
+ o = self._object
+ o = self._object
+ o.faces = []
+ smooth = self.smooth
+ for f in self.faces:
+ if len(f) > 4: #it's a NGON
+ faces = toTriangles(f)
+ for nf in faces:
+ nf.smooth = smooth
+ o.faces.append(nf)
+ else:
+ o.faces.append(f)
+ o.update()
+
+ def link(self, material):
+ """Link material 'material' with the mesh. Note that a mesh can
+currently have up to 16 materials, which are referenced by
+Face().materialIndex"""
+ mats = self._object.materials
+ if material in mats:
+ print "material already assigned to mesh"
+ return
+ mats.append(material._object)
+
+ def unlink(self, material):
+ """Unlink (remove) material 'material' from the mesh. Note
+that the material indices per face need to be updated."""
+ self._object.materials.remove(material._object)
+
+ def setMaterials(self, materials = []):
+ """Sets materials. 'materials' must be a list of valid material objects
+Note that a mesh can currently have up to 16 materials, which are referenced
+by Face().materialIndex"""
+
+ self._object.materials = (map(lambda x: x._object, materials))
+
+ def getMaterials(self, materials = []):
+ """Returns materials assigned to the mesh"""
+ return shadow._List(self._object.materials, Material.Material)
+
+def New():
+ return rawMesh()
+
+def get(name = None):
+ """If 'name' given, the Mesh 'name' is returned if existing, 'None' otherwise."""
+ if name:
+ ob = _NMesh.GetRaw(name)
+ if ob:
+ return rawMesh(ob)
+ else:
+ return None
+ else:
+ raise SystemError, "get() for Meshes is not yet supported"
+
diff --git a/intern/python/modules/Blender/NMesh.py b/intern/python/modules/Blender/NMesh.py
new file mode 100644
index 00000000000..3e6c60bab21
--- /dev/null
+++ b/intern/python/modules/Blender/NMesh.py
@@ -0,0 +1,192 @@
+"""The Blender NMesh module
+
+ This module provides access to the raw **Mesh** data block.
+
+ Examples will not be given, as the life time of this module will be
+ most probably limited. Use the 'Mesh' module instead.
+"""
+
+import _Blender.NMesh as _NMesh
+import shadow
+
+class Mesh(shadow.shadow):
+ """The NMesh object
+
+ This contains a copy of the raw mesh object data.
+
+ Attributes
+
+ verts -- A list of vertices of type 'Vert'
+
+ faces -- List of faces of type 'Face'
+"""
+ def update(self):
+ """updates the mesh object in Blender with the modified mesh data"""
+ self._object.update()
+
+class Vert:
+ """Vertex object
+
+ Attributes
+
+ co -- The vertex coordinates (x, y, z)
+
+ no -- Vertex normal vector (nx, ny, nz)
+
+ uvco -- Vertex texture ("sticky") coordinates
+
+ index -- The vertex index, if owned by a mesh
+"""
+
+class Face:
+ """Face object
+
+ Attributes
+
+ mode -- Display mode, see NMesh.FaceModes
+
+ flag -- flag bit vector, specifying selection flags.
+ see NMesh.FaceFlags
+
+ transp -- transparency mode bit vector; see NMesh.FaceTranspModes
+
+ v -- List of Face vertices
+
+ col -- List of Vertex colours
+
+ materialIndex -- Material index (referring to one of the Materials in
+ the Meshes material list, see Mesh documentation
+
+ smooth -- Flag whether smooth normals should be calculated (1 = yes)
+
+ image -- Reference to texture image object
+
+ uv -- A list of per-face UV coordinates:
+ [(u0, v0), (u1, v1), (u2, v2), .. ]
+"""
+
+class Col:
+ """Colour object
+
+ See NMesh module documentation for an example.
+
+ Attributes
+
+ r, g, b, a -- The RGBA components of the colour
+ A component must lie in the range of [0, 255]
+"""
+
+
+class FaceModes:
+ """Face mode bit flags
+
+ BILLBOARD -- always orient after camera
+
+ DYNAMIC -- respond to collisions
+
+ INVISIBLE -- invisible face
+
+ HALO -- halo face, always point to camera
+
+ LIGHT -- dynamic lighting
+
+ OBCOL -- use object colour instead of vertex colours
+
+ SHADOW -- shadow type
+
+ SHAREDCOL -- shared vertex colors (per vertex)
+
+ TEX -- has texture image
+
+ TILES -- uses tiled image
+
+ TWOSIDE -- twosided face
+"""
+ t = _NMesh.Const
+ BILLBOARD = t.BILLBOARD
+ DYNAMIC = t.DYNAMIC
+ INVISIBLE = t.INVISIBLE
+ HALO = t.HALO
+ LIGHT = t.LIGHT
+ OBCOL = t.OBCOL
+ SHADOW = t.SHADOW
+ SHAREDCOL = t.SHAREDCOL
+ TEX = t.TEX
+ TILES = t.TILES
+ TWOSIDE = t.TWOSIDE
+ del t
+
+
+class FaceTranspModes:
+ """Readonly dictionary
+
+...containing Face transparency draw modes. They are of type 'enum', i.e.
+can not be combined like a bit vector.
+
+ SOLID -- draw solid
+
+ ADD -- add to background(halo)
+
+ ALPHA -- draw with transparency
+
+ SUB -- subtract from background
+"""
+ t = _NMesh.Const
+ SOLID = t.SOLID
+ ADD = t.ADD
+ ALPHA = t.ALPHA
+ SUB = t.SUB
+ del t
+
+class FaceFlags:
+ """Readonly dictionary
+
+...containing Face flags bitvectors:
+
+ SELECT -- selected
+
+ HIDE -- hidden
+
+ ACTIVE -- the active face
+"""
+ t = _NMesh.Const
+ SELECT = t.SELECT
+ HIDE = t.HIDE
+ ACTIVE = t.ACTIVE
+ del t
+
+
+def New(name = None):
+ """Creates a new NMesh mesh object and returns it"""
+ pass
+
+def GetRaw(name = None):
+ """If 'name' specified, the Mesh object with 'name' is returned, 'None'
+if not existant. Otherwise, a new empty Mesh is initialized and returned."""
+ pass
+
+def PutRaw(mesh, name = "Mesh"):
+ """Creates a Mesh Object instance in Blender, i.e. a Mesh Object in the
+current Scene and returns a reference to it. If 'name' specified, the Mesh
+'name' is overwritten. In this case, no Object reference is returned."""
+ pass
+
+def GetRawFromObject(name):
+ """This returns the mesh as used by the object, which
+means it contains all deformations and modifications."""
+ pass
+
+# override all these functions again, because we only used them for
+# documentation -- NMesh will be no longer supported in future
+
+New = _NMesh.New
+GetRaw = _NMesh.GetRaw
+PutRaw = _NMesh.PutRaw
+GetRawFromObject = _NMesh.GetRawFromObject
+Const = _NMesh.Const
+Vert = _NMesh.Vert
+Face = _NMesh.Face
+Col = _NMesh.Col
+
+def NMesh(data):
+ return data
diff --git a/intern/python/modules/Blender/Object.py b/intern/python/modules/Blender/Object.py
new file mode 100644
index 00000000000..7fefedf4725
--- /dev/null
+++ b/intern/python/modules/Blender/Object.py
@@ -0,0 +1,391 @@
+##
+## Blender API mid level layer 01/2002 // strubi@blender.nl
+##
+## $Id$
+##
+
+"""The Blender Object module
+
+ This module provides **Object** manipulation routines.
+
+ Example::
+
+ from Blender import Object
+ ob = Object.get('Plane')
+ actobj = Object.getSelected()[0] # get active Object
+ print actobj.loc # print position
+ ob.makeParent([actobj]) # make ob the parent of actobj
+"""
+
+import _Blender.Object as _Object
+
+import shadow
+reload(shadow) # XXX
+
+class _C:
+ pass
+
+InstanceType = type(_C())
+del _C # don't export this
+
+
+def _Empty_nodata(obj):
+ return None
+
+class Object(shadow.hasIPO):
+ """Blender Object
+
+ A Blender Object (note the capital O) is the instance of a 3D structure,
+ or rather, the Object that is (normally) visible in your Blender Scene.
+
+ An instance of a Blender Object object is created by::
+
+ from Blender import Object
+ ob = Object.New(type) # type must be a valid type string,
+ # see Object.Types
+
+ ...
+
+ Attributes
+
+ Note that it is in general not recommended to access the Object's
+ attributes directly. Please rather use the get-/set- functions instead.
+
+ loc -- position vector (LocX, LocY, LocZ)
+
+ dloc -- delta position vector (dLocX, dLocY, dLocZ)
+
+ rot -- euler rotation vector (RotX, RotY, RotZ).
+ Warning: this may change in future.
+
+ drot -- delta rotation euler vector (dRotX, dRotY, dRotZ)
+ Warning: this may change in future.
+
+ size -- scale vector (SizeX, SizeY, SizeZ)
+
+ dsize -- delta scale vector (dSizeX, dSizeY, dSizeZ)
+
+ layer -- layer bitvector (20 bit), defining what layers the object is
+ visible in
+
+
+ The following items are listed here only for compatibility to older
+ scripts and are READ-ONLY! **USE the get- functions instead!**
+
+ data -- reference to the data object (e.g. Mesh, Camera, Lamp, etc.)
+
+ parent -- reference to the parent object, if existing, 'None' otherwise.
+
+ track -- reference to the tracked object, if existing, 'None' otherwise.
+
+ This bit mask can be read and written:
+
+ colbits -- the Material usage mask. A set bit #n means:
+ The Material #n in the *Object's* material list is used.
+ Otherwise, the Material #n of the Objects *Data* material list
+ is displayed.
+"""
+
+ def __init__(self, object = None):
+ """Returns an empty shadow Object"""
+ self._object = object
+
+ def __repr__(self):
+ return "[Object \"%s\"]" % self.name
+
+ def link(self, data):
+ """Links Object 'self' with data 'data'. The data type must match
+the Object's type, so you cannot link a Lamp to a mesh type Object.
+'data' can also be an Ipo object (IpoBlock)
+"""
+ from _Blender import Types
+ # special case for NMesh:
+ if type(data) == Types.NMeshType:
+ return self._object.link(data)
+ elif type(data) == InstanceType:
+ if data.__class__.__name__ == "rawMesh":
+ data.update() # update mesh
+ elif data.__class__.__name__ == "IpoBlock":
+ self.setIpo(data)
+
+ return shadow._link(self, data)
+
+ def copy(self):
+ """Returns a copy of 'self'.
+This is a true, linked copy, i.e. the copy shares the same data as the
+original. The returned object is *free*, meaning, not linked to any scene."""
+ return Object(self._object.copy())
+
+ #def clone(self):
+ #"""Makes a clone of the specified object in the current scene and
+##returns its reference"""
+ #return Object(self._object.clone())
+
+ def shareFrom(self, object):
+ """Link data of 'self' with data of 'object'. This works only if
+'object' has the same type as 'self'."""
+ return Object(self._object.shareFrom(object._object))
+
+ def getMatrix(self):
+ """Returns the object matrix"""
+ return self._object.getMatrix()
+
+ def getInverseMatrix(self):
+ """Returns the object's inverse matrix"""
+ return self._object.getInverseMatrix()
+
+ def getData(self):
+ "Returns the Datablock object containing the object's data, e.g. Mesh"
+ t = self._object.getType()
+ data = self._object.data
+ try:
+ return self._dataWrappers[t][1](data)
+ except:
+ raise TypeError, "getData() not yet supported for this object type"
+
+ def getDeformData(self):
+ """Returns the Datablock object containing the object's deformed data.
+Currently, this is only supported for a Mesh"""
+ import _Blender.NMesh as _NMesh
+ t = self._object.getType()
+ if t == self.Types['Mesh']:
+ data = _NMesh.GetRawFromObject(self.name)
+ return self._dataWrappers[t][1](data)
+ else:
+ raise TypeError, "getDeformData() not yet supported for this object type"
+
+ def getType(self):
+ "Returns type string of Object, which is one of Object.Types.keys()"
+ t = self._object.getType()
+ try:
+ return self._dataWrappers[t][0]
+ except:
+ return "<unsupported>"
+
+ def getParent(self):
+ "Returns object's parent object"
+ if self._object.parent:
+ return Object(self._object.parent)
+ return None
+
+ def getTracked(self):
+ "Returns object's tracked object"
+ if self._object.track:
+ return Object(self._object.track)
+ return None
+
+# FUTURE FEATURE :-) :
+# def getLocation():
+# """Returns the object's location (x, y, z).
+#By default, the location vector is always relative to the object's parent.
+#If the location of another coordinate system is wanted, specify 'origin' by
+#the object whose coordinate system the location should be calculated in.
+
+#If world coordinates are wanted, set 'relative' = "World"."""
+
+ def getLocation(self, relative = None):
+ """Returns the object's location (x, y, z). For the moment,
+'relative' has no effect."""
+ l = self._object.loc
+ return (l[0], l[1], l[2])
+
+ def setLocation(self, location, relative = None):
+ """Sets the object's location. 'location' must be a vector triple.
+See 'getLocation()' about relative coordinate systems."""
+ l = self._object.loc # make sure this is copied
+ l[0], l[1], l[2] = location
+
+ def getDeltaLocation(self):
+ """Returns the object's delta location (x, y, z)"""
+ l = self._object.dloc
+ return (l[0], l[1], l[2])
+
+ def setDeltaLocation(self, delta_location):
+ """Sets the object's delta location which must be a vector triple"""
+ l = self._object.dloc # make sure this is copied
+ l[0], l[1], l[2] = delta_location
+
+ def getEuler(self):
+ """Returns the object's rotation as Euler rotation vector
+(rotX, rotY, rotZ)"""
+ e = self._object.rot
+ return (e[0], e[1], e[2])
+
+ def setEuler(self, euler = (0.0, 0.0, 0.0)):
+ """Sets the object's rotation according to the specified Euler angles.
+'euler' must be a vector triple"""
+ e = self._object.rot
+ e[0], e[1], e[2] = euler
+
+ def makeParent(self, objlist, mode = 0, fast = 0):
+ """Makes 'self' the parent of the objects in 'objlist' which must be
+a list of valid Objects.
+If specified:
+
+ mode -- 0: make parent with inverse
+
+ 1: without inverse
+
+ fast -- 0: update scene hierarchy automatically
+
+ 1: don't update scene hierarchy (faster). In this case, you
+ must explicitely update the Scene hierarchy, see:
+ 'Blender.Scene.getCurrent().update()'"""
+ list = map(lambda x: x._object, objlist)
+ return Object(self._object.makeParent(list, mode, fast))
+
+ def clrParent(self, mode = 0, fast = 0):
+ """Clears parent object.
+If specified:
+
+ mode -- 2: keep object transform
+
+ fast > 0 -- don't update scene hierarchy (faster)"""
+ return Object(self._object.clrParent(mode, fast))
+
+ def getMaterials(self):
+ """Returns list of materials assigned to the object"""
+ from Blender import Material
+ return shadow._List(self._object.getMaterials(), Material.Material)
+
+ def setMaterials(self, materials = []):
+ """Sets materials. 'materials' must be a list of valid material objects"""
+ o = self._object
+ old_mask = o.colbits
+ o.colbits = -1 # set material->object linking
+ o.setMaterials(map(lambda x: x._object, materials))
+ o.colbits = old_mask
+
+ def materialUsage(self, flag):
+ """Determines the way the material is used and returns status.
+
+'flag' = 'Data' : Materials assigned to the object's data are shown. (default)
+
+'flag' = 'Object' : Materials assigned to the object are shown.
+
+The second case is desired when the object's data wants to be shared among
+objects, but not the Materials assigned to their data. See also 'colbits'
+attribute for more (and no future compatible) control."""
+ if flag == "Object":
+ self._object.colbits = -1
+ elif flag == "Data":
+ self._object.colbits = 0
+ return self._object.colbits
+ else:
+ raise TypeError, "unknown mode %s" % flag
+
+ _getters = {}
+
+ from Blender import Mesh, Camera, Lamp
+
+ t = _Object.Types
+ Types = {"Camera" : t.CAMERA,
+ "Empty" : t.EMPTY,
+ "Lamp" : t.LAMP,
+ "Mesh" : t.MESH,
+ }
+
+ # create lookup table for data wrappers
+ _dataWrappers = range(max(Types.values()) + 1)
+ _dataWrappers[t.MESH] = ("Mesh", Mesh.rawMesh)
+ _dataWrappers[t.CAMERA] = ("Camera", Camera.Camera)
+ _dataWrappers[t.LAMP] = ("Lamp", Lamp.Lamp)
+ _dataWrappers[t.EMPTY] = ("Empty", _Empty_nodata)
+
+ t = _Object.DrawTypes
+ DrawTypes = {"Bounds" : t.BOUNDBOX,
+ "Wire" : t.WIRE,
+ "Solid" : t.SOLID,
+ "Shaded" : t.SHADED,
+ }
+
+ t = _Object.DrawModes
+ DrawModes = {"axis" : t.AXIS,
+ "boundbox" : t.BOUNDBOX,
+ "texspace" : t.TEXSPACE,
+ "name" : t.NAME,
+ }
+
+
+ del t
+ del Mesh, Camera, Lamp
+
+ def getDrawMode(self):
+ """Returns the Object draw modes as a list of strings"""
+ return shadow._getModeBits(self.DrawModes, self._object.drawMode)
+
+ def setDrawMode(self, *args):
+ """Sets the Object's drawing modes as a list of strings"""
+ self._object.drawMode = shadow._setModeBits(self.DrawModes, args)
+
+ def getDrawType(self):
+ """Returns the Object draw type"""
+ for k in self.DrawTypes.keys():
+ if self.DrawTypes[k] == self.drawType:
+ return k
+
+ def setDrawType(self, name):
+ """Sets the Object draw type. 'name' must be one of:
+
+* 'Bounds' : Draw bounding box only
+
+* 'Wire' : Draw in wireframe mode
+
+* 'Solid' : Draw solid
+
+* 'Shaded' : Draw solid, shaded and textures
+"""
+ try:
+ self._object.drawType = self.DrawTypes[name]
+ except:
+ raise TypeError, "type must be one of %s" % self.DrawTypes.keys()
+
+
+##################
+# MODULE FUNCTIONS
+
+def New(objtype, name = None):
+ """Creates a new, empty object and returns it.
+'objtype' is a string and must be one of::
+
+ Camera
+ Empty
+ Mesh
+ Lamp
+
+More object types will be supported in future.
+
+Example::
+
+ ob = Object.New('Camera')
+"""
+
+ if type(objtype) == type(0):
+ obj = Object(_Object.New(objtype)) # emulate old syntax
+ else:
+ t = Object.Types[objtype]
+ obj = Object(_Object.New(t))
+ return obj
+
+def get(name = None):
+ """If 'name' given, the Object 'name' is returned if existing, 'None' otherwise.
+If no name is given, a list of all Objects is returned"""
+ if name:
+ ob = _Object.get(name)
+ if ob:
+ return Object(ob)
+ else:
+ return None
+ else:
+ return shadow._List(_Object.get(), Object)
+
+Get = get # emulation
+
+def getSelected():
+ """Returns a list of selected Objects in the active layer(s).
+The active object is the first in the list, if visible"""
+ return shadow._List(_Object.getSelected(), Object)
+
+GetSelected = getSelected # emulation
+
+Types = _Object.Types # for compatibility
diff --git a/intern/python/modules/Blender/Scene.py b/intern/python/modules/Blender/Scene.py
new file mode 100644
index 00000000000..a6deaeb5a46
--- /dev/null
+++ b/intern/python/modules/Blender/Scene.py
@@ -0,0 +1,143 @@
+"""The Blender Scene module
+
+ This module provides *Scene* manipulation routines.
+
+ Example::
+
+ from Blender import Scene
+
+ curscene = Scene.getCurrent()
+ ob = curscene.getChildren()[0] # first object
+ newscene = Scene.New('testscene')
+ cam = curscene.getCurrentCamera() # get current camera object
+ newscene.link(ob) # link 'ob' to Scene
+ newscene.link(cam)
+ newscene.makeCurrent() # make current Scene
+"""
+import _Blender.Scene as _Scene
+
+from Object import Object
+import shadow
+
+class Scene(shadow.shadowEx):
+ """Wrapper for Scene DataBlock
+"""
+ def link(self, object):
+ """Links Object 'object' into Scene 'self'."""
+ # This is a strange workaround; Python does not release
+ # 'self' (and thus self._object) when an exception in the C API occurs.
+ # Therefore, we catch that exception and do it ourselves..
+ # Maybe Python 2.2 is able to resolve this reference dependency ?
+ try:
+ return self._object.link(object._object)
+ except:
+ del self._object
+ raise
+
+ def unlink(self, object):
+ """Unlinks (deletes) Object 'object' from Scene."""
+ ret = self._object.unlink(object._object)
+ return ret
+
+ def copy(self, duplicate_objects = 1):
+ """Returns a copy of itself.
+
+The optional argument defines, how the Scene's children objects are
+duplicated::
+
+ 0: Link Objects
+ 1: Link Object data
+ 2: Full Copy"""
+ return Scene(self._object.copy(duplicate_objects))
+
+ def update(self):
+ """Updates scene 'self'.
+ This function explicitely resorts the base list of a newly created object
+ hierarchy."""
+ return self._object.update()
+
+ def makeCurrent(self):
+ """Makes 'self' the current Scene"""
+ return self._object.makeCurrent()
+
+ def frameSettings(self, start = None, end = None, current = None):
+ """Sets or retrieves the Scene's frame settings.
+If the frame arguments are specified, they are set.
+A tuple (start, end, current) is returned in any case."""
+ if start and end and current:
+ return self._object.frameSettings(start, end, current)
+ else:
+ return self._object.frameSettings()
+
+ def currentFrame(self, frame = None):
+ """If 'frame' is given, the current frame is set and returned in any case"""
+ if frame:
+ return self._object.frameSettings(-1, -1, frame)
+ return self._object.frameSettings()[2]
+
+ def startFrame(self, frame = None):
+ """If 'frame' is given, the start frame is set and returned in any case"""
+ if frame:
+ return self._object.frameSettings(frame, -1, -1)
+ return self._object.frameSettings()[0]
+
+ def endFrame(self, frame = None):
+ """If 'frame' is given, the end frame is set and returned in any case"""
+ if frame:
+ return self._object.frameSettings(-1, frame, -1)
+ return self._object.frameSettings()[1]
+
+ def getChildren(self):
+ """Returns a list of the Scene's children Objects"""
+ return shadow._List(self._object.getChildren(), Object)
+
+ def getCurrentCamera(self):
+ """Returns current active camera Object"""
+ cam = self._object.getCurrentCamera()
+ if cam:
+ return Object(cam)
+
+ def setCurrentCamera(self, object):
+ """Sets the current active camera Object 'object'"""
+ return self._object.setCurrentCamera(object._object)
+
+ def getRenderdir(self):
+ """Returns directory where rendered images are saved to"""
+ return self._object.getRenderdir(self._object)
+
+ def getBackbufdir(self):
+ """Returns the Backbuffer images location"""
+ return self._object.getBackbufdir(self._object)
+
+# Module methods
+
+def New(name = 'Scene'):
+ """Creates and returns new Scene with (optionally given) name"""
+ return Scene(_Scene.New(name))
+
+def get(name = None):
+ """Returns a Scene object with name 'name' if given, None if not existing,
+or a list of all Scenes otherwise."""
+ if name:
+ ob = _Scene.get(name)
+ if ob:
+ return Scene(ob)
+ else:
+ return None
+ else:
+ return shadow._List(_Scene.get(), Scene)
+
+Get = get # emulation
+
+def getCurrent():
+ """Returns the currently active Scene"""
+ sc = Scene(_Scene.getCurrent())
+ return sc
+
+def unlink(scene):
+ """Removes the Scene 'scene' from Blender"""
+ if scene._object.name == _Scene.getCurrent().name:
+ raise SystemError, "current Scene can not be removed!"
+ for ob in scene.getChildren():
+ scene.unlink(ob)
+ return _Scene.unlink(scene._object)
diff --git a/intern/python/modules/Blender/Text.py b/intern/python/modules/Blender/Text.py
new file mode 100644
index 00000000000..0d5f615f190
--- /dev/null
+++ b/intern/python/modules/Blender/Text.py
@@ -0,0 +1,57 @@
+"""The Blender Text module
+
+ This module lets you manipulate the Text buffers inside Blender.
+ Text objects are currently owned by the Text editor in Blender.
+
+ Example::
+
+ from Blender import Text
+ text = Text.New('Text') # create new text buffer
+ text.write('hello') # write string
+ Text.unlink(text) # delete
+"""
+
+import _Blender.Text as _Text
+
+class Text:
+ """Wrapper for Text DataBlock"""
+
+ def clear(self):
+ """Clears the Text objects text buffer"""
+ pass
+
+ def write(self, string):
+ """Appends 'string' to the text buffer"""
+ pass
+
+ def asLines(self):
+ """Returns the text buffer as a list of lines (strings)"""
+ pass
+
+ def set(self, attr, val):
+ """Set the Text attribute of name 'name' to value 'val'.
+
+Currently supported::
+
+ follow_cursor : 1: Text output follows the cursor"""
+
+# Module methods
+
+def New(name = None):
+ """Creates new empty Text with (optionally given) name and returns it"""
+ pass
+
+def get(name = None):
+ """Returns a Text object with name 'name' if given, 'None' if not existing,
+or a list of all Text objects in Blender otherwise."""
+ pass
+
+def unlink(text):
+ """Removes the Text 'text' from the Blender text window"""
+ pass
+
+
+# override:
+New = _Text.New
+get = _Text.get
+unlink = _Text.unlink
diff --git a/intern/python/modules/Blender/Types.py b/intern/python/modules/Blender/Types.py
new file mode 100644
index 00000000000..d49d9c35407
--- /dev/null
+++ b/intern/python/modules/Blender/Types.py
@@ -0,0 +1 @@
+from _Blender.Types import *
diff --git a/intern/python/modules/Blender/Window.py b/intern/python/modules/Blender/Window.py
new file mode 100644
index 00000000000..e51ab894dfa
--- /dev/null
+++ b/intern/python/modules/Blender/Window.py
@@ -0,0 +1,65 @@
+"""The Blender Window module
+
+This module currently only supports redrawing commands of windows.
+Later on, it will allow screen manipulations and access to Window
+properties"""
+
+import _Blender.Window as _Window
+
+t = _Window.Types
+Const = t # emulation
+
+Types = { 'View' : t.VIEW3D,
+ 'Ipo' : t.IPO,
+ 'Oops' : t.OOPS,
+ 'Button' : t.BUTS,
+ 'File' : t.FILE,
+ 'Image' : t.IMAGE,
+ 'Text' : t.TEXT,
+ 'Action' : t.ACTION,
+ }
+
+del t
+
+def Redraw(t= 'View'):
+ """Redraws all windows of the type 't' which must be one of:
+
+* "View" - The 3D view
+
+* "Ipo" - The Ipo Window
+
+* "Oops" - The OOPS (scenegraph) window
+
+* "Button" - The Button Window
+
+* "File" - The File Window
+
+* "Image" - The Image Window (UV editor)
+
+* "Text" - The Text editor
+
+* "Action" - The Action Window"""
+
+ if type(t) == type(1):
+ return _Window.Redraw(t)
+ try:
+ _Window.Redraw(Types[t])
+ except:
+ raise TypeError, "type must be one of %s" % Types.keys()
+
+def RedrawAll():
+ """Redraws the whole screen"""
+ _Window.RedrawAll()
+
+def drawProgressBar(val, text):
+ """Draws a progress bar behind the Blender version information.
+'val' is a float value <= 1.0, 'text' contains info about what is currently
+being done.
+This function must be called with 'val' = 0.0 at start and end of the executed
+(and probably time consuming) action.
+The user may cancel the progress with the 'Esc' key, in this case, 0 is returned,
+1 else."""
+ return _Window.draw_progressbar(val, text)
+
+draw_progressbar = _Window.draw_progressbar # emulation
+QRedrawAll = _Window.QRedrawAll
diff --git a/intern/python/modules/Blender/World.py b/intern/python/modules/Blender/World.py
new file mode 100644
index 00000000000..e0c42d33f16
--- /dev/null
+++ b/intern/python/modules/Blender/World.py
@@ -0,0 +1,157 @@
+import _Blender.World as _World
+
+import shadow
+
+def _getAmbCol(obj):
+ return obj.ambR, obj.ambG, obj.ambB
+
+def _setAmbCol(obj, rgb):
+ obj.ambR, obj.ambG, obj.ambB = rgb
+
+def _getZenCol(obj):
+ return obj.zenR, obj.zenG, obj.zenB
+
+def _setZenCol(obj, rgb):
+ obj.zenR, obj.zenG, obj.zenB = rgb
+
+def _getHorCol(obj):
+ return obj.horR, obj.horG, obj.horB
+
+def _setHorCol(obj, rgb):
+ obj.horR, obj.horG, obj.horB = rgb
+
+def _setMist(obj, mist):
+ obj.mistStart = mist.start
+ obj.mistDepth = mist.depth
+ obj.mistHeight = mist.height
+ obj.mistType = mist.type
+
+def _getMist(obj):
+ mist = Mist()
+ mist.start = obj.mistStart
+ mist.depth = obj.mistDepth
+ mist.height = obj.mistHeight
+ mist.type = obj.mistType
+ return mist
+
+class World(shadow.hasIPO, shadow.hasModes):
+ """Wrapper for Blender World DataBlock
+
+ Attributes
+
+ horCol -- horizon colour triple '(r, g, b)' where r, g, b must lie
+ in the range of [0.0, 1.0]
+
+ zenCol -- zenith colour triple
+
+ ambCol -- ambient colour triple
+
+ exposure -- exposure value
+
+ mist -- mist structure, see class Mist
+
+ starDensity -- star density (the higher, the more stars)
+
+ starMinDist -- the minimum distance to the camera
+
+ starSize -- size of the stars
+
+ starColNoise -- star colour noise
+
+ gravity -- The gravity constant (9.81 for earth gravity)
+"""
+
+ SkyTypes = {'blend' : 1,
+ 'real' : 2,
+ 'paper' : 4,
+ }
+
+ Modes = {'mist' : 1,
+ 'stars' : 2,
+ }
+
+ _emulation = {'Expos' : "exposure",
+ 'HorR' : "horR",
+ 'HorG' : "horG",
+ 'HorB' : "horB",
+ 'ZenR' : "zenR",
+ 'ZenG' : "zenG",
+ 'ZenB' : "zenB",
+ 'StarDi' : "starDensity",
+ 'StarSi' : "starSize",
+ 'MisSta' : "mistStart",
+ 'MisDi' : "mistDepth",
+ 'MisHi' : "mistHeight",
+ }
+
+ _setters = {'horCol' : _getHorCol,
+ 'zenCol' : _getZenCol,
+ 'ambCol' : _getAmbCol,
+ 'mist' : _getMist,
+ }
+
+ _setters = {'horCol' : _setHorCol,
+ 'zenCol' : _setZenCol,
+ 'ambCol' : _setAmbCol,
+ 'mist' : _setMist,
+ }
+
+ def getSkyType(self):
+ """Returns a list of the set Sky properties, see setSkyType()"""
+ list = []
+ for k in self.SkyTypes.keys():
+ i = self.SkyTypes[k]
+ if self._object.skyType & i:
+ list.append(k)
+ return list
+
+ def setSkyType(self, *args):
+ """Set the sky type. This function takes a variable number
+of string arguments of ['blend', 'real', 'paper']"""
+ flags = 0
+ try:
+ for a in args:
+ flags |= self.SkyTypes[a]
+ except:
+ raise TypeError, "mode must be one of" % self.SkyTypes.keys()
+ self._object.skyType = flags
+
+
+class Mist:
+ """Mist structure
+
+ Attributes
+
+ start -- start of the mist
+
+ depth -- depth of the "mist wall"
+
+ height -- height of the mist layer
+"""
+
+ Types = { 'quadratic' : 0,
+ 'linear' : 1,
+ 'sqrt' : 2,
+ }
+
+ def __init__(self):
+ self.start = 0.0
+ self.depth = 0.0
+ self.height = 0.0
+ self.type = 0
+
+ def setType(self, name):
+ """Set the Mist type (one of ['quadratic', 'linear', 'sqrt'])"""
+ try:
+ t = self.Types[name]
+ else:
+ raise TypeError, "type must be one of %s" % self.Types.keys()
+ self.type = t
+
+ def getType(self):
+ """Returns the Mist type as string. See setType()"""
+ for k in self.Types.keys():
+ if self.Types[k] == self.type:
+ return k
+
+
diff --git a/intern/python/modules/Blender/__init__.py b/intern/python/modules/Blender/__init__.py
new file mode 100644
index 00000000000..7356d9ddf9f
--- /dev/null
+++ b/intern/python/modules/Blender/__init__.py
@@ -0,0 +1,23 @@
+#
+# The Blender main module wrapper
+# (c) 06/2001, NaN // strubi@blender.nl
+
+__all__ = ["Object", "Image", "NMesh", "Window", "Mesh", "Tools", "sys",
+ "Lamp", "Scene", "Draw", "Camera", "Material", "Types", "Ipo",
+ "BGL"]
+
+import _Blender
+
+Get = _Blender.Get
+Redraw = _Blender.Redraw
+link = _Blender.link
+bylink = _Blender.bylink
+
+import Object, Image, Mesh, Window, Tools, sys, Lamp, Scene, Draw, Camera
+import Material, NMesh, BGL, Types, Ipo, Text
+
+deg = lambda x: 0.0174532925199 * x # conversion from degrees to radians
+
+import __builtin__
+__builtin__.deg = deg
+
diff --git a/intern/python/modules/Blender/shadow.py b/intern/python/modules/Blender/shadow.py
new file mode 100644
index 00000000000..15c5de88f66
--- /dev/null
+++ b/intern/python/modules/Blender/shadow.py
@@ -0,0 +1,195 @@
+#
+# Blender mid level modules
+# author: strubi@blender.nl
+#
+#
+
+"""Shadow class module
+
+ These classes shadow the internal Blender objects
+
+ There is no need for you to use the shadow module really - it is
+ just there for documentation. Blender object classes with a common
+ subset of function members derive from these sub classes.
+"""
+
+
+def _List(list, Wrapper):
+ """This function returns list of wrappers, taking a list of raw objects
+and the wrapper method"""
+ return map(Wrapper, list)
+
+def _getModeBits(dict, attr):
+ list = []
+ for k in dict.keys():
+ i = dict[k]
+ if attr & i:
+ list.append(k)
+ return list
+
+def _setModeBits(dict, args):
+ flags = 0
+ try:
+ for a in args:
+ flags |= dict[a]
+ except:
+ raise TypeError, "mode must be one of %s" % dict.keys()
+ return flags
+
+
+def _link(self, data):
+ """Links Object 'self' with data 'data'. The data type must match
+the Object's type, so you cannot link a Lamp to a mesh type Object"""
+ try:
+ self._object.link(data._object)
+ except:
+ print "Users:", self._object.users
+
+class shadow:
+ """This is the shadow base class"""
+ _getters = {}
+ _setters = {}
+ _emulation = {}
+
+ def __init__(self, object):
+ self._object = object
+
+ def __getattr__(self, a):
+ try:
+ return getattr(self._object, a)
+ except:
+ if self._emulation.has_key(a):
+ return getattr(self._object, self._emulation[a])
+ elif self._getters.has_key(a):
+ return self._getters[a](self)
+ else:
+ raise AttributeError, a
+
+ def __setattr__(self, a, val):
+ if a == "_object":
+ self.__dict__['_object'] = val
+ return
+
+ try:
+ setattr(self.__dict__['_object'], a, val)
+ except:
+ if self._emulation.has_key(a):
+ setattr(self.__dict__['_object'], self._emulation[a], val)
+ elif self._setters.has_key(a):
+ self._setters[a](self, val)
+ else:
+ raise AttributeError, a
+ link = _link
+
+ def rename(self, name):
+ """Tries to set the name of the object to 'name'. If the name already
+exists, a unique name is created by appending a version number (e.g. '.001')
+to 'name'. The effective name is returned."""
+ self._object.name = name
+ return self._object.name
+
+def _getattrEx(self, a):
+ if self._emulation.has_key(a):
+ return getattr(self._object, self._emulation[a])
+ elif self._getters.has_key(a):
+ return self._getters[a](self)
+ else:
+ return getattr(self._object, a)
+
+class shadowEx:
+ """This is the shadow base class with a minor change; check for
+emulation attributes happens before access to the raw object's attributes"""
+ _getters = {}
+ _setters = {}
+ _emulation = {}
+
+ def __del__(self):
+ self.__dict__.clear()
+
+ def __init__(self, object):
+ self._object = object
+
+ def __getattr__(self, a):
+ return _getattrEx(self, a)
+
+ def __setattr__(self, a, val):
+ if a == "_object":
+ self.__dict__['_object'] = val
+ return
+
+ if self._emulation.has_key(a):
+ setattr(self.__dict__['_object'], self._emulation[a], val)
+ elif self._setters.has_key(a):
+ self._setters[a](self, val)
+ else:
+ setattr(self.__dict__['_object'], a, val)
+
+ def __repr__(self):
+ return repr(self._object)
+
+ def rename(self, name):
+ """Tries to set the name of the object to 'name'. If the name already
+exists, a unique name is created by appending a version number (e.g. '.001')
+to 'name'. The effective name is returned."""
+ self._object.name = name
+ return self._object.name
+
+ link = _link
+
+class hasIPO(shadowEx):
+ """Object class which has Ipo curves assigned"""
+
+ def getIpo(self):
+ "Returns the Ipo assigned to 'self'"
+ import Ipo
+ return Ipo.IpoBlock(self._object.ipo)
+
+ def setIpo(self, ipo):
+ "Assigns the IpoBlock 'ipo' to 'self'"
+ return self._object.assignIpo(ipo._object)
+
+ def __getattr__(self, a):
+ if a == "ipo":
+ print "ipo member access deprecated, use self.getIpo() instead!"
+ return self.getIpo()
+ else:
+ return _getattrEx(self, a)
+
+class hasModes(shadowEx):
+ """Object class which has different Modes"""
+ def getMode(self):
+ """Returns a list of the modes which are set for 'self'"""
+ list = []
+ for k in self.Modes.keys():
+ i = self.Modes[k]
+ if self._object.mode & i:
+ list.append(k)
+ return list
+
+ def setMode(self, *args):
+ """Set the mode of 'self'. This function takes a variable number
+of string arguments of the types listed in self.Modes"""
+ flags = 0
+ try:
+ for a in args:
+ flags |= self.Modes[a]
+ except:
+ raise TypeError, "mode must be one of" % self.Modes.keys()
+ self._object.mode = flags
+
+class dict:
+ """readonly dictionary shadow"""
+ _emulation = {}
+
+ def __init__(self, dict):
+ self._dict = dict
+
+ def __getitem__(self, key):
+ try:
+ return self._dict[key]
+ except:
+ key = _emulation[key]
+ return self._dict[key]
+
+ def __repr__(self):
+ return repr(self._dict)
diff --git a/intern/python/modules/Blender/sys.py b/intern/python/modules/Blender/sys.py
new file mode 100644
index 00000000000..f76c0074c1f
--- /dev/null
+++ b/intern/python/modules/Blender/sys.py
@@ -0,0 +1,20 @@
+from _Blender.sys import *
+
+sep = dirsep # path separator ('/' or '\')
+
+class Path:
+ def dirname(self, name):
+ return dirname(name)
+ def join(self, a, *p):
+ path = a
+ for b in p:
+ if b[:1] == dirsep:
+ path = b
+ elif path == '' or path[-1:] == dirsep:
+ path = path + b
+ else:
+ path = path + dirsep + b
+ return path
+
+path = Path()
+