Initial revision
This commit is contained in:
167
intern/python/modules/beta/Objects.py
Normal file
167
intern/python/modules/beta/Objects.py
Normal file
@@ -0,0 +1,167 @@
|
||||
from Blender import Scene
|
||||
import Blender.NMesh as _NMesh
|
||||
import Blender.Material as Material
|
||||
|
||||
|
||||
defaultUV = [(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0)]
|
||||
|
||||
FACEFLAGS = _NMesh.Const
|
||||
DEFAULTFLAGS = FACEFLAGS.LIGHT + FACEFLAGS.DYNAMIC
|
||||
|
||||
curface = None
|
||||
tessfaces = None
|
||||
|
||||
def error():
|
||||
pass
|
||||
def beginPolygon():
|
||||
global curface
|
||||
global tessfaces
|
||||
curface = _NMesh.Face()
|
||||
def endPolygon():
|
||||
global curface
|
||||
global tessfaces
|
||||
tessfaces.append(curface)
|
||||
def addVertex(v):
|
||||
global curface
|
||||
curface.v.append(v)
|
||||
curface.uv.append((v.uvco[0], v.uvco[1]))
|
||||
|
||||
class Face:
|
||||
def __init__(self, vlist):
|
||||
self.v= vlist
|
||||
self.uv = []
|
||||
self.mode = 0
|
||||
|
||||
class shadow:
|
||||
def __setattr__(self, name, val):
|
||||
setattr(self.data, name, val)
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.data, name)
|
||||
def __repr__(self):
|
||||
return repr(self.data)
|
||||
|
||||
##########################################
|
||||
# replacement xMesh (NMesh shadow class)
|
||||
|
||||
class shadowNVert: #shadow NMVert class for the tesselator
|
||||
def __init__(self):
|
||||
self.vert = None
|
||||
self.uv = []
|
||||
def __len__(self):
|
||||
return 3
|
||||
def __getitem__(self, i):
|
||||
return self.vert.co[i]
|
||||
|
||||
def Color(r, g, b, a = 1.0):
|
||||
return _NMesh.Col(255 * r, 255 * g, 255 * b, 255 * a)
|
||||
|
||||
class shadowNMesh:
|
||||
def __init__(self, name = None, default_flags = None):
|
||||
self.scene = Scene.getCurrent()
|
||||
self.data = _NMesh.GetRaw()
|
||||
self.name = name
|
||||
if default_flags:
|
||||
flags = default_flags
|
||||
else:
|
||||
flags = DEFAULTFLAGS
|
||||
self.flags = flags
|
||||
self.smooth = 0
|
||||
self.faces = []
|
||||
try:
|
||||
import tess
|
||||
self.tess = tess.Tess(256, beginPolygon, endPolygon, error, addVertex)
|
||||
except:
|
||||
#print "couldn't import tesselator"
|
||||
self.tess = None
|
||||
self.curface = None
|
||||
self.tessfaces = []
|
||||
self.recalc_normals = 1
|
||||
|
||||
def __del__(self):
|
||||
del self.data
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == 'vertices':
|
||||
return self.data.verts
|
||||
else:
|
||||
return getattr(self.data, name)
|
||||
|
||||
def __repr__(self):
|
||||
return "Mesh: %d faces, %d vertices" % (len(self.faces), len(self.verts))
|
||||
def toNMFaces(self, ngon):
|
||||
# This should be a Publisher only feature...once the tesselation
|
||||
# is improved. The GLU tesselator of Mesa < 4.0 is crappy...
|
||||
if not self.tess:
|
||||
return [] # no faces converted
|
||||
import tess
|
||||
i = 0
|
||||
global tessfaces
|
||||
tessfaces = []
|
||||
tess.beginPolygon(self.tess)
|
||||
for v in ngon.v:
|
||||
if len(ngon.uv) == len(ngon.v):
|
||||
v.uvco = ngon.uv[i]
|
||||
tess.vertex(self.tess, (v.co[0], v.co[1], v.co[2]), v)
|
||||
i += 1
|
||||
tess.endPolygon(self.tess)
|
||||
return tessfaces
|
||||
|
||||
def hasFaceUV(self, true):
|
||||
self.data.hasFaceUV(true)
|
||||
|
||||
def addVert(self, v):
|
||||
vert = _NMesh.Vert(v[0], v[1], v[2])
|
||||
self.data.verts.append(vert)
|
||||
return vert
|
||||
|
||||
def addFace(self, vlist, flags = None, makedefaultUV = 0):
|
||||
n = len(vlist)
|
||||
if n > 4:
|
||||
face = Face(vlist)
|
||||
else:
|
||||
face = _NMesh.Face()
|
||||
for v in vlist:
|
||||
face.v.append(v)
|
||||
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 write(self):
|
||||
from Blender import Object
|
||||
# new API style:
|
||||
self.update()
|
||||
ob = Object.New(Object.Types.MESH) # create object
|
||||
ob.link(self.data) # link mesh data to it
|
||||
self.scene.link(ob)
|
||||
return ob
|
||||
|
||||
def update(self):
|
||||
from Blender.Types import NMFaceType
|
||||
smooth = self.smooth
|
||||
for f in self.faces:
|
||||
if type(f) == NMFaceType:
|
||||
f.smooth = smooth
|
||||
self.data.faces.append(f)
|
||||
f.materialIndex = 0
|
||||
else: #it's a NGON (shadow face)
|
||||
faces = self.toNMFaces(f)
|
||||
for nf in faces:
|
||||
nf.smooth = smooth
|
||||
nf.materialIndex = 0
|
||||
self.data.faces.append(nf)
|
||||
|
||||
if not self.name:
|
||||
self.name = "Mesh"
|
||||
|
||||
def assignMaterial(self, material):
|
||||
self.data.materials = [material._object]
|
||||
|
||||
Mesh = shadowNMesh
|
||||
Vert = shadowNVert
|
||||
|
182
intern/python/modules/beta/Scenegraph.py
Normal file
182
intern/python/modules/beta/Scenegraph.py
Normal file
@@ -0,0 +1,182 @@
|
||||
|
||||
"""This is a basic scenegraph module for Blender
|
||||
It contains low level API calls..."""
|
||||
|
||||
# (c) 2001, Martin Strubel // onk@section5.de
|
||||
|
||||
from utils 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()
|
1
intern/python/modules/beta/__init__.py
Normal file
1
intern/python/modules/beta/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
__all__ = ["Scenegraph", "Objects"]
|
Reference in New Issue
Block a user