Initial revision
This commit is contained in:
1
intern/python/modules/Blender/BGL.py
Normal file
1
intern/python/modules/Blender/BGL.py
Normal file
@@ -0,0 +1 @@
|
||||
from _Blender.BGL import *
|
106
intern/python/modules/Blender/Camera.py
Normal file
106
intern/python/modules/Blender/Camera.py
Normal file
@@ -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
|
||||
|
||||
|
1
intern/python/modules/Blender/Draw.py
Normal file
1
intern/python/modules/Blender/Draw.py
Normal file
@@ -0,0 +1 @@
|
||||
from _Blender.Draw import *
|
52
intern/python/modules/Blender/Image.py
Normal file
52
intern/python/modules/Blender/Image.py
Normal file
@@ -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
|
||||
|
279
intern/python/modules/Blender/Ipo.py
Normal file
279
intern/python/modules/Blender/Ipo.py
Normal file
@@ -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
|
168
intern/python/modules/Blender/Lamp.py
Normal file
168
intern/python/modules/Blender/Lamp.py
Normal file
@@ -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
|
251
intern/python/modules/Blender/Material.py
Normal file
251
intern/python/modules/Blender/Material.py
Normal file
@@ -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
|
250
intern/python/modules/Blender/Mesh.py
Normal file
250
intern/python/modules/Blender/Mesh.py
Normal file
@@ -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"
|
||||
|
192
intern/python/modules/Blender/NMesh.py
Normal file
192
intern/python/modules/Blender/NMesh.py
Normal file
@@ -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
|
391
intern/python/modules/Blender/Object.py
Normal file
391
intern/python/modules/Blender/Object.py
Normal file
@@ -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
|
143
intern/python/modules/Blender/Scene.py
Normal file
143
intern/python/modules/Blender/Scene.py
Normal file
@@ -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)
|
57
intern/python/modules/Blender/Text.py
Normal file
57
intern/python/modules/Blender/Text.py
Normal file
@@ -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
|
1
intern/python/modules/Blender/Types.py
Normal file
1
intern/python/modules/Blender/Types.py
Normal file
@@ -0,0 +1 @@
|
||||
from _Blender.Types import *
|
65
intern/python/modules/Blender/Window.py
Normal file
65
intern/python/modules/Blender/Window.py
Normal file
@@ -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
|
157
intern/python/modules/Blender/World.py
Normal file
157
intern/python/modules/Blender/World.py
Normal file
@@ -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
|
||||
|
||||
|
23
intern/python/modules/Blender/__init__.py
Normal file
23
intern/python/modules/Blender/__init__.py
Normal file
@@ -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
|
||||
|
195
intern/python/modules/Blender/shadow.py
Normal file
195
intern/python/modules/Blender/shadow.py
Normal file
@@ -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)
|
20
intern/python/modules/Blender/sys.py
Normal file
20
intern/python/modules/Blender/sys.py
Normal file
@@ -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()
|
||||
|
Reference in New Issue
Block a user