forked from bartvdbraak/blender
c57ca3c86a
etc. there. Maarten
183 lines
4.4 KiB
Python
183 lines
4.4 KiB
Python
|
|
"""This is a basic scenegraph module for Blender
|
|
It contains low level API calls..."""
|
|
|
|
# (c) 2001, Martin Strubel // onk@section5.de
|
|
|
|
from util import quat #quaternions
|
|
|
|
from Blender import Object, Lamp, Scene
|
|
|
|
|
|
TOLERANCE = 0.01
|
|
|
|
def uniform_scale(vec):
|
|
v0 = vec[0]
|
|
d = abs(vec[1] - v0)
|
|
if d > TOLERANCE:
|
|
return 0
|
|
d = abs(vec[2] - v0)
|
|
if d > TOLERANCE:
|
|
return 0
|
|
return v0
|
|
|
|
class Transform:
|
|
"""An abstract transform, containing translation, rotation and scale information"""
|
|
def __init__(self):
|
|
self.scale = (1.0, 1.0, 1.0)
|
|
self.translation = (0.0, 0.0, 0.0)
|
|
self.rotation = quat.Quat()
|
|
self.scaleOrientation = quat.Quat() # axis, angle
|
|
self.parent = None
|
|
def __mul__(self, other):
|
|
s = uniform_scale(self.scale)
|
|
if not s:
|
|
raise RuntimeError, "non uniform scale, can't multiply"
|
|
t = Transform()
|
|
sc = other.scale
|
|
t.scale = (s * sc[0], s * sc[1], s * sc[2])
|
|
t.rotation = self.rotation * other.rotation
|
|
tr = s * apply(quat.Vector, other.translation)
|
|
t.translation = self.rotation.asMatrix() * tr + self.translation
|
|
return t
|
|
def getLoc(self):
|
|
t = self.translation
|
|
return (t[0], t[1], t[2]) # make sure it's a tuple..silly blender
|
|
def calcRotfromAxis(self, axisrotation):
|
|
self.rotation = apply(quat.fromRotAxis,axisrotation)
|
|
def getRot(self):
|
|
return self.rotation.asEuler()
|
|
def getSize(self):
|
|
s = self.scale
|
|
return (s[0], s[1], s[2])
|
|
def __repr__(self):
|
|
return "Transform: rot: %s loc:%s" % (self.getRot(), self.getLoc())
|
|
def copy(self):
|
|
"returns copy of self"
|
|
t = Transform()
|
|
t.scale = self.scale
|
|
t.translation = self.translation
|
|
t.rotation = self.rotation
|
|
t.scaleOrientation = self.scaleOrientation
|
|
return t
|
|
|
|
class BID:
|
|
"Blender named Object ID"
|
|
def __init__(self, name):
|
|
self.name = name
|
|
self.data = None
|
|
|
|
class BScene:
|
|
def __init__(self, name = None):
|
|
from Blender import Scene
|
|
self.dict = {'Image': {}, 'Object':{}, 'Mesh' : {}}
|
|
self.name = name
|
|
def __getitem__(self, name):
|
|
return self.dict[name]
|
|
def __setitem__(self, name, val):
|
|
self.dict[name] = val
|
|
def has_key(self, name):
|
|
if self.dict.has_key(name):
|
|
return 1
|
|
else:
|
|
return 0
|
|
def getnewID(self, templ):
|
|
n = 0
|
|
name = templ
|
|
while self.dict.has_key(name):
|
|
n += 1
|
|
name = "%s.%03d" % (templ, n)
|
|
return name
|
|
|
|
class BSGNode:
|
|
"Blender Scenegraph node"
|
|
isRoot = 0
|
|
def __init__(self, object = None, type = "", name = ""):
|
|
self.type = type
|
|
self.name = name
|
|
self.children = []
|
|
self.level = 0
|
|
self.object = object
|
|
def addChildren(self, children):
|
|
self.children += children
|
|
def traverse(self, visitor):
|
|
ret = visitor()
|
|
for c in self.children:
|
|
c.traverse(visitor)
|
|
return ret
|
|
def setDepth(self, level):
|
|
self.level = level
|
|
for c in self.children:
|
|
c.setDepth(level + 1)
|
|
def update(self):
|
|
ob.name = self.name
|
|
def __repr__(self):
|
|
l = self.level
|
|
children = ""
|
|
pre = l * ' '
|
|
return "\n%s%s [%s] ->%s" % (pre, self.name, self.type, self.children)
|
|
|
|
class ObjectNode(BSGNode):
|
|
def __init__(self, object = None, type = "", name = ""):
|
|
self.transform = Transform()
|
|
self.scene = Scene.getCurrent()
|
|
BSGNode.__init__(self, object, type, name)
|
|
def makeParent(self, child):
|
|
self.child = parent
|
|
child.parent = self
|
|
def clone(self):
|
|
ob = self.object
|
|
newob = ob.copy()
|
|
self.scene.link(newob)
|
|
new = ObjectNode(newob)
|
|
new.transform = self.transform.copy()
|
|
return new
|
|
def insert(self, child):
|
|
self.children.append(child)
|
|
child.level = self.level + 1
|
|
ob = child.object
|
|
self.object.makeParent([ob], 1, 1)
|
|
# first parent, THEN set local transform
|
|
child.update()
|
|
def applyTransform(self, tf):
|
|
self.transform = tf * self.transform
|
|
def update(self):
|
|
ob = self.object
|
|
t = self.transform
|
|
ob.loc = t.getLoc()
|
|
ob.size = t.getSize()
|
|
ob.rot = t.getRot()
|
|
ob.name = self.name
|
|
|
|
def NodefromData(ob, type, name):
|
|
new = ObjectNode(None, type, name)
|
|
if ob:
|
|
obj = ob
|
|
else:
|
|
obj = Object.New(type)
|
|
Scene.getCurrent().link(obj)
|
|
if not obj:
|
|
raise RuntimeError, "FATAL: could not create object"
|
|
new.object= obj
|
|
new.object.name = name
|
|
#new.fromData(ob)
|
|
return new
|
|
|
|
class RootNode(ObjectNode):
|
|
"""stupid simple scenegraph prototype"""
|
|
level = 0
|
|
isRoot = 1
|
|
type = 'Root'
|
|
name = 'ROOT'
|
|
|
|
def __init__(self, object = None, type = "", name = ""):
|
|
from Blender import Scene
|
|
self.transform = Transform()
|
|
BSGNode.__init__(self, object, type, name)
|
|
self.scene = Scene.getCurrent()
|
|
def insert(self, child):
|
|
child.update()
|
|
self.children.append(child)
|
|
def update(self):
|
|
self.scene.update()
|