blender/intern/python/modules/Blender/Object.py
Wouter van Heyst 6b65e39a44 Revert to the FUTURE_PYTHON_API, this means:
- switching the define on in buildsystems (NaN, auto and msvc are done)
- again import _Blender, which is the C module, from the Python modules
2003-02-06 03:30:25 +00:00

392 lines
11 KiB
Python

##
## 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