Paste Code
Paste Blends
Paste Images
# --------------------------------------------------------------------------
# Illusoft Collada 1.4 plugin for Blender version 0.2.65
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# Copyright (C) 2006: Illusoft - colladablender@illusoft.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License,
# or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------

from cutils import *
import collada
import sys
import Blender
from Blender.Mathutils import *
import math
import datetime

class Translator(object):
isImporter = False

def __init__(self, isImporter, version, debugM, fileName,_useTriangles, _usePolygons, _bakeMatrices, _exportSelection, _createNewScene, _clearScene, _lookAt, _exportPhysics, _exportCurrentScene, _exportRelativePaths, _useUV):
global __version__, debugMode, usePhysics, useTriangles, usePolygons, bakeMatrices, exportSelection, createNewScene, clearScene, lookAt, replaceNames, exportPhysics, exportCurrentScene, useRelativePaths, useUV
__version__ = version
debugMode = debugM
usePhysics = None
useTriangles = _useTriangles
usePolygons = _usePolygons
bakeMatrices = _bakeMatrices
exportSelection = _exportSelection
createNewScene = _createNewScene
clearScene = _clearScene
lookAt = _lookAt
exportPhysics = _exportPhysics
exportCurrentScene = _exportCurrentScene
useRelativePaths = _exportRelativePaths
useUV = _useUV

replaceNames = clearScene

self.isImporter = isImporter
self.fileName = ''
if self.isImporter:
self.__Import(fileName)
else:
self.__Export(fileName)

def __Import(self,fileName=''):
documentTranslator = DocumentTranslator(fileName)
documentTranslator.Import(fileName)

def __Export(self,filename=''):
documentTranslator = DocumentTranslator(filename)
documentTranslator.Export(filename)


class DocumentTranslator(object):
isImport = None
ids = []
sceneGraph = None

cameraLibrary = None
## geometryLibrary = None
## controllerLibrary = None
## animationLibrary = None
## materialLibrary = None
texturesLibrary = None
lampsLibrary = None
colladaDocument = None
scenesLibrary = None

def CreateID(self, name, typeName=None):
if not (name in self.ids):
self.ids.append(name)
return name
else:
tempName = name;
if not(typeName is None) and name.rfind(typeName) >= 0:
# Check for existing number at the end?
return self.IncrementString(tempName)
else:
return self.CreateID(tempName+typeName, typeName)

def IncrementString(self, name):
tempName = name;
if name.rfind('.') >= 0:
while tempName[-1:].isdigit():
tempName = tempName[:-1]
digitStr = name[-(len(name)-len(tempName)):]
digit = 1
if len(digitStr) > 0 and len(digitStr) != len(name):
digit = int(digitStr)+1
return tempName+str(digit).zfill(3)
else:
return name+'.001'

def __init__(self, fileName):
self.isImport = False
self.scenesLibrary = ScenesLibrary(self) #<library_visual_scenes> ?
self.sceneGraph = SceneGraph(self) #<scene>?
self.lampsLibrary = LampsLibrary(self)
self.colladaDocument = None
self.texturesLibrary = TexturesLibrary(self)
self.camerasLibrary = CamerasLibrary(self)
self.materialsLibrary = MaterialsLibrary(self)
self.meshLibrary = MeshLibrary(self) #<library_geometry?
# Doug: I need something like the following so that repetitive
# geometry displays correctly in GoogleEarth (GE):
# my needs: slf.nodeLibrary = NoedeLibrary(self)
#I misspelled so you can see this code has never been implemented
# I get this approach from examining SketchUp output when
# using their Component approach for repetitive geometry
# I need to wrap each instance_geometry in a <node>
# in the <library_nodes> section and
#then instance_node in the library_visual_scenes
#collada.py has a nodeslibrary
self.nodesLibrary = NodesLibrary(self) #Doug added

self.filename = None
self.filePath = ''




self.currentBScene = Blender.Scene.getCurrent()

self.progressCount = 0.4
self.progressField = (1.0 - self.progressCount)
self.progressStep = 0.0
self.progressPartCount = 0.0

self.tMat = Matrix()

def CreateNameForObject(self, name, replace, myType):
if not replace:
return name

if myType == 'object':
try:
ob = Blender.Object.Get(name)
ob.name = self.CreateNameForObject(self.IncrementString(ob.name), True, 'object')
except ValueError:
pass
elif myType == 'mesh':
try:
mesh = Blender.Mesh.Get(name)
if not mesh is None:
mesh.name = self.CreateNameForObject(self.IncrementString(mesh.name), True, 'mesh')
except ValueError:
pass

return name

def Import(self, fileName):
global debugMode, createNewScene

self.filename = fileName
self.filePath = Blender.sys.dirname(self.filename) + Blender.sys.sep
self.isImport = True
Blender.Window.EditMode(0)
Blender.Window.DrawProgressBar(0.0, 'Starting Import')

if createNewScene:
self.currentBScene = Blender.Scene.New('Scene')
self.currentBScene.makeCurrent()
else:
self.currentBScene = Blender.Scene.getCurrent()

# Create a new Collada document
Blender.Window.DrawProgressBar(0.1, 'Get Collada Document')
self.colladaDocument = collada.DaeDocument(debugMode)

# Setup the libraries
self.camerasLibrary.SetDaeLibrary(self.colladaDocument.camerasLibrary)
self.lampsLibrary.SetDaeLibrary(self.colladaDocument.lightsLibrary)
self.texturesLibrary.SetDaeLibrary(self.colladaDocument.imagesLibrary)
self.materialsLibrary.SetDaeLibrary(self.colladaDocument.materialsLibrary)
self.meshLibrary.SetDaeLibrary(self.colladaDocument.geometriesLibrary)

# Parse the COLLADA file
self.colladaDocument.LoadDocumentFromFile(fileName)

if self.colladaDocument.asset.upAxis == collada.DaeSyntax.Y_UP:
self.tMat[0][0] = 0
self.tMat[1][1] = 0
self.tMat[2][2] = 0
self.tMat[0][1] = 1
self.tMat[1][2] = 1
self.tMat[2][0] = 1

self.progressStep = self.progressField/(self.colladaDocument.GetItemCount()+1)

# Read the COLLADA stucture and build the scene in Blender.
Blender.Window.DrawProgressBar(0.4, 'Translate Collada 2 Blender')
self.sceneGraph.LoadFromCollada(self.colladaDocument.scene)

self.Progress()

def Export(self, fileName):
global __version__, filename
filename = fileName
self.ids = []
self.isImport = False
Blender.Window.EditMode(0)

# Create a new Collada document
self.colladaDocument = collada.DaeDocument(debugMode)
daeAsset = collada.DaeAsset()
daeAsset.upAxis = 'Z_UP'
daeAsset.created = datetime.datetime.today()
daeAsset.modified = datetime.datetime.today()
daeAsset.unit = collada.DaeUnit()
## daeAsset.unit.name = 'centimeter'
## daeAsset.unit.meter = '0.01'
daeAsset.unit.name = 'meter' #meter works better in googleEarth
daeAsset.unit.meter = '1.0'
daeContributor = collada.DaeContributor()
daeContributor.author = 'Illusoft Collada 1.4.0 plugin for Blender - http://colladablender.illusoft.com'
daeContributor.authoringTool = 'Blender v:%s - Illusoft Collada Exporter v:%s' % (Blender.Get('version'), __version__)
daeContributor.sourceData = GetValidFilename(Blender.Get('filename'))
daeAsset.contributors.append(daeContributor)

self.colladaDocument.asset = daeAsset


daeScene = collada.DaeScene()

# Loop throug all scenes
for bScene in Blender.Scene.Get():
if not exportCurrentScene or self.currentBScene == bScene:
daeInstanceVisualScene = collada.DaeVisualSceneInstance()
daeInstancePhysicsScene = collada.DaePhysicsSceneInstance()
daeVisualScene = self.colladaDocument.visualScenesLibrary.FindObject(bScene.name)
if daeVisualScene is None:
sceneGraph = SceneGraph(self)
scenesList = sceneGraph.SaveToDae(bScene)
daeVisualScene = scenesList[0]
if exportPhysics:
daePhysicsScene = scenesList[1]

daeInstanceVisualScene.object = daeVisualScene

#self.colladaDocument.visualScenesLibrary.AddItem(daeIntanceVisualScene)
daeScene.iVisualScenes.append(daeInstanceVisualScene)
if exportPhysics:
daeInstancePhysicsScene.object = daePhysicsScene
daeScene.iPhysicsScenes.append(daeInstancePhysicsScene)

#self.colladaDocument.visualScenesLibrary.AddItem(sceneGraph.ObjectToDae(bScene))
#daeScene = collada.DaeScene()
#daeScene.AddInstance()


self.colladaDocument.scene = daeScene

self.colladaDocument.SaveDocumentToFile(fileName)

def Progress(self):
self.progressPartCount = 0.0
self.progressCount += self.progressStep
Blender.Window.DrawProgressBar(self.progressCount, 'Creating Blender Nodes...')

def ProgressPart(self, val, text):
self.progressPartCount += val
Blender.Window.DrawProgressBar(self.progressCount+self.progressPartCount*self.progressStep,text)

class SceneGraph(object):

def __init__(self, document):
self.document = document
self.name = ''

self.childNodes = dict()
self.rootNodes = []

self.objectNames = dict()
# Get the current blender scene
#self.currentBScene = Blender.Scene.getCurrent()

def LoadFromCollada(self, colladaScene):
global debugMode, newScene, clearScene

# When in debugMode, delete everything from the scene before proceding
if debugMode or clearScene:
print "Delete everything from the scene.."
bNodes = Blender.Object.Get()

newScene = Blender.Scene.New("new Scene")
newScene.makeCurrent()
Blender.Scene.Unlink(self.document.currentBScene)
self.document.currentBScene = newScene

if colladaScene == None:
return False

visualScenes = colladaScene.GetVisualScenes()
if visualScenes is None:
return
# For now, only pick the first available Visual Scene
visualScene = visualScenes[0]
if visualScene is None:
return

Blender.Window.DrawProgressBar(0.5,'Build the items on the scene')
# loop trough all nodes
for daeNode in visualScene.nodes:
sceneNode = SceneNode(self.document, self)
ob = sceneNode.ObjectFromDae(daeNode)
self.objectNames[daeNode.id] = ob.name
##sceneNode.ObjectFromDae(daeNode)

# Now get the physics Scene
physicsScenes = colladaScene.GetPhysicsScenes()
if not (physicsScenes is None) and len(physicsScenes) > 0:
# For now, only pick the fist available physics Scene
physicsScene = physicsScenes[0]
for iPhysicsModel in physicsScene.iPhysicsModels:
physicsNode = PhysicsNode(self.document)
physicsNode.LoadFromDae(iPhysicsModel, self.objectNames)


# Update the current Scene.
self.document.currentBScene.update(1)

def SaveToDae(self, bScene):
global exportSelection, exportPhysics
daeVisualScene = collada.DaeVisualScene()
daeVisualScene.id = daeVisualScene.name = self.document.CreateID(bScene.name,'-Scene')

daePhysicsScene = collada.DaePhysicsScene()
daePhysicsScene.id = daePhysicsScene.name = self.document.CreateID(bScene.name+'-Physics', '-Scene')

#Doug: Blender stores a pointer to the parent node with each node. But not a list of children. Typically for
#scene graph exporters - X3D, DAE - you need to construct a list of children for each node before processing
if exportSelection:
self.rootNodes = Blender.Object.GetSelected()
self.childNodes = []
else: # now loop trough all nodes in this scene and create a list with root nodes and children
for node in bScene.getChildren():
pNode = node.parent
if pNode is None:
self.rootNodes.append(node)
else:
try:
self.childNodes[pNode.name].append(node) #Doug: append yourself to your parent's list of children
except:
self.childNodes[pNode.name] = [node]
#Doug: now process
# Begin with the rootnodes
for rootNode in self.rootNodes:
sceneNode = SceneNode(self.document,self)
nodeResult = sceneNode.SaveToDae(rootNode,self.childNodes)
daeNode = nodeResult[0]
daeVisualScene.nodes.append(daeNode)
if exportPhysics:
daeInstancePhysicsModel = nodeResult[1]
daePhysicsScene.iPhysicsModels.append(daeInstancePhysicsModel)

self.document.colladaDocument.visualScenesLibrary.AddItem(daeVisualScene)
if exportPhysics:
self.document.colladaDocument.physicsScenesLibrary.AddItem(daePhysicsScene)
return (daeVisualScene, daePhysicsScene)

class PhysicsNode(object):
dynamic = 0
child = 1
actor = 2
inertiaLockX = 3
inertiaLockY = 4
inertiaLockZ = 5
doFH = 6
rotFH = 7
anisotropicFriction = 8
ghost = 9
rigidBody = 10
bounds = 11
collisionResponse = 12

def __init__(self, document):
self.document = document

def LoadFromDae(self, daeInstancePhysicsModel, objectNames):
global usePhysics
if not(usePhysics is None) and not usePhysics:
return

for iRigidBody in daeInstancePhysicsModel.iRigidBodies:
# Get the real blender name instead of the collada name.
realObjectName = objectNames[iRigidBody.targetString]
# Get the Blender object with the specified name.
bObject = Blender.Object.Get(realObjectName)
# Check if physics is supported.
if usePhysics is None:
usePhysics = hasattr(bObject, "rbShapeBoundType")
if not usePhysics:
return

# Get the rigid body.
rigidBody = iRigidBody.body
# Get the common technique of the rigid body.
rigidBodyT = rigidBody.techniqueCommon
# Get the physics material.
physicsMaterial = rigidBodyT.GetPhysicsMaterial()
# Get the shapes of the bounding volumes in this rigid body.
shapes = rigidBodyT.shapes

# The Rigid Body Flags
rbFlags = 0 + rigidBodyT.dynamic + (1 << self.actor) + (1 << self.rigidBody) + (1 << self.bounds)
rbShapeBoundType = 0
# For now only get the first shape
shape = shapes[0]
# Check the type of the shape
if isinstance(shape, collada.DaeGeometryShape):
##print shape, shape.iGeometry.object.data
if isinstance(shape.iGeometry.object.data, collada.DaeMesh):
rbShapeBoundType = 4
else:
rbShapeBoundType = 5
elif isinstance(shape, collada.DaeBoxShape):
rbShapeBoundType = 0
elif isinstance(shape, collada.DaeSphereShape):
rbShapeBoundType = 1
elif isinstance(shape, collada.DaeCylinderShape):
rbShapeBoundType = 2
elif isinstance(shape, collada.DaeTaperedCylinderShape):
rbShapeBoundType = 3

bObject.rbFlags = rbFlags
if not (rigidBodyT.mass is None):
bObject.rbMass = rigidBodyT.mass

bObject.rbShapeBoundType = rbShapeBoundType


class SceneNode(object):

def __init__(self, document, sceneNode):
self.id = ''
self.type = ''
self.document = document

def ObjectFromDae(self,daeNode):
global replaceNames
self.document.Progress()
self.id = daeNode.id
self.type = daeNode.type

if daeNode.IsJoint():
# it's a Joint, not implemented yet
return
pass
else : #its a Node
newObject = None
dataObject = None
daeInstances = daeNode.GetInstances()

if len(daeInstances) == 0:
newObject = Blender.Object.New('Empty',self.id)
else:
# if only one instance is in this node, add it.
if len (daeInstances)== 1:
# Get the instance
daeInstance = daeInstances[0]
# Check which type the instance is
if isinstance(daeInstance,collada.DaeAnimationInstance):
newObject = Blender.Object.New('Empty',self.id)
elif isinstance(daeInstance,collada.DaeCameraInstance):
newObject = Blender.Object.New('Camera',self.id)
dataObject = self.document.camerasLibrary.FindObject(daeInstance,True)
elif isinstance(daeInstance,collada.DaeControllerInstance):
newObject = Blender.Object.New('Empty',self.id)
elif isinstance(daeInstance,collada.DaeGeometryInstance):
newObject = Blender.Object.New('Mesh',self.document.CreateNameForObject(self.id,replaceNames, 'object'))
dataObject = self.document.meshLibrary.FindObject(daeInstance,True)
elif isinstance(daeInstance,collada.DaeLightInstance):
newObject = Blender.Object.New('Lamp',self.id)
dataObject = self.document.lampsLibrary.FindObject(daeInstance,True)
elif isinstance(daeInstance,collada.DaeNodeInstance):
newObject = Blender.Object.New('Empty',self.id)
elif isinstance(daeInstance,collada.DaeVisualSceneInstance):
newObject = Blender.Object.New('Empty',self.id)
else:
print daeInstance
return
# Link the new Object to the dataObject
if dataObject != None:
newObject.link(dataObject)
else: # otherwise, create an empty node and attach the different instances to it
newObject = Blender.Object.New('Empty',self.id)
# finish this

self.document.currentBScene.link(newObject)

# TODO: MAYBE CHANGE THIS LATER update the mesh..
if newObject.getType() == 'Mesh':
newObject.getData().update(1,1,1)
# Set the vertex colors.
for f in newObject.getData(mesh=1).faces:
for c in f.col:
c.r = 255
c.g = 255
c.b = 255
c.a = 255

# Do the transformation
mat = Matrix().resize4x4()
for i in range(len(daeNode.transforms)):
transform = daeNode.transforms[len(daeNode.transforms)-(i+1)]
type = transform[0]
data = transform[1]
if type == collada.DaeSyntax.TRANSLATE:
mat = mat*TranslationMatrix(Vector(data)* self.document.tMat)
elif type == collada.DaeSyntax.ROTATE:
mat = mat*RotationMatrix(data[3],4,'r',Vector([data[0],data[1],data[2]])* self.document.tMat)
elif type == collada.DaeSyntax.SCALE:
skewVec = Vector(data[0],data[1], data[2])*self.document.tMat
mat = mat * Matrix([skewVec.x,0,0,0],[0,skewVec.y,0,0],[0,0,skewVec.z,0],[0,0,0,1])
elif type == collada.DaeSyntax.SKEW:
s = math.tan(data[0]*angleToRadian)
rotVec = Vector(data[1],data[2],data[3])*self.document.tMat
transVec = Vector(data[4],data[5],data[6])*self.document.tMat
fac1 = s*transVec.x
fac2 = s*transVec.y
fac3 = s*transVec.z

mat = mat * Matrix([1+fac1*rotVec.x,fac1*rotVec.y,fac1*rotVec.z,0],[fac2*rotVec.x,1+fac2*rotVec.y,fac2*rotVec.z,0],[fac3*rotVec.x,fac3*rotVec.y,1+fac3*rotVec.z,0],[0,0,0,1])
elif type == collada.DaeSyntax.LOOKAT:
# TODO: use the correct up-axis
position = Vector([data[0],data[1], data[2]])
target = Vector([data[3],data[4], data[5]])
up = Vector([data[6],data[7], data[8]]).normalize()
front = (position-target).normalize()
side = -1*CrossVecs(front, up).normalize()
m = Matrix().resize4x4()

m[0][0] = side.x
m[0][1] = side.y
m[0][2] = side.z

m[1][0] = up.x
m[1][1] = up.y
m[1][2] = up.z

m[2][0] = front.x
m[2][1] = front.y
m[2][2] = front.z

m[3][0] = position.x
m[3][1] = position.y
m[3][2] = position.z

mat = mat*m

elif type == collada.DaeSyntax.MATRIX:
mat = mat * data

newObject.setMatrix(mat)
childlist = []
for daeChild in daeNode.nodes:
childSceneNode = SceneNode(self.document,self)
object = childSceneNode.ObjectFromDae(daeChild)
if not(object is None):
childlist.append(object)
newObject.makeParent(childlist,0,1)

return newObject

def SaveToDae(self,bNode,childNodes):
global bakeMatrices, exportSelection
daeNode = collada.DaeNode()
daeNode.id = daeNode.name = self.document.CreateID(bNode.name,'-Node')# +'-node'

# Get the transformations
if bakeMatrices :
mat = Blender.Mathutils.CopyMat(bNode.matrix).transpose()
daeNode.transforms.append([collada.DaeSyntax.MATRIX, mat])
else:
#Doug: start vrml code from vrml2 exporter
from Blender import Mathutils
ob_matrix = Mathutils.Matrix(bNode.getMatrix('localspace')) #'worldspace'))
matrix = ob_matrix
e = matrix.rotationPart().toEuler()

v = matrix.translationPart()
location = (v.x,v.y,v.z)
mrot = e.toMatrix().resize4x4()
try:
mrot.invert()
except:
print "Warning: %s has degenerate transformation!" % (thisName)
return

diag = matrix * mrot
sizeX = diag[0][0]
sizeY = diag[1][1]
sizeZ = diag[2][2]
scales = (sizeX,sizeY,sizeZ)
#Doug: end vrml code
e.x *= 3.141596/180.0
e.y *= 3.141596/180.0
e.z *= 3.141596/180.0

daeNode.transforms.append([collada.DaeSyntax.TRANSLATE, location])
#daeNode.transforms.append([collada.DaeSyntax.TRANSLATE, bNode.getLocation()])

#euler = bNode.getEuler()
euler = e
rotxVec = [1,0,0,euler.x*radianToAngle]
rotyVec = [0,1,0,euler.y*radianToAngle]
rotzVec = [0,0,1,euler.z*radianToAngle]

##rotVec = [round(euler.x*radianToAngle,3), round(euler.y*radianToAngle,3), round(euler.z*radianToAngle,3)]
if euler.z != 0: daeNode.transforms.append([collada.DaeSyntax.ROTATE, rotzVec])
if euler.y != 0: daeNode.transforms.append([collada.DaeSyntax.ROTATE, rotyVec])
if euler.x != 0: daeNode.transforms.append([collada.DaeSyntax.ROTATE, rotxVec])

#daeNode.transforms.append([collada.DaeSyntax.SCALE, bNode.getSize()])
daeNode.transforms.append([collada.DaeSyntax.SCALE, scales ])

# Get the instance
type = bNode.getType()
instance = None
meshID = None
if type == 'Mesh':
dougsMethod = 1
if dougsMethod:
#Doug: modified to wrap geometry in a library node and instance the library node instead
#of the geometry, so repetitive (component) geometry displays properly
instance_g = None
instance_g = collada.DaeGeometryInstance()
daeGeometry = self.document.colladaDocument.geometriesLibrary.FindObject(bNode.getData(True))
meshNode = MeshNode(self.document)
if daeGeometry is None:
daeGeometry = meshNode.SaveToDae(bNode.getData())
meshID = daeGeometry.id
bindMaterials = meshNode.GetBindMaterials(bNode.getData(), daeGeometry.uvTextures)
instance_g.object = daeGeometry
instance_g.bindMaterials = bindMaterials
#instance the geometry from a library node
daeLibNode = self.document.colladaDocument.nodesLibrary.FindObject(daeGeometry.id+'-ln') #generic search for .id
libNode = LibnodeNode(self.document)
if daeLibNode is None:
daeLibNode = libNode.SaveToDae(daeGeometry) #should return a class DaeNode
daeLibNode.iGeometries.append(instance_g)
#now instance the library node from the scene node (instead of instancing the geometry directly)
instance = collada.DaeNodeInstance()
instance.object = daeLibNode
daeNode.iNodes.append(instance)

else:
#original code
instance = collada.DaeGeometryInstance()
daeGeometry = self.document.colladaDocument.geometriesLibrary.FindObject(bNode.getData(True))
meshNode = MeshNode(self.document)
if daeGeometry is None:
daeGeometry = meshNode.SaveToDae(bNode.getData())
meshID = daeGeometry.id
bindMaterials = meshNode.GetBindMaterials(bNode.getData(), daeGeometry.uvTextures)
instance.object = daeGeometry
instance.bindMaterials = bindMaterials
daeNode.iGeometries.append(instance)

elif type == 'Camera':
instance = collada.DaeCameraInstance()
daeCamera = self.document.colladaDocument.camerasLibrary.FindObject(bNode.getData(True))
if daeCamera is None:
cameraNode = CameraNode(self.document)
daeCamera = cameraNode.SaveToDae(bNode.getData())
instance.object = daeCamera
daeNode.iCameras.append(instance)
elif type == 'Lamp':
instance = collada.DaeLightInstance()
daeLight = self.document.colladaDocument.lightsLibrary.FindObject(bNode.getData(True))
if daeLight is None:
lampNode = LampNode(self.document)
daeLight = lampNode.SaveToDae(bNode.getData())
instance.object = daeLight
daeNode.iLights.append(instance)

if not exportSelection:
myChildNodes = []
if childNodes.has_key(bNode.name):
myChildNodes = childNodes[bNode.name]

for bNode in myChildNodes:
sceneNode = SceneNode(self.document, self)
daeNode.nodes.append(sceneNode.SaveToDae(bNode,childNodes)[0])

daePhysicsInstance = self.SavePhysicsToDae(bNode, meshID, daeNode)

return (daeNode, daePhysicsInstance)

def SavePhysicsToDae(self, bNode, meshID, daeNode):
global usePhysics, exportPhysics
if meshID is None or (not(usePhysics is None) and not usePhysics or not exportPhysics):
return None

# Check if physics is supported.
if usePhysics is None:
usePhysics = hasattr(bNode, "rbShapeBoundType")
if not usePhysics:
return None

rbFlags = [0 for a in range(16)]
rbF = bNode.rbFlags
lastIndex = 0;
# Get the bit flags
while rbF > 0:
val = rbF >> 1
if val << 1 == rbF:
#rbFlags.append(0)
rbFlags[lastIndex] = 0
else:
#rbFlags.append(1)
rbFlags[lastIndex] = 1
lastIndex += 1
rbF = val

daePhysicsModel = collada.DaePhysicsModel();
daePhysicsModel.id = daePhysicsModel.name = self.document.CreateID(daeNode.id,'-PhysicsModel')
daeRigidBody = collada.DaeRigidBody();
daeRigidBody.id = daeRigidBody.name = self.document.CreateID(daeNode.id,'-RigidBody')
daeRigidBodyTechniqueCommon = collada.DaeRigidBody.DaeTechniqueCommon()
daeRigidBodyTechniqueCommon.dynamic = bool(rbFlags[0])
daeRigidBodyTechniqueCommon.mass = bNode.rbMass
# check the shape of the rigid body.
if bNode.rbShapeBoundType == 0: # Box
shape = collada.DaeBoxShape()
shape.halfExtents = list(bNode.rbHalfExtents)
elif bNode.rbShapeBoundType == 1: # Sphere
shape = collada.DaeSphereShape()
shape.radius = bNode.rbRadius
elif bNode.rbShapeBoundType == 2: # Cylinder
shape = collada.DaeCylinderShape()
shape.radius = [[bNode.rbRadius],[bNode.rbRadius]]
shape.height = bNode.rbHalfExtents[2]
elif bNode.rbShapeBoundType == 3: # Cone
shape = collada.DaeTaperedCylinderShape()
shape.radius1 = [[bNode.rbRadius],[bNode.rbRadius]]
shape.radius2 = [0 , 0]
shape.height = bNode.rbHalfExtents[2]
else: # Convex hull or # Static Triangle Mesh
shape = collada.DaeGeometryShape()
iGeometry = collada.DaeGeometryInstance()
if bNode.rbShapeBoundType == 5:
object = self.document.colladaDocument.geometriesLibrary.FindObject(daeNode.id+'-Convex')
else:
object = self.document.colladaDocument.geometriesLibrary.FindObject(meshID)
if object is None:
object = collada.DaeGeometry()
object.id = object.name = self.document.CreateID(daeNode.id,'-ConvexGeom')
convexMesh = collada.DaeConvexMesh()
convexMesh.convexHullOf = meshID
object.data = convexMesh
self.document.colladaDocument.geometriesLibrary.AddItem(object)
iGeometry.object = object
shape.iGeometry = iGeometry

# Create a physics material.
daePhysicsMaterial = self.document.colladaDocument.physicsMaterialsLibrary.FindObject(daeNode.id+'-PxMaterial')
if daePhysicsMaterial is None:
daePhysicsMaterial = collada.DaePhysicsMaterial()
##daePhysicsMaterial.restitution = bNode.rbRestitution
##daePhysicsMaterial.staticFriction = bNode.rbFriction
daePhysicsMaterial.id = daePhysicsMaterial.name = self.document.CreateID(daeNode.id, '-PhysicsMaterial')
self.document.colladaDocument.physicsMaterialsLibrary.AddItem(daePhysicsMaterial)

# Create a physics material instance.
daePhysicsMaterialInstance = collada.DaePhysicsMaterialInstance()
# Set the physics material of this instance
daePhysicsMaterialInstance.object = daePhysicsMaterial


# add the shape to the commom technique.
daeRigidBodyTechniqueCommon.shapes.append(shape)
# Set the material of the common technique.
daeRigidBodyTechniqueCommon.iPhysicsMaterial = daePhysicsMaterialInstance
# Set the common technique of this rigid body.
daeRigidBody.techniqueCommon = daeRigidBodyTechniqueCommon

# Add the rigid body to the physics model.
daePhysicsModel.rigidBodies.append(daeRigidBody)
# Create a new RigidBody instance
daeRigidBodyInstance = collada.DaeRigidBodyInstance()
# Set the rigid body of this instance
daeRigidBodyInstance.body = daeRigidBody
# Set the node of this instance
daeRigidBodyInstance.target = daeNode

# Create a new Physics Model Instance.
daePhysicsModelInstance = collada.DaePhysicsModelInstance()
# Set the Physics Model of this instance.
daePhysicsModelInstance.object = daePhysicsModel
# add the rigidbody instance to this physics model instance.
daePhysicsModelInstance.iRigidBodies.append(daeRigidBodyInstance)
# add the physics model to the library.
self.document.colladaDocument.physicsModelsLibrary.items.append(daePhysicsModel)
return daePhysicsModelInstance

class MeshNode(object):
def __init__(self,document):
self.document = document
self.materials = []

def FindMaterial(self, bMaterials,name):
for i in range(len(bMaterials)):
if bMaterials[i].name == name:
return i
return -1

def LoadFromDae(self, daeGeometry):
global replaceNames
meshID = daeGeometry.id
meshName = daeGeometry.name

# Create a new meshObject
bMesh2 = Blender.NMesh.New(self.document.CreateNameForObject(meshID,replaceNames,'mesh'))

if isinstance(daeGeometry.data,collada.DaeMesh): # check if it's a mesh
materials = []
for matName, material in self.materials.iteritems():
materials.append(material)
bMesh2.materials = materials

faces = []

daeMesh = daeGeometry.data
daeVertices = daeMesh.vertices

# Get all the sources
sources = dict()
for source in daeMesh.sources:
sources[source.id] = source.vectors

# Get the Position Input
vPosInput = daeVertices.FindInput('POSITION')

# Get the Normal Input
vNorInput = daeVertices.FindInput('NORMAL')


# Keep track of the Blender Vertices
pVertices = []

self.document.ProgressPart(0.0,'Create Vertices')



# Create all the vertices.
for i in sources[vPosInput.source]:
vPosVector = Vector(i[0], i[1], i[2]) * self.document.tMat
pVertices.append(Blender.NMesh.Vert(vPosVector.x, vPosVector.y, vPosVector.z))
bMesh2.verts = pVertices

faceVerts = [] # The list of vertices for each face to add
edgeVerts = [] # The list of vertices for each edge to add

# Now create the primitives
self.document.ProgressPart(0.5,'Create Primitives')
daePrimitives = daeMesh.primitives
for primitive in daePrimitives:
# Get the UV Input
vUvInput = primitive.FindInput('TEXCOORD')
uvs = []
if not (vUvInput is None):
for i in sources[vUvInput.source]:
vUvVector = Vector(i[0],i[1])
uvs.append(vUvVector)
inputs = primitive.inputs
maxOffset = primitive.GetMaxOffset()+1 # The number of values for one vertice
vertCount = 0 # The number of vertices for one primitive
realVertCount = 0 # The number of vertices for one primitive
plist = [] # The list with all primitives
if isinstance(primitive, collada.DaePolygons): # Polygons
plist = primitive.polygons
vertCount = 4
elif isinstance(primitive, collada.DaeTriangles): # Triangles
plist.append(primitive.triangles)
vertCount = 3
elif isinstance(primitive, collada.DaeLines): # Lines
plist.append(primitive.lines)
vertCount = 2
realVertCount = vertCount
# Loop through each P (primitive)
for p in plist:
if vertCount == 4:
realVertCount = len(p)/maxOffset
pIndex = 0
# A list with edges in this face
faceEdges = []
# a list to store all the created faces in to add them to the mesh afterwards.
allFaceVerts = []
# loop through all the values in this 'p'
while pIndex < len(p):
# Keep track of the verts in this face
curFaceVerts2 = []
uvList = []
# for every vertice for this primitive
for i in range(realVertCount):
# Check all the inputs and do the right thing
for input in inputs:
inputVal = p[pIndex+(i*maxOffset)+input.offset]
if input.semantic == "VERTEX":
vert2 = pVertices[inputVal]
curFaceVerts2.append(vert2)
elif input.semantic == "TEXCOORD":
uvList.append((uvs[inputVal][0],uvs[inputVal][1]))
elif input.semantic == "NORMAL":
pass
if vertCount > 2:
faceCount = 1 + (realVertCount-4) / 2 + (realVertCount-4) % 2
firstIndex = 2
lastIndex = 1
for a in range(faceCount):
newFirstIndex = (firstIndex + 1) % realVertCount
newLastIndex = (lastIndex -1) % realVertCount
fuv = []
if newFirstIndex != newLastIndex:
fv = [curFaceVerts2[firstIndex]] + [curFaceVerts2[newFirstIndex]] + [curFaceVerts2[newLastIndex]] + [curFaceVerts2[lastIndex]]
if len(uvList) == realVertCount:
fuv = [uvList[firstIndex]] + [uvList[newFirstIndex]] + [uvList[newLastIndex]] + [uvList[lastIndex]]
else:
fv = [curFaceVerts2[firstIndex]] + [curFaceVerts2[newFirstIndex]] + [curFaceVerts2[lastIndex]]
if len(uvList) == realVertCount:
fuv = [uvList[firstIndex]] + [uvList[newFirstIndex]] + [uvList[lastIndex]]
firstIndex = newFirstIndex
lastIndex = newLastIndex
# Create a new Face.
newFace = Blender.NMesh.Face(fv)
# Set the UV Coordinates
newFace.uv = fuv
# Add the new face to the list
faces.append(newFace)
# Add the material to this face
if primitive.material != '':
# Find the material index.
matIndex = self.FindMaterial(bMesh2.materials, self.materials[primitive.material].name)
# Set the material index for the new face.
newFace.materialIndex = matIndex
textures = self.materials[primitive.material].getTextures()
if len(textures) > 0 and not (textures[0] is None):
texture = textures[0]
image = texture.tex.getImage()
if not image is None:
newFace.image = image
else:
bMesh2.addEdge(curFaceVerts2[0], curFaceVerts2[1])
# update the index
pIndex += realVertCount * maxOffset
bMesh2.faces = faces
return bMesh2

def SaveToDae(self, bMesh):
global useTriangles, usePolygons, useUV

useNormal = 0
#me = bMesh #Mesh.Get("Mesh")
faces = bMesh.faces
for f in faces:
if f.smooth:
useNormal = 1
#print 'bMesh.mode=',bMesh.mode,' Modes.Autosmooth=',Blender.Mesh.Modes.AUTOSMOOTH
#print 'useNormalface=',useNormal,' mesh.mode&Authosmooth=',(bMesh.mode & Blender.Mesh.Modes.AUTOSMOOTH)
useNormal = useNormal or (bMesh.mode & Blender.Mesh.Modes.AUTOSMOOTH)
#print 'useNormal=',useNormal

uvTextures = dict()

daeGeometry = collada.DaeGeometry()
daeGeometry.id = daeGeometry.name = self.document.CreateID(bMesh.name,'-Geometry')

daeMesh = collada.DaeMesh()

# Keep track of the edges in faces
faceEdges = []

#Position
daeSource = collada.DaeSource()
daeSource.id = self.document.CreateID(daeGeometry.id,'-Position')
daeFloatArray = collada.DaeFloatArray()
daeFloatArray.id = self.document.CreateID(daeSource.id,'-array')
daeSource.source = daeFloatArray
daeSource.techniqueCommon = collada.DaeSource.DaeTechniqueCommon()
accessor = collada.DaeAccessor()
daeSource.techniqueCommon.accessor = accessor
accessor.source = daeFloatArray.id
accessor.count = len(bMesh.verts)
accessor.AddParam('X','float')
accessor.AddParam('Y','float')
accessor.AddParam('Z','float')

#Normals
if useNormal:
daeSourceNormals = collada.DaeSource()
daeSourceNormals.id = self.document.CreateID(daeGeometry.id,'-Normals')
daeFloatArrayNormals = collada.DaeFloatArray()
daeFloatArrayNormals.id = self.document.CreateID(daeSourceNormals.id,'-array')
daeSourceNormals.source = daeFloatArrayNormals
daeSourceNormals.techniqueCommon = collada.DaeSource.DaeTechniqueCommon()
accessorNormals = collada.DaeAccessor()
daeSourceNormals.techniqueCommon.accessor = accessorNormals
accessorNormals.source = daeFloatArrayNormals.id
accessorNormals.count = len(bMesh.verts)
accessorNormals.AddParam('X','float')
accessorNormals.AddParam('Y','float')
accessorNormals.AddParam('Z','float')

#UV
daeSourceTextures = collada.DaeSource()
daeSourceTextures.id = self.document.CreateID(daeGeometry.id , '-UV')
daeFloatArrayTextures = collada.DaeFloatArray()
daeFloatArrayTextures.id = self.document.CreateID(daeSourceTextures.id,'-array')
daeSourceTextures.source = daeFloatArrayTextures
daeSourceTextures.techniqueCommon = collada.DaeSource.DaeTechniqueCommon()
accessorTextures = collada.DaeAccessor()
daeSourceTextures.techniqueCommon.accessor = accessorTextures
accessorTextures.source = daeFloatArrayTextures.id
accessorTextures.AddParam('S','float')
accessorTextures.AddParam('T','float');


#Vertex
daeVertices = collada.DaeVertices()
daeVertices.id = self.document.CreateID(daeGeometry.id,'-Vertex')
daeInput = collada.DaeInput()
#--position
daeInput.semantic = 'POSITION'
daeInput.source = daeSource.id
daeVertices.inputs.append(daeInput)
#--normal
if useNormal:
daeInputNormals = collada.DaeInput()
daeInputNormals.semantic = 'NORMAL'
daeInputNormals.source = daeSourceNormals.id
daeVertices.inputs.append(daeInputNormals)
daeMesh.vertices = daeVertices

for vert in bMesh.verts:
for co in vert.co:
daeFloatArray.data.append(co)
if useNormal:
for no in vert.no:
daeFloatArrayNormals.data.append(no)


daePolygonsDict = dict()
daeTrianglesDict = dict()
daeLines = None

mesh = Blender.Mesh.Get(bMesh.name);

# Loop trough all the faces
for face in mesh.faces:
matIndex = -1
if not useUV and bMesh.materials and len(bMesh.materials) > 0:
matIndex = face.mat
elif mesh.faceUV and (useUV or bMesh.materials is None or len(bMesh.materials) == 0):
if not face.image is None:
matIndex = face.image.name
elif bMesh.materials and len(bMesh.materials) > 0:
#C
matIndex = face.mat

vertCount = len(face.verts)

# Create a new function which adds vertices to a list.
def AddVerts(verts,uvs,prlist):
prevVert = None
lastVert = verts[-1]

for v_index in range(len(verts)):
# Get the vertice
vert = verts[v_index]
# Add the vertice to the end of the list.
prlist.append(vert.index)
# If the mesh has UV-coords, add these to the textures array.
if mesh.faceUV:
##daeFloatArrayTextures.data.append(face.uv[v_index][0])
##daeFloatArrayTextures.data.append(face.uv[v_index][1])
daeFloatArrayTextures.data.append(uvs[v_index][0])
daeFloatArrayTextures.data.append(uvs[v_index][1])
prlist.append(len(daeFloatArrayTextures.data)/2-1)
accessorTextures.count = accessorTextures.count + 1
# Add the edge to the faceEdges list.
if prevVert != None:
faceEdges.append(mesh.findEdges(prevVert, vert))
else:
faceEdges.append(mesh.findEdges([(vert, lastVert)]))
# Update the prevVert vertice.
prevVert = vert

#for googleEarth the following triangulation needs to be generalized I think.
#Q. are all faces quads or triangles? What happens to the ones that aren't
if (vertCount == 3 and not usePolygons) or (useTriangles and vertCount == 4): # triangle
# Iff a Triangle Item for the current material not exists, create one.
daeTrianglesDict.setdefault(matIndex, collada.DaeTriangles())

if vertCount == 3:
#so far the triangles seem to display correctly
# Add al the vertices to the triangle list.
##AddVerts(face.verts,daeTrianglesDict[matIndex].triangles)
uvs = []
if mesh.faceUV:
uvs = face.uv[:]
AddVerts(face.verts,uvs,daeTrianglesDict[matIndex].triangles)
# Update the vertice count for the trianglelist.
daeTrianglesDict[matIndex].count += 1
else: # Convert quad polygon to triangles
#there is something in blender scripts mesh.quadToTriangle()
#it looks like first you have to select the quads to convert
#the following code seems to convert a quad to 2 triangles, but
#does nothing with the uvs ... that might be the problem.
verts1 = face.verts[:3] #0,1,2
verts2 = face.verts[2:] + tuple([face.verts[0]]) #2,3,0
#next 3 lines added mar22_08
uvs1 = []
uvs2 = []
if mesh.faceUV:
uvs1 = face.uv[:3]
uvs2 = face.uv[2:] + tuple([face.uv[0]])
# Add al the vertices to the triangle list.
##AddVerts(verts1,daeTrianglesDict[matIndex].triangles)
##AddVerts(verts2, daeTrianglesDict[matIndex].triangles)
AddVerts(verts1,uvs1,daeTrianglesDict[matIndex].triangles)
AddVerts(verts2,uvs2,daeTrianglesDict[matIndex].triangles)
# Update the vertice count for the trianglelist.
daeTrianglesDict[matIndex].count += 2
else: # polygon but googleEarth doesn't seem to like polygons - never displays
# Iff a Polygon Item for the current material not exists, create one.
daePolygonsDict.setdefault(matIndex, collada.DaePolygons())
# for each polygon, create a new P element
pverts = []
# Add al the vertices to the pverts list.
AddVerts(face.verts,pverts)
# Add the pverts list to the polygons list.
daePolygonsDict[matIndex].polygons.append(pverts)
# Update the vertice count for the polygonlist.
daePolygonsDict[matIndex].count += 1
if mesh.faceUV:
if not face.image is None:
if not face.image.name in uvTextures:
uvTextures[face.image.name] = self.document.CreateID(face.image.name, "-Material")
# Loop through all the edges
for edge in mesh.edges:
if not edge.index in faceEdges:
if daeLines == None: daeLines = collada.DaeLines()
daeLines.count += 1
daeLines.lines.append(edge.v1.index)
daeLines.lines.append(edge.v2.index)

daeInput = collada.DaeInput()
daeInput.semantic = 'VERTEX'
daeInput.offset = 0
daeInput.source = daeVertices.id

daeInputUV = collada.DaeInput()
daeInputUV.semantic = 'TEXCOORD'
daeInputUV.offset = 1
daeInputUV.source = daeSourceTextures.id

materialName = ''

for k, daeTriangles in daeTrianglesDict.iteritems():
if k != -1:
if not useUV and not bMesh.materials is None and len(bMesh.materials) > 0 and k >= 0:
daeTriangles.material = bMesh.materials[k].name
elif mesh.faceUV and (useUV or bMesh.materials is None or len(bMesh.materials) == 0):
daeTriangles.material = uvTextures[k]
elif bMesh.materials and len(bMesh.materials) > 0 and k >= 0:
daeTriangles.material = bMesh.materials[k].name
daeTriangles.inputs.append(daeInput)
if mesh.faceUV:
daeTriangles.inputs.append(daeInputUV)
daeMesh.primitives.append(daeTriangles)

for k, daePolygons in daePolygonsDict.iteritems():
if k != -1:
if not useUV and not bMesh.materials is None and len(bMesh.materials) > 0 and k >= 0:
daePolygons.material = bMesh.materials[k].name
elif mesh.faceUV and (useUV or bMesh.materials is None or len(bMesh.materials) == 0):
daePolygons.material = uvTextures[k]
daePolygons.inputs.append(daeInput)
if mesh.faceUV:
daePolygons.inputs.append(daeInputUV)
daeMesh.primitives.append(daePolygons)

if daeLines != None:
daeLines.inputs.append(daeInput)
daeMesh.primitives.append(daeLines)

daeMesh.sources.append(daeSource)
if useNormal:
daeMesh.sources.append(daeSourceNormals)
if mesh.faceUV:
daeMesh.sources.append(daeSourceTextures)

daeGeometry.data = daeMesh

self.document.colladaDocument.geometriesLibrary.AddItem(daeGeometry)
daeGeometry.uvTextures = uvTextures
return daeGeometry

def GetBindMaterials(self, bMesh, uvTextures):
global useUV

bindMaterials = []
mesh = Blender.Mesh.Get(bMesh.name);
# now check the materials
## print 'bmesh.name=',bMesh.name, ' useUV=',useUV
## print ' bMesh.materials=',bMesh.materials
## print 'lenbMeshMat=',len(bMesh.materials)

if (not useUV) and bMesh.materials and len(bMesh.materials) > 0:
## print 'Section A'
daeBindMaterial = collada.DaeFxBindMaterial()
for bMaterial in bMesh.materials:
instance = collada.DaeFxMaterialInstance()
daeMaterial = self.document.colladaDocument.materialsLibrary.FindObject(bMaterial.name)
if daeMaterial is None:
materialNode = MaterialNode(self.document)
daeMaterial = materialNode.SaveToDae(bMaterial)
instance.object = daeMaterial
daeBindMaterial.techniqueCommon.iMaterials.append(instance)
# now we have to add this bindmaterial to the intance of this geometry
bindMaterials.append(daeBindMaterial)
elif mesh.faceUV and (useUV or bMesh.materials is None or len(bMesh.materials) == 0):
## print 'Section B'
daeBindMaterial = collada.DaeFxBindMaterial()
for imageName, imageNameUnique in uvTextures.iteritems():
image = Blender.Image.Get(imageName)
instance = collada.DaeFxMaterialInstance()
daeMaterial = self.document.colladaDocument.materialsLibrary.FindObject(imageNameUnique)
if daeMaterial is None:
textureNode = TextureNode(self.document)
daeMaterial = textureNode.SaveToDae(image)
daeMaterial.id = daeMaterial.name = imageNameUnique
instance.object = daeMaterial
daeBindMaterial.techniqueCommon.iMaterials.append(instance)
# now we have to add this bindmaterial to the intance of this geometry
bindMaterials.append(daeBindMaterial)
elif bMesh.materials and len(bMesh.materials) > 0:
## print 'Section C - same as section A'
daeBindMaterial = collada.DaeFxBindMaterial()
for bMaterial in bMesh.materials:
instance = collada.DaeFxMaterialInstance()
daeMaterial = self.document.colladaDocument.materialsLibrary.FindObject(bMaterial.name)
if daeMaterial is None:
materialNode = MaterialNode(self.document)
daeMaterial = materialNode.SaveToDae(bMaterial)
instance.object = daeMaterial
daeBindMaterial.techniqueCommon.iMaterials.append(instance)
# now we have to add this bindmaterial to the intance of this geometry
bindMaterials.append(daeBindMaterial)

return bindMaterials

class TextureNode(object):
def __init__(self, document):
self.document = document

def LoadFromDae(self, daeImage):
imageID = daeImage.id
imageName = daeImage.name

bTexture = Blender.Texture.New(imageID)

filename = ''
if Blender.sys.exists(daeImage.initFrom):
filename = daeImage.initFrom
elif Blender.sys.exists(self.document.filePath + daeImage.initFrom):
filename = self.document.filePath + daeImage.initFrom


if filename <> '':
bTexture.setType('Image')
img = Blender.Image.Load(filename)
bTexture.setImage(img)
else:
print 'image not found: %s'%(daeImage.initFrom)

return bTexture

def SaveToDae(self, bImage):
daeMaterial = collada.DaeFxMaterial()
##daeMaterial.id = daeMaterial.name = self.document.CreateID(bImage.name, '-Material')
self.document.colladaDocument.materialsLibrary.AddItem(daeMaterial)

instance = collada.DaeFxEffectInstance()
daeEffect = self.document.colladaDocument.effectsLibrary.FindObject(bImage.name+'-fx')

if daeEffect is None:
daeEffect = collada.DaeFxEffect()
daeEffect.id = daeEffect.name = self.document.CreateID(bImage.name , '-fx')

shader = collada.DaeFxShadeLambert()
daeImage = self.document.colladaDocument.imagesLibrary.FindObject(bImage.name)
if daeImage is None: # Create the image
daeImage = collada.DaeImage()
daeImage.id = daeImage.name = self.document.CreateID(bImage.name,'-image')
daeImage.initFrom = Blender.sys.expandpath(bImage.filename)
if useRelativePaths:
daeImage.initFrom = CreateRelativePath(filename, daeImage.initFrom)
self.document.colladaDocument.imagesLibrary.AddItem(daeImage)
daeTexture = collada.DaeFxTexture()
daeTexture.texture = daeImage.id
shader.AddValue(collada.DaeFxSyntax.DIFFUSE, daeTexture)

daeEffect.AddShader(shader)
#Doug: added Mar3008 next 3 lines
#if (meshNode.mode & Blender.Mesh.Modes.DOUBLESIDED):
if 1:
daeEffect.AddDoubleSided(1)

self.document.colladaDocument.effectsLibrary.AddItem(daeEffect)
instance.object = daeEffect

daeMaterial.iEffects.append(instance)

return daeMaterial

class MaterialNode(object):
def __init__(self, document):
self.document = document

def LoadFromDae(self, daeMaterial):
materialID = daeMaterial.id
materialName = daeMaterial.name

bMat = Blender.Material.New(materialID)
for i in daeMaterial.iEffects:
daeEffect = self.document.colladaDocument.effectsLibrary.FindObject(i.url)
shader = daeEffect.profileCommon.technique.shader
if shader.transparent:
tcol = shader.transparent.color.rgba
tkey = 1
if shader.transparency:
tkey = shader.transparency.float
alpha = 1 - tkey * (tcol[0]*0.21 + tcol[1]*0.71 + tcol[2]*0.08)
bMat.setAlpha(alpha)
elif shader.transparency:
alpha = 1 - shader.transparency.float
if shader.reflective:
color = shader.reflective.color.rgba
bMat.setMirCol(color[0], color[1], color[2])
if shader.reflectivity:
bMat.setRef(shader.reflectivity.float)

if isinstance(shader,collada.DaeFxShadeLambert) or isinstance(shader, collada.DaeFxShadeBlinn) or isinstance(shader, collada.DaeFxShadePhong):
bMat.setDiffuseShader(Blender.Material.Shaders.DIFFUSE_LAMBERT)
if shader.diffuse:
##print shader.diffuse.color.rgba, shader.diffuse.color
if not (shader.diffuse.color is None):
color = shader.diffuse.color.rgba
bMat.setRGBCol(color[0],color[1], color[2])
if not (shader.diffuse.texture is None): # Texture
texture = shader.diffuse.texture.texture
if not (texture is None):
bTexture = self.document.texturesLibrary.FindObject(texture, True)
if not bTexture is None:
bMat.setTexture(0, bTexture, Blender.Texture.TexCo.UV)

bMat.setSpec(0)

if isinstance(shader, collada.DaeFxShadeBlinn) or isinstance(shader, collada.DaeFxShadePhong):
if not isinstance(shader, collada.DaeFxShadePhong):
bMat.setSpecShader(Blender.Material.Shaders.SPEC_BLINN)
if shader.indexOfRefraction:
shader.indexOfRefraction.float
bMat.setRefracIndex(shader.indexOfRefraction.float)
else:
bMat.setSpecShader(Blender.Material.Shaders.SPEC_PHONG)
if shader.specular:
specColor = shader.specular.color.rgba
bMat.setSpecCol(specColor[0], specColor[1], specColor[2])
bMat.setSpec(1)
if shader.shininess:
bMat.setHardness(int(shader.shininess.float) * 4)

return bMat

def SaveToDae(self, bMaterial):
global useRelativePaths, filename
daeMaterial = collada.DaeFxMaterial()
daeMaterial.id = daeMaterial.name = self.document.CreateID(bMaterial.name, '-Material')

instance = collada.DaeFxEffectInstance()
daeEffect = self.document.colladaDocument.effectsLibrary.FindObject(bMaterial.name+'-fx')
meshNode = MeshNode(self.document)
if daeEffect is None:
daeEffect = collada.DaeFxEffect()
daeEffect.id = daeEffect.name = self.document.CreateID(bMaterial.name , '-fx')
shader = None
if bMaterial.getSpec() > 0.0:
if bMaterial.getSpecShader() == Blender.Material.Shaders.SPEC_BLINN:
shader = collada.DaeFxShadeBlinn()
shader.AddValue(collada.DaeFxSyntax.INDEXOFREFRACTION, bMaterial.getRefracIndex())
else:
shader = collada.DaeFxShadePhong()
shader.AddValue(collada.DaeFxSyntax.SPECULAR, [col * bMaterial.getSpec() for col in bMaterial.getSpecCol()]+[1])
shader.AddValue(collada.DaeFxSyntax.SHININESS, bMaterial.getHardness() * 0.25)

else :
shader = collada.DaeFxShadeLambert()

# Check if a texture is used for color
textures = bMaterial.getTextures()
for mTex in textures:
# Check if this texture is mapped to Color
if not mTex is None and mTex.mapto == Blender.Texture.MapTo.COL:
texture = mTex.tex
if not texture.image is None and Blender.sys.exists(texture.image.filename):
daeImage = self.document.colladaDocument.imagesLibrary.FindObject(texture.name)
if daeImage is None: # Create the image
daeImage = collada.DaeImage()
daeImage.id = daeImage.name = self.document.CreateID(texture.name,'-image')
daeImage.initFrom = Blender.sys.expandpath(texture.image.filename)
if useRelativePaths:
daeImage.initFrom = CreateRelativePath(filename, daeImage.initFrom)
self.document.colladaDocument.imagesLibrary.AddItem(daeImage)
daeTexture = collada.DaeFxTexture()
daeTexture.texture = daeImage.id
shader.AddValue(collada.DaeFxSyntax.DIFFUSE, daeTexture)
break

shader.AddValue(collada.DaeFxSyntax.DIFFUSE,bMaterial.getRGBCol()+[1])
shader.AddValue(collada.DaeFxSyntax.TRANSPARENCY, 1 - bMaterial.alpha)
shader.AddValue(collada.DaeFxSyntax.TRANSPARENT, [1,1,1,1])
shader.AddValue(collada.DaeFxSyntax.EMISSION, [col * bMaterial.getEmit() for col in bMaterial.getRGBCol()] + [1])
shader.AddValue(collada.DaeFxSyntax.AMBIENT, [col * bMaterial.getAmb() for col in bMaterial.getRGBCol()] + [1])
shader.AddValue(collada.DaeFxSyntax.REFLECTIVE, bMaterial.getMirCol() + [1])
shader.AddValue(collada.DaeFxSyntax.REFLECTIVITY, bMaterial.getRef())
daeEffect.AddShader(shader)

#Doug: added Mar3008 next 3 lines
#if (meshNode.mode & Blender.Mesh.Modes.DOUBLESIDED):
if 1:
daeEffect.AddDoubleSided(1)

self.document.colladaDocument.effectsLibrary.AddItem(daeEffect)
instance.object = daeEffect

daeMaterial.iEffects.append(instance)

self.document.colladaDocument.materialsLibrary.AddItem(daeMaterial)
return daeMaterial

class CameraNode(object):
def __init__(self,document):
self.document = document

def LoadFromDae(self, daeCamera):
camID = daeCamera.id
camName = daeCamera.name
camType = 'persp'
clipStart = daeCamera.optics.techniqueCommon.znear
clipEnd = daeCamera.optics.techniqueCommon.zfar

if daeCamera.optics.techniqueCommon.GetType() == collada.DaeSyntax.ORTHOGRAPHIC:
camType = 'ortho'

camera = Blender.Camera.New(camType,camID)
camera.clipStart = clipStart
camera.clipEnd = clipEnd
return camera


def SaveToDae(self, bCamera):
daeCamera = collada.DaeCamera()
daeCamera.id = daeCamera.name = self.document.CreateID(bCamera.name,'-Camera')
daeOptics = collada.DaeOptics()
daeTechniqueCommon = None
if bCamera.type == 1: # orthographic
daeTechniqueCommon = collada.DaeOptics.DaeOrthoGraphic()
else: # perspective
daeTechniqueCommon = collada.DaeOptics.DaePerspective()
lens = bCamera.getLens( )
daeTechniqueCommon.yfov = 2 * ( math.atan( 16.0 / lens ) ) * radianToAngle

daeTechniqueCommon.znear = bCamera.clipStart
daeTechniqueCommon.zfar = bCamera.clipEnd

daeOptics.techniqueCommon = daeTechniqueCommon
daeCamera.optics = daeOptics

self.document.colladaDocument.camerasLibrary.AddItem(daeCamera)
return daeCamera

class LibnodeNode(object): #Doug added for <library_nodes>
def __init__(self,document):
self.document = document

def LoadFromDae(self, daeNode):
libnodeID = daeNode.id
libnodeName = daeNode.name

libnode = Blender.Object.New()
return libnode


def SaveToDae(self, libnode):
daeNode = collada.DaeNode()
## print 'in LibnodeNode.SaveToDae libnode.name=',libnode.name
daeNode.id = daeNode.name = self.document.CreateID(libnode.name,'-ln')
## print 'daeNode.id=',daeNode.id
daeTechniqueCommon = None
#Doug: somewhere here I do I need to copy something from libnode to daeNode?

self.document.colladaDocument.nodesLibrary.AddItem(daeNode)
return daeNode

class LampNode(object):
def __init__(self,document):
self.document = document

def LoadFromDae(self, daeLight):

lampID = daeLight.id
lampName = daeLight.name

# Create a new lampObject
lamp = Blender.Lamp.New('Sun',lampID)

if daeLight.techniqueCommon.GetType() == collada.DaeSyntax.DIRECTIONAL:
lamp.type = Blender.Lamp.Types.Sun
elif daeLight.techniqueCommon.GetType() == collada.DaeSyntax.POINT:
lamp.type = Blender.Lamp.Types.Lamp
# Get the attenuation
constAtt = daeLight.techniqueCommon.constantAttenuation
linAtt = daeLight.techniqueCommon.linearAttenuation
# set the attenuation
lamp.energy = 1-constAtt
if linAtt > 0.0:
lamp.dist = (lamp.energy/2)/ linAtt
else:
lamp.dist = 5000.0
elif daeLight.techniqueCommon.GetType() == collada.DaeSyntax.SPOT:
lamp.type = Blender.Lamp.Types.Spot
# Get the attenuation
constAtt = daeLight.techniqueCommon.constantAttenuation
linAtt = daeLight.techniqueCommon.linearAttenuation
# set the attenuation
lamp.energy = 1-constAtt
if linAtt > 0.0:
lamp.dist = (0.5 - constAtt)/ linAtt
else:
lamp.dist = 5000.0
lamp.spotSize = daeLight.techniqueCommon.falloffAngle
lamp.spotBlend = daeLight.techniqueCommon.falloffExponent
elif daeLight.techniqueCommon.GetType() == collada.DaeSyntax.AMBIENT:
lamp.type = Blender.Lamp.Types.Hemi


# Set the color
lamp.col = daeLight.techniqueCommon.color

return lamp

def SaveToDae(self, bLamp):
daeLight = collada.DaeLight()
daeLight.id = daeLight.name = self.document.CreateID(bLamp.name,'-Light')

daeTechniqueCommon = None
if bLamp.type == Blender.Lamp.Types.Hemi: # Ambient
daeTechniqueCommon = collada.DaeLight.DaeAmbient()
elif bLamp.type == Blender.Lamp.Types.Lamp: # Point light
daeTechniqueCommon = collada.DaeLight.DaePoint()
elif bLamp.type == Blender.Lamp.Types.Spot: # Spot
daeTechniqueCommon = collada.DaeLight.DaeSpot()
daeTechniqueCommon.constantAttenuation = 1-bLamp.energy
daeTechniqueCommon.linearAttenuation = (0.5 - daeTechniqueCommon.constantAttenuation)/bLamp.dist
elif bLamp.type == Blender.Lamp.Types.Sun: # Directional
daeTechniqueCommon = collada.DaeLight.DaeDirectional()
else: # area
daeTechniqueCommon = collada.DaeOptics.TechniqueCommon()

daeTechniqueCommon.color = bLamp.col
daeLight.techniqueCommon = daeTechniqueCommon

self.document.colladaDocument.lightsLibrary.AddItem(daeLight)
return daeLight

class Library(object):
def __init__(self, document):
self.objects = dict()
self.document = document
self.daeLibrary = None

def SetDaeLibrary(self, daeLibrary):
self.daeLibrary = daeLibrary

def FindObject(self, daeInstance, fromDae):
for k in self.objects:

if 'url' in dir(daeInstance) and k == daeInstance.url:
return self.objects[k][0]
elif 'target' in dir(daeInstance) and k == daeInstance.target:
return self.objects[k][0]
if fromDae:
# dataObject not in library, so add it
return self.LoadFromDae(daeInstance)
else:
return self.SaveToDae(daeIntance)

def FindObjectEx(self, bObject):
for k in self.objects:
if k == id:
return self.objects[k][0]

return self.SaveToDae(bObject)


def LoadFromDae(self, daeInstance):
Debug.Debug('Library: Please override this method','WARNING')

def SaveToDae(self, bScene):
Debug.Debug('Library: Please override this method','WARNING')

class ScenesLibrary(Library):

def LoadFromDae(self, daeInstance):
daeVisualScene = self.daeLibrary.FindObject(daeInstance.url)
# TODO: implement multiple scenes
return None

def SaveToDae(self, id):
pass
#print bScene

class CamerasLibrary(Library):

def LoadFromDae(self, daeInstance):
daeCamera = self.daeLibrary.FindObject(daeInstance.url)
if daeCamera is None:
Debug.Debug('CamerasLibrary: Object with this ID does not exist','ERROR')
return

camID = daeCamera.id
camName = daeCamera.name

cameraNode = CameraNode(self.document)
camera = cameraNode.LoadFromDae(daeCamera)

self.objects[camID] = [camera,camera.name]
return camera

def SaveToDae(self, id):
pass

class LampsLibrary(Library):

def LoadFromDae(self, daeInstance):
daeLight = self.daeLibrary.FindObject(daeInstance.url)
if daeLight is None:
Debug.Debug('LightsLibrary: Object with this ID does not exist','ERROR')
return
lampID = daeLight.id
lampName = daeLight.name

lampNode = LampNode(self.document)
lamp = lampNode.LoadFromDae(daeLight)

self.objects[lampID] = [lamp,lamp.name]
return lamp

def SaveToDae(self, id):
pass

class MeshLibrary(Library):

def LoadFromDae(self, daeInstance):
daeGeometry = self.daeLibrary.FindObject(daeInstance.url)
if daeGeometry is None:
Debug.Debug('MeshLibrary: Object with this ID does not exist','ERROR')
return
meshID = daeGeometry.id
meshName = daeGeometry.name

meshNode = MeshNode(self.document)

# Get the materials ( only get the first one right now)
bMaterials = daeInstance.bindMaterials
meshNode.materials = dict()
if bMaterials:
for bMaterial in bMaterials:
for iMaterial in bMaterial.techniqueCommon.iMaterials:
Material = self.document.materialsLibrary.FindObject(iMaterial,True)
meshNode.materials[iMaterial.target] = Material
##print 'Mat:',Material
##print meshNode.materials
## bMaterial = bMaterials[0]
## if bMaterial:
## iMaterials = bMaterial.techniqueCommon.iMaterials
## if iMaterials:
## if iMaterials[0]:
## meshNode.materials = [self.document.materialsLibrary.FindObject(iMaterials[0],True)]
##

bMesh = meshNode.LoadFromDae(daeGeometry)

# Add this mesh in this library, under it's real name
self.objects[meshID] = [bMesh,bMesh.name]
return bMesh

def SaveToDae(self, id):
pass

class NodesLibrary(Library): #Doug added this. Looks like its just a debug wrapper for import - dont need for export

def LoadFromDae(self, daeInstance):
daeLibNode = self.daeLibrary.FindObject(daeInstance.target)
if daeLibNode is None:
Debug.Debug('NodeLibrary: Object with this TARGET:%s does not exist'%(daeInstance.target),'ERROR')
return
nodeID = daeLibNode.id
nodeName = daeLibNode.name

libNodeNode = LibNodeNode(self.document)

bLibNode = libNodeNode.LoadFromDae(daeLibNode)

# Add this mesh in this library, under it's real name
self.objects[nodeID] = [bLibNode,bLibNode.name]
return bLibNode

def SaveToDae(self, id):
pass

class MaterialsLibrary(Library):

def LoadFromDae(self, daeInstance):
daeMaterial = self.daeLibrary.FindObject(daeInstance.target)
if daeMaterial is None:
Debug.Debug('MaterialLibrary: Object with this TARGET:%s does not exist'%(daeInstance.target),'ERROR')
return
materialID = daeMaterial.id
materialName = daeMaterial.name

materialNode = MaterialNode(self.document)

bMaterial = materialNode.LoadFromDae(daeMaterial)

# Add this mesh in this library, under it's real name
self.objects[materialID] = [bMaterial,bMaterial.name]
return bMaterial

def SaveToDae(self, id):
pass

class TexturesLibrary(Library):

def LoadFromDae(self, daeImage):
if daeImage is None:
Debug.Debug('TexturesLibrary: Object with this TARGET:%s does not exist'%(daeImage),'ERROR')
return
imageID = daeImage.id
imageName = daeImage.name

textureNode = TextureNode(self.document)
bTexture = textureNode.LoadFromDae(daeImage)
bTexture.setType('Image')

# Add this texture in this library, under it's real name
self.objects[imageID] = [bTexture,bTexture.name]
return bTexture

def SaveToDae(self, id):
pass
  1. # --------------------------------------------------------------------------
  2. # Illusoft Collada 1.4 plugin for Blender version 0.2.65
  3. # --------------------------------------------------------------------------
  4. # ***** BEGIN GPL LICENSE BLOCK *****
  5. #
  6. # Copyright (C) 2006: Illusoft - colladablender@illusoft.com
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 2 of the License,
  11. # or (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License
  19. # along with this program; if not, write to the Free Software Foundation,
  20. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  21. #
  22. # ***** END GPL LICENCE BLOCK *****
  23. # --------------------------------------------------------------------------
  24.  
  25. from cutils import *
  26. import collada
  27. import sys
  28. import Blender
  29. from Blender.Mathutils import *
  30. import math
  31. import datetime
  32.  
  33. class Translator(object):
  34.         isImporter = False
  35.        
  36.         def __init__(self, isImporter, version, debugM, fileName,_useTriangles, _usePolygons, _bakeMatrices, _exportSelection, _createNewScene, _clearScene, _lookAt, _exportPhysics, _exportCurrentScene, _exportRelativePaths, _useUV):
  37.                 global __version__, debugMode, usePhysics, useTriangles, usePolygons, bakeMatrices, exportSelection, createNewScene, clearScene, lookAt, replaceNames, exportPhysics, exportCurrentScene, useRelativePaths, useUV
  38.                 __version__ = version
  39.                 debugMode = debugM
  40.                 usePhysics = None
  41.                 useTriangles = _useTriangles
  42.                 usePolygons = _usePolygons
  43.                 bakeMatrices = _bakeMatrices
  44.                 exportSelection = _exportSelection
  45.                 createNewScene = _createNewScene
  46.                 clearScene = _clearScene
  47.                 lookAt = _lookAt
  48.                 exportPhysics = _exportPhysics
  49.                 exportCurrentScene = _exportCurrentScene
  50.                 useRelativePaths = _exportRelativePaths
  51.                 useUV = _useUV
  52.                
  53.                 replaceNames = clearScene
  54.                
  55.                 self.isImporter = isImporter
  56.                 self.fileName = ''
  57.                 if self.isImporter:
  58.                         self.__Import(fileName)
  59.                 else:
  60.                         self.__Export(fileName)
  61.        
  62.         def __Import(self,fileName=''):
  63.                 documentTranslator = DocumentTranslator(fileName)                        
  64.                 documentTranslator.Import(fileName)
  65.                
  66.         def __Export(self,filename=''):
  67.                 documentTranslator = DocumentTranslator(filename)
  68.                 documentTranslator.Export(filename)  
  69.                                
  70.                
  71. class DocumentTranslator(object):
  72.         isImport = None
  73.         ids = []
  74.         sceneGraph = None
  75.        
  76.         cameraLibrary = None
  77. ##        geometryLibrary = None
  78. ##        controllerLibrary = None
  79. ##        animationLibrary = None
  80. ##        materialLibrary = None
  81.         texturesLibrary = None
  82.         lampsLibrary = None
  83.         colladaDocument = None
  84.         scenesLibrary = None
  85.        
  86.         def CreateID(self, name, typeName=None):
  87.                 if not (name in self.ids):
  88.                         self.ids.append(name)
  89.                         return name
  90.                 else:
  91.                         tempName = name;
  92.                         if not(typeName is None) and name.rfind(typeName) >= 0:
  93.                                 # Check for existing number at the end?
  94.                                 return self.IncrementString(tempName)
  95.                         else:
  96.                                 return self.CreateID(tempName+typeName, typeName)
  97.        
  98.         def IncrementString(self, name):
  99.                 tempName = name;
  100.                 if name.rfind('.') >= 0:
  101.                         while tempName[-1:].isdigit():
  102.                                 tempName =      tempName[:-1]
  103.                         digitStr = name[-(len(name)-len(tempName)):]
  104.                         digit = 1
  105.                         if len(digitStr) > 0 and len(digitStr) != len(name):
  106.                                 digit = int(digitStr)+1
  107.                         return tempName+str(digit).zfill(3)
  108.                 else:
  109.                         return name+'.001'
  110.                                        
  111.         def __init__(self, fileName):
  112.                 self.isImport = False
  113.                 self.scenesLibrary = ScenesLibrary(self) #<library_visual_scenes> ?
  114.                 self.sceneGraph = SceneGraph(self)       #<scene>?       
  115.                 self.lampsLibrary = LampsLibrary(self)
  116.                 self.colladaDocument = None
  117.                 self.texturesLibrary = TexturesLibrary(self)
  118.                 self.camerasLibrary = CamerasLibrary(self)
  119.                 self.materialsLibrary = MaterialsLibrary(self)
  120.                 self.meshLibrary = MeshLibrary(self)     #<library_geometry?
  121.                 # Doug: I need something like the following so that repetitive
  122.                 # geometry displays correctly in GoogleEarth (GE):
  123.                 # my needs: slf.nodeLibrary = NoedeLibrary(self)
  124.                 #I misspelled so you can see this code has never been implemented
  125.                 # I get this approach from examining SketchUp output when
  126.                 # using their Component approach for repetitive geometry
  127.                 # I need to wrap each instance_geometry in a <node>
  128.                 # in the <library_nodes> section and
  129.                 #then instance_node in the library_visual_scenes
  130.                 #collada.py has a nodeslibrary
  131.                 self.nodesLibrary = NodesLibrary(self) #Doug added
  132.                
  133.                 self.filename = None
  134.                 self.filePath = ''
  135.                
  136.                
  137.                
  138.                
  139.                 self.currentBScene = Blender.Scene.getCurrent()
  140.                                
  141.                 self.progressCount = 0.4
  142.                 self.progressField = (1.0 - self.progressCount)
  143.                 self.progressStep = 0.0
  144.                 self.progressPartCount = 0.0
  145.                
  146.                 self.tMat = Matrix()
  147.        
  148.         def CreateNameForObject(self, name, replace, myType):
  149.                 if not replace:
  150.                         return name
  151.                
  152.                 if myType == 'object':
  153.                         try:
  154.                                 ob = Blender.Object.Get(name)
  155.                                 ob.name = self.CreateNameForObject(self.IncrementString(ob.name), True, 'object')
  156.                         except ValueError:
  157.                                 pass
  158.                 elif myType == 'mesh':                                   
  159.                         try:
  160.                                 mesh = Blender.Mesh.Get(name)
  161.                                 if not mesh is None:
  162.                                         mesh.name = self.CreateNameForObject(self.IncrementString(mesh.name), True, 'mesh')
  163.                         except ValueError:
  164.                                 pass
  165.                        
  166.                 return name
  167.                
  168.         def Import(self, fileName):
  169.                 global debugMode, createNewScene
  170.                
  171.                 self.filename = fileName
  172.                 self.filePath = Blender.sys.dirname(self.filename) + Blender.sys.sep
  173.                 self.isImport = True
  174.                 Blender.Window.EditMode(0)
  175.                 Blender.Window.DrawProgressBar(0.0, 'Starting Import')
  176.                
  177.                 if createNewScene:
  178.                         self.currentBScene = Blender.Scene.New('Scene')
  179.                         self.currentBScene.makeCurrent()
  180.                 else:
  181.                         self.currentBScene = Blender.Scene.getCurrent()
  182.                
  183.                 # Create a new Collada document
  184.                 Blender.Window.DrawProgressBar(0.1, 'Get Collada Document')
  185.                 self.colladaDocument = collada.DaeDocument(debugMode)
  186.                
  187.                 # Setup the libraries
  188.                 self.camerasLibrary.SetDaeLibrary(self.colladaDocument.camerasLibrary)
  189.                 self.lampsLibrary.SetDaeLibrary(self.colladaDocument.lightsLibrary)
  190.                 self.texturesLibrary.SetDaeLibrary(self.colladaDocument.imagesLibrary)
  191.                 self.materialsLibrary.SetDaeLibrary(self.colladaDocument.materialsLibrary)
  192.                 self.meshLibrary.SetDaeLibrary(self.colladaDocument.geometriesLibrary)
  193.                
  194.                 # Parse the COLLADA file
  195.                 self.colladaDocument.LoadDocumentFromFile(fileName)
  196.                
  197.                 if self.colladaDocument.asset.upAxis == collada.DaeSyntax.Y_UP:
  198.                         self.tMat[0][0] = 0
  199.                         self.tMat[1][1] = 0
  200.                         self.tMat[2][2] = 0
  201.                         self.tMat[0][1] = 1
  202.                         self.tMat[1][2] = 1
  203.                         self.tMat[2][0] = 1
  204.                        
  205.                 self.progressStep = self.progressField/(self.colladaDocument.GetItemCount()+1)
  206.                
  207.                 # Read the COLLADA stucture and build the scene in Blender.
  208.                 Blender.Window.DrawProgressBar(0.4, 'Translate Collada 2 Blender')
  209.                 self.sceneGraph.LoadFromCollada(self.colladaDocument.scene)
  210.                
  211.                 self.Progress()
  212.        
  213.         def Export(self, fileName):
  214.                 global __version__, filename
  215.                 filename = fileName
  216.                 self.ids = []
  217.                 self.isImport = False
  218.                 Blender.Window.EditMode(0)
  219.                
  220.                 # Create a new Collada document
  221.                 self.colladaDocument = collada.DaeDocument(debugMode)
  222.                 daeAsset = collada.DaeAsset()
  223.                 daeAsset.upAxis = 'Z_UP'
  224.                 daeAsset.created = datetime.datetime.today()
  225.                 daeAsset.modified = datetime.datetime.today()
  226.                 daeAsset.unit = collada.DaeUnit()
  227. ##              daeAsset.unit.name = 'centimeter'
  228. ##              daeAsset.unit.meter = '0.01'
  229.                 daeAsset.unit.name = 'meter'  #meter works better in googleEarth
  230.                 daeAsset.unit.meter = '1.0'
  231.                 daeContributor = collada.DaeContributor()
  232.                 daeContributor.author = 'Illusoft Collada 1.4.0 plugin for Blender - http://colladablender.illusoft.com'
  233.                 daeContributor.authoringTool = 'Blender v:%s - Illusoft Collada Exporter v:%s' % (Blender.Get('version'), __version__)           
  234.                 daeContributor.sourceData = GetValidFilename(Blender.Get('filename'))
  235.                 daeAsset.contributors.append(daeContributor)
  236.                
  237.                 self.colladaDocument.asset = daeAsset
  238.                
  239.                
  240.                 daeScene = collada.DaeScene()
  241.                
  242.                 # Loop throug all scenes
  243.                 for bScene in Blender.Scene.Get():
  244.                         if not exportCurrentScene or self.currentBScene == bScene:
  245.                                 daeInstanceVisualScene = collada.DaeVisualSceneInstance()
  246.                                 daeInstancePhysicsScene = collada.DaePhysicsSceneInstance()
  247.                                 daeVisualScene = self.colladaDocument.visualScenesLibrary.FindObject(bScene.name)
  248.                                 if daeVisualScene is None:
  249.                                         sceneGraph = SceneGraph(self)
  250.                                         scenesList = sceneGraph.SaveToDae(bScene)
  251.                                         daeVisualScene = scenesList[0]
  252.                                         if exportPhysics:
  253.                                                 daePhysicsScene = scenesList[1]
  254.                                    
  255.                                 daeInstanceVisualScene.object = daeVisualScene
  256.                                
  257.                                 #self.colladaDocument.visualScenesLibrary.AddItem(daeIntanceVisualScene)
  258.                                 daeScene.iVisualScenes.append(daeInstanceVisualScene)
  259.                                 if exportPhysics:
  260.                                         daeInstancePhysicsScene.object = daePhysicsScene
  261.                                         daeScene.iPhysicsScenes.append(daeInstancePhysicsScene)
  262.                                
  263.                                 #self.colladaDocument.visualScenesLibrary.AddItem(sceneGraph.ObjectToDae(bScene))
  264.                                 #daeScene = collada.DaeScene()
  265.                                 #daeScene.AddInstance()
  266.                
  267.                
  268.                 self.colladaDocument.scene = daeScene
  269.                
  270.                 self.colladaDocument.SaveDocumentToFile(fileName)
  271.                
  272.         def Progress(self):
  273.                 self.progressPartCount = 0.0
  274.                 self.progressCount += self.progressStep
  275.                 Blender.Window.DrawProgressBar(self.progressCount, 'Creating Blender Nodes...')
  276.                
  277.         def ProgressPart(self, val, text):
  278.                 self.progressPartCount += val
  279.                 Blender.Window.DrawProgressBar(self.progressCount+self.progressPartCount*self.progressStep,text)
  280.                        
  281. class SceneGraph(object):
  282.        
  283.         def __init__(self, document):
  284.                 self.document = document
  285.                 self.name = ''           
  286.                
  287.                 self.childNodes = dict()
  288.                 self.rootNodes = []
  289.                
  290.                 self.objectNames = dict()
  291.                 # Get the current blender scene
  292.                 #self.currentBScene = Blender.Scene.getCurrent()
  293.        
  294.         def LoadFromCollada(self, colladaScene):
  295.                 global debugMode, newScene, clearScene
  296.                
  297.                 # When in debugMode, delete everything from the scene before proceding
  298.                 if debugMode or clearScene:
  299.                         print "Delete everything from the scene.."
  300.                         bNodes = Blender.Object.Get()
  301.                        
  302.                         newScene = Blender.Scene.New("new Scene")
  303.                         newScene.makeCurrent()
  304.                         Blender.Scene.Unlink(self.document.currentBScene)
  305.                         self.document.currentBScene = newScene
  306.                        
  307.                 if colladaScene == None:
  308.                         return False
  309.                
  310.                 visualScenes = colladaScene.GetVisualScenes()
  311.                 if visualScenes is None:
  312.                         return           
  313.                 # For now, only pick the first available Visual Scene
  314.                 visualScene = visualScenes[0]
  315.                 if visualScene is None:
  316.                         return           
  317.                
  318.                 Blender.Window.DrawProgressBar(0.5,'Build the items on the scene')
  319.                 # loop trough all nodes            
  320.                 for daeNode in visualScene.nodes:
  321.                         sceneNode = SceneNode(self.document, self)
  322.                         ob = sceneNode.ObjectFromDae(daeNode)
  323.                         self.objectNames[daeNode.id] = ob.name
  324.                         ##sceneNode.ObjectFromDae(daeNode)
  325.                
  326.                 # Now get the physics Scene
  327.                 physicsScenes = colladaScene.GetPhysicsScenes()
  328.                 if not (physicsScenes is None) and len(physicsScenes) > 0:                       
  329.                         # For now, only pick the fist available physics Scene
  330.                         physicsScene = physicsScenes[0]
  331.                         for iPhysicsModel in physicsScene.iPhysicsModels:
  332.                                 physicsNode = PhysicsNode(self.document)
  333.                                 physicsNode.LoadFromDae(iPhysicsModel, self.objectNames)
  334.                        
  335.                        
  336.                 # Update the current Scene.
  337.                 self.document.currentBScene.update(1)
  338.        
  339.         def SaveToDae(self, bScene):
  340.                 global exportSelection, exportPhysics
  341.                 daeVisualScene = collada.DaeVisualScene()
  342.                 daeVisualScene.id = daeVisualScene.name = self.document.CreateID(bScene.name,'-Scene')
  343.                
  344.                 daePhysicsScene = collada.DaePhysicsScene()
  345.                 daePhysicsScene.id = daePhysicsScene.name = self.document.CreateID(bScene.name+'-Physics', '-Scene')
  346.  
  347.                 #Doug: Blender stores a pointer to the parent node with each node. But not a list of children. Typically for
  348.                 #scene graph exporters - X3D, DAE - you need to construct a list of children for each node before processing
  349.                 if exportSelection:
  350.                         self.rootNodes = Blender.Object.GetSelected()
  351.                         self.childNodes = []
  352.                 else: # now loop trough all nodes in this scene and create a list with root nodes and children
  353.                         for node in bScene.getChildren():
  354.                                 pNode = node.parent
  355.                                 if pNode is None:
  356.                                         self.rootNodes.append(node)
  357.                                 else:
  358.                                         try:
  359.                                                 self.childNodes[pNode.name].append(node) #Doug: append yourself to your parent's list of children
  360.                                         except:
  361.                                                 self.childNodes[pNode.name] = [node]
  362.                 #Doug: now process                     
  363.                 # Begin with the rootnodes
  364.                 for rootNode in self.rootNodes:
  365.                         sceneNode = SceneNode(self.document,self)
  366.                         nodeResult = sceneNode.SaveToDae(rootNode,self.childNodes)
  367.                         daeNode = nodeResult[0]
  368.                         daeVisualScene.nodes.append(daeNode)
  369.                         if exportPhysics:
  370.                                 daeInstancePhysicsModel = nodeResult[1]                            
  371.                                 daePhysicsScene.iPhysicsModels.append(daeInstancePhysicsModel)
  372.                        
  373.                 self.document.colladaDocument.visualScenesLibrary.AddItem(daeVisualScene)
  374.                 if exportPhysics:
  375.                         self.document.colladaDocument.physicsScenesLibrary.AddItem(daePhysicsScene)
  376.                 return (daeVisualScene, daePhysicsScene)
  377.        
  378. class PhysicsNode(object):
  379.         dynamic = 0
  380.         child = 1
  381.         actor = 2
  382.         inertiaLockX = 3
  383.         inertiaLockY = 4
  384.         inertiaLockZ = 5
  385.         doFH = 6
  386.         rotFH = 7
  387.         anisotropicFriction = 8
  388.         ghost = 9
  389.         rigidBody = 10
  390.         bounds = 11
  391.         collisionResponse = 12
  392.        
  393.         def __init__(self, document):
  394.                 self.document = document
  395.                
  396.         def LoadFromDae(self, daeInstancePhysicsModel, objectNames):
  397.                 global usePhysics
  398.                 if not(usePhysics is None) and not usePhysics:
  399.                         return
  400.                
  401.                 for iRigidBody in daeInstancePhysicsModel.iRigidBodies:
  402.                         # Get the real blender name instead of the collada name.
  403.                         realObjectName = objectNames[iRigidBody.targetString]
  404.                         # Get the Blender object with the specified name.
  405.                         bObject = Blender.Object.Get(realObjectName)
  406.                         # Check if physics is supported.
  407.                         if usePhysics is None:
  408.                                 usePhysics = hasattr(bObject, "rbShapeBoundType")
  409.                                 if not usePhysics:
  410.                                         return
  411.  
  412.                         # Get the rigid body.
  413.                         rigidBody = iRigidBody.body
  414.                         # Get the common technique of the rigid body.
  415.                         rigidBodyT = rigidBody.techniqueCommon
  416.                         # Get the physics material.
  417.                         physicsMaterial = rigidBodyT.GetPhysicsMaterial()
  418.                         # Get the shapes of the bounding volumes in this rigid body.
  419.                         shapes = rigidBodyT.shapes
  420.                        
  421.                         # The Rigid Body Flags
  422.                         rbFlags = 0 + rigidBodyT.dynamic + (1 << self.actor) + (1 << self.rigidBody) + (1 << self.bounds)
  423.                         rbShapeBoundType = 0
  424.                         # For now only get the first shape
  425.                         shape = shapes[0]
  426.                         # Check the type of the shape
  427.                         if isinstance(shape, collada.DaeGeometryShape):
  428.                                 ##print shape, shape.iGeometry.object.data
  429.                                 if isinstance(shape.iGeometry.object.data, collada.DaeMesh):
  430.                                         rbShapeBoundType = 4
  431.                                 else:
  432.                                         rbShapeBoundType = 5
  433.                         elif isinstance(shape, collada.DaeBoxShape):
  434.                                 rbShapeBoundType = 0
  435.                         elif isinstance(shape, collada.DaeSphereShape):
  436.                                 rbShapeBoundType = 1
  437.                         elif isinstance(shape, collada.DaeCylinderShape):
  438.                                 rbShapeBoundType = 2
  439.                         elif isinstance(shape, collada.DaeTaperedCylinderShape):
  440.                                 rbShapeBoundType = 3               
  441.                                
  442.                         bObject.rbFlags = rbFlags
  443.                         if not (rigidBodyT.mass is None):
  444.                                 bObject.rbMass = rigidBodyT.mass
  445.                        
  446.                         bObject.rbShapeBoundType = rbShapeBoundType
  447.                        
  448.  
  449. class SceneNode(object):
  450.        
  451.         def __init__(self, document, sceneNode):
  452.                 self.id = ''
  453.                 self.type = ''
  454.                 self.document = document
  455.                
  456.         def ObjectFromDae(self,daeNode):
  457.                 global replaceNames
  458.                 self.document.Progress()
  459.                 self.id = daeNode.id
  460.                 self.type = daeNode.type
  461.                
  462.                 if daeNode.IsJoint():
  463.                         # it's a Joint, not implemented yet
  464.                         return
  465.                         pass
  466.                 else : #its a Node                       
  467.                         newObject = None
  468.                         dataObject = None
  469.                         daeInstances = daeNode.GetInstances()
  470.                        
  471.                         if len(daeInstances) == 0:
  472.                                 newObject = Blender.Object.New('Empty',self.id)
  473.                         else:
  474.                                 # if only one instance is in this node, add it.
  475.                                 if len (daeInstances)== 1:
  476.                                         # Get the instance
  477.                                         daeInstance = daeInstances[0]
  478.                                         # Check which type the instance is
  479.                                         if isinstance(daeInstance,collada.DaeAnimationInstance):
  480.                                                 newObject = Blender.Object.New('Empty',self.id)
  481.                                         elif isinstance(daeInstance,collada.DaeCameraInstance):
  482.                                                 newObject = Blender.Object.New('Camera',self.id)
  483.                                                 dataObject = self.document.camerasLibrary.FindObject(daeInstance,True)
  484.                                         elif isinstance(daeInstance,collada.DaeControllerInstance):
  485.                                                 newObject = Blender.Object.New('Empty',self.id)
  486.                                         elif isinstance(daeInstance,collada.DaeGeometryInstance):
  487.                                                 newObject = Blender.Object.New('Mesh',self.document.CreateNameForObject(self.id,replaceNames, 'object'))
  488.                                                 dataObject = self.document.meshLibrary.FindObject(daeInstance,True)
  489.                                         elif isinstance(daeInstance,collada.DaeLightInstance):
  490.                                                 newObject = Blender.Object.New('Lamp',self.id)
  491.                                                 dataObject = self.document.lampsLibrary.FindObject(daeInstance,True)
  492.                                         elif isinstance(daeInstance,collada.DaeNodeInstance):
  493.                                                 newObject = Blender.Object.New('Empty',self.id)
  494.                                         elif isinstance(daeInstance,collada.DaeVisualSceneInstance):
  495.                                                 newObject = Blender.Object.New('Empty',self.id)
  496.                                         else:
  497.                                                 print daeInstance
  498.                                                 return
  499.                                         # Link the new Object to the dataObject
  500.                                         if dataObject != None:
  501.                                                 newObject.link(dataObject)
  502.                                 else:  # otherwise, create an empty node and attach the different instances to it
  503.                                         newObject = Blender.Object.New('Empty',self.id)
  504.                                         # finish this
  505.                                        
  506.                         self.document.currentBScene.link(newObject)
  507.                        
  508.                         # TODO: MAYBE CHANGE THIS LATER update the mesh..
  509.                         if newObject.getType() == 'Mesh':
  510.                                 newObject.getData().update(1,1,1)
  511.                                 # Set the vertex colors.
  512.                                 for f in newObject.getData(mesh=1).faces:
  513.                                         for c in f.col:
  514.                                                 c.r = 255
  515.                                                 c.g = 255
  516.                                                 c.b = 255
  517.                                                 c.a = 255                                        
  518.                        
  519.                         # Do the transformation
  520.                         mat = Matrix().resize4x4()
  521.                         for i in range(len(daeNode.transforms)):
  522.                                 transform = daeNode.transforms[len(daeNode.transforms)-(i+1)]
  523.                                 type = transform[0]
  524.                                 data = transform[1]
  525.                                 if type == collada.DaeSyntax.TRANSLATE:
  526.                                         mat = mat*TranslationMatrix(Vector(data)* self.document.tMat)
  527.                                 elif type == collada.DaeSyntax.ROTATE:
  528.                                         mat = mat*RotationMatrix(data[3],4,'r',Vector([data[0],data[1],data[2]])* self.document.tMat)
  529.                                 elif type == collada.DaeSyntax.SCALE:
  530.                                         skewVec = Vector(data[0],data[1], data[2])*self.document.tMat
  531.                                         mat = mat * Matrix([skewVec.x,0,0,0],[0,skewVec.y,0,0],[0,0,skewVec.z,0],[0,0,0,1])
  532.                                 elif type == collada.DaeSyntax.SKEW:
  533.                                         s = math.tan(data[0]*angleToRadian)
  534.                                         rotVec = Vector(data[1],data[2],data[3])*self.document.tMat
  535.                                         transVec = Vector(data[4],data[5],data[6])*self.document.tMat
  536.                                         fac1 = s*transVec.x
  537.                                         fac2 = s*transVec.y
  538.                                         fac3 = s*transVec.z                                
  539.                                        
  540.                                         mat = mat * Matrix([1+fac1*rotVec.x,fac1*rotVec.y,fac1*rotVec.z,0],[fac2*rotVec.x,1+fac2*rotVec.y,fac2*rotVec.z,0],[fac3*rotVec.x,fac3*rotVec.y,1+fac3*rotVec.z,0],[0,0,0,1])
  541.                                 elif type == collada.DaeSyntax.LOOKAT:
  542.                                         # TODO: use the correct up-axis
  543.                                         position = Vector([data[0],data[1], data[2]])
  544.                                         target = Vector([data[3],data[4], data[5]])
  545.                                         up = Vector([data[6],data[7], data[8]]).normalize()
  546.                                         front = (position-target).normalize()
  547.                                         side = -1*CrossVecs(front, up).normalize()
  548.                                         m = Matrix().resize4x4()
  549.  
  550.                                         m[0][0] = side.x
  551.                                         m[0][1] = side.y
  552.                                         m[0][2] = side.z
  553.                                        
  554.                                         m[1][0] = up.x
  555.                                         m[1][1] = up.y
  556.                                         m[1][2] = up.z
  557.                                        
  558.                                         m[2][0] = front.x
  559.                                         m[2][1] = front.y
  560.                                         m[2][2] = front.z
  561.                                        
  562.                                         m[3][0] = position.x
  563.                                         m[3][1] = position.y
  564.                                         m[3][2] = position.z
  565.                                        
  566.                                         mat = mat*m
  567.                                        
  568.                                 elif type == collada.DaeSyntax.MATRIX:
  569.                                         mat = mat * data
  570.                                        
  571.                         newObject.setMatrix(mat)
  572.                         childlist = []
  573.                         for daeChild in daeNode.nodes:
  574.                                 childSceneNode = SceneNode(self.document,self)
  575.                                 object = childSceneNode.ObjectFromDae(daeChild)
  576.                                 if not(object is None):
  577.                                         childlist.append(object)
  578.                         newObject.makeParent(childlist,0,1)
  579.                        
  580.                         return newObject
  581.                
  582.         def SaveToDae(self,bNode,childNodes):
  583.                 global bakeMatrices, exportSelection
  584.                 daeNode = collada.DaeNode()
  585.                 daeNode.id = daeNode.name = self.document.CreateID(bNode.name,'-Node')# +'-node'
  586.                
  587.                 # Get the transformations
  588.                 if bakeMatrices :
  589.                         mat = Blender.Mathutils.CopyMat(bNode.matrix).transpose()
  590.                         daeNode.transforms.append([collada.DaeSyntax.MATRIX, mat])
  591.                 else:
  592.                         #Doug: start vrml code from vrml2 exporter
  593.                         from Blender import Mathutils
  594.                         ob_matrix = Mathutils.Matrix(bNode.getMatrix('localspace')) #'worldspace'))
  595.                         matrix =  ob_matrix
  596.                         e      = matrix.rotationPart().toEuler()
  597.  
  598.                         v = matrix.translationPart()
  599.                         location = (v.x,v.y,v.z)
  600.                         mrot = e.toMatrix().resize4x4()
  601.                         try:
  602.                                 mrot.invert()
  603.                         except:
  604.                                 print "Warning: %s has degenerate transformation!" % (thisName)
  605.                                 return
  606.                            
  607.                         diag = matrix * mrot
  608.                         sizeX = diag[0][0]
  609.                         sizeY = diag[1][1]
  610.                         sizeZ = diag[2][2]
  611.                         scales = (sizeX,sizeY,sizeZ)
  612.                         #Doug: end vrml code
  613.                         e.x *= 3.141596/180.0
  614.                         e.y *= 3.141596/180.0
  615.                         e.z *= 3.141596/180.0
  616.                        
  617.                         daeNode.transforms.append([collada.DaeSyntax.TRANSLATE, location])
  618.                         #daeNode.transforms.append([collada.DaeSyntax.TRANSLATE, bNode.getLocation()])
  619.                        
  620.                         #euler = bNode.getEuler()
  621.                         euler = e
  622.                         rotxVec = [1,0,0,euler.x*radianToAngle]
  623.                         rotyVec = [0,1,0,euler.y*radianToAngle]
  624.                         rotzVec = [0,0,1,euler.z*radianToAngle]
  625.                        
  626.                         ##rotVec = [round(euler.x*radianToAngle,3), round(euler.y*radianToAngle,3), round(euler.z*radianToAngle,3)]
  627.                         if euler.z != 0: daeNode.transforms.append([collada.DaeSyntax.ROTATE, rotzVec])
  628.                         if euler.y != 0: daeNode.transforms.append([collada.DaeSyntax.ROTATE, rotyVec])
  629.                         if euler.x != 0: daeNode.transforms.append([collada.DaeSyntax.ROTATE, rotxVec])
  630.                        
  631.                         #daeNode.transforms.append([collada.DaeSyntax.SCALE, bNode.getSize()])
  632.                         daeNode.transforms.append([collada.DaeSyntax.SCALE, scales ])
  633.                        
  634.                 # Get the instance
  635.                 type = bNode.getType()
  636.                 instance  = None
  637.                 meshID = None
  638.                 if type == 'Mesh':
  639.                         dougsMethod = 1
  640.                         if dougsMethod:
  641.                                 #Doug: modified to wrap geometry in a library node and instance the library node instead
  642.                                 #of the geometry, so repetitive (component) geometry displays properly
  643.                                 instance_g = None  
  644.                                 instance_g = collada.DaeGeometryInstance()
  645.                                 daeGeometry = self.document.colladaDocument.geometriesLibrary.FindObject(bNode.getData(True))
  646.                                 meshNode = MeshNode(self.document)
  647.                                 if daeGeometry is None:                            
  648.                                         daeGeometry = meshNode.SaveToDae(bNode.getData())
  649.                                 meshID = daeGeometry.id
  650.                                 bindMaterials = meshNode.GetBindMaterials(bNode.getData(), daeGeometry.uvTextures)
  651.                                 instance_g.object = daeGeometry
  652.                                 instance_g.bindMaterials = bindMaterials
  653.                                 #instance the geometry from a library node
  654.                                 daeLibNode = self.document.colladaDocument.nodesLibrary.FindObject(daeGeometry.id+'-ln') #generic search for .id
  655.                                 libNode = LibnodeNode(self.document)
  656.                                 if daeLibNode is None:
  657.                                         daeLibNode = libNode.SaveToDae(daeGeometry) #should return a class DaeNode
  658.                                         daeLibNode.iGeometries.append(instance_g)
  659.                                 #now instance the library node from the scene node (instead of instancing the geometry directly)
  660.                                 instance = collada.DaeNodeInstance()
  661.                                 instance.object = daeLibNode
  662.                                 daeNode.iNodes.append(instance)
  663.  
  664.                         else:
  665.                                 #original code
  666.                                 instance = collada.DaeGeometryInstance()
  667.                                 daeGeometry = self.document.colladaDocument.geometriesLibrary.FindObject(bNode.getData(True))
  668.                                 meshNode = MeshNode(self.document)
  669.                                 if daeGeometry is None:                            
  670.                                         daeGeometry = meshNode.SaveToDae(bNode.getData())
  671.                                 meshID = daeGeometry.id
  672.                                 bindMaterials = meshNode.GetBindMaterials(bNode.getData(), daeGeometry.uvTextures)
  673.                                 instance.object = daeGeometry
  674.                                 instance.bindMaterials = bindMaterials
  675.                                 daeNode.iGeometries.append(instance)
  676.                        
  677.                 elif type == 'Camera':
  678.                         instance = collada.DaeCameraInstance()
  679.                         daeCamera = self.document.colladaDocument.camerasLibrary.FindObject(bNode.getData(True))
  680.                         if daeCamera is None:
  681.                                 cameraNode = CameraNode(self.document)
  682.                                 daeCamera = cameraNode.SaveToDae(bNode.getData())
  683.                         instance.object = daeCamera
  684.                         daeNode.iCameras.append(instance)
  685.                 elif type == 'Lamp':
  686.                         instance = collada.DaeLightInstance()
  687.                         daeLight = self.document.colladaDocument.lightsLibrary.FindObject(bNode.getData(True))
  688.                         if daeLight is None:
  689.                                 lampNode = LampNode(self.document)
  690.                                 daeLight = lampNode.SaveToDae(bNode.getData())
  691.                         instance.object = daeLight
  692.                         daeNode.iLights.append(instance)
  693.                
  694.                 if not exportSelection:    
  695.                         myChildNodes = []
  696.                         if childNodes.has_key(bNode.name):
  697.                                 myChildNodes = childNodes[bNode.name]            
  698.                
  699.                         for bNode in myChildNodes:
  700.                                 sceneNode = SceneNode(self.document, self)
  701.                                 daeNode.nodes.append(sceneNode.SaveToDae(bNode,childNodes)[0])
  702.                
  703.                 daePhysicsInstance = self.SavePhysicsToDae(bNode, meshID, daeNode)
  704.                        
  705.                 return (daeNode, daePhysicsInstance)
  706.        
  707.         def SavePhysicsToDae(self, bNode, meshID, daeNode):
  708.                 global usePhysics, exportPhysics
  709.                 if meshID is None or (not(usePhysics is None) and not usePhysics or not exportPhysics):
  710.                         return None
  711.                
  712.                 # Check if physics is supported.
  713.                 if usePhysics is None:
  714.                         usePhysics = hasattr(bNode, "rbShapeBoundType")
  715.                         if not usePhysics:
  716.                                 return None
  717.                
  718.                 rbFlags = [0 for a in range(16)]
  719.                 rbF = bNode.rbFlags
  720.                 lastIndex = 0;
  721.                 # Get the bit flags
  722.                 while rbF > 0:
  723.                         val = rbF >> 1
  724.                         if val << 1 == rbF:
  725.                                 #rbFlags.append(0)
  726.                                 rbFlags[lastIndex] = 0
  727.                         else:
  728.                                 #rbFlags.append(1)
  729.                                 rbFlags[lastIndex] = 1
  730.                         lastIndex += 1
  731.                         rbF = val
  732.                
  733.                 daePhysicsModel = collada.DaePhysicsModel();
  734.                 daePhysicsModel.id = daePhysicsModel.name = self.document.CreateID(daeNode.id,'-PhysicsModel')
  735.                 daeRigidBody = collada.DaeRigidBody();
  736.                 daeRigidBody.id = daeRigidBody.name = self.document.CreateID(daeNode.id,'-RigidBody')
  737.                 daeRigidBodyTechniqueCommon = collada.DaeRigidBody.DaeTechniqueCommon()
  738.                 daeRigidBodyTechniqueCommon.dynamic = bool(rbFlags[0])
  739.                 daeRigidBodyTechniqueCommon.mass = bNode.rbMass
  740.                 # check the shape of the rigid body.
  741.                 if bNode.rbShapeBoundType == 0: # Box
  742.                         shape = collada.DaeBoxShape()
  743.                         shape.halfExtents = list(bNode.rbHalfExtents)
  744.                 elif bNode.rbShapeBoundType == 1: # Sphere
  745.                         shape = collada.DaeSphereShape()
  746.                         shape.radius = bNode.rbRadius
  747.                 elif bNode.rbShapeBoundType == 2: # Cylinder
  748.                         shape = collada.DaeCylinderShape()
  749.                         shape.radius = [[bNode.rbRadius],[bNode.rbRadius]]
  750.                         shape.height = bNode.rbHalfExtents[2]
  751.                 elif bNode.rbShapeBoundType == 3: # Cone
  752.                         shape = collada.DaeTaperedCylinderShape()
  753.                         shape.radius1 = [[bNode.rbRadius],[bNode.rbRadius]]
  754.                         shape.radius2 = [0 , 0]
  755.                         shape.height = bNode.rbHalfExtents[2]
  756.                 else: # Convex hull or # Static Triangle Mesh
  757.                         shape = collada.DaeGeometryShape()
  758.                         iGeometry = collada.DaeGeometryInstance()
  759.                         if bNode.rbShapeBoundType == 5:
  760.                                 object = self.document.colladaDocument.geometriesLibrary.FindObject(daeNode.id+'-Convex')
  761.                         else:
  762.                                 object = self.document.colladaDocument.geometriesLibrary.FindObject(meshID)
  763.                         if object is None:
  764.                                 object = collada.DaeGeometry()
  765.                                 object.id = object.name = self.document.CreateID(daeNode.id,'-ConvexGeom')
  766.                                 convexMesh = collada.DaeConvexMesh()
  767.                                 convexMesh.convexHullOf = meshID
  768.                                 object.data = convexMesh                                                                                                       
  769.                                 self.document.colladaDocument.geometriesLibrary.AddItem(object)
  770.                         iGeometry.object = object       
  771.                         shape.iGeometry = iGeometry
  772.                
  773.                 # Create a physics material.
  774.                 daePhysicsMaterial = self.document.colladaDocument.physicsMaterialsLibrary.FindObject(daeNode.id+'-PxMaterial')
  775.                 if daePhysicsMaterial is None:
  776.                         daePhysicsMaterial = collada.DaePhysicsMaterial()
  777.                         ##daePhysicsMaterial.restitution = bNode.rbRestitution
  778.                         ##daePhysicsMaterial.staticFriction = bNode.rbFriction
  779.                         daePhysicsMaterial.id = daePhysicsMaterial.name = self.document.CreateID(daeNode.id, '-PhysicsMaterial')
  780.                         self.document.colladaDocument.physicsMaterialsLibrary.AddItem(daePhysicsMaterial)
  781.                                                
  782.                 # Create a physics material instance.
  783.                 daePhysicsMaterialInstance = collada.DaePhysicsMaterialInstance()
  784.                 # Set the physics material of this instance
  785.                 daePhysicsMaterialInstance.object = daePhysicsMaterial
  786.                
  787.                
  788.                 # add the shape to the commom technique.
  789.                 daeRigidBodyTechniqueCommon.shapes.append(shape)                               
  790.                 # Set the material of the common technique.
  791.                 daeRigidBodyTechniqueCommon.iPhysicsMaterial = daePhysicsMaterialInstance
  792.                 # Set the common technique of this rigid body.
  793.                 daeRigidBody.techniqueCommon = daeRigidBodyTechniqueCommon
  794.                
  795.                 # Add the rigid body to the physics model.
  796.                 daePhysicsModel.rigidBodies.append(daeRigidBody)
  797.                 # Create a new RigidBody instance
  798.                 daeRigidBodyInstance = collada.DaeRigidBodyInstance()
  799.                 # Set the rigid body of this instance
  800.                 daeRigidBodyInstance.body = daeRigidBody
  801.                 # Set the node of this instance
  802.                 daeRigidBodyInstance.target = daeNode
  803.                
  804.                 # Create a new Physics Model Instance.
  805.                 daePhysicsModelInstance = collada.DaePhysicsModelInstance()
  806.                 # Set the Physics Model of this instance.
  807.                 daePhysicsModelInstance.object = daePhysicsModel
  808.                 # add the rigidbody instance to this physics model instance.
  809.                 daePhysicsModelInstance.iRigidBodies.append(daeRigidBodyInstance)
  810.                 # add the physics model to the library.
  811.                 self.document.colladaDocument.physicsModelsLibrary.items.append(daePhysicsModel)
  812.                 return daePhysicsModelInstance                           
  813.        
  814. class MeshNode(object):
  815.         def __init__(self,document):
  816.                 self.document = document
  817.                 self.materials = []
  818.        
  819.         def FindMaterial(self, bMaterials,name):
  820.                 for i in range(len(bMaterials)):
  821.                         if bMaterials[i].name == name:
  822.                                 return i
  823.                 return -1
  824.        
  825.         def LoadFromDae(self, daeGeometry):
  826.                 global replaceNames      
  827.                 meshID = daeGeometry.id
  828.                 meshName = daeGeometry.name
  829.                
  830.                 # Create a new meshObject
  831.                 bMesh2 = Blender.NMesh.New(self.document.CreateNameForObject(meshID,replaceNames,'mesh'))
  832.  
  833.                 if isinstance(daeGeometry.data,collada.DaeMesh): # check if it's a mesh
  834.                         materials = []
  835.                         for matName, material in self.materials.iteritems():
  836.                                 materials.append(material)
  837.                         bMesh2.materials = materials
  838.                        
  839.                         faces = []
  840.                        
  841.                         daeMesh = daeGeometry.data
  842.                         daeVertices = daeMesh.vertices
  843.                        
  844.                         # Get all the sources
  845.                         sources = dict()
  846.                         for source in daeMesh.sources:
  847.                                 sources[source.id] = source.vectors
  848.  
  849.                         # Get the Position Input
  850.                         vPosInput = daeVertices.FindInput('POSITION')
  851.  
  852.                         # Get the Normal Input
  853.                         vNorInput = daeVertices.FindInput('NORMAL')
  854.                                                
  855.                        
  856.                         # Keep track of the Blender Vertices
  857.                         pVertices = []
  858.                        
  859.                         self.document.ProgressPart(0.0,'Create Vertices')
  860.                        
  861.                        
  862.                        
  863.                         # Create all the vertices.
  864.                         for i in sources[vPosInput.source]:
  865.                                 vPosVector = Vector(i[0], i[1], i[2]) * self.document.tMat
  866.                                 pVertices.append(Blender.NMesh.Vert(vPosVector.x, vPosVector.y, vPosVector.z))
  867.                         bMesh2.verts = pVertices                               
  868.                                
  869.                         faceVerts = [] # The list of vertices for each face to add
  870.                         edgeVerts = [] # The list of vertices for each edge to add
  871.                        
  872.                         # Now create the primitives
  873.                         self.document.ProgressPart(0.5,'Create Primitives')
  874.                         daePrimitives = daeMesh.primitives
  875.                         for primitive in daePrimitives:
  876.                                 # Get the UV Input
  877.                                 vUvInput = primitive.FindInput('TEXCOORD')
  878.                                 uvs = []
  879.                                 if not (vUvInput is None):
  880.                                         for i in sources[vUvInput.source]:
  881.                                                 vUvVector = Vector(i[0],i[1])
  882.                                                 uvs.append(vUvVector)
  883.                                 inputs = primitive.inputs
  884.                                 maxOffset = primitive.GetMaxOffset()+1 # The number of values for one vertice
  885.                                 vertCount = 0 # The number of vertices for one primitive
  886.                                 realVertCount = 0 # The number of vertices for one primitive
  887.                                 plist = [] # The list with all primitives
  888.                                 if isinstance(primitive, collada.DaePolygons): # Polygons
  889.                                         plist = primitive.polygons
  890.                                         vertCount = 4
  891.                                 elif isinstance(primitive, collada.DaeTriangles): # Triangles
  892.                                         plist.append(primitive.triangles)
  893.                                         vertCount = 3
  894.                                 elif isinstance(primitive, collada.DaeLines): # Lines
  895.                                         plist.append(primitive.lines)
  896.                                         vertCount = 2
  897.                                 realVertCount = vertCount
  898.                                 # Loop through each P (primitive)       
  899.                                 for p in plist:
  900.                                         if vertCount == 4:
  901.                                                 realVertCount = len(p)/maxOffset
  902.                                         pIndex = 0
  903.                                         # A list with edges in this face
  904.                                         faceEdges = []
  905.                                         # a list to store all the created faces in to add them to the mesh afterwards.
  906.                                         allFaceVerts = []
  907.                                         # loop through all the values in this 'p'
  908.                                         while pIndex < len(p):
  909.                                                 # Keep track of the verts in this face
  910.                                                 curFaceVerts2 = []
  911.                                                 uvList  = []
  912.                                                 # for every vertice for this primitive
  913.                                                 for i in range(realVertCount):
  914.                                                         # Check all the inputs and do the right thing
  915.                                                         for input in inputs:                                                           
  916.                                                                 inputVal = p[pIndex+(i*maxOffset)+input.offset]                                                            
  917.                                                                 if input.semantic == "VERTEX":
  918.                                                                         vert2 = pVertices[inputVal]
  919.                                                                         curFaceVerts2.append(vert2)
  920.                                                                 elif input.semantic == "TEXCOORD":
  921.                                                                         uvList.append((uvs[inputVal][0],uvs[inputVal][1]))
  922.                                                                 elif input.semantic == "NORMAL":
  923.                                                                         pass                                               
  924.                                                 if vertCount > 2:
  925.                                                         faceCount = 1 + (realVertCount-4) / 2 + (realVertCount-4) % 2                                                    
  926.                                                         firstIndex = 2
  927.                                                         lastIndex = 1                                                  
  928.                                                         for a in range(faceCount):
  929.                                                                 newFirstIndex = (firstIndex + 1) % realVertCount
  930.                                                                 newLastIndex = (lastIndex -1) % realVertCount
  931.                                                                 fuv = []
  932.                                                                 if newFirstIndex != newLastIndex:
  933.                                                                         fv = [curFaceVerts2[firstIndex]] + [curFaceVerts2[newFirstIndex]] + [curFaceVerts2[newLastIndex]] +  [curFaceVerts2[lastIndex]]
  934.                                                                         if len(uvList) == realVertCount:
  935.                                                                                 fuv = [uvList[firstIndex]] + [uvList[newFirstIndex]] + [uvList[newLastIndex]] + [uvList[lastIndex]]
  936.                                                                 else:
  937.                                                                         fv = [curFaceVerts2[firstIndex]] + [curFaceVerts2[newFirstIndex]] + [curFaceVerts2[lastIndex]]
  938.                                                                         if len(uvList) == realVertCount:
  939.                                                                                 fuv = [uvList[firstIndex]] + [uvList[newFirstIndex]] + [uvList[lastIndex]]
  940.                                                                 firstIndex = newFirstIndex
  941.                                                                 lastIndex = newLastIndex
  942.                                                                 # Create a new Face.
  943.                                                                 newFace = Blender.NMesh.Face(fv)
  944.                                                                 # Set the UV Coordinates
  945.                                                                 newFace.uv = fuv
  946.                                                                 # Add the new face to the list
  947.                                                                 faces.append(newFace)
  948.                                                                 # Add the material to this face
  949.                                                                 if primitive.material != '':
  950.                                                                         # Find the material index.
  951.                                                                         matIndex = self.FindMaterial(bMesh2.materials, self.materials[primitive.material].name)
  952.                                                                         # Set the material index for the new face.
  953.                                                                         newFace.materialIndex = matIndex
  954.                                                                         textures = self.materials[primitive.material].getTextures()
  955.                                                                         if len(textures) > 0 and not (textures[0] is None):
  956.                                                                                 texture = textures[0]
  957.                                                                                 image = texture.tex.getImage()
  958.                                                                                 if not image is None:
  959.                                                                                         newFace.image = image
  960.                                                 else:
  961.                                                         bMesh2.addEdge(curFaceVerts2[0], curFaceVerts2[1])
  962.                                                 # update the index
  963.                                                 pIndex += realVertCount * maxOffset
  964.                                         bMesh2.faces = faces
  965.                 return bMesh2
  966.        
  967.         def SaveToDae(self, bMesh):
  968.                 global useTriangles, usePolygons, useUV
  969.                
  970.                 useNormal = 0
  971.                 #me = bMesh #Mesh.Get("Mesh")
  972.                 faces = bMesh.faces
  973.                 for f in faces:
  974.                        if f.smooth:
  975.                                useNormal = 1
  976.                 #print 'bMesh.mode=',bMesh.mode,' Modes.Autosmooth=',Blender.Mesh.Modes.AUTOSMOOTH
  977.                 #print 'useNormalface=',useNormal,' mesh.mode&Authosmooth=',(bMesh.mode & Blender.Mesh.Modes.AUTOSMOOTH)
  978.                 useNormal = useNormal or (bMesh.mode & Blender.Mesh.Modes.AUTOSMOOTH)
  979.                 #print 'useNormal=',useNormal
  980.                
  981.                 uvTextures = dict()
  982.                
  983.                 daeGeometry = collada.DaeGeometry()
  984.                 daeGeometry.id = daeGeometry.name = self.document.CreateID(bMesh.name,'-Geometry')
  985.                
  986.                 daeMesh = collada.DaeMesh()                        
  987.                
  988.                 # Keep track of the edges in faces
  989.                 faceEdges = []
  990.  
  991.                 #Position
  992.                 daeSource = collada.DaeSource()
  993.                 daeSource.id = self.document.CreateID(daeGeometry.id,'-Position')
  994.                 daeFloatArray = collada.DaeFloatArray()
  995.                 daeFloatArray.id = self.document.CreateID(daeSource.id,'-array')
  996.                 daeSource.source = daeFloatArray
  997.                 daeSource.techniqueCommon = collada.DaeSource.DaeTechniqueCommon()
  998.                 accessor = collada.DaeAccessor()
  999.                 daeSource.techniqueCommon.accessor = accessor
  1000.                 accessor.source = daeFloatArray.id
  1001.                 accessor.count = len(bMesh.verts)
  1002.                 accessor.AddParam('X','float')
  1003.                 accessor.AddParam('Y','float')
  1004.                 accessor.AddParam('Z','float')           
  1005.  
  1006.                 #Normals
  1007.                 if useNormal:
  1008.                         daeSourceNormals = collada.DaeSource()
  1009.                         daeSourceNormals.id = self.document.CreateID(daeGeometry.id,'-Normals')
  1010.                         daeFloatArrayNormals = collada.DaeFloatArray()
  1011.                         daeFloatArrayNormals.id = self.document.CreateID(daeSourceNormals.id,'-array')
  1012.                         daeSourceNormals.source = daeFloatArrayNormals
  1013.                         daeSourceNormals.techniqueCommon = collada.DaeSource.DaeTechniqueCommon()
  1014.                         accessorNormals = collada.DaeAccessor()
  1015.                         daeSourceNormals.techniqueCommon.accessor = accessorNormals
  1016.                         accessorNormals.source = daeFloatArrayNormals.id
  1017.                         accessorNormals.count = len(bMesh.verts)
  1018.                         accessorNormals.AddParam('X','float')
  1019.                         accessorNormals.AddParam('Y','float')
  1020.                         accessorNormals.AddParam('Z','float')
  1021.  
  1022.                 #UV
  1023.                 daeSourceTextures = collada.DaeSource()
  1024.                 daeSourceTextures.id = self.document.CreateID(daeGeometry.id , '-UV')
  1025.                 daeFloatArrayTextures = collada.DaeFloatArray()
  1026.                 daeFloatArrayTextures.id = self.document.CreateID(daeSourceTextures.id,'-array')
  1027.                 daeSourceTextures.source = daeFloatArrayTextures
  1028.                 daeSourceTextures.techniqueCommon = collada.DaeSource.DaeTechniqueCommon()
  1029.                 accessorTextures = collada.DaeAccessor()
  1030.                 daeSourceTextures.techniqueCommon.accessor = accessorTextures
  1031.                 accessorTextures.source = daeFloatArrayTextures.id
  1032.                 accessorTextures.AddParam('S','float')
  1033.                 accessorTextures.AddParam('T','float');
  1034.                
  1035.  
  1036.                 #Vertex
  1037.                 daeVertices = collada.DaeVertices()
  1038.                 daeVertices.id = self.document.CreateID(daeGeometry.id,'-Vertex')
  1039.                 daeInput = collada.DaeInput()
  1040.                 #--position
  1041.                 daeInput.semantic = 'POSITION'
  1042.                 daeInput.source = daeSource.id
  1043.                 daeVertices.inputs.append(daeInput)
  1044.                 #--normal
  1045.                 if useNormal:
  1046.                         daeInputNormals = collada.DaeInput()
  1047.                         daeInputNormals.semantic = 'NORMAL'
  1048.                         daeInputNormals.source = daeSourceNormals.id
  1049.                         daeVertices.inputs.append(daeInputNormals)
  1050.                 daeMesh.vertices = daeVertices
  1051.                
  1052.                 for vert in bMesh.verts:
  1053.                         for co in vert.co:                               
  1054.                                 daeFloatArray.data.append(co)
  1055.                         if useNormal:
  1056.                                 for no in vert.no:
  1057.                                         daeFloatArrayNormals.data.append(no)
  1058.                
  1059.                
  1060.                 daePolygonsDict = dict()
  1061.                 daeTrianglesDict = dict()
  1062.                 daeLines = None
  1063.                
  1064.                 mesh = Blender.Mesh.Get(bMesh.name);
  1065.                
  1066.                 # Loop trough all the faces
  1067.                 for face in mesh.faces:
  1068.                         matIndex = -1
  1069.                         if not useUV and bMesh.materials and len(bMesh.materials) > 0:
  1070.                                 matIndex = face.mat
  1071.                         elif mesh.faceUV and (useUV or bMesh.materials is None or len(bMesh.materials) == 0):
  1072.                                 if not face.image is None:
  1073.                                         matIndex = face.image.name
  1074.                         elif bMesh.materials and len(bMesh.materials) > 0:
  1075.                                 #C
  1076.                                 matIndex = face.mat
  1077.                        
  1078.                         vertCount = len(face.verts)
  1079.                                                                        
  1080.                         # Create a new function which adds vertices to a list.
  1081.                         def AddVerts(verts,uvs,prlist):
  1082.                                 prevVert = None
  1083.                                 lastVert = verts[-1]
  1084.                                
  1085.                                 for v_index in range(len(verts)):
  1086.                                         # Get the vertice
  1087.                                         vert = verts[v_index]
  1088.                                         # Add the vertice to the end of the list.
  1089.                                         prlist.append(vert.index)
  1090.                                         # If the mesh has UV-coords, add these to the textures array.
  1091.                                         if mesh.faceUV:
  1092.                                                 ##daeFloatArrayTextures.data.append(face.uv[v_index][0])
  1093.                                                 ##daeFloatArrayTextures.data.append(face.uv[v_index][1])
  1094.                                                 daeFloatArrayTextures.data.append(uvs[v_index][0])
  1095.                                                 daeFloatArrayTextures.data.append(uvs[v_index][1])
  1096.                                                 prlist.append(len(daeFloatArrayTextures.data)/2-1)
  1097.                                                 accessorTextures.count = accessorTextures.count + 1
  1098.                                         # Add the edge to the faceEdges list.
  1099.                                         if prevVert != None:
  1100.                                                 faceEdges.append(mesh.findEdges(prevVert, vert))
  1101.                                         else:
  1102.                                                 faceEdges.append(mesh.findEdges([(vert, lastVert)]))
  1103.                                         # Update the prevVert vertice.
  1104.                                         prevVert = vert
  1105.  
  1106.                         #for googleEarth the following triangulation needs to be generalized I think.
  1107.                         #Q. are all faces quads or triangles? What happens to the ones that aren't
  1108.                         if (vertCount == 3 and not usePolygons) or (useTriangles and vertCount == 4): # triangle                               
  1109.                                 # Iff a Triangle Item for the current material not exists, create one.
  1110.                                 daeTrianglesDict.setdefault(matIndex, collada.DaeTriangles())
  1111.                                
  1112.                                 if vertCount == 3:
  1113.                                         #so far the triangles seem to display correctly
  1114.                                         # Add al the vertices to the triangle list.
  1115.                                         ##AddVerts(face.verts,daeTrianglesDict[matIndex].triangles)
  1116.                                         uvs = []
  1117.                                         if mesh.faceUV:
  1118.                                                 uvs = face.uv[:]
  1119.                                         AddVerts(face.verts,uvs,daeTrianglesDict[matIndex].triangles)
  1120.                                         # Update the vertice count for the trianglelist.
  1121.                                         daeTrianglesDict[matIndex].count += 1
  1122.                                 else: # Convert quad polygon to triangles
  1123.                                         #there is something in blender scripts mesh.quadToTriangle()
  1124.                                         #it looks like first you have to select the quads to convert
  1125.                                         #the following code seems to convert a quad to 2 triangles, but
  1126.                                         #does nothing with the uvs ... that might be the problem.
  1127.                                         verts1 = face.verts[:3]   #0,1,2
  1128.                                         verts2 = face.verts[2:] + tuple([face.verts[0]]) #2,3,0
  1129.                                         #next 3 lines added mar22_08
  1130.                                         uvs1 = []
  1131.                                         uvs2 = []
  1132.                                         if mesh.faceUV:
  1133.                                                 uvs1 = face.uv[:3]
  1134.                                                 uvs2 = face.uv[2:] + tuple([face.uv[0]])
  1135.                                         # Add al the vertices to the triangle list.
  1136.                                         ##AddVerts(verts1,daeTrianglesDict[matIndex].triangles)
  1137.                                         ##AddVerts(verts2, daeTrianglesDict[matIndex].triangles)
  1138.                                         AddVerts(verts1,uvs1,daeTrianglesDict[matIndex].triangles)
  1139.                                         AddVerts(verts2,uvs2,daeTrianglesDict[matIndex].triangles)
  1140.                                         # Update the vertice count for the trianglelist.
  1141.                                         daeTrianglesDict[matIndex].count += 2                      
  1142.                         else: # polygon but googleEarth doesn't seem to like polygons - never displays
  1143.                                 # Iff a Polygon Item for the current material not exists, create one.
  1144.                                 daePolygonsDict.setdefault(matIndex, collada.DaePolygons())
  1145.                                 # for each polygon, create a new P element
  1146.                                 pverts = []
  1147.                                 # Add al the vertices to the pverts list.
  1148.                                 AddVerts(face.verts,pverts)
  1149.                                 # Add the pverts list to the polygons list.
  1150.                                 daePolygonsDict[matIndex].polygons.append(pverts)
  1151.                                 # Update the vertice count for the polygonlist.
  1152.                                 daePolygonsDict[matIndex].count += 1
  1153.                         if mesh.faceUV:
  1154.                                 if not face.image is None:
  1155.                                         if not face.image.name in uvTextures:
  1156.                                                 uvTextures[face.image.name] = self.document.CreateID(face.image.name, "-Material")
  1157.                 # Loop through all the edges
  1158.                 for edge in mesh.edges:
  1159.                         if not edge.index in faceEdges:
  1160.                                 if daeLines == None: daeLines = collada.DaeLines()
  1161.                                 daeLines.count += 1
  1162.                                 daeLines.lines.append(edge.v1.index)
  1163.                                 daeLines.lines.append(edge.v2.index)
  1164.                
  1165.                 daeInput = collada.DaeInput()
  1166.                 daeInput.semantic = 'VERTEX'
  1167.                 daeInput.offset = 0
  1168.                 daeInput.source = daeVertices.id
  1169.                
  1170.                 daeInputUV = collada.DaeInput()
  1171.                 daeInputUV.semantic = 'TEXCOORD'
  1172.                 daeInputUV.offset = 1
  1173.                 daeInputUV.source = daeSourceTextures.id
  1174.                
  1175.                 materialName = ''
  1176.                        
  1177.                 for k, daeTriangles in daeTrianglesDict.iteritems():
  1178.                         if k != -1:
  1179.                                 if not useUV and not bMesh.materials is None and len(bMesh.materials) > 0 and k >= 0:
  1180.                                         daeTriangles.material = bMesh.materials[k].name
  1181.                                 elif mesh.faceUV and (useUV or bMesh.materials is None or len(bMesh.materials) == 0):
  1182.                                         daeTriangles.material = uvTextures[k]
  1183.                                 elif bMesh.materials and len(bMesh.materials) > 0 and k >= 0:
  1184.                                         daeTriangles.material = bMesh.materials[k].name
  1185.                         daeTriangles.inputs.append(daeInput)
  1186.                         if mesh.faceUV:
  1187.                                 daeTriangles.inputs.append(daeInputUV)
  1188.                         daeMesh.primitives.append(daeTriangles)
  1189.                
  1190.                 for k, daePolygons in daePolygonsDict.iteritems():
  1191.                         if k != -1:
  1192.                                 if not useUV and not bMesh.materials is None and len(bMesh.materials) > 0 and k >= 0:
  1193.                                         daePolygons.material = bMesh.materials[k].name
  1194.                                 elif mesh.faceUV and (useUV or bMesh.materials is None or len(bMesh.materials) == 0):
  1195.                                         daePolygons.material = uvTextures[k]
  1196.                         daePolygons.inputs.append(daeInput)
  1197.                         if mesh.faceUV:
  1198.                                 daePolygons.inputs.append(daeInputUV)
  1199.                         daeMesh.primitives.append(daePolygons)
  1200.                
  1201.                 if daeLines != None:
  1202.                         daeLines.inputs.append(daeInput)
  1203.                         daeMesh.primitives.append(daeLines)
  1204.                
  1205.                 daeMesh.sources.append(daeSource)
  1206.                 if useNormal:
  1207.                         daeMesh.sources.append(daeSourceNormals)
  1208.                 if mesh.faceUV:
  1209.                         daeMesh.sources.append(daeSourceTextures)
  1210.                
  1211.                 daeGeometry.data = daeMesh
  1212.                
  1213.                 self.document.colladaDocument.geometriesLibrary.AddItem(daeGeometry)
  1214.                 daeGeometry.uvTextures = uvTextures
  1215.                 return daeGeometry
  1216.        
  1217.         def GetBindMaterials(self, bMesh, uvTextures):
  1218.                 global useUV
  1219.                
  1220.                 bindMaterials = []
  1221.                 mesh = Blender.Mesh.Get(bMesh.name);
  1222.                 # now check the materials
  1223. ##              print 'bmesh.name=',bMesh.name, ' useUV=',useUV
  1224. ##              print ' bMesh.materials=',bMesh.materials
  1225. ##              print 'lenbMeshMat=',len(bMesh.materials)
  1226.                
  1227.                 if (not useUV) and bMesh.materials and len(bMesh.materials) > 0:
  1228. ##                        print 'Section A'
  1229.                         daeBindMaterial = collada.DaeFxBindMaterial()
  1230.                         for bMaterial in bMesh.materials:                                
  1231.                                 instance = collada.DaeFxMaterialInstance()
  1232.                                 daeMaterial = self.document.colladaDocument.materialsLibrary.FindObject(bMaterial.name)
  1233.                                 if daeMaterial is None:
  1234.                                         materialNode = MaterialNode(self.document)
  1235.                                         daeMaterial = materialNode.SaveToDae(bMaterial)
  1236.                                 instance.object = daeMaterial
  1237.                                 daeBindMaterial.techniqueCommon.iMaterials.append(instance)
  1238.                         # now we have to add this bindmaterial to the intance of this geometry
  1239.                         bindMaterials.append(daeBindMaterial)
  1240.                 elif mesh.faceUV and (useUV or bMesh.materials is None or len(bMesh.materials) == 0):
  1241. ##                        print 'Section B'
  1242.                         daeBindMaterial = collada.DaeFxBindMaterial()
  1243.                         for imageName, imageNameUnique in uvTextures.iteritems():
  1244.                                 image = Blender.Image.Get(imageName)
  1245.                                 instance = collada.DaeFxMaterialInstance()
  1246.                                 daeMaterial = self.document.colladaDocument.materialsLibrary.FindObject(imageNameUnique)
  1247.                                 if daeMaterial is None:
  1248.                                         textureNode = TextureNode(self.document)
  1249.                                         daeMaterial = textureNode.SaveToDae(image)
  1250.                                         daeMaterial.id = daeMaterial.name = imageNameUnique
  1251.                                 instance.object = daeMaterial
  1252.                                 daeBindMaterial.techniqueCommon.iMaterials.append(instance)                            
  1253.                         # now we have to add this bindmaterial to the intance of this geometry
  1254.                         bindMaterials.append(daeBindMaterial)
  1255.                 elif bMesh.materials and len(bMesh.materials) > 0:
  1256. ##                        print 'Section C - same as section A'
  1257.                         daeBindMaterial = collada.DaeFxBindMaterial()
  1258.                         for bMaterial in bMesh.materials:                                
  1259.                                 instance = collada.DaeFxMaterialInstance()
  1260.                                 daeMaterial = self.document.colladaDocument.materialsLibrary.FindObject(bMaterial.name)
  1261.                                 if daeMaterial is None:
  1262.                                         materialNode = MaterialNode(self.document)
  1263.                                         daeMaterial = materialNode.SaveToDae(bMaterial)
  1264.                                 instance.object = daeMaterial
  1265.                                 daeBindMaterial.techniqueCommon.iMaterials.append(instance)
  1266.                         # now we have to add this bindmaterial to the intance of this geometry
  1267.                         bindMaterials.append(daeBindMaterial)
  1268.                        
  1269.                 return bindMaterials
  1270.        
  1271. class TextureNode(object):
  1272.         def __init__(self, document):
  1273.                 self.document = document
  1274.                
  1275.         def LoadFromDae(self, daeImage):
  1276.                 imageID = daeImage.id
  1277.                 imageName = daeImage.name
  1278.                
  1279.                 bTexture = Blender.Texture.New(imageID)
  1280.                
  1281.                 filename = ''
  1282.                 if Blender.sys.exists(daeImage.initFrom):
  1283.                         filename = daeImage.initFrom
  1284.                 elif Blender.sys.exists(self.document.filePath + daeImage.initFrom):
  1285.                         filename = self.document.filePath + daeImage.initFrom
  1286.                
  1287.                
  1288.                 if filename <> '':
  1289.                         bTexture.setType('Image')                        
  1290.                         img = Blender.Image.Load(filename)               
  1291.                         bTexture.setImage(img)
  1292.                 else:
  1293.                         print 'image not found: %s'%(daeImage.initFrom)
  1294.                        
  1295.                 return bTexture
  1296.        
  1297.         def SaveToDae(self, bImage):
  1298.                 daeMaterial = collada.DaeFxMaterial()
  1299.                 ##daeMaterial.id = daeMaterial.name = self.document.CreateID(bImage.name, '-Material')
  1300.                 self.document.colladaDocument.materialsLibrary.AddItem(daeMaterial)
  1301.                
  1302.                 instance = collada.DaeFxEffectInstance()
  1303.                 daeEffect = self.document.colladaDocument.effectsLibrary.FindObject(bImage.name+'-fx')
  1304.                
  1305.                 if daeEffect is None:
  1306.                         daeEffect = collada.DaeFxEffect()
  1307.                         daeEffect.id = daeEffect.name = self.document.CreateID(bImage.name , '-fx')
  1308.                        
  1309.                         shader = collada.DaeFxShadeLambert()
  1310.                         daeImage = self.document.colladaDocument.imagesLibrary.FindObject(bImage.name)                             
  1311.                         if daeImage is None: # Create the image
  1312.                                 daeImage = collada.DaeImage()
  1313.                                 daeImage.id = daeImage.name = self.document.CreateID(bImage.name,'-image')
  1314.                                 daeImage.initFrom = Blender.sys.expandpath(bImage.filename)
  1315.                                 if useRelativePaths:
  1316.                                         daeImage.initFrom = CreateRelativePath(filename, daeImage.initFrom)                                                                                                                              
  1317.                                 self.document.colladaDocument.imagesLibrary.AddItem(daeImage)
  1318.                                 daeTexture = collada.DaeFxTexture()
  1319.                                 daeTexture.texture = daeImage.id
  1320.                                 shader.AddValue(collada.DaeFxSyntax.DIFFUSE, daeTexture)
  1321.                                
  1322.                         daeEffect.AddShader(shader)
  1323.                         #Doug: added Mar3008 next 3 lines
  1324.                         #if (meshNode.mode & Blender.Mesh.Modes.DOUBLESIDED):
  1325.                         if 1:
  1326.                                 daeEffect.AddDoubleSided(1)
  1327.                        
  1328.                         self.document.colladaDocument.effectsLibrary.AddItem(daeEffect)                    
  1329.                 instance.object = daeEffect
  1330.                
  1331.                 daeMaterial.iEffects.append(instance)
  1332.                
  1333.                 return daeMaterial
  1334.        
  1335. class MaterialNode(object):
  1336.         def __init__(self, document):
  1337.                 self.document = document
  1338.                
  1339.         def LoadFromDae(self, daeMaterial):
  1340.                 materialID = daeMaterial.id
  1341.                 materialName = daeMaterial.name
  1342.                
  1343.                 bMat = Blender.Material.New(materialID)
  1344.                 for i in daeMaterial.iEffects:
  1345.                         daeEffect = self.document.colladaDocument.effectsLibrary.FindObject(i.url)               
  1346.                         shader = daeEffect.profileCommon.technique.shader
  1347.                         if shader.transparent:
  1348.                                 tcol = shader.transparent.color.rgba           
  1349.                                 tkey = 1
  1350.                                 if shader.transparency:
  1351.                                         tkey = shader.transparency.float
  1352.                                 alpha = 1 - tkey * (tcol[0]*0.21 + tcol[1]*0.71 + tcol[2]*0.08)
  1353.                                 bMat.setAlpha(alpha)
  1354.                         elif shader.transparency:
  1355.                                 alpha = 1 - shader.transparency.float
  1356.                         if shader.reflective:
  1357.                                 color = shader.reflective.color.rgba
  1358.                                 bMat.setMirCol(color[0], color[1], color[2])
  1359.                         if shader.reflectivity:
  1360.                                 bMat.setRef(shader.reflectivity.float)
  1361.  
  1362.                         if isinstance(shader,collada.DaeFxShadeLambert) or isinstance(shader, collada.DaeFxShadeBlinn) or isinstance(shader, collada.DaeFxShadePhong):
  1363.                                 bMat.setDiffuseShader(Blender.Material.Shaders.DIFFUSE_LAMBERT)
  1364.                                 if shader.diffuse:
  1365.                                         ##print shader.diffuse.color.rgba, shader.diffuse.color
  1366.                                         if not (shader.diffuse.color is None):
  1367.                                                 color = shader.diffuse.color.rgba
  1368.                                                 bMat.setRGBCol(color[0],color[1], color[2])
  1369.                                         if not (shader.diffuse.texture is None): # Texture
  1370.                                                 texture = shader.diffuse.texture.texture
  1371.                                                 if not (texture is None):
  1372.                                                         bTexture = self.document.texturesLibrary.FindObject(texture, True)
  1373.                                                         if not bTexture is None:
  1374.                                                                 bMat.setTexture(0, bTexture, Blender.Texture.TexCo.UV)
  1375.                                                
  1376.                                 bMat.setSpec(0)                  
  1377.                        
  1378.                         if isinstance(shader, collada.DaeFxShadeBlinn) or isinstance(shader, collada.DaeFxShadePhong):
  1379.                                 if not isinstance(shader, collada.DaeFxShadePhong):
  1380.                                         bMat.setSpecShader(Blender.Material.Shaders.SPEC_BLINN)
  1381.                                         if shader.indexOfRefraction:
  1382.                                                 shader.indexOfRefraction.float
  1383.                                                 bMat.setRefracIndex(shader.indexOfRefraction.float)
  1384.                                 else:
  1385.                                         bMat.setSpecShader(Blender.Material.Shaders.SPEC_PHONG)
  1386.                                 if shader.specular:
  1387.                                         specColor = shader.specular.color.rgba
  1388.                                         bMat.setSpecCol(specColor[0], specColor[1], specColor[2])
  1389.                                 bMat.setSpec(1)
  1390.                                 if shader.shininess:
  1391.                                         bMat.setHardness(int(shader.shininess.float) * 4)
  1392.                        
  1393.                 return bMat        
  1394.                
  1395.         def SaveToDae(self, bMaterial):
  1396.                 global useRelativePaths, filename
  1397.                 daeMaterial = collada.DaeFxMaterial()
  1398.                 daeMaterial.id = daeMaterial.name = self.document.CreateID(bMaterial.name, '-Material')
  1399.                
  1400.                 instance = collada.DaeFxEffectInstance()
  1401.                 daeEffect = self.document.colladaDocument.effectsLibrary.FindObject(bMaterial.name+'-fx')
  1402.                 meshNode = MeshNode(self.document)
  1403.                 if daeEffect is None:
  1404.                         daeEffect = collada.DaeFxEffect()
  1405.                         daeEffect.id = daeEffect.name = self.document.CreateID(bMaterial.name , '-fx')
  1406.                         shader = None
  1407.                         if bMaterial.getSpec() > 0.0:
  1408.                                 if bMaterial.getSpecShader() == Blender.Material.Shaders.SPEC_BLINN:
  1409.                                         shader = collada.DaeFxShadeBlinn()
  1410.                                         shader.AddValue(collada.DaeFxSyntax.INDEXOFREFRACTION, bMaterial.getRefracIndex())
  1411.                                 else:
  1412.                                         shader = collada.DaeFxShadePhong()                               
  1413.                                 shader.AddValue(collada.DaeFxSyntax.SPECULAR, [col * bMaterial.getSpec() for col in bMaterial.getSpecCol()]+[1])
  1414.                                 shader.AddValue(collada.DaeFxSyntax.SHININESS, bMaterial.getHardness() * 0.25)
  1415.                                
  1416.                         else :
  1417.                                 shader = collada.DaeFxShadeLambert()
  1418.                        
  1419.                         # Check if a texture is used for color
  1420.                         textures = bMaterial.getTextures()
  1421.                         for mTex in textures:                            
  1422.                                 # Check if this texture is mapped to Color
  1423.                                 if not mTex is None and mTex.mapto == Blender.Texture.MapTo.COL:
  1424.                                         texture = mTex.tex
  1425.                                         if not texture.image is None and Blender.sys.exists(texture.image.filename):
  1426.                                                 daeImage = self.document.colladaDocument.imagesLibrary.FindObject(texture.name)                                    
  1427.                                                 if daeImage is None: # Create the image
  1428.                                                         daeImage = collada.DaeImage()
  1429.                                                         daeImage.id = daeImage.name = self.document.CreateID(texture.name,'-image')
  1430.                                                         daeImage.initFrom = Blender.sys.expandpath(texture.image.filename)
  1431.                                                         if useRelativePaths:
  1432.                                                                 daeImage.initFrom = CreateRelativePath(filename, daeImage.initFrom)                                                                                                                              
  1433.                                                         self.document.colladaDocument.imagesLibrary.AddItem(daeImage)
  1434.                                                         daeTexture = collada.DaeFxTexture()
  1435.                                                         daeTexture.texture = daeImage.id
  1436.                                                         shader.AddValue(collada.DaeFxSyntax.DIFFUSE, daeTexture)
  1437.                                                         break
  1438.                        
  1439.                         shader.AddValue(collada.DaeFxSyntax.DIFFUSE,bMaterial.getRGBCol()+[1])
  1440.                         shader.AddValue(collada.DaeFxSyntax.TRANSPARENCY, 1 - bMaterial.alpha)
  1441.                         shader.AddValue(collada.DaeFxSyntax.TRANSPARENT, [1,1,1,1])
  1442.                         shader.AddValue(collada.DaeFxSyntax.EMISSION, [col * bMaterial.getEmit() for col in bMaterial.getRGBCol()] + [1])
  1443.                         shader.AddValue(collada.DaeFxSyntax.AMBIENT, [col * bMaterial.getAmb() for col in bMaterial.getRGBCol()] + [1])
  1444.                         shader.AddValue(collada.DaeFxSyntax.REFLECTIVE, bMaterial.getMirCol() + [1])
  1445.                         shader.AddValue(collada.DaeFxSyntax.REFLECTIVITY, bMaterial.getRef())
  1446.                         daeEffect.AddShader(shader)
  1447.  
  1448.                         #Doug: added Mar3008 next 3 lines
  1449.                         #if (meshNode.mode & Blender.Mesh.Modes.DOUBLESIDED):
  1450.                         if 1:
  1451.                                 daeEffect.AddDoubleSided(1)
  1452.                                
  1453.                         self.document.colladaDocument.effectsLibrary.AddItem(daeEffect)                    
  1454.                 instance.object = daeEffect
  1455.                
  1456.                 daeMaterial.iEffects.append(instance)
  1457.                
  1458.                 self.document.colladaDocument.materialsLibrary.AddItem(daeMaterial)
  1459.                 return daeMaterial
  1460.                
  1461. class CameraNode(object):
  1462.         def __init__(self,document):
  1463.                 self.document = document
  1464.        
  1465.         def LoadFromDae(self, daeCamera):
  1466.                 camID = daeCamera.id
  1467.                 camName = daeCamera.name
  1468.                 camType = 'persp'
  1469.                 clipStart = daeCamera.optics.techniqueCommon.znear
  1470.                 clipEnd = daeCamera.optics.techniqueCommon.zfar
  1471.                
  1472.                 if daeCamera.optics.techniqueCommon.GetType() == collada.DaeSyntax.ORTHOGRAPHIC:
  1473.                         camType = 'ortho'
  1474.                
  1475.                 camera = Blender.Camera.New(camType,camID)
  1476.                 camera.clipStart = clipStart
  1477.                 camera.clipEnd = clipEnd
  1478.                 return camera
  1479.  
  1480.        
  1481.         def SaveToDae(self, bCamera):
  1482.                 daeCamera = collada.DaeCamera()
  1483.                 daeCamera.id = daeCamera.name = self.document.CreateID(bCamera.name,'-Camera')
  1484.                 daeOptics = collada.DaeOptics()
  1485.                 daeTechniqueCommon = None
  1486.                 if bCamera.type == 1: # orthographic
  1487.                         daeTechniqueCommon = collada.DaeOptics.DaeOrthoGraphic()
  1488.                 else: # perspective
  1489.                         daeTechniqueCommon = collada.DaeOptics.DaePerspective()
  1490.                         lens = bCamera.getLens( )
  1491.                         daeTechniqueCommon.yfov = 2 * ( math.atan( 16.0 / lens ) ) * radianToAngle
  1492.                        
  1493.                 daeTechniqueCommon.znear = bCamera.clipStart
  1494.                 daeTechniqueCommon.zfar = bCamera.clipEnd
  1495.                
  1496.                 daeOptics.techniqueCommon = daeTechniqueCommon
  1497.                 daeCamera.optics = daeOptics
  1498.                
  1499.                 self.document.colladaDocument.camerasLibrary.AddItem(daeCamera)
  1500.                 return daeCamera
  1501.        
  1502. class LibnodeNode(object):  #Doug added for <library_nodes>
  1503.         def __init__(self,document):
  1504.                 self.document = document
  1505.        
  1506.         def LoadFromDae(self, daeNode):
  1507.                 libnodeID = daeNode.id
  1508.                 libnodeName = daeNode.name
  1509.                
  1510.                 libnode = Blender.Object.New()
  1511.                 return libnode
  1512.  
  1513.        
  1514.         def SaveToDae(self, libnode):
  1515.                 daeNode = collada.DaeNode()
  1516. ##              print 'in LibnodeNode.SaveToDae libnode.name=',libnode.name
  1517.                 daeNode.id = daeNode.name = self.document.CreateID(libnode.name,'-ln')
  1518. ##              print 'daeNode.id=',daeNode.id
  1519.                 daeTechniqueCommon = None
  1520.                 #Doug: somewhere here I do I need to copy something from libnode to daeNode?
  1521.                
  1522.                 self.document.colladaDocument.nodesLibrary.AddItem(daeNode)
  1523.                 return daeNode
  1524.        
  1525. class LampNode(object):
  1526.         def __init__(self,document):
  1527.                 self.document = document
  1528.                
  1529.         def LoadFromDae(self, daeLight):
  1530.                
  1531.                 lampID = daeLight.id
  1532.                 lampName = daeLight.name
  1533.                
  1534.                 # Create a new lampObject
  1535.                 lamp = Blender.Lamp.New('Sun',lampID)
  1536.                
  1537.                 if daeLight.techniqueCommon.GetType() == collada.DaeSyntax.DIRECTIONAL:
  1538.                         lamp.type = Blender.Lamp.Types.Sun
  1539.                 elif daeLight.techniqueCommon.GetType() == collada.DaeSyntax.POINT:
  1540.                         lamp.type = Blender.Lamp.Types.Lamp
  1541.                         # Get the attenuation
  1542.                         constAtt = daeLight.techniqueCommon.constantAttenuation
  1543.                         linAtt = daeLight.techniqueCommon.linearAttenuation
  1544.                         # set the attenuation
  1545.                         lamp.energy = 1-constAtt
  1546.                         if linAtt > 0.0:
  1547.                                 lamp.dist = (lamp.energy/2)/ linAtt
  1548.                         else:
  1549.                                 lamp.dist = 5000.0
  1550.                 elif daeLight.techniqueCommon.GetType() == collada.DaeSyntax.SPOT:
  1551.                         lamp.type = Blender.Lamp.Types.Spot
  1552.                         # Get the attenuation
  1553.                         constAtt = daeLight.techniqueCommon.constantAttenuation
  1554.                         linAtt = daeLight.techniqueCommon.linearAttenuation
  1555.                         # set the attenuation
  1556.                         lamp.energy = 1-constAtt
  1557.                         if linAtt > 0.0:
  1558.                                 lamp.dist = (0.5 - constAtt)/ linAtt
  1559.                         else:
  1560.                                 lamp.dist = 5000.0
  1561.                         lamp.spotSize = daeLight.techniqueCommon.falloffAngle
  1562.                         lamp.spotBlend = daeLight.techniqueCommon.falloffExponent
  1563.                 elif daeLight.techniqueCommon.GetType() == collada.DaeSyntax.AMBIENT:
  1564.                         lamp.type = Blender.Lamp.Types.Hemi
  1565.                        
  1566.  
  1567.                 # Set the color
  1568.                 lamp.col = daeLight.techniqueCommon.color
  1569.                
  1570.                 return lamp
  1571.        
  1572.         def SaveToDae(self, bLamp):
  1573.                 daeLight = collada.DaeLight()
  1574.                 daeLight.id = daeLight.name = self.document.CreateID(bLamp.name,'-Light')
  1575.                
  1576.                 daeTechniqueCommon = None
  1577.                 if bLamp.type == Blender.Lamp.Types.Hemi: # Ambient
  1578.                         daeTechniqueCommon = collada.DaeLight.DaeAmbient()
  1579.                 elif bLamp.type == Blender.Lamp.Types.Lamp: # Point light
  1580.                         daeTechniqueCommon = collada.DaeLight.DaePoint()
  1581.                 elif bLamp.type == Blender.Lamp.Types.Spot: # Spot
  1582.                         daeTechniqueCommon = collada.DaeLight.DaeSpot()
  1583.                         daeTechniqueCommon.constantAttenuation = 1-bLamp.energy
  1584.                         daeTechniqueCommon.linearAttenuation = (0.5 - daeTechniqueCommon.constantAttenuation)/bLamp.dist
  1585.                 elif bLamp.type == Blender.Lamp.Types.Sun: # Directional
  1586.                         daeTechniqueCommon = collada.DaeLight.DaeDirectional()
  1587.                 else: # area
  1588.                         daeTechniqueCommon = collada.DaeOptics.TechniqueCommon()
  1589.                
  1590.                 daeTechniqueCommon.color = bLamp.col   
  1591.                 daeLight.techniqueCommon = daeTechniqueCommon
  1592.                
  1593.                 self.document.colladaDocument.lightsLibrary.AddItem(daeLight)
  1594.                 return daeLight
  1595.                
  1596. class Library(object):
  1597.         def __init__(self, document):
  1598.                 self.objects = dict()
  1599.                 self.document = document
  1600.                 self.daeLibrary = None
  1601.                
  1602.         def SetDaeLibrary(self, daeLibrary):
  1603.                 self.daeLibrary = daeLibrary
  1604.        
  1605.         def FindObject(self, daeInstance, fromDae):
  1606.                 for k in self.objects:
  1607.                        
  1608.                         if 'url' in dir(daeInstance) and k == daeInstance.url:
  1609.                                 return self.objects[k][0]
  1610.                         elif 'target' in dir(daeInstance) and k == daeInstance.target:
  1611.                                 return self.objects[k][0]                
  1612.                 if fromDae:
  1613.                         # dataObject not in library, so add it
  1614.                         return self.LoadFromDae(daeInstance)
  1615.                 else:
  1616.                         return self.SaveToDae(daeIntance)
  1617.        
  1618.         def FindObjectEx(self, bObject):
  1619.                 for k in self.objects:
  1620.                         if k == id:
  1621.                                 return self.objects[k][0]
  1622.                
  1623.                 return self.SaveToDae(bObject)
  1624.                
  1625.                
  1626.         def LoadFromDae(self, daeInstance):
  1627.                 Debug.Debug('Library: Please override this method','WARNING')
  1628.                
  1629.         def SaveToDae(self, bScene):
  1630.                 Debug.Debug('Library: Please override this method','WARNING')
  1631.                        
  1632. class ScenesLibrary(Library):
  1633.        
  1634.         def LoadFromDae(self, daeInstance):        
  1635.                 daeVisualScene = self.daeLibrary.FindObject(daeInstance.url)
  1636.                 # TODO: implement multiple scenes
  1637.                 return None
  1638.        
  1639.         def SaveToDae(self, id):
  1640.                 pass
  1641.                 #print bScene
  1642.                                
  1643. class CamerasLibrary(Library):
  1644.        
  1645.         def LoadFromDae(self, daeInstance):
  1646.                 daeCamera = self.daeLibrary.FindObject(daeInstance.url)
  1647.                 if daeCamera is None:
  1648.                         Debug.Debug('CamerasLibrary: Object with this ID does not exist','ERROR')
  1649.                         return
  1650.                
  1651.                 camID = daeCamera.id
  1652.                 camName = daeCamera.name
  1653.                
  1654.                 cameraNode = CameraNode(self.document)
  1655.                 camera = cameraNode.LoadFromDae(daeCamera)
  1656.  
  1657.                 self.objects[camID] = [camera,camera.name]
  1658.                 return camera
  1659.        
  1660.         def SaveToDae(self, id):
  1661.                 pass
  1662.                
  1663. class LampsLibrary(Library):
  1664.        
  1665.         def LoadFromDae(self, daeInstance):        
  1666.                 daeLight = self.daeLibrary.FindObject(daeInstance.url)
  1667.                 if daeLight is None:
  1668.                         Debug.Debug('LightsLibrary: Object with this ID does not exist','ERROR')
  1669.                         return
  1670.                 lampID = daeLight.id
  1671.                 lampName = daeLight.name
  1672.                
  1673.                 lampNode = LampNode(self.document)
  1674.                 lamp = lampNode.LoadFromDae(daeLight)
  1675.                
  1676.                 self.objects[lampID] = [lamp,lamp.name]
  1677.                 return lamp
  1678.        
  1679.         def SaveToDae(self, id):
  1680.                 pass
  1681.                
  1682. class MeshLibrary(Library):
  1683.        
  1684.         def LoadFromDae(self, daeInstance):        
  1685.                 daeGeometry = self.daeLibrary.FindObject(daeInstance.url)
  1686.                 if daeGeometry is None:
  1687.                         Debug.Debug('MeshLibrary: Object with this ID does not exist','ERROR')
  1688.                         return
  1689.                 meshID = daeGeometry.id
  1690.                 meshName = daeGeometry.name
  1691.                
  1692.                 meshNode = MeshNode(self.document)
  1693.                
  1694.                 # Get the materials ( only get the first one right now)
  1695.                 bMaterials = daeInstance.bindMaterials
  1696.                 meshNode.materials = dict()
  1697.                 if bMaterials:
  1698.                         for bMaterial in bMaterials:
  1699.                                 for iMaterial in bMaterial.techniqueCommon.iMaterials:
  1700.                                         Material = self.document.materialsLibrary.FindObject(iMaterial,True)
  1701.                                         meshNode.materials[iMaterial.target] = Material
  1702.                                         ##print 'Mat:',Material
  1703.                 ##print meshNode.materials
  1704. ##                        bMaterial = bMaterials[0]
  1705. ##                        if bMaterial:
  1706. ##                                iMaterials = bMaterial.techniqueCommon.iMaterials
  1707. ##                                if iMaterials:
  1708. ##                                        if iMaterials[0]:
  1709. ##                                                meshNode.materials = [self.document.materialsLibrary.FindObject(iMaterials[0],True)]
  1710. ##                       
  1711.                
  1712.                 bMesh = meshNode.LoadFromDae(daeGeometry)
  1713.  
  1714.                 # Add this mesh in this library, under it's real name
  1715.                 self.objects[meshID] = [bMesh,bMesh.name]
  1716.                 return bMesh
  1717.        
  1718.         def SaveToDae(self, id):
  1719.                 pass
  1720.  
  1721. class NodesLibrary(Library):   #Doug added this. Looks like its just a debug wrapper for import - dont need for export
  1722.        
  1723.         def LoadFromDae(self, daeInstance):        
  1724.                 daeLibNode = self.daeLibrary.FindObject(daeInstance.target)
  1725.                 if daeLibNode is None:
  1726.                         Debug.Debug('NodeLibrary: Object with this TARGET:%s does not exist'%(daeInstance.target),'ERROR')
  1727.                         return
  1728.                 nodeID = daeLibNode.id
  1729.                 nodeName = daeLibNode.name
  1730.                
  1731.                 libNodeNode = LibNodeNode(self.document)
  1732.                
  1733.                 bLibNode = libNodeNode.LoadFromDae(daeLibNode)
  1734.  
  1735.                 # Add this mesh in this library, under it's real name
  1736.                 self.objects[nodeID] = [bLibNode,bLibNode.name]
  1737.                 return bLibNode
  1738.        
  1739.         def SaveToDae(self, id):
  1740.                 pass
  1741.                
  1742. class MaterialsLibrary(Library):
  1743.        
  1744.         def LoadFromDae(self, daeInstance):        
  1745.                 daeMaterial = self.daeLibrary.FindObject(daeInstance.target)
  1746.                 if daeMaterial is None:
  1747.                         Debug.Debug('MaterialLibrary: Object with this TARGET:%s does not exist'%(daeInstance.target),'ERROR')
  1748.                         return
  1749.                 materialID = daeMaterial.id
  1750.                 materialName = daeMaterial.name
  1751.                
  1752.                 materialNode = MaterialNode(self.document)
  1753.                
  1754.                 bMaterial = materialNode.LoadFromDae(daeMaterial)
  1755.  
  1756.                 # Add this mesh in this library, under it's real name
  1757.                 self.objects[materialID] = [bMaterial,bMaterial.name]
  1758.                 return bMaterial
  1759.        
  1760.         def SaveToDae(self, id):
  1761.                 pass
  1762.  
  1763. class TexturesLibrary(Library):
  1764.        
  1765.         def LoadFromDae(self, daeImage):               
  1766.                 if daeImage is None:
  1767.                         Debug.Debug('TexturesLibrary: Object with this TARGET:%s does not exist'%(daeImage),'ERROR')
  1768.                         return
  1769.                 imageID = daeImage.id
  1770.                 imageName = daeImage.name
  1771.                
  1772.                 textureNode = TextureNode(self.document)
  1773.                 bTexture = textureNode.LoadFromDae(daeImage)
  1774.                 bTexture.setType('Image')
  1775.                
  1776.                 # Add this texture in this library, under it's real name
  1777.                 self.objects[imageID] = [bTexture,bTexture.name]
  1778.                 return bTexture
  1779.        
  1780.         def SaveToDae(self, id):
  1781.                 pass
  1782.  
go to heaven