diff options
Diffstat (limited to 'intern/python/modules/Blender/Object.py')
-rw-r--r-- | intern/python/modules/Blender/Object.py | 391 |
1 files changed, 391 insertions, 0 deletions
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 |