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 xml.dom.minidom import *
import xmlUtils
from cutils import *
from datetime import *

# The number of decimals to export floats to
ROUND = 5

# TODO: finish DaeDocument
class DaeDocument(object):

def __init__(self, debugM = False):
global debugMode
debugMode = debugM

self.colladaVersion = '1.4.0'
self.version = ''
self.xmlns = ''
self.asset = DaeAsset()
self.extras = []


# create all the libraries
self.animationsLibrary = DaeLibrary(DaeSyntax.LIBRARY_ANIMATIONS,DaeAnimation,DaeSyntax.ANIMATION)
self.animationClipsLibrary = DaeLibrary(DaeSyntax.LIBRARY_ANIMATION_CLIPS,DaeAnimationClip,DaeSyntax.ANIMATION_CLIP)
self.camerasLibrary = DaeLibrary(DaeSyntax.LIBRARY_CAMERAS,DaeCamera,DaeSyntax.CAMERA)
self.controllersLibrary = DaeLibrary(DaeSyntax.LIBRARY_CONTROLLERS,DaeController,DaeSyntax.CONTROLLER)
self.effectsLibrary = DaeLibrary(DaeSyntax.LIBRARY_EFFECTS,DaeFxEffect,DaeFxSyntax.EFFECT)
self.geometriesLibrary = DaeLibrary(DaeSyntax.LIBRARY_GEOMETRIES,DaeGeometry,DaeSyntax.GEOMETRY)
self.imagesLibrary = DaeLibrary(DaeSyntax.LIBRARY_IMAGES, DaeImage, DaeSyntax.IMAGE)
self.lightsLibrary = DaeLibrary(DaeSyntax.LIBRARY_LIGHTS,DaeLight,DaeSyntax.LIGHT)
self.materialsLibrary = DaeLibrary(DaeSyntax.LIBRARY_MATERIALS,DaeFxMaterial,DaeFxSyntax.MATERIAL)
self.nodesLibrary = DaeLibrary(DaeSyntax.LIBRARY_NODES, DaeNode, DaeSyntax.NODE)
self.visualScenesLibrary = DaeLibrary(DaeSyntax.LIBRARY_VISUAL_SCENES,DaeVisualScene,DaeSyntax.VISUAL_SCENE)

# Physics Support
self.physicsMaterialsLibrary = DaeLibrary(DaeSyntax.LIBRARY_PHYSICS_MATERIALS, DaePhysicsMaterial, DaePhysicsSyntax.PHYSICS_MATERIAL)
self.physicsScenesLibrary = DaeLibrary(DaeSyntax.LIBRARY_PHYSICS_SCENES, DaePhysicsScene, DaePhysicsSyntax.PHYSICS_SCENE)

self.physicsModelsLibrary = DaeLibrary(DaeSyntax.LIBRARY_PHYSICS_MODELS, DaePhysicsModel, DaePhysicsSyntax.PHYSICS_MODEL)

self.scene = None
self.physicsScene = None

def LoadDocumentFromFile(self, filename):
global debugMode
# Build DOM tree
doc = parse( filename )

# Get COLLADA element
colladaNode = doc.documentElement

# Get Attributes
self.version = colladaNode.getAttribute(DaeSyntax.VERSION)
if not IsVersionOk(self.version, self.colladaVersion):
Debug.Debug('The version of the file (%s) is older then the version supported by this plugin(%s).'%(self.version, self.colladaVersion),'ERROR')
doc.unlink()
return
self.xmlns = colladaNode.getAttribute(DaeSyntax.XMLNS)

# get the assets element
self.asset.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.ASSET))

# get the extra elements
self.extras = CreateObjectsFromXml(self,colladaNode,DaeSyntax.EXTRA,DaeExtra)

# parse all the libraries
self.imagesLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_IMAGES))
self.animationsLibrary.LoadFromXml(self, xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_IMAGES))
self.animationClipsLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_ANIMATION_CLIPS))
self.camerasLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_CAMERAS))
self.controllersLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_CONTROLLERS))
self.effectsLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_EFFECTS))
self.geometriesLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_GEOMETRIES))
self.lightsLibrary.LoadFromXml(self, xmlUtils.FindElementByTagName(colladaNode, DaeSyntax.LIBRARY_LIGHTS))
self.materialsLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_MATERIALS))
self.nodesLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_NODES))
self.visualScenesLibrary.LoadFromXml(self, xmlUtils.FindElementByTagName(colladaNode, DaeSyntax.LIBRARY_VISUAL_SCENES))

self.physicsMaterialsLibrary.LoadFromXml(self, xmlUtils.FindElementByTagName(colladaNode, DaeSyntax.LIBRARY_PHYSICS_MATERIALS))
self.physicsModelsLibrary.LoadFromXml(self, xmlUtils.FindElementByTagName(colladaNode, DaeSyntax.LIBRARY_PHYSICS_MODELS))
self.physicsScenesLibrary.LoadFromXml(self, xmlUtils.FindElementByTagName(colladaNode, DaeSyntax.LIBRARY_PHYSICS_SCENES))

# Get the sceneNodes
sceneNodes = colladaNode.getElementsByTagName(DaeSyntax.SCENE)

# Get the scene
sceneNode = xmlUtils.FindElementByTagName(colladaNode, DaeSyntax.SCENE)
if sceneNode != None:
scene = DaeScene()
scene.LoadFromXml(self, sceneNode)
self.scene = scene

doc.unlink()

if debugMode:
Debug.Debug('Directly exporting this DaeDocument...','DEBUG')
self.SaveDocumentToFile(filename+'_out.dae')

def SaveDocumentToFile(self, filename):
self.version = '1.4.0'
self.xmlns = 'http://www.collada.org/2005/11/COLLADASchema'
colladaNode = Element(DaeSyntax.COLLADA)
colladaNode.setAttribute(DaeSyntax.VERSION, self.version)
colladaNode.setAttribute(DaeSyntax.XMLNS, self.xmlns)

colladaNode.appendChild(self.asset.SaveToXml(self))

# add the labraries
AppendChild(self,colladaNode,self.animationsLibrary)
AppendChild(self,colladaNode,self.animationClipsLibrary)
AppendChild(self,colladaNode,self.camerasLibrary)
AppendChild(self,colladaNode,self.controllersLibrary)
AppendChild(self,colladaNode,self.effectsLibrary)
AppendChild(self,colladaNode,self.geometriesLibrary)
AppendChild(self,colladaNode,self.imagesLibrary)
AppendChild(self,colladaNode,self.lightsLibrary)
AppendChild(self,colladaNode,self.materialsLibrary)
AppendChild(self,colladaNode,self.nodesLibrary)
AppendChild(self,colladaNode,self.visualScenesLibrary)
AppendChild(self,colladaNode,self.physicsMaterialsLibrary)
AppendChild(self,colladaNode,self.physicsModelsLibrary)
AppendChild(self,colladaNode,self.physicsScenesLibrary)

AppendChild(self,colladaNode,self.scene)

# write xml to the file
fileref = open(filename, 'w')
fileref.write(xmlUtils.ToXml(colladaNode))
fileref.flush()
fileref.close()
colladaNode.unlink()

def GetItemCount(self):
return (##self.animationClipsLibrary.GetItemCount()+
##self.animationsLibrary.GetItemCount()+
##self.camerasLibrary.GetItemCount()+
##self.controllersLibrary.GetItemCount()+
##self.effectsLibrary.GetItemCount()+
self.geometriesLibrary.GetItemCount()+
self.lightsLibrary.GetItemCount()+
##self.materialsLibrary.GetItemCount()+
self.nodesLibrary.GetItemCount()##+
##self.visualScenesLibrary.GetItemCount()
)

def __str__(self):
return '%s version: %s, xmlns: %s, asset: %s, extras: %s, scene: %s'%(type(self), self.version, self.xmlns, self.asset, self.extras, self.scene)

class DaeEntity(object):
def __init__(self):
self.syntax = 'UNKNOWN'

def LoadFromXml(self, daeDocument, xmlNode):
Debug.Debug('DaeEntity: Override this method for %s'%(type(self)),'WARNING')

def SaveToXml(self, daeDocument):
node = Element(self.syntax)
return node

def GetType(self):
return self.syntax

class DaeElement(DaeEntity):

def __init__(self):
super(DaeElement,self).__init__()

self.id = ''
self.name = ''


def LoadFromXml(self,daeDocument, xmlNode):
if xmlNode is None:
return

self.id = xmlNode.getAttribute(DaeSyntax.ID)
self.name = xmlNode.getAttribute(DaeSyntax.NAME)

def SaveToXml(self, daeDocument):
node = super(DaeElement,self).SaveToXml(daeDocument)
SetAttribute(node,DaeSyntax.ID,StripString(self.id))
SetAttribute(node,DaeSyntax.NAME, StripString(self.name))
return node

def __str__(self):
return super(DaeElement,self).__str__()+'id: %s, name: %s'%(self.id, self.name)

# TODO: finish DaeLibrary
class DaeLibrary(DaeElement):
def __init__(self, syntax, objectType, objectSyntax):
super(DaeLibrary,self).__init__()

self.extras = []
self.asset = None
self.items = []

self.__objectSyntax = objectSyntax

self.syntax = syntax
self.__objectType = objectType

def LoadFromXml(self,daeDocument, xmlNode):
if xmlNode is None:
return
super(DaeLibrary,self).LoadFromXml(daeDocument, xmlNode)

self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
self.items = CreateObjectsFromXml(daeDocument, xmlNode, self.__objectSyntax, self.__objectType)

def SaveToXml(self,daeDocument):
if len(self.items) > 0:
node = super(DaeLibrary,self).SaveToXml(daeDocument)
# Add the assets
AppendChild(daeDocument,node,self.asset)
# Add the library_items
AppendChilds(daeDocument,node,self.items)
# Add the extra's
AppendChilds(self,node,self.extras)
return node
else:
return None
def GetItemCount(self):
return len(self.items)

def FindObject(self,url):
for i in self.items:
if i.id == url:
return i
return None

def AddItem(self,item):
self.items.append(item)

def __str__(self):
return super(DaeLibrary,self).__str__() + 'extras: %s, asset: %s, items: %s'%(self.extras, self.asset, self.items)

class DaeAsset(DaeEntity):
def __init__(self):
super(DaeAsset,self).__init__()
self.contributors = []
self.created = None
self.modified = None
self.revision = None
self.title = None
self.subject = None
self.keywords = []
self.unit = DaeUnit()
self.upAxis = 'Y_UP'

self.syntax = DaeSyntax.ASSET

def LoadFromXml(self, daeDocument, xmlNode):
if xmlNode is None:
return
# Get the contributor(s)
self.contributors = CreateObjectsFromXml(daeDocument, xmlNode,DaeSyntax.CONTRIBUTOR,DaeContributor)
# Get created
self.created = xmlUtils.ReadDateTime(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.CREATED))
# Get modified
self.modified = xmlUtils.ReadDateTime(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.MODIFIED))
# Get revision
self.revision = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.REVISION))
# Get title
self.title = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.TITLE))
# Get subject
self.subject = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.SUBJECT))
# Get keywords
self.keywords = xmlUtils.GetStringArrayFromNodes(xmlNode.getElementsByTagName(DaeSyntax.KEYWORDS))
# Get Unit
self.unit.LoadFromXml(daeDocument, xmlUtils.FindElementByTagName(xmlNode, DaeSyntax.UNIT))
# Get upAxis
self.upAxis = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.UP_AXIS))

def SaveToXml(self, daeDocument):
node = Element(DaeSyntax.ASSET)
AppendChilds(daeDocument,node, self.contributors)
AppendTextChild(node, DaeSyntax.CREATED, self.created)
AppendTextChild(node, DaeSyntax.MODIFIED, self.modified)
AppendTextChild(node, DaeSyntax.REVISION, self.revision)
AppendTextChild(node, DaeSyntax.TITLE, self.title)
AppendTextChild(node, DaeSyntax.SUBJECT, self.subject)
AppendChild(daeDocument, node, self.unit)
AppendTextChild(node, DaeSyntax.UP_AXIS, self.upAxis)



return node


def __str__(self):
return super(DaeAsset,self).__str__()+'contributors: %s, created: %s, modified: %s, revision: %s, title: %s, subject: %s, keywords: %s, unit: %s, upAxis: %s'%(self.contributors, self.created, self.modified, self.revision, self.title, self.subject, self.keywords, self.unit, self.upAxis)

# TODO: finish DaeScene
class DaeScene(DaeEntity):
def __init__(self):
super(DaeScene,self).__init__()
self.extras = []
self.iVisualScenes = []
self.iPhysicsScenes = []

self.syntax = DaeSyntax.SCENE

def LoadFromXml(self, daeDocument, xmlNode):
if xmlNode is None:
return
self.iVisualScenes = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_VISUAL_SCENE, DaeVisualSceneInstance)
self.iPhysicsScenes = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_PHYSICS_SCENE, DaePhysicsSceneInstance)

def SaveToXml(self, daeDocument):
node = super(DaeScene,self).SaveToXml(daeDocument)
AppendChilds(daeDocument, node, self.iVisualScenes)
AppendChilds(daeDocument, node, self.iPhysicsScenes)
return node

def GetVisualScenes(self):
result = []
for i in self.iVisualScenes:
result.append(i.object)
return result

def GetPhysicsScenes(self):
result = []
for i in self.iPhysicsScenes:
result.append(i.object)
return result

def __str__(self):
return super(DaeScene,self).__str__()+'extras: %s, visualScenes: %s, physicsScenes: %s'%(self.extras, self.iVisualScenes, self.iPhysicsScenes)


class DaeUnit(DaeEntity):
def __init__(self):
super(DaeUnit,self).__init__()
self.name = 'meter'
self.meter = 1.0

self.syntax = DaeSyntax.UNIT

def LoadFromXml(self, daeDocument, xmlNode):
if xmlNode is None:
return
name = xmlNode.getAttribute(DaeSyntax.NAME)
if name != '':
self.name = name

meter = xmlNode.getAttribute(DaeSyntax.METER)
if meter != '':
self.meter = float(meter)

def SaveToXml(self,daeDocument):
node = super(DaeUnit, self).SaveToXml(daeDocument)
SetAttribute(node, DaeSyntax.METER, self.meter)
SetAttribute(node, DaeSyntax.NAME, self.name)
return node

def __str__(self):
return super(DaeUnit, self).__str__()+' name: %s, meter: %s'%(self.name, self.meter)

class DaeContributor(DaeEntity):
def __init__(self):
super(DaeContributor, self).__init__()
self.author = ''
self.authoringTool = ''
self.comments = ''
self.copyright = ''
self.sourceData = ''

self.syntax = DaeSyntax.CONTRIBUTOR

def LoadFromXml(self, daeDocument, xmlNode):
self.author = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.AUTHOR))
self.authoringTool = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.AUTHORING_TOOL))
self.comments = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.COMMENTS))
self.copyright = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.COPYRIGHT))
self.sourceData = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.SOURCE_DATA))

def SaveToXml(self, daeDocument):
node = super(DaeContributor, self).SaveToXml(daeDocument)
AppendTextChild(node, DaeSyntax.AUTHOR, self.author)
AppendTextChild(node, DaeSyntax.AUTHORING_TOOL, self.authoringTool)
AppendTextChild(node, DaeSyntax.COMMENTS, self.comments)
AppendTextChild(node, DaeSyntax.COPYRIGHT, self.copyright)
AppendTextChild(node, DaeSyntax.SOURCE_DATA, self.sourceData)
return node


def __str__(self):
return super(DaeContributor,self).__str__() + 'author: %s, authoring_tool: %s, comments: %s, copyright: %s, sourceData: %s'%(self.author, self.authoringTool, self.comments, self.copyright, self.sourceData)

class DaeAnimation(DaeElement):
pass
class DaeAnimationClip(DaeElement):
pass
class DaeCamera(DaeElement):
def __init__(self):
super(DaeCamera,self).__init__()
self.asset = None
self.extras = []
self.optics = DaeOptics()
self.imager = None
self.syntax = DaeSyntax.CAMERA

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeCamera, self).LoadFromXml(daeDocument, xmlNode)
self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
self.optics.LoadFromXml(daeDocument, xmlUtils.FindElementByTagName(xmlNode, DaeSyntax.OPTICS))
self.imager = CreateObjectFromXml(daeDocument,xmlNode, DaeSyntax.IMAGER,DaeImager)


def SaveToXml(self, daeDocument):
node = super(DaeCamera, self).SaveToXml(daeDocument)
# Add the assets
AppendChild(daeDocument,node,self.asset)
# Add the optics
node.appendChild(self.optics.SaveToXml(daeDocument))
# Add the imager
AppendChild(daeDocument,node,self.imager)
# Add the extra's
AppendChilds(self,node,self.extras)
return node

def __str__(self):
return super(DaeCamera,self).__str__()+'asset: %s, optics: %s, imager: %s, extras: %s'%(self.asset, self.optics, self.imager, self.extras)

class DaeController(DaeElement):
pass
class DaeImage(DaeElement):
def __init__(self):
super(DaeImage,self).__init__()
self.format = None
self.height = None
self.width = None
self.depth = None
self.initFrom = None
self.syntax = DaeSyntax.IMAGE

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeImage, self).LoadFromXml(daeDocument, xmlNode)
self.format = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.FORMAT)
self.height = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.HEIGHT)
self.width = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.WIDTH)
self.depth = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.DEPTH)
self.initFrom = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode, DaeSyntax.INIT_FROM))

def SaveToXml(self, daeDocument):
node = super(DaeImage, self).SaveToXml(daeDocument)
SetAttribute(node, DaeSyntax.FORMAT, self.format)
SetAttribute(node, DaeSyntax.HEIGHT, self.height)
SetAttribute(node, DaeSyntax.WIDTH, self.width)
SetAttribute(node, DaeSyntax.DEPTH, self.depth)
AppendTextChild(node, DaeSyntax.INIT_FROM,self.initFrom, None)
return node

##class DaeMaterial(DaeElement):
## def __init__(self):
## super(DaeMaterial,self).__init__()
## self.asset = None
## self.iEffects = []
## self.extras = None
## self.syntax = DaeSyntax.MATERIAL
##
## def LoadFromXml(self, daeDocument, xmlNode):
## super(DaeMaterial, self).LoadFromXml(daeDocument, xmlNode)
## self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
## self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
## self.iEffects = CreateObjectsFromXml(daeDocument,xmlNode, DaeSyntax.INSTANCE_EFFECT, DaeEffectInstance)
##
## def SaveToXml(self, daeDocument):
## node = super(DaeMaterial, self).SaveToXml(daeDocument)
## # Add the assets
## AppendChild(daeDocument,node,self.asset)
## # Add the effect instances
## AppendChilds(daeDocument, node, self.iEffects)
## # Add the extra's
## AppendChilds(self,node,self.extras)
## return node
##
## def __str__(self):
## return super(DaeLight,self).__str__()+' assets: %s, data: %s, extras: %s'%(self.asset, self.data, self.extras)

class DaeGeometry(DaeElement):
def __init__(self):
super(DaeGeometry,self).__init__()
self.asset = None
self.data = None
self.extras = None
self.syntax = DaeSyntax.GEOMETRY

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeGeometry, self).LoadFromXml(daeDocument, xmlNode)
self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)

self.data = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.MESH, DaeMesh)
if self.data is None:
self.data = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.CONVEX_MESH, DaeConvexMesh)
if self.data is None:
self.data = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.SPLINE, DaeSpline)

def SaveToXml(self, daeDocument):
node = super(DaeGeometry, self).SaveToXml(daeDocument)
# Add the assets
AppendChild(daeDocument,node,self.asset)
# Add the data
AppendChild(daeDocument, node, self.data)
# Add the extra's
AppendChilds(self,node,self.extras)
return node

def __str__(self):
return super(DaeGeometry,self).__str__()+' assets: %s, data: %s, extras: %s'%(self.asset, self.data, self.extras)

class DaeConvexMesh(DaeEntity):
def __init__(self):
super(DaeConvexMesh, self).__init__()
self.syntax = DaeSyntax.CONVEX_MESH
self.convexHullOf = None

def LoadFromXml(self, daeDocument, xmlNode):
self.convexHullOf = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.CONVEX_HULL_OF)

def SaveToXml(self, daeDocument):
node = super(DaeConvexMesh, self).SaveToXml(daeDocument)
SetAttribute(node, DaeSyntax.CONVEX_HULL_OF, StripString(self.convexHullOf))
return node

class DaeMesh(DaeEntity):
def __init__(self):
super(DaeMesh, self).__init__()
self.sources = []
self.vertices = None
self.primitives = []
self.extras = []
self.syntax = DaeSyntax.MESH

def LoadFromXml(self, daeDocument, xmlNode):
if xmlNode is None:
return
self.vertices = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.VERTICES, DaeVertices)
self.sources = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.SOURCE, DaeSource)

lines = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.LINES, DaeLines)
linestrips = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.LINESTRIPS, DaeLineStrips)
polygons = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.POLYGONS, DaePolygons)
polylist = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.POLYLIST, DaePolylist)
triangles = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.TRIANGLES, DaeTriangles)
trifans = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.TRIFANS, DaeTriFans)
tristrips = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.TRISTRIPS, DaeTriStrips)
if lines != None: self.primitives += lines
if linestrips != None: self.primitives += linestrips
if polygons != None: self.primitives += polygons
if polylist != None: self.primitives += polylist
if triangles != None: self.primitives += triangles
if trifans != None: self.primitives += trifans
if tristrips != None: self.primitives += tristrips

self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)

def FindSource(self,input):
for s in self.sources:
if s.id == input.source:
return s
return None

def SaveToXml(self, daeDocument):
node = super(DaeMesh, self).SaveToXml(daeDocument)
AppendChilds(daeDocument, node, self.sources)
AppendChild(daeDocument, node, self.vertices)
AppendChilds(daeDocument, node, self.primitives)
AppendChilds(daeDocument, node, self.extras)
return node
class DaeVertices(DaeElement):
def __init__(self):
super(DaeVertices,self).__init__()
self.inputs = []
self.extras = []

self.syntax = DaeSyntax.VERTICES

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeVertices,self).LoadFromXml(daeDocument, xmlNode)
self.inputs = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INPUT, DaeInput)
self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)

def SaveToXml(self, daeDocument):
node = super(DaeVertices, self).SaveToXml(daeDocument)
AppendChilds(daeDocument, node, self.inputs)
AppendChilds(daeDocument, node, self.extras)
return node

def FindInput(self, semantic):
for i in self.inputs:
if i.semantic == semantic:
return i
return None

def __str__(self):
return super(DaeVertices,self).__str__() + ' inputs: %s, extras: %s'%(self.inputs, self.extras)

class DaeInput(DaeEntity):
def __init__(self):
super(DaeInput, self).__init__()
self.offset = None
self.semantic = ''
self.source = ''
self.set = ''
self.syntax = DaeSyntax.INPUT

def LoadFromXml(self, daeDocument, xmlNode):
self.offset = CastAttributeFromXml(xmlNode, DaeSyntax.OFFSET, int)
self.semantic = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.SEMANTIC)
self.source = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.SOURCE)[1:]
self.set = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.SET)

def SaveToXml(self, daeDocument):
node = super(DaeInput, self).SaveToXml(daeDocument)
SetAttribute(node,DaeSyntax.OFFSET, self.offset)
SetAttribute(node,DaeSyntax.SEMANTIC, self.semantic)
SetAttribute(node,DaeSyntax.SOURCE, StripString('#'+self.source))
SetAttribute(node,DaeSyntax.SET, self.set)
return node

class DaeSource(DaeElement):
def __init__(self):
super(DaeSource, self).__init__()
self.source = DaeArray()
self.vectors = []
self.techniqueCommon = None
self.techniques = []

self.syntax = DaeSyntax.SOURCE

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeSource,self).LoadFromXml(daeDocument, xmlNode)
if xmlNode is None:
return
bools = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.BOOL_ARRAY, DaeBoolArray)
floats = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.FLOAT_ARRAY, DaeFloatArray)
ints = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.INT_ARRAY, DaeIntArray)
if bools != None:
self.source = bools
elif floats != None:
self.source = floats
elif ints != None:
self.source = ints

self.techniqueCommon = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.TECHNIQUE_COMMON, DaeSource.DaeTechniqueCommon)
self.techniques = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.TECHNIQUE,DaeTechnique)

for i in range(0,self.techniqueCommon.accessor.count):
vec = []
for j in range(0,self.techniqueCommon.accessor.stride):
vec.append(self.source.data[i*self.techniqueCommon.accessor.stride+j])
self.vectors.append(vec)

def SaveToXml(self, daeDocument):
node = super(DaeSource, self).SaveToXml(daeDocument)
## if len(self.vectors) > 0:
## if type(self.vectors[0][0]) == float:
## self.source = DaeFloatArray()
## self.source.id = self.id+'-array'
##
## for i in range(len(self.vectors)):
## for j in range(len(self.vectors[i])):
## self.source.data.append(self.vectors[i][j])

# Add the source
AppendChild(daeDocument, node, self.source)
# Add the technique common
AppendChild(daeDocument,node,self.techniqueCommon)
# Add the techniques
AppendChilds(daeDocument, node, self.techniques)
return node

def __str__(self):
return super(DaeSource,self).__str__()+' source: %s, techniqueCommon: %s, techniques: %s'%(self.source, self.techniqueCommon, self.techniques)

class DaeTechniqueCommon(DaeEntity):
def __init__(self):
self.accessor = None
self.syntax = DaeSyntax.TECHNIQUE_COMMON

def LoadFromXml(self, daeDocument, xmlNode):
self.accessor = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ACCESSOR, DaeAccessor)

def SaveToXml(self, daeDocument):
node = super(DaeSource.DaeTechniqueCommon,self).SaveToXml(daeDocument)
AppendChild(daeDocument,node, self.accessor)
return node

def __str__(self):
return super(DaeSource.DaeTechniqueCommon,self).__str__()+' accessor: %s'%(self.accessor)

class DaeLight(DaeElement):
def __init__(self):
super(DaeLight,self).__init__()
self.asset = None
self.techniqueCommon = DaeLight.DaeTechniqueCommon()
self.techniques = []
self.extras = None
self.syntax = DaeSyntax.LIGHT

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeLight, self).LoadFromXml(daeDocument, xmlNode)
self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
##self.techniqueCommon.LoadFromXml(daeDocument, xmlUtils.FindElementByTagName(xmlNode, DaeSyntax.TECHNIQUE_COMMON))
self.techniques = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.TECHNIQUE,DaeTechnique)

lightSourceNode = xmlUtils.RemoveWhiteSpaceNode(xmlUtils.FindElementByTagName(xmlNode, DaeSyntax.TECHNIQUE_COMMON)).firstChild
lightSourceName = lightSourceNode.localName
if lightSourceName == DaeSyntax.DIRECTIONAL:
self.techniqueCommon = DaeLight.DaeDirectional()
elif lightSourceName == DaeSyntax.SPOT:
self.techniqueCommon = DaeLight.DaeSpot()
elif lightSourceName == DaeSyntax.AMBIENT:
self.techniqueCommon = DaeLight.DaeAmbient()
elif lightSourceName == DaeSyntax.POINT:
self.techniqueCommon = DaeLight.DaePoint()
self.techniqueCommon.LoadFromXml(daeDocument,lightSourceNode)

def SaveToXml(self, daeDocument):
node = super(DaeLight, self).SaveToXml(daeDocument)
# Add the assets
AppendChild(daeDocument,node,self.asset)
# Add the technique common
AppendChild(daeDocument,node,self.techniqueCommon)
# Add the techniques
AppendChilds(daeDocument, node, self.techniques)
# Add the extra's
AppendChilds(self,node,self.extras)
return node

def __str__(self):
return super(DaeLight,self).__str__()+' techniqueCommon: %s, techniques: %s'%(self.techniqueCommon, self.techniques)

class DaeTechniqueCommon(DaeEntity):
def __init__(self):
self.color = []
self.lightSource = None
self.syntax = DaeSyntax.TECHNIQUE_COMMON

def LoadFromXml(self, daeDocument, xmlNode):
self.color = ToFloat3(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.COLOR)))

def SaveToXml(self, daeDocument):
node = Element(DaeSyntax.TECHNIQUE_COMMON)
child = super(DaeLight.DaeTechniqueCommon,self).SaveToXml(daeDocument)
AppendTextChild(child,DaeSyntax.COLOR, self.color)
node.appendChild(child)
return node

def __str__(self):
return super(DaeLight.DaeTechniqueCommon,self).__str__()+' color: %s'%(self.color)

class DaeAmbient(DaeTechniqueCommon):
def __init__(self):
super(DaeLight.DaeAmbient,self).__init__()
self.syntax = DaeSyntax.AMBIENT

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeLight.DaeAmbient,self).LoadFromXml(daeDocument, xmlNode)

def SaveToXml(self, daeDocument):
node = super(DaeLight.DaeAmbient,self).SaveToXml(daeDocument)
return node

def __str__(self):
return super(DaeLight.DaeAmbient,self).__str__()

class DaeSpot(DaeTechniqueCommon):
def __init__(self):
super(DaeLight.DaeSpot,self).__init__()
self.defConstantAttenuation = 0.0
self.defLinearAttenuation = 0.0
self.defQuadraticAttenuation = 0.0
self.defFalloffAngle = 180.0
self.defFalloffExponent = 0.0

self.constantAttenuation = 0.0
self.linearAttenuation = 0.0
self.quadraticAttenuation = 0.0
self.falloffAngle = 180.0
self.falloffExponent = 0.0
self.syntax = DaeSyntax.SPOT

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeLight.DaeSpot,self).LoadFromXml(daeDocument, xmlNode)
self.constantAttenuation = CastFromXml(daeDocument,xmlNode,DaeSyntax.CONSTANT_ATTENUATION, float, self.defConstantAttenuation)
self.linearAttenuation = CastFromXml(daeDocument,xmlNode,DaeSyntax.LINEAR_ATTENUATION,float, self.defLinearAttenuation)
self.quadraticAttenuation = CastFromXml(daeDocument, xmlNode,DaeSyntax.QUADRATIC_ATTENUATION, float, self.defQuadraticAttenuation)
self.falloffAngle = CastFromXml(daeDocument, xmlNode, DaeSyntax.FALLOFF_ANGLE, float, self.defFalloffAngle)
self.falloffExponent = CastFromXml(daeDocument, xmlNode, DaeSyntax.FALLOFF_EXPONENT, float, self.defFalloffExponent)

def SaveToXml(self, daeDocument):
node = super(DaeLight.DaeSpot,self).SaveToXml(daeDocument)
AppendTextChild(node.firstChild,DaeSyntax.CONSTANT_ATTENUATION, self.constantAttenuation, self.defConstantAttenuation)
AppendTextChild(node.firstChild,DaeSyntax.LINEAR_ATTENUATION, self.linearAttenuation, self.defLinearAttenuation)
AppendTextChild(node.firstChild,DaeSyntax.QUADRATIC_ATTENUATION, self.quadraticAttenuation, self.defQuadraticAttenuation)
AppendTextChild(node.firstChild,DaeSyntax.FALLOFF_ANGLE, self.falloffAngle, self.defFalloffAngle)
AppendTextChild(node.firstChild,DaeSyntax.FALLOFF_EXPONENT, self.falloffExponent, self.defFalloffExponent)
return node

def __str__(self):
return super(DaeLight.DaeSpot,self).__str__()+' const.att: %s, lin.att: %s, quad.att: %s, falloffAngle: %s, falloffExponent: %s'%(self.constantAttenuation, self.linearAttenuation, self.quadraticAttenuation, self.falloffAngle, self.falloffExponent)

class DaeDirectional(DaeTechniqueCommon):
# default direction is [0,0,-1] pointing down the -Z axis.
# To change the direction, change the transform of the parent DaeNode
def __init__(self):
super(DaeLight.DaeDirectional,self).__init__()
self.syntax = DaeSyntax.DIRECTIONAL

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeLight.DaeDirectional,self).LoadFromXml(daeDocument, xmlNode)

def SaveToXml(self, daeDocument):
node = super(DaeLight.DaeDirectional,self).SaveToXml(daeDocument)
return node

def __str__(self):
return super(DaeLight.DaeDirectional,self).__str__()

class DaePoint(DaeTechniqueCommon):
def __init__(self):
super(DaeLight.DaePoint,self).__init__()
self.constantAttenuation = 0.0
self.linearAttenuation = 0.0
self.quadraticAttenuation = 0.0
self.syntax = DaeSyntax.POINT

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeLight.DaePoint,self).LoadFromXml(daeDocument, xmlNode)
self.constantAttenuation = CastFromXml(daeDocument,xmlNode,DaeSyntax.CONSTANT_ATTENUATION, float)
self.linearAttenuation = CastFromXml(daeDocument,xmlNode,DaeSyntax.LINEAR_ATTENUATION,float)
self.quadraticAttenuation = CastFromXml(daeDocument, xmlNode,DaeSyntax.QUADRATIC_ATTENUATION, float)

def SaveToXml(self, daeDocument):
node = super(DaeLight.DaePoint,self).SaveToXml(daeDocument)
AppendTextChild(node.firstChild,DaeSyntax.CONSTANT_ATTENUATION, self.constantAttenuation)
AppendTextChild(node.firstChild,DaeSyntax.LINEAR_ATTENUATION, self.linearAttenuation)
AppendTextChild(node.firstChild,DaeSyntax.QUADRATIC_ATTENUATION, self.quadraticAttenuation)
return node

def __str__(self):
return super(DaeLight.DaePoint,self).__str__()+' const.att: %s, lin.att: %s, quad.att: %s'%(self.constantAttenuation, self.linearAttenuation, self.quadraticAttenuation)

class DaeVisualScene(DaeElement):
def __init__(self):
super(DaeVisualScene,self).__init__()
self.asset = None
self.extras = None
self.nodes = []
self.syntax = DaeSyntax.VISUAL_SCENE

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeVisualScene, self).LoadFromXml(daeDocument, xmlNode)
self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
self.nodes = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.NODE, DaeNode)

def SaveToXml(self, daeDocument):
node = super(DaeVisualScene, self).SaveToXml(daeDocument)
# Add the assets
AppendChild(daeDocument,node,self.asset)
# Add the nodes
AppendChilds(daeDocument, node, self.nodes)
# Add the extra's
AppendChilds(self,node,self.extras)
return node

def FindNode(self, nodeUrl):
for n in self.nodes:
if n.id == nodeUrl:
return n
return None


def __str__(self):
return super(DaeVisualScene,self).__str__()+' asset: %s, nodes: %s, extras: %s'%(self.asset, self.nodes, self.extras)

class DaeNode(DaeElement):

NODE = 2
JOINT = 1

def __init__(self):
super(DaeNode,self).__init__()
self.sid = None
self.type = DaeNode.NODE
self.layer = None
self.transforms = []
self.nodes = [] #Doug: child nodes defined in nested xml

#Doug: instances - references to items defined elsewhere
# ie iNode <instance_node url="#someothernode"/>
self.iAnimations = []
self.iCameras = []
self.iControllers = []
self.iGeometries = []
self.iLights = []
self.iNodes = []
self.iVisualScenes = []

self.syntax = DaeSyntax.NODE

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeNode, self).LoadFromXml(daeDocument, xmlNode)
self.sid = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.SID)
type = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.TYPE)
if type == DaeSyntax.TYPE_JOINT:
self.type = DaeNode.JOINT
else:
self.type = DaeNode.NODE
self.layer = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.LAYER)

# Get transforms
xmlUtils.RemoveWhiteSpaceNode(xmlNode)
child = xmlNode.firstChild
while child != None:
name = child.localName
if name == DaeSyntax.TRANSLATE:
self.transforms.append([name,ToFloatList(xmlUtils.ReadContents(child))])
elif name == DaeSyntax.ROTATE:
self.transforms.append([name,ToFloatList(xmlUtils.ReadContents(child))])
elif name == DaeSyntax.SCALE:
self.transforms.append([name,ToFloatList(xmlUtils.ReadContents(child))])
elif name == DaeSyntax.SKEW:
self.transforms.append([name,ToFloatList(xmlUtils.ReadContents(child))])
elif name == DaeSyntax.LOOKAT:
self.transforms.append([name,ToFloatList(xmlUtils.ReadContents(child))])
elif name == DaeSyntax.MATRIX:
self.transforms.append([name,ToMatrix4(xmlUtils.ReadContents(child))])

child = child.nextSibling

# Get the instances
self.iAnimations = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_ANIMATION, DaeAnimationInstance)
self.iCameras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_CAMERA, DaeCameraInstance)
self.iControllers = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_CONTROLLER, DaeControllerInstance)
self.iGeometries = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_GEOMETRY, DaeGeometryInstance)
self.iLights = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_LIGHT, DaeLightInstance)
self.iNodes = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_NODE, DaeNodeInstance)
self.iVisualScenes = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_VISUAL_SCENE, DaeVisualSceneInstance)

# Get childs nodes
self.nodes = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.NODE, DaeNode)

def SaveToXml(self, daeDocument):
node = super(DaeNode, self).SaveToXml(daeDocument)
SetAttribute(node, DaeSyntax.SID, self.sid)
if self.type == DaeSyntax.TYPE_JOINT:
SetAttribute(node, DaeSyntax.TYPE, DaeNode.GetType(self.type))

SetAttribute(node, DaeSyntax.LAYER, self.layer)
for i in self.transforms:
writeTransform = False
el = Element(i[0])
val = i[1]
if i[0] == DaeSyntax.MATRIX:
val = MatrixToString(val,ROUND)
AppendTextChild(node,i[0],val)
else:
val = ListToString(RoundList(val, 5))
if i[0] == DaeSyntax.SCALE:
AppendTextChild(node,i[0],val,"1.0 1.0 1.0")
elif i[0] == DaeSyntax.TRANSLATE:
AppendTextChild(node,i[0],val,"0.0 0.0 0.0")
elif i[0] == DaeSyntax.ROTATE:
AppendTextChild(node,i[0],val,"0.0 0.0 0.0 0.0")
elif i[0] == DaeSyntax.SKEW:
AppendTextChild(node,i[0],val)
elif i[0] == DaeSyntax.MATRIX or i[0] == DaeSyntax.LOOKAT:
AppendTextChild(node,i[0],val)

AppendChilds(daeDocument, node, self.nodes)

AppendChilds(daeDocument, node, self.iAnimations)
AppendChilds(daeDocument, node, self.iCameras)
AppendChilds(daeDocument, node, self.iControllers)
AppendChilds(daeDocument, node, self.iGeometries)
AppendChilds(daeDocument, node, self.iLights)
AppendChilds(daeDocument, node, self.iNodes)
AppendChilds(daeDocument, node, self.iVisualScenes)

return node

def IsJoint(self):
return self.type == DaeNode.JOINT

def GetType(type):
if type == DaeNode.JOINT:
return DaeSyntax.TYPE_JOINT
else:
return DaeSyntax.TYPE_NODE
GetType = staticmethod(GetType)

def GetInstances(self):
return []+self.iAnimations+self.iCameras+self.iControllers+self.iGeometries+self.iLights+self.iNodes



# TODO: finish DaeTechnique
class DaeTechnique(DaeEntity):
def __init__(self):
super(DaeTechnique,self).__init__()
self.profile = ''
self.xmlns = ''
self.syntax = DaeSyntax.TECHNIQUE

def LoadFromXml(self, daeDocument, xmlNode):
self.profile = xmlNode.getAttribute(DaeSyntax.PROFILE)
self.xmlns = xmlNode.getAttribute(DaeSyntax.XMLNS)

def SaveToXml(self, daeDocument):
node = super(DaeTechnique,self).SaveToXml(daeDocument)
node.setAttribute(DaeSyntax.PROFILE, self.profile)
SetAttribute(node, DaeSyntax.XMLNS, self.xmlns)
return node

class DaeOptics(DaeEntity):
def __init__(self):
super(DaeOptics,self).__init__()
self.techniqueCommon = DaeOptics.DaeTechniqueCommon()
self.techniques = []
self.extras = None
self.syntax = DaeSyntax.OPTICS

def LoadFromXml(self, daeDocument, xmlNode):
self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
#self.techniqueCommon.LoadFromXml(daeDocument, xmlUtils.FindElementByTagName(xmlNode, DaeSyntax.TECHNIQUE_COMMON))
self.techniques = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.TECHNIQUE,DaeTechnique)

opticsSourceNode = xmlUtils.RemoveWhiteSpaceNode(xmlUtils.FindElementByTagName(xmlNode, DaeSyntax.TECHNIQUE_COMMON)).firstChild
opticsSourceName = opticsSourceNode.localName
if opticsSourceName == DaeSyntax.PERSPECTIVE:
self.techniqueCommon = DaeOptics.DaePerspective()
elif opticsSourceName == DaeSyntax.ORTHOGRAPHIC:
self.techniqueCommon = DaeOptics.DaeOrthoGraphic()
self.techniqueCommon.LoadFromXml(daeDocument,opticsSourceNode)

def SaveToXml(self, daeDocument):
node = super(DaeOptics, self).SaveToXml(daeDocument)
# Add the technique common
AppendChild(daeDocument,node,self.techniqueCommon)
# Add the techniques
AppendChilds(daeDocument, node, self.techniques)
# Add the extra's
AppendChilds(self,node,self.extras)
return node

def __str__(self):
return super(DaeOptics,self).__str__()+' extras: %s, techniqueCommon: %s, techniques: %s'%(self.extras, self.techniqueCommon, self.techniques)

class DaeTechniqueCommon(DaeEntity):
def __init__(self):
self.znear = 0.0
self.zfar = 0.0
self.aspectRatio = None

self.syntax = DaeSyntax.TECHNIQUE_COMMON

def LoadFromXml(self, daeDocument, xmlNode):
self.znear = ToFloat(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.ZNEAR)))
self.zfar = ToFloat(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.ZFAR)))
self.aspectRatio = ToFloat(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.ASPECT_RATIO)))

def SaveToXml(self, daeDocument):
node = Element(DaeSyntax.TECHNIQUE_COMMON)
child = super(DaeOptics.DaeTechniqueCommon,self).SaveToXml(daeDocument)
## AppendTextChild(child,DaeSyntax.ZNEAR, self.znear)
## AppendTextChild(child,DaeSyntax.ZFAR, self.zfar)
## AppendTextChild(child,DaeSyntax.ASPECT_RATIO, self.aspectRatio)
node.appendChild(child)
return node

def SavePropertiesToXml(self, daeDocument, node):
AppendTextChild(node,DaeSyntax.ZNEAR, self.znear)
AppendTextChild(node,DaeSyntax.ZFAR, self.zfar)
AppendTextChild(node,DaeSyntax.ASPECT_RATIO, self.aspectRatio)

def __str__(self):
return super(DaeOptics.DaeTechniqueCommon,self).__str__()+' znear: %s, zfar: %s, aspectRatio: %s'%(self.znear, self.zfar, self.aspectRatio)

class DaePerspective(DaeTechniqueCommon):
def __init__(self):
super(DaeOptics.DaePerspective,self).__init__()
self.xfov = None
self.yfov = None
self.syntax = DaeSyntax.PERSPECTIVE

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeOptics.DaePerspective,self).LoadFromXml(daeDocument, xmlNode)
self.xfov = ToFloat(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.XFOV)))
self.yfov = ToFloat(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.YFOV)))

def SaveToXml(self, daeDocument):
node = super(DaeOptics.DaePerspective,self).SaveToXml(daeDocument)
AppendTextChild(node.firstChild,DaeSyntax.XFOV, self.xfov)
AppendTextChild(node.firstChild,DaeSyntax.YFOV, self.yfov)
super(DaeOptics.DaePerspective,self).SavePropertiesToXml(daeDocument, node.firstChild)
return node

def __str__(self):
return super(DaeOptics.DaePerspective,self).__str__()+' xfov: %s, yfov: %s'%(self.xfov, self.yfov)

class DaeOrthoGraphic(DaeTechniqueCommon):
def __init__(self):
super(DaeOptics.DaeOrthoGraphic,self).__init__()
self.xmag = None
self.ymag = None
self.syntax = DaeSyntax.ORTHOGRAPHIC

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeOptics.DaeOrthoGraphic,self).LoadFromXml(daeDocument, xmlNode)
self.xmag = ToFloat(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.XMAG)))
self.ymag = ToFloat(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.YMAG)))

def SaveToXml(self, daeDocument):
node = super(DaeOptics.DaeOrthoGraphic,self).SaveToXml(daeDocument)
AppendTextChild(node.firstChild,DaeSyntax.XMAG, self.xmag)
AppendTextChild(node.firstChild,DaeSyntax.YMAG, self.ymag)
return node

def __str__(self):
return super(DaeOptics.DaeOrthoGraphic,self).__str__()+ 'xmag: %s, ymag: %s'%(self.xmag, self.ymag)

class DaeImager(DaeEntity):
def __init__(self):
super(DaeImager,self).__init__()
self.techniques = []
self.extras = None
self.syntax = DaeSyntax.IMAGER

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeImager, self).LoadFromXml(daeDocument, xmlNode)
self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
self.techniques = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.TECHNIQUE,DaeTechnique)

def SaveToXml(self, daeDocument):
node = super(DaeOptics, self).SaveToXml(daeDocument)
# Add the techniques
AppendChilds(daeDocument, node, self.techniques)
# Add the extra's
AppendChilds(self,node,self.extras)
return node

def __str__(self):
return super(DaeImager,self).__str__()+' extras: %s, techniques: %s'%(self.techniqueCommon, self.techniques)


class DaeExtra(DaeEntity):
def __init__(self):
super(DaeExtra,self).__init__()
self.type = None
self.techniques = []
self.syntax = DaeSyntax.EXTRA

def LoadFromXml(self, daeDocument, xmlNode):
self.type = xmlNode.getAttribute(DaeSyntax.TYPE)
self.techniques = CreateObjectsFromXml(daeDocument, xmlNode,DaeSyntax.TECHNIQUE,DaeTechnique)

def SaveToXml(self, daeDocument):
node = super(DaeExtra,self).SaveToXml(daeDocument)
AppendChilds(daeDocument, node, self.techniques)
return node


def __str__(self):
return super(DaeExtra,self).__str__()+'techniques: %s'%(self.techniques)

class DaeAccessor(DaeEntity):
def __init__(self):
super(DaeAccessor,self).__init__()
self.count = 0
self.offset = None
self.source = ''
self.stride = None
self.params = []

self.syntax = DaeSyntax.ACCESSOR

def LoadFromXml(self,daeDocument, xmlNode):
self.count = CastAttributeFromXml(xmlNode, DaeSyntax.COUNT,int,0)
self.offset = CastAttributeFromXml(xmlNode, DaeSyntax.OFFSET,int)
self.source = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.SOURCE)
self.stride = CastAttributeFromXml(xmlNode, DaeSyntax.STRIDE,int)
self.params = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.PARAM, DaeParam)

def SaveToXml(self, daeDocument):
node = super(DaeAccessor,self).SaveToXml(daeDocument)
node.setAttribute(DaeSyntax.COUNT, str(self.count))
SetAttribute(node,DaeSyntax.OFFSET, self.offset)
node.setAttribute(DaeSyntax.SOURCE, StripString('#'+self.source))
SetAttribute(node, DaeSyntax.STRIDE, len(self.params))
AppendChilds(daeDocument, node, self.params)
return node

def AddParam(self, name, type):
param = DaeParam()
param.name = name
param.type = type
self.params.append(param)

class DaeParam(DaeEntity):
def __init__(self):
super(DaeParam,self).__init__()
self.name = None
self.semantic = None
self.sid = None
self.type = ''
self.syntax = DaeSyntax.PARAM

def LoadFromXml(self, daeDocument, xmlNode):
self.semantic = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.SEMANTIC)
self.sid = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.SID)
self.name = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.NAME)
self.type = xmlNode.getAttribute(DaeSyntax.TYPE)

def SaveToXml(self, daeDocument):
node = super(DaeParam,self).SaveToXml(daeDocument)
SetAttribute(node, DaeSyntax.SEMANTIC, self.semantic)
SetAttribute(node, DaeSyntax.SID, self.sid)
SetAttribute(node, DaeSyntax.NAME, self.name)
node.setAttribute(DaeSyntax.TYPE, self.type)
return node

class DaeArray(DaeElement):
def __init__(self):
super(DaeArray, self).__init__()
self.count = 0
self.data = []

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeArray, self).LoadFromXml(daeDocument, xmlNode)
self.count = ToInt(xmlUtils.ReadAttribute(xmlNode, DaeSyntax.COUNT))
self.data = ToList(xmlUtils.ReadContents(xmlNode))

def SaveToXml(self, daeDocument):
node = super(DaeArray,self).SaveToXml(daeDocument)
SetAttribute(node, DaeSyntax.COUNT, len(self.data))
AppendTextInChild(node, self.data)
return node

def __str__(self):
return super(DaeArray,self).__str__()+' count: %s'%(self.count)


class DaeFloatArray(DaeArray):
def __init__(self):
super(DaeFloatArray, self).__init__()
self.syntax = DaeSyntax.FLOAT_ARRAY

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeFloatArray, self).LoadFromXml(daeDocument, xmlNode)
self.data = ToFloatList(self.data)


class DaeIntArray(DaeArray):
def __init__(self):
super(DaeIntArray, self).__init__()
self.syntax = DaeSyntax.INT_ARRAY

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeIntArray, self).LoadFromXml(daeDocument, xmlNode)
self.data = ToIntList(self.data)

class DaeBoolArray(DaeArray):
def __init__(self):
super(DaeBoolArray, self).__init__()
self.syntax = DaeSyntax.BOOL_ARRAY

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeBoolArray, self).LoadFromXml(daeDocument, xmlNode)
self.data = ToBoolList(self.data)

class DaeNameArray(DaeArray):
def __init__(self):
super(DaeNameArray, self).__init__()
self.syntax = DaeSyntax.NAME_ARRAY

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeNameArray, self).LoadFromXml(daeDocument, xmlNode)
##self.data = ToFloatList(self.data)

class DaeIDREFArray(DaeArray):
def __init__(self):
super(DaeIDREFArray, self).__init__()
self.syntax = DaeSyntax.IDREF_ARRAY

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeIDREFArray, self).LoadFromXml(daeDocument, xmlNode)
##self.data = ToFloatList(self.data)


#---Primitive Classes---
class DaePrimitive(DaeEntity):
def __init__(self):
super(DaePrimitive, self).__init__()
self.name = None
self.count = 0
self.material = ''
self.inputs = []

def LoadFromXml(self, daeDocument, xmlNode):
self.name = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.NAME)
self.count = int(xmlUtils.ReadAttribute(xmlNode, DaeSyntax.COUNT))
self.material = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.MATERIAL)

def SaveToXml(self, daeDocument):
node = super(DaePrimitive, self).SaveToXml(daeDocument)
SetAttribute(node, DaeSyntax.NAME, self.name)
SetAttribute(node, DaeSyntax.MATERIAL, StripString(self.material))
node.setAttribute(DaeSyntax.COUNT, str(self.count))
return node

def GetMaxOffset(self):
if self.inputs != []:
return max([i.offset for i in self.inputs])
else:
return None

def FindInput(self, semantic):
for i in self.inputs:
if i.semantic == semantic:
return i
return None

class DaeLines(DaePrimitive):
def __init__(self):
super(DaeLines, self).__init__()
self.syntax = DaeSyntax.LINES
self.lines = []

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeLines,self).LoadFromXml(daeDocument, xmlNode)
self.syntax = DaeSyntax.LINES
self.inputs = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INPUT, DaeInput)
self.lines = ToIntList(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.P)))

def SaveToXml(self, daeDocument):
node = super(DaeLines,self).SaveToXml(daeDocument)
AppendChilds(daeDocument, node, self.inputs)
AppendTextChild(node, DaeSyntax.P, self.lines)
return node

class DaeLineStrips(DaePrimitive):
def __init__(self):
super(DaeLineStrips, self).__init__()
self.syntax = DaeSyntax.LINESTRIPS

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeLineStrips,self).LoadFromXml(daeDocument, xmlNode)



class DaePolygons(DaePrimitive):
def __init__(self):
super(DaePolygons, self).__init__()
self.syntax = DaeSyntax.POLYGONS
self.polygons = []
self.holedPolygons = []

def LoadFromXml(self, daeDocument, xmlNode):
super(DaePolygons,self).LoadFromXml(daeDocument, xmlNode)
self.polygons = xmlUtils.GetListFromNodes(xmlNode.getElementsByTagName(DaeSyntax.P), int)
self.inputs = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INPUT, DaeInput)

def SaveToXml(self, daeDocument):
node = super(DaePolygons,self).SaveToXml(daeDocument)
AppendChilds(daeDocument, node, self.inputs)
xmlUtils.AppendChilds(node, DaeSyntax.P, self.polygons)
return node

class DaePolylist(DaePrimitive):
def __init__(self):
super(DaePolylist, self).__init__()
self.syntax = DaeSyntax.POLYLIST

def LoadFromXml(self, daeDocument, xmlNode):
super(DaePolylist,self).LoadFromXml(daeDocument, xmlNode)

class DaeTriangles(DaePrimitive):
def __init__(self):
super(DaeTriangles, self).__init__()
self.triangles = []
self.syntax = DaeSyntax.TRIANGLES

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeTriangles,self).LoadFromXml(daeDocument, xmlNode)
self.triangles = ToIntList(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.P)))
self.inputs = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INPUT, DaeInput)

def SaveToXml(self, daeDocument):
node = super(DaeTriangles,self).SaveToXml(daeDocument)
AppendChilds(daeDocument, node, self.inputs)
AppendTextChild(node, DaeSyntax.P, self.triangles)
return node

class DaeTriFans(DaePrimitive):
def __init__(self):
super(DaeTriFans, self).__init__()
self.syntax = DaeSyntax.TRIFANS

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeTriFans,self).LoadFromXml(daeDocument, xmlNode)

class DaeTriStrips(DaePrimitive):
def __init__(self):
super(DaeTriStrips, self).__init__()
self.syntax = DaeSyntax.TRISTRIPS

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeTriStrips,self).LoadFromXml(daeDocument, xmlNode)
#---instance Classes---
class DaeInstance(DaeEntity):
def __init__(self):
super(DaeInstance, self).__init__()
self.url = ''
self.extras = []
self.object = None

def LoadFromXml(self, daeDocument, xmlNode):
self.url = ReadNodeUrl(xmlNode)
self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)

def SaveToXml(self, daeDocument):
node = super(DaeInstance,self).SaveToXml(daeDocument)
AppendChilds(daeDocument, node, self.extras)
WriteNodeUrl(node, self.object.id)
return node

class DaeAnimationInstance(DaeInstance):
def __init__(self):
super(DaeAnimationInstance, self).__init__()
self.syntax = DaeSyntax.INSTANCE_ANIMATION

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeAnimationInstance,self).LoadFromXml(daeDocument, xmlNode)
self.object = daeDocument.animationsLibrary.FindObject(self.url)

def SaveToXml(self, daeDocument):
node = super(DaeAnimationInstance,self).SaveToXml(daeDocument)
return node

class DaeCameraInstance(DaeInstance):
def __init__(self):
super(DaeCameraInstance, self).__init__()
self.syntax = DaeSyntax.INSTANCE_CAMERA

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeCameraInstance,self).LoadFromXml(daeDocument, xmlNode)
self.object = daeDocument.camerasLibrary.FindObject(self.url)

def SaveToXml(self, daeDocument):
node = super(DaeCameraInstance,self).SaveToXml(daeDocument)
return node

class DaeControllerInstance(DaeInstance):
def __init__(self):
super(DaeControllerInstance, self).__init__()
self.skeletons = []
self.bindMaterials = []
self.syntax = DaeSyntax.INSTANCE_CONTROLLER

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeControllerInstance,self).LoadFromXml(daeDocument, xmlNode)
self.skeletons = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.SKELETON, DaeSkeleton)
self.bindMaterials = CreateObjectsFromXml(daeDocument, xmlNode, DaeFxSyntax.BIND_MATERIAL, DaeFxBindMaterial)
self.object = daeDocument.controllersLibrary.FindObject(self.url)

def SaveToXml(self, daeDocument):
node = super(DaeControllerInstance,self).SaveToXml(daeDocument)
AppendChilds(daeDocument, node, self.skeletons)
AppendChilds(daeDocument, node, self.bindMaterials)
return node

# TODO: finish DaeEffectInstance
class DaeEffectInstance(DaeInstance):
def __init__(self):
super(DaeEffectInstance, self).__init__()

self.syntax = DaeSyntax.INSTANCE_EFFECT

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeEffectInstance,self).LoadFromXml(daeDocument, xmlNode)
self.object = daeDocument.effectsLibrary.FindObject(self.url)

def SaveToXml(self, daeDocument):
node = super(DaeEffectInstance,self).SaveToXml(daeDocument)
return node

class DaeGeometryInstance(DaeInstance):
def __init__(self):
super(DaeGeometryInstance, self).__init__()
self.bindMaterials = []
self.syntax = DaeSyntax.INSTANCE_GEOMETRY

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeGeometryInstance,self).LoadFromXml(daeDocument, xmlNode)
self.bindMaterials = CreateObjectsFromXml(daeDocument, xmlNode, DaeFxSyntax.BIND_MATERIAL, DaeFxBindMaterial)
self.object = daeDocument.geometriesLibrary.FindObject(self.url)

def SaveToXml(self, daeDocument):
node = super(DaeGeometryInstance,self).SaveToXml(daeDocument)
AppendChilds(daeDocument, node, self.bindMaterials)
return node

class DaeLightInstance(DaeInstance):
def __init__(self):
super(DaeLightInstance, self).__init__()
self.syntax = DaeSyntax.INSTANCE_LIGHT

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeLightInstance,self).LoadFromXml(daeDocument, xmlNode)
self.object = daeDocument.lightsLibrary.FindObject(self.url)

def SaveToXml(self, daeDocument):
node = super(DaeLightInstance,self).SaveToXml(daeDocument)
return node

class DaeNodeInstance(DaeInstance):
def __init__(self):
super(DaeNodeInstance, self).__init__()
self.syntax = DaeSyntax.INSTANCE_NODE

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeNodeInstance,self).LoadFromXml(daeDocument, xmlNode)
self.object = daeDocument.nodesLibrary.FindObject(self.url)

def SaveToXml(self, daeDocument):
node = super(DaeNodeInstance,self).SaveToXml(daeDocument)
return node

class DaeVisualSceneInstance(DaeInstance):
def __init__(self):
super(DaeVisualSceneInstance, self).__init__()
self.syntax = DaeSyntax.INSTANCE_VISUAL_SCENE

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeVisualSceneInstance,self).LoadFromXml(daeDocument, xmlNode)
self.object = daeDocument.visualScenesLibrary.FindObject(self.url)

def SaveToXml(self, daeDocument):
node = super(DaeVisualSceneInstance,self).SaveToXml(daeDocument)
return node


class DaeSkeleton(DaeEntity):
def __init__(self):
super(DaeSkeleton,self).__init__()
self.iControllers = []

def LoadFromXml(self, daeDocument, xmlNode):
self.iControllers = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_CONTROLLER, DaeControllerInstance)

def SaveToXml(self, daeDocument):
node = super(DaeSkeleton, self).SaveToXml(daeDocument)
AppendChilds(daeDocument, node, self.iControllers)
return node


class DaeSyntax(object):

#---collada---
COLLADA = 'COLLADA'
VERSION = 'version'
XMLNS = 'xmlns'

BODY = 'body'
TARGET = 'target'

ASSET = 'asset'

ID = 'id'
NAME = 'name'
URL = 'url'

COUNT = 'count'
OFFSET = 'offset'
STRIDE = 'stride'

METER = 'meter'
SID = 'sid'
SEMANTIC = 'semantic'
PARAM = 'param'

PROFILE = 'profile'
TECHNIQUE = 'technique'
TECHNIQUE_COMMON = 'technique_common'

##BIND_MATERIAL = 'bind_material'
SKELETON = 'skeleton'

P = 'p'
PH = 'ph'
H = 'h'


INPUT = 'input'
SET = 'set'

#---light---
COLOR = 'color'
AMBIENT = 'ambient'
SPOT = 'spot'
DIRECTIONAL = 'directional'
POINT = 'point'

CONSTANT_ATTENUATION = 'constant_attenuation'
LINEAR_ATTENUATION = 'linear_attenuation'
QUADRATIC_ATTENUATION = 'quadratic_attenuation'

FALLOFF_ANGLE = 'falloff_angle'
FALLOFF_EXPONENT = 'falloff_exponent'

#---camera--
OPTICS = 'optics'
PERSPECTIVE = 'perspective'
ORTHOGRAPHIC = 'orthographic'
IMAGER = 'imager'
ZNEAR = 'znear'
ZFAR = 'zfar'
XFOV = 'xfov'
YFOV = 'yfov'
XMAG = 'xmag'
YMAG ='ymag'
ASPECT_RATIO = 'aspect_ratio'

#---geometry---
MESH = 'mesh'
CONVEX_MESH ='convex_mesh'
SPLINE = 'spline'
SOURCE ='source'
VERTICES = 'vertices'
ACCESSOR = 'accessor'

CONVEX_HULL_OF = 'convex_hull_of'

#---primitives---
LINES = 'lines'
LINESTRIPS = 'linestrips'
POLYGONS = 'polygons'
POLYLIST = 'polylist'
TRIANGLES = 'triangles'
TRIFANS = 'trifans'
TRISTRIPS = 'tristrips'

#---libraries---
LIBRARY_ANIMATIONS = 'library_animations'
LIBRARY_ANIMATION_CLIPS = 'library_animation_clips'
LIBRARY_CAMERAS = 'library_cameras'
LIBRARY_CONTROLLERS = 'library_controllers'
LIBRARY_EFFECTS = 'library_effects'
LIBRARY_FORCE_FIELDS = 'library_force_fields'
LIBRARY_GEOMETRIES = 'library_geometries'
LIBRARY_IMAGES = 'library_images'
LIBRARY_LIGHTS = 'library_lights'
LIBRARY_MATERIALS = 'library_materials'
#LIBRARY_NODES = 'library_NODES' #Doug: looks funny - should be library_nodes?
LIBRARY_NODES = 'library_nodes'
LIBRARY_PHYSICS_MATERIALS = 'library_physics_materials'
LIBRARY_PHYSICS_MODELS = 'library_physics_models'
LIBRARY_PHYSICS_SCENES = 'library_physics_scenes'
LIBRARY_VISUAL_SCENES = 'library_visual_scenes'

SCENE = 'scene'
EXTRA = 'extra'
TYPE = 'type'
LIGHT = 'light'
CAMERA = 'camera'
ANIMATION = 'animation'
ANIMATION_CLIP = 'animation_clip'
GEOMETRY = 'geometry'
IMAGE = 'image'
##EFFECT = 'effect'
VISUAL_SCENE = 'visual_scene'
CONTROLLER = 'controller'
MATERIAL = 'material'

#---asset---
CONTRIBUTOR = 'contributor'
CREATED = 'created'
MODIFIED = 'modified'
REVISION = 'revision'
TITLE = 'title'
SUBJECT = 'subject'
KEYWORDS = 'keywords'
UNIT = 'unit'
UP_AXIS = 'up_axis'

Y_UP = 'Y_UP'
Z_UP = 'Z_UP'

#---contributor---
AUTHOR = 'author'
AUTHORING_TOOL = 'authoring_tool'
COMMENTS = 'comments'
COPYRIGHT = 'copyright'
SOURCE_DATA = 'source_data'

#---array---
FLOAT_ARRAY = 'float_array'
NAME_ARRAY = 'name_array'
BOOL_ARRAY = 'bool_array'
INT_ARRAY = 'int_array'
IDREF_ARRAY = 'IDREF_array'

#---node---
NODE = 'node'
TYPE_JOINT = 'JOINT'
TYPE_NODE = 'NODE'
LAYER = 'layer'

#---transforms---
TRANSLATE = 'translate'
ROTATE = 'rotate'
SCALE = 'scale'
SKEW = 'skew'
MATRIX = 'matrix'
LOOKAT = 'lookat'

#---instances---
INSTANCE_ANIMATION = 'instance_animation'
INSTANCE_CAMERA = 'instance_camera'
INSTANCE_CONTROLLER = 'instance_controller'
##INSTANCE_EFFECT = 'instance_effect'
INSTANCE_GEOMETRY = 'instance_geometry'
INSTANCE_LIGHT = 'instance_light'
INSTANCE_NODE = 'instance_node'
INSTANCE_VISUAL_SCENE = 'instance_visual_scene'
INSTANCE_PHYSICS_SCENE = 'instance_physics_scene'

#---image---
FORMAT = 'format'
DEPTH = 'depth'
HEIGHT = 'height'
WIDTH = 'width'
INIT_FROM = 'init_from'

class DaeFxBindMaterial(DaeEntity):
def __init__(self):
super(DaeFxBindMaterial, self).__init__()
self.syntax = DaeFxSyntax.BIND_MATERIAL
self.techniqueCommon = DaeFxBindMaterial.DaeFxTechniqueCommon()

def LoadFromXml(self, daeDocument, xmlNode):
self.techniqueCommon = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.TECHNIQUE_COMMON, DaeFxBindMaterial.DaeFxTechniqueCommon)

def SaveToXml(self, daeDocument):
node = super(DaeFxBindMaterial,self).SaveToXml(daeDocument)
AppendChild(daeDocument, node, self.techniqueCommon)
return node

class DaeFxTechniqueCommon(DaeEntity):
def __init__(self):
self.syntax = DaeFxSyntax.TECHNIQUE_COMMON
self.iMaterials = []

def LoadFromXml(self, daeDocument, xmlNode):
self.iMaterials = CreateObjectsFromXml(daeDocument, xmlNode, DaeFxSyntax.INSTANCE_MATERIAL, DaeFxMaterialInstance)

def SaveToXml(self, daeDocument):
node = super(DaeFxBindMaterial.DaeFxTechniqueCommon,self).SaveToXml(daeDocument)
AppendChilds(daeDocument, node, self.iMaterials)
return node

def __str__(self):
return super(DaeFxBindMaterial.DaeFxTechniqueCommon,self).__str__()


class DaeFxMaterialInstance(DaeEntity):
def __init__(self):
super(DaeFxMaterialInstance, self).__init__()
self.target = ''
self.symbol = ''
self.object = None
self.syntax = DaeFxSyntax.INSTANCE_MATERIAL

def LoadFromXml(self, daeDocument, xmlNode):
self.target = xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.TARGET)[1:]
self.symbol = xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.SYMBOL)
self.object = daeDocument.materialsLibrary.FindObject(self.target)

def SaveToXml(self, daeDocument):
node = super(DaeFxMaterialInstance,self).SaveToXml(daeDocument)
SetAttribute(node, DaeFxSyntax.TARGET, StripString('#'+self.object.id))
SetAttribute(node, DaeFxSyntax.SYMBOL, StripString(self.object.id))
return node

class DaeFxMaterial(DaeElement):
def __init__(self):
super(DaeFxMaterial, self).__init__()
self.asset = None
self.iEffects = []
self.extras = None
self.syntax = DaeFxSyntax.MATERIAL

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeFxMaterial, self).LoadFromXml(daeDocument, xmlNode)
self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
self.iEffects = CreateObjectsFromXml(daeDocument,xmlNode, DaeFxSyntax.INSTANCE_EFFECT, DaeFxEffectInstance)

def SaveToXml(self, daeDocument):
node = super(DaeFxMaterial,self).SaveToXml(daeDocument)
# Add the assets
AppendChild(daeDocument,node,self.asset)
# Add the effect instances
AppendChilds(daeDocument, node, self.iEffects)
# Add the extra's
AppendChilds(self,node,self.extras)
return node

def __str__(self):
return super(DaeFxMaterial,self).__str__()+' assets: %s, iEffects: %s, extras: %s'%(self.asset, self.iEffects, self.extras)

class DaeFxEffectInstance(DaeEntity):
def __init__(self):
super(DaeFxEffectInstance, self).__init__()
self.url = ''
self.syntax = DaeFxSyntax.INSTANCE_EFFECT

def LoadFromXml(self, daeDocument, xmlNode):
self.url = xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.URL)[1:]
self.object = daeDocument.effectsLibrary.FindObject(self.url)

def SaveToXml(self, daeDocument):
node = super(DaeFxEffectInstance,self).SaveToXml(daeDocument)
SetAttribute(node, DaeFxSyntax.URL, StripString('#'+self.object.id))
return node

class DaeFxEffect(DaeElement):
def __init__(self):
super(DaeFxEffect, self).__init__()
self.profileCommon = DaeFxProfileCommon()
self.syntax = DaeFxSyntax.EFFECT


def LoadFromXml(self, daeDocument, xmlNode):
super(DaeFxEffect, self).LoadFromXml(daeDocument, xmlNode)
self.profileCommon = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.PROFILE_COMMON, DaeFxProfileCommon)

def SaveToXml(self, daeDocument):
node = super(DaeFxEffect,self).SaveToXml(daeDocument)
AppendChild(daeDocument, node, self.profileCommon)
return node

def __str__(self):
return super(DaeFxEffect, self).__str__() + ', profileCommon: %s' % (self.profileCommon)

def AddShader(self, daeShader):
self.profileCommon.technique.shader = daeShader
def AddDoubleSided(self, val):
if self.profileCommon.extra == None:
self.profileCommon.AddExtra()
self.profileCommon.extra.technique.AddDoubleSided(val)

class DaeFxProfileCommon(DaeEntity):
def __init__(self):
super(DaeFxProfileCommon, self).__init__()
self.technique = DaeFxTechnique()
self.images = []
self.newParams = []
self.syntax = DaeFxSyntax.PROFILE_COMMON
self.extra = None #Doug: added Mar3008


def LoadFromXml(self, daeDocument, xmlNode):
self.images = CreateObjectsFromXml(daeDocument, xmlNode, DaeFxSyntax.IMAGE, DaeFxImage)
self.newParams = CreateObjectsFromXml(daeDocument, xmlNode, DaeFxSyntax.NEWPARAM, DaeFxNewParam)
self.technique = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.TECHNIQUE, DaeFxTechnique)
self.extra = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.EXTRA, DaeFxExtra) #Doug: added Mar3008

def SaveToXml(self, daeDocument):
node = super(DaeFxProfileCommon,self).SaveToXml(daeDocument)
AppendChilds(daeDocument, node, self.images)
AppendChilds(daeDocument, node, self.newParams)
AppendChild(daeDocument, node, self.technique)
AppendChild(daeDocument, node, self.extra) #Doug: added Mar3008
return node
def AddExtra(self):
if not self.extra:
self.extra = DaeFxExtra()

def __str__(self):
return super(DaeFxProfileCommon, self).__str__() + ', technique: %s, images: %s, newParams: %s' % (self.technique, self.images, self.newParams)

class DaeFxExtra(DaeEntity): #Doug: added Mar3008 - there is a DaeExtra which could be used instead or for guidance
def __init__(self):
super(DaeFxExtra, self).__init__()
self.technique = DaeFxTechnique()
#self.images = []
#self.newParams = []
self.syntax = DaeFxSyntax.EXTRA
#self.extra = [] #Doug: added Mar3008


def LoadFromXml(self, daeDocument, xmlNode):
#self.images = CreateObjectsFromXml(daeDocument, xmlNode, DaeFxSyntax.IMAGE, DaeFxImage)
#self.newParams = CreateObjectsFromXml(daeDocument, xmlNode, DaeFxSyntax.NEWPARAM, DaeFxNewParam)
self.technique = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.TECHNIQUE, DaeFxTechnique)
#self.extra = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.EXTRA, DaeFxExtra)

def SaveToXml(self, daeDocument):
node = super(DaeFxExtra,self).SaveToXml(daeDocument)
#AppendChilds(daeDocument, node, self.images)
#AppendChilds(daeDocument, node, self.newParams)
AppendChild(daeDocument, node, self.technique)
return node

def __str__(self):
#return super(DaeFxExtra, self).__str__() + ', technique: %s, images: %s, newParams: %s' % (self.technique, self.images, self.newParams)
return super(DaeFxExtra, self).__str__() + ', technique: %s' % (self.technique)

class DaeFxImage(DaeEntity):
def __init__(self):
super(DaeFxImage, self).__init__()
self.syntax = DaeFxSyntax.IMAGE

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeFxImage, self).LoadFromXml(daeDocument, xmlNode)

def SaveToXml(self, daeDocument):
node = super(DaeFxImage,self).SaveToXml(daeDocument)
return node

class DaeFxNewParam(DaeEntity):
def __init__(self):
super(DaeFxNewParam, self).__init__()
self.syntax = DaeFxSyntax.NEWPARAM

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeFxNewParam, self).LoadFromXml(daeDocument, xmlNode)

def SaveToXml(self, daeDocument):
node = super(DaeFxNewParam,self).SaveToXml(daeDocument)
return node

class DaeFxTechnique(DaeEntity):
def __init__(self):
super(DaeFxTechnique, self).__init__()
self.syntax = DaeFxSyntax.TECHNIQUE
self.shader = DaeFxShadeConstant()
self.sid = ''
self.doubleside = DaeFxDoubleSided() #Doug: added Mar3008

def LoadFromXml(self, daeDocument, xmlNode):
# TODO: add asset and extra?
self.sid = xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.SID)
#Doug: added Mar3008 the following 5 lines about googleearth profile and doublesided
profile = xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.PROFILE)
if profile == DaeFxSyntax.GOOGLEEARTH:
lightSourceNode = xmlUtils.FindElementByTagName(xmlNode, DaeFxSyntax.DOUBLESIDED)
if lightSourceNode:
self.doubleside = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.DOUBLE_SIDED, DaeFxDoubleSided)
else:
lightSourceNode = xmlUtils.FindElementByTagName(xmlNode, DaeFxSyntax.CONSTANT)
if lightSourceNode:
self.shader = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.CONSTANT, DaeFxShadeConstant)
else:
lightSourceNode = xmlUtils.FindElementByTagName(xmlNode, DaeFxSyntax.LAMBERT)
if lightSourceNode:
self.shader = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.LAMBERT, DaeFxShadeLambert)
else:
lightSourceNode = xmlUtils.FindElementByTagName(xmlNode, DaeFxSyntax.BLINN)
if lightSourceNode:
self.shader = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.BLINN, DaeFxShadeBlinn)
else:
lightSourceNode = xmlUtils.FindElementByTagName(xmlNode, DaeFxSyntax.PHONG)
self.shader = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.PHONG, DaeFxShadePhong)


def SaveToXml(self, daeDocument):
node = super(DaeFxTechnique,self).SaveToXml(daeDocument)
if self.doubleside.value:
node.setAttribute(DaeFxSyntax.PROFILE, DaeFxSyntax.GOOGLEEARTH)
AppendChild(daeDocument, node, self.doubleside)
else:
node.setAttribute(DaeFxSyntax.SID, self.sid)
AppendChild(daeDocument, node, self.shader)
return node

def AddDoubleSided(self, val): #Doug: added Mar3008
self.doubleside.AddValue(val)

def __str__(self):
if self.doubleside.doublesided:
return super(DaeFxTechnique,self).__str__()+' doublesided: %s'%(self.doubleside)
else:
return super(DaeFxTechnique,self).__str__()+' shader: %s'%(self.shader)

class DaeFxDoubleSided(DaeEntity): #Doug: added Mar3008
def __init__(self):
super(DaeFxDoubleSided, self).__init__()
self.value = None
self.syntax = DaeFxSyntax.DOUBLE_SIDED

def LoadFromXml(self, daeDocument, xmlNode):
#self.value = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.DOUBLE_SIDED, DaeFxCommonContainer, True)
self.value = CastFromXml(daeDocument, xmlNode, self.syntax, int)

def SaveToXml(self, daeDocument):
node = super(DaeFxDoubleSided,self).SaveToXml(daeDocument)
#def AppendTextInChild(xmlNode, object):
AppendTextInChild(node,int(self.value))
#AppendTextChild(node, self.syntax, int(self.value)) #not quie the right thing- dont need syntax again
return node

def AddValue(self, val):
self.value = int(val)

class DaeFxShadeConstant(DaeEntity):
def __init__(self):
super(DaeFxShadeConstant, self).__init__()
self.emission = None
self.reflective = None
self.reflectivity = None
self.transparent = None
self.transparency = None
self.indexOfRefraction = None

self.syntax = DaeFxSyntax.CONSTANT

def LoadFromXml(self, daeDocument, xmlNode):
self.emission = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.EMISSION, DaeFxCommonColorAndTextureContainer, True)
self.reflective = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.REFLECTIVE, DaeFxCommonColorAndTextureContainer, True)
self.reflectivity = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.REFLECTIVITY, DaeFxCommonFloatAndParamContainer, True)
self.transparent = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.TRANSPARENT, DaeFxCommonColorAndTextureContainer, True)
self.transparency = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.TRANSPARENCY, DaeFxCommonFloatAndParamContainer, True)
self.indexOfRefraction = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.INDEXOFREFRACTION, DaeFxCommonFloatAndParamContainer, True)

def SaveToXml(self, daeDocument):
node = super(DaeFxShadeConstant,self).SaveToXml(daeDocument)
AppendChild(daeDocument, node, self.emission)
if isinstance(self, DaeFxShadeLambert):
AppendChild(daeDocument, node, self.ambient)
AppendChild(daeDocument, node, self.diffuse)
if isinstance(self,DaeFxShadeBlinn):
AppendChild(daeDocument, node, self.specular)
AppendChild(daeDocument, node, self.shininess)
AppendChild(daeDocument, node, self.reflective)
AppendChild(daeDocument, node, self.reflectivity)
AppendChild(daeDocument, node, self.transparent)
AppendChild(daeDocument, node, self.transparency)
AppendChild(daeDocument, node, self.indexOfRefraction)
return node

def AddValue(self, type, val):
col = DaeFxColor()
col.rgba = val
if type == DaeFxSyntax.EMISSION:
if not self.emission:
self.emission = DaeFxCommonColorAndTextureContainer(type)
self.emission.color = col
elif type == DaeFxSyntax.REFLECTIVE:
if not self.reflective:
self.reflective = DaeFxCommonColorAndTextureContainer(type)
self.reflective.color = col
elif type == DaeFxSyntax.REFLECTIVITY:
if not self.reflectivity:
self.reflectivity = DaeFxCommonFloatAndParamContainer(type)
self.reflectivity.float = val
elif type == DaeFxSyntax.TRANSPARENT:
if not self.transparent:
self.transparent = DaeFxCommonColorAndTextureContainer(type)
self.transparent.color = col
elif type == DaeFxSyntax.TRANSPARENCY:
if not self.transparency:
self.transparency = DaeFxCommonFloatAndParamContainer(type)
self.transparency.float = val
elif type == DaeFxSyntax.INDEXOFREFRACTION:
if not self.indexOfRefraction:
self.indexOfRefraction = DaeFxCommonFloatAndParamContainer(type)
self.indexOfRefraction.float = val
else:
Debug.Debug('DaeFxShadeConstant: type: %s not recognised'%(type),'ERROR')



class DaeFxShadeLambert(DaeFxShadeConstant):
def __init__(self):
super(DaeFxShadeLambert, self).__init__()
self.ambient = None
self.diffuse = None
self.syntax = DaeFxSyntax.LAMBERT

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeFxShadeLambert, self).LoadFromXml(daeDocument, xmlNode)
self.ambient = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.AMBIENT, DaeFxCommonColorAndTextureContainer, True)
self.diffuse = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.DIFFUSE, DaeFxCommonColorAndTextureContainer, True)


def SaveToXml(self, daeDocument):
node = super(DaeFxShadeLambert,self).SaveToXml(daeDocument)
#AppendChild(daeDocument, node, self.ambient)
#AppendChild(daeDocument, node, self.diffuse)
return node

def AddValue(self, type, val):
col = DaeFxColor()
col.rgba = val
if type == DaeFxSyntax.DIFFUSE:
if not self.diffuse:
self.diffuse = DaeFxCommonColorAndTextureContainer(type)
if isinstance(val, DaeFxTexture): # its a texture
self.diffuse.texture = val
else: # it's a color
self.diffuse.color = col
elif type == DaeFxSyntax.AMBIENT:
if not self.ambient:
self.ambient = DaeFxCommonColorAndTextureContainer(type)
self.ambient.color = col
else:
super(DaeFxShadeLambert,self).AddValue(type, val)

class DaeFxShadeBlinn(DaeFxShadeLambert):
def __init__(self):
super(DaeFxShadeBlinn, self).__init__()
self.specular = None
self.shininess = None
self.syntax = DaeFxSyntax.BLINN

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeFxShadeBlinn, self).LoadFromXml(daeDocument, xmlNode)
self.specular = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.SPECULAR, DaeFxCommonColorAndTextureContainer, True)
self.shininess = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.SHININESS, DaeFxCommonFloatAndParamContainer, True)


def SaveToXml(self, daeDocument):
node = super(DaeFxShadeBlinn,self).SaveToXml(daeDocument)
#AppendChild(daeDocument, node, self.specular)
#AppendChild(daeDocument, node, self.shininess)
return node

def AddValue(self, type, val):
col = DaeFxColor()
col.rgba = val
if type == DaeFxSyntax.SPECULAR:
if not self.specular:
self.specular = DaeFxCommonColorAndTextureContainer(type)
self.specular.color = col
elif type == DaeFxSyntax.SHININESS:
if not self.shininess:
self.shininess = DaeFxCommonFloatAndParamContainer(type)
self.shininess.float = val
else:
super(DaeFxShadeBlinn,self).AddValue(type, val)

class DaeFxShadePhong(DaeFxShadeBlinn):
def __init__(self):
super(DaeFxShadePhong, self).__init__()
self.syntax = DaeFxSyntax.PHONG

class DaeFxCommonColorAndTextureContainer(DaeEntity):
def __init__(self, syntax='UNKNOWN'):
super(DaeFxCommonColorAndTextureContainer, self).__init__()
self.color = None
self.texture = None
self.syntax = syntax

def LoadFromXml(self, daeDocument, xmlNode):
self.color = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.COLOR, DaeFxColor)
self.texture = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.TEXTURE, DaeFxTexture)

def SaveToXml(self, daeDocument):
node = super(DaeFxCommonColorAndTextureContainer,self).SaveToXml(daeDocument)
AppendChild(daeDocument, node, self.color)
AppendChild(daeDocument, node, self.texture)
return node

class DaeFxCommonFloatAndParamContainer(DaeEntity):
def __init__(self, syntax = 'UNKNOWN'):
super(DaeFxCommonFloatAndParamContainer, self).__init__()
self.float = None
self.param = None
self.syntax = syntax

def LoadFromXml(self, daeDocument, xmlNode):
self.float = CastFromXml(daeDocument, xmlNode, DaeFxSyntax.FLOAT, float)
##self.param = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.PARAM, DaeFxParam)

def SaveToXml(self, daeDocument):
node = super(DaeFxCommonFloatAndParamContainer,self).SaveToXml(daeDocument)
AppendTextChild(node, DaeFxSyntax.FLOAT, self.float)
AppendChild(daeDocument, node, self.param)
return node

class DaeFxCommonContainer(DaeEntity): #Doug: added Mar3008
def __init__(self, cast = str):
super(DaeFxCommonContainer, self).__init__()
self.value = None
self.cast = cast
self.syntax = syntax

def LoadFromXml(self, daeDocument, xmlNode):
self.value = CastFromXml(daeDocument, xmlNode, self.syntax, self.cast)
#def CastFromXml(colladaDocument, xmlNode, nodeType, cast, default=None):
##self.param = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.PARAM, DaeFxParam)

def SaveToXml(self, daeDocument):
node = super(DaeFxCommonContainer,self).SaveToXml(daeDocument)
AppendTextChild(node, self.syntax, self.cast(self.value))
#def AppendTextChild(xmlNode,syntax, object, default = None):
#AppendChild(daeDocument, node, false)
return node

class DaeFxColor(DaeEntity):
def __init__(self):
super(DaeFxColor, self).__init__()
self.sid = ''
self.rgba = []
self.syntax = DaeFxSyntax.COLOR

def LoadFromXml(self, daeDocument, xmlNode):
self.sid = xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.SID)
self.rgba = ToFloatList(xmlUtils.ReadContents(xmlNode))

def SaveToXml(self, daeDocument):
node = super(DaeFxColor,self).SaveToXml(daeDocument)
SetAttribute(node, DaeFxSyntax.SID, self.sid)
AppendTextInChild(node, self.rgba)
return node

class DaeFxTexture(DaeEntity):
def __init__(self):
super(DaeFxTexture, self).__init__()
self.texture = ''
self.textCoord = ''
self.syntax = DaeFxSyntax.TEXTURE

def LoadFromXml(self, daeDocument, xmlNode):
self.texture = daeDocument.imagesLibrary.FindObject(xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.TEXTURE))
self.textCoord = xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.TEXCOORD)

def SaveToXml(self, daeDocument):
node = super(DaeFxTexture,self).SaveToXml(daeDocument)
SetAttribute(node, DaeFxSyntax.TEXTURE, StripString(self.texture))
SetAttribute(node, DaeFxSyntax.TEXCOORD, self.textCoord)
return node

class DaeFxSyntax(object):
COLOR = 'color'
INSTANCE_MATERIAL = 'instance_material'
INSTANCE_EFFECT = 'instance_effect'
TECHNIQUE_COMMON = 'technique_common'
SID = 'sid'
EMISSION = 'emission'
REFLECTIVE ='reflective'
REFLECTIVITY = 'reflectivity'
TRANSPARENT = 'transparent'
TRANSPARENCY = 'transparency'
INDEXOFREFRACTION = 'index_of_refraction'
TEXTURE = 'texture'
TEXCOORD = 'texcoord'
AMBIENT = 'ambient'
DIFFUSE = 'diffuse'

BIND_MATERIAL ='bind_material'
PROFILE_COMMON = 'profile_COMMON'
SYMBOL = 'symbol'
MATERIAL = 'material'
EFFECT = 'effect'

TARGET = 'target'
URL = 'url'
SYMBOL = 'symbol'

BLINN = 'blinn'
SHININESS = 'shininess'
SPECULAR = 'specular'
PHONG = 'phong'

IMAGE = 'image'
NEWPARAM = 'newparam'
TECHNIQUE = 'technique'
EXTRA = 'extra' #Doug: added Mar3008
DOUBLE_SIDED = 'double_sided' #Doug: added Mar3008
PROFILE = 'profile' #Doug: added Mar3008
GOOGLEEARTH = 'GOOGLEEARTH' #Doug: added Mar3008

CONSTANT = 'constant'
LAMBERT = 'lambert'

FLOAT ='float'
#---COLLADA PHYSICS---
class DaePhysicsScene(DaeElement):
def __init__(self):
super(DaePhysicsScene,self).__init__()
self.asset = None
self.extras = None
self.iPhysicsModels = []
self.syntax = DaePhysicsSyntax.PHYSICS_SCENE

def LoadFromXml(self, daeDocument, xmlNode):
super(DaePhysicsScene, self).LoadFromXml(daeDocument, xmlNode)
self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
self.iPhysicsModels = CreateObjectsFromXml(daeDocument, xmlNode, DaePhysicsSyntax.INSTANCE_PHYSICS_MODEL, DaePhysicsModelInstance)

def SaveToXml(self, daeDocument):
node = super(DaePhysicsScene, self).SaveToXml(daeDocument)
# Add the assets
AppendChild(daeDocument,node,self.asset)
# Add the phyics models
AppendChilds(daeDocument, node, self.iPhysicsModels)
# Add the extra's
AppendChilds(self,node,self.extras)
return node

def __str__(self):
return super(DaePhysicsScene,self).__str__()+' asset: %s, iPhysicsModels: %s, extras: %s'%(self.asset, self.iPhysicsModels, self.extras)

class DaePhysicsModelInstance(DaeInstance):
def __init__(self):
super(DaePhysicsModelInstance, self).__init__()
self.syntax = DaePhysicsSyntax.INSTANCE_PHYSICS_MODEL
self.iRigidBodies = []

def LoadFromXml(self, daeDocument, xmlNode):
super(DaePhysicsModelInstance,self).LoadFromXml(daeDocument, xmlNode)
self.object = daeDocument.physicsModelsLibrary.FindObject(self.url)
self.iRigidBodies = self.CreateInstanceRigidBodies(daeDocument, xmlNode, self.object)

def SaveToXml(self, daeDocument):
node = super(DaePhysicsModelInstance,self).SaveToXml(daeDocument)
AppendChilds(daeDocument, node, self.iRigidBodies)
return node

def CreateInstanceRigidBodies(self, daeDocument, xmlNode, physicsModel):
objects = []
CreateObjectsFromXml(daeDocument, xmlNode, DaePhysicsSyntax.INSTANCE_RIGID_BODY, DaeRigidBodyInstance)
nodes = xmlUtils.FindElementsByTagName(xmlNode,DaePhysicsSyntax.INSTANCE_RIGID_BODY)
for node in nodes:
object = DaeRigidBodyInstance()
object.LoadFromXml(daeDocument, node)
object.body = physicsModel.FindRigidBody(object.bodyString)
n = None
for visualScene in daeDocument.visualScenesLibrary.items:
n = visualScene.FindNode(object.targetString)
if not (n is None):
break
object.target = n
objects.append(object)
return objects


class DaePhysicsSceneInstance(DaeInstance):
def __init__(self):
super(DaePhysicsSceneInstance, self).__init__()
self.syntax = DaeSyntax.INSTANCE_PHYSICS_SCENE

def LoadFromXml(self, daeDocument, xmlNode):
super(DaePhysicsSceneInstance,self).LoadFromXml(daeDocument, xmlNode)
self.object = daeDocument.physicsScenesLibrary.FindObject(self.url)

def SaveToXml(self, daeDocument):
node = super(DaePhysicsSceneInstance,self).SaveToXml(daeDocument)
return node

class DaePhysicsMaterialInstance(DaeInstance):
def __init__(self):
super(DaePhysicsMaterialInstance, self).__init__()
self.syntax = DaePhysicsSyntax.INSTANCE_PHYSICS_MATERIAL

def LoadFromXml(self, daeDocument, xmlNode):
super(DaePhysicsMaterialInstance,self).LoadFromXml(daeDocument, xmlNode)
self.object = daeDocument.physicsMaterialsLibrary.FindObject(self.url)

def SaveToXml(self, daeDocument):
node = super(DaePhysicsMaterialInstance,self).SaveToXml(daeDocument)
return node

class DaeRigidBodyInstance(DaeEntity):
def __init__(self):
super(DaeRigidBodyInstance, self).__init__()
self.syntax = DaePhysicsSyntax.INSTANCE_RIGID_BODY
self.body = None
self.target = None
self.bodyString = ''
self.targetString = ''

def LoadFromXml(self, daeDocument, xmlNode):
self.bodyString = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.BODY)
self.targetString = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.TARGET)[1:]

def SaveToXml(self, daeDocument):
node = super(DaeRigidBodyInstance,self).SaveToXml(daeDocument)
SetAttribute(node, DaeSyntax.BODY, StripString(self.body.name))
SetAttribute(node, DaeSyntax.TARGET, StripString('#'+self.target.id))
return node

class DaePhysicsModel(DaeElement):
def __init__(self):
super(DaePhysicsModel,self).__init__()
self.syntax = DaePhysicsSyntax.PHYSICS_MODEL
self.rigidBodies = []

def LoadFromXml(self, daeDocument, xmlNode):
super(DaePhysicsModel, self).LoadFromXml(daeDocument, xmlNode)
self.rigidBodies = CreateObjectsFromXml(daeDocument, xmlNode, DaePhysicsSyntax.RIGID_BODY, DaeRigidBody)

def SaveToXml(self, daeDocument):
node = super(DaePhysicsModel, self).SaveToXml(daeDocument)
# Add the rigid bodies
AppendChilds(daeDocument, node, self.rigidBodies)
return node

def FindRigidBody(self, url):
for rigidBody in self.rigidBodies:
if rigidBody.sid == url:
return rigidBody
return None

class DaePhysicsMaterial(DaeElement):
def __init__(self):
super(DaePhysicsMaterial,self).__init__()
self.syntax = DaePhysicsSyntax.PHYSICS_MATERIAL
self.techniqueCommon = DaePhysicsMaterial.DaeTechniqueCommon()

def LoadFromXml(self, daeDocument, xmlNode):
super(DaePhysicsMaterial, self).LoadFromXml(daeDocument, xmlNode)
self.techniqueCommon = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.TECHNIQUE_COMMON, DaePhysicsMaterial.DaeTechniqueCommon)

def SaveToXml(self, daeDocument):
node = super(DaePhysicsMaterial, self).SaveToXml(daeDocument)
AppendChild(daeDocument,node,self.techniqueCommon)
return node

class DaeTechniqueCommon(DaeEntity):
def __init__(self):
super(DaePhysicsMaterial.DaeTechniqueCommon,self).__init__()
self.syntax = DaeSyntax.TECHNIQUE_COMMON
self.dynamicFriction = 0
self.restitution = 0
self.staticFriction = 0

def LoadFromXml(self, daeDocument, xmlNode):
self.dynamicFriction = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.DYNAMIC_FRICTION, float, 0)
self.restitution = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.RESTITUTION, float, 0)
self.staticFriction = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.STATIC_FRICTION, float, 0)

def SaveToXml(self, daeDocument):
node = super(DaePhysicsMaterial.DaeTechniqueCommon,self).SaveToXml(daeDocument)
AppendTextChild(node, DaePhysicsSyntax.DYNAMIC_FRICTION, self.dynamicFriction, None)
AppendTextChild(node, DaePhysicsSyntax.RESTITUTION, self.restitution, None)
AppendTextChild(node, DaePhysicsSyntax.STATIC_FRICTION, self.staticFriction, None)
return node

def __str__(self):
return super(DaePhysicsMaterial.DaeTechniqueCommon,self).__str__()

class DaeRigidBody(DaeEntity):
def __init__(self):
super(DaeRigidBody, self).__init__()
self.syntax = DaePhysicsSyntax.RIGID_BODY
self.name = ''
self.sid = ''
self.techniqueCommon = DaeRigidBody.DaeTechniqueCommon()

def LoadFromXml(self, daeDocument, xmlNode):
self.name = xmlNode.getAttribute(DaeSyntax.NAME)
self.sid = xmlNode.getAttribute(DaeSyntax.SID)
self.techniqueCommon = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.TECHNIQUE_COMMON, DaeRigidBody.DaeTechniqueCommon)

def SaveToXml(self, daeDocument):
node = super(DaeRigidBody, self).SaveToXml(daeDocument)
SetAttribute(node,DaeSyntax.NAME, StripString(self.name))
SetAttribute(node,DaeSyntax.SID, StripString(self.name))
AppendChild(daeDocument,node,self.techniqueCommon)
return node

class DaeTechniqueCommon(DaeEntity):
def __init__(self):
super(DaeRigidBody.DaeTechniqueCommon, self).__init__()
self.syntax = DaeSyntax.TECHNIQUE_COMMON
self.iPhysicsMaterial = None
self.physicsMaterial = None
self.dynamic = True
self.mass = None
self.inertia = None
self.shapes = []

def LoadFromXml(self, daeDocument, xmlNode):
self.iPhysicsMaterial = CreateObjectFromXml(daeDocument, xmlNode, DaePhysicsSyntax.INSTANCE_PHYSICS_MATERIAL, DaePhysicsMaterialInstance)
self.physicsMaterial = CreateObjectFromXml(daeDocument, xmlNode, DaePhysicsSyntax.PHYSICS_MATERIAL, DaePhysicsMaterial)
self.dynamic = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.DYNAMIC,bool,True)
self.mass = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.MASS, float, 1)
self.inertia = ToFloat3(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaePhysicsSyntax.INERTIA)))

shapeNodes = xmlUtils.FindElementsByTagName(xmlNode, DaePhysicsSyntax.SHAPE)
for shapeNode in shapeNodes:
s = xmlUtils.FindElementByTagName(shapeNode, DaePhysicsSyntax.BOX)
b = None
if not (s is None):
b = DaeBoxShape()
else:
s = xmlUtils.FindElementByTagName(shapeNode, DaePhysicsSyntax.SPHERE)
if not (s is None):
b = DaeSphereShape()
else:
s = xmlUtils.FindElementByTagName(shapeNode, DaePhysicsSyntax.PLANE)
if not (s is None):
b = DaePlaneShape()
else:
s = xmlUtils.FindElementByTagName(shapeNode, DaeSyntax.INSTANCE_GEOMETRY)
if not (s is None):
b = DaeGeometryShape()
else:
s = xmlUtils.FindElementByTagName(shapeNode, DaePhysicsSyntax.CYLINDER)
if not (s is None):
b = DaeCylinderShape()
else:
s = xmlUtils.FindElementByTagName(shapeNode, DaePhysicsSyntax.TAPERED_CYLINDER)
if not (s is None):
b = DaeTaperedCylinderShape()
else:
s = xmlUtils.FindElementByTagName(shapeNode, DaePhysicsSyntax.CAPSULE)
if not (s is None):
b = DaeCapsule()
else: # TAPERED_CAPSULE
b = DaeTaperedCapsuleShape()
b.LoadFromXml(daeDocument, s)
self.shapes.append(b)

def SaveToXml(self, daeDocument):
node = super(DaeRigidBody.DaeTechniqueCommon,self).SaveToXml(daeDocument)
AppendChild(daeDocument,node,self.iPhysicsMaterial)
AppendChild(daeDocument,node,self.physicsMaterial)
shapes = Element(DaePhysicsSyntax.SHAPE)
AppendChilds(daeDocument, shapes, self.shapes)
node.appendChild(shapes)
AppendTextChild(node, DaePhysicsSyntax.DYNAMIC, self.dynamic, None)
AppendTextChild(node, DaePhysicsSyntax.MASS, self.mass, None)
AppendTextChild(node, DaePhysicsSyntax.INERTIA, self.inertia, None)
return node

def GetPhysicsMaterial(self):
if not (self.physicsMaterial is None):
return self.physicsMaterial
else:
return self.iPhysicsMaterial.object

def __str__(self):
return super(DaeRigidBody.DaeTechniqueCommon,self).__str__()

class DaeShape(DaeEntity):
def __init__(self):
super(DaeShape, self).__init__()
self.mass = None
self.density = None
self.syntax = DaePhysicsSyntax.SHAPE

def LoadFromXml(self, daeDocument, xmlNode):
self.iGeometry = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_GEOMETRY,DaeGeometryInstance)
self.mass = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.MASS, float, None)
self.density = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.DENSITY, float, None)

def SaveToXml(self, daeDocument):
node = super(DaeShape, self).SaveToXml(daeDocument)
AppendTextChild(node, DaePhysicsSyntax.MASS, self.mass, None)
AppendTextChild(node, DaePhysicsSyntax.DENSITY, self.density, None)
return node

class DaeBoxShape(DaeShape):
def __init__(self):
super(DaeBoxShape, self).__init__()
self.halfExtents = []
self.syntax = DaePhysicsSyntax.BOX

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeBoxShape, self).LoadFromXml(daeDocument, xmlNode)
self.halfExtents = ToFloat3(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaePhysicsSyntax.HALF_EXTENTS)))

def SaveToXml(self, daeDocument):
node = super(DaeBoxShape, self).SaveToXml(daeDocument)
AppendTextChild(node, DaePhysicsSyntax.HALF_EXTENTS, self.halfExtents)
return node

class DaeSphereShape(DaeShape):
def __init__(self):
super(DaeSphereShape, self).__init__()
self.radius = None
self.syntax = DaePhysicsSyntax.SPHERE

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeSphereShape, self).LoadFromXml(daeDocument, xmlNode)
self.radius = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.RADIUS, float)

def SaveToXml(self, daeDocument):
node = super(DaeSphereShape, self).SaveToXml(daeDocument)
AppendTextChild(node, DaePhysicsSyntax.RADIUS, self.radius)
return node

class DaeCylinderShape(DaeShape):
def __init__(self):
super(DaeCylinderShape, self).__init__()
self.radius = [1 , 1]
self.height = None
self.syntax = DaePhysicsSyntax.CYLINDER

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeCylinderShape, self).LoadFromXml(daeDocument, xmlNode)
self.radius = ToFloat2(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode, DaePhysicsSyntax.RADIUS)),'Not a valid radius found. Must consist of 2 floats')
self.height = CastFromXml(daeDocument, xmlNode, DaeSyntax.HEIGHT, float)

def SaveToXml(self, daeDocument):
node = super(DaeCylinderShape, self).SaveToXml(daeDocument)
AppendTextChild(node, DaePhysicsSyntax.RADIUS, self.radius)
AppendTextChild(node, DaeSyntax.HEIGHT, self.height)
return node

class DaeTaperedCylinderShape(DaeShape):
def __init__(self):
super(DaeTaperedCylinderShape, self).__init__()
self.radius1 = [1 , 1]
self.radius2 = [1 , 1]
self.height = None
self.syntax = DaePhysicsSyntax.TAPERED_CYLINDER

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeTaperedCylinderShape, self).LoadFromXml(daeDocument, xmlNode)
self.radius1 = ToFloat2(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode, DaePhysicsSyntax.RADIUS1)),'Not a valid radius found. Must consist of 2 floats')
self.radius2 = ToFloat2(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode, DaePhysicsSyntax.RADIUS2)), 'Not a valid radius found. Must consist of 2 floats')
self.height = CastFromXml(daeDocument, xmlNode, DaeSyntax.HEIGHT, float)

def SaveToXml(self, daeDocument):
node = super(DaeTaperedCylinderShape, self).SaveToXml(daeDocument)
AppendTextChild(node, DaePhysicsSyntax.RADIUS1, self.radius1)
AppendTextChild(node, DaePhysicsSyntax.RADIUS2, self.radius2)
AppendTextChild(node, DaeSyntax.HEIGHT, self.height)
return node

class DaePlaneShape(DaeShape):
def __init__(self):
super(DaePlaneShape, self).__init__()
self.equation = []
self.syntax = DaePhysicsSyntax.PLANE

def LoadFromXml(self, daeDocument, xmlNode):
super(DaePlaneShape, self).LoadFromXml(daeDocument, xmlNode)
self.equation = ToFloat4(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaePhysicsSyntax.EQUATION)))

def SaveToXml(self, daeDocument):
node = super(DaePlaneShape, self).SaveToXml(daeDocument)
AppendTextChild(node, DaePhysicsSyntax.EQUATION, self.equation)
return node

class DaeCapsuleShape(DaeShape):
def __init__(self):
super(DaeCapsuleShape, self).__init__()
self.radius = None
self.height = None
self.syntax = DaePhysicsSyntax.CAPSULE

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeCapsuleShape, self).LoadFromXml(daeDocument, xmlNode)
self.radius = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.RADIUS, float)
self.height = CastFromXml(daeDocument, xmlNode, DaeSyntax.HEIGHT, float)

def SaveToXml(self, daeDocument):
node = super(DaeCapsuleShape, self).SaveToXml(daeDocument)
AppendTextChild(node, DaePhysicsSyntax.RADIUS, self.radius)
AppendTextChild(node, DaeSyntax.HEIGHT, self.height)
return node

class DaeGeometryShape(DaeShape):
def __init__(self):
super(DaeGeometryShape, self).__init__()
self.iGeometry = None

def LoadFromXml(self, daeDocument, xmlNode):
super(DaeGeometryShape, self).LoadFromXml(daeDocument, xmlNode)
self.iGeometry = DaeGeometryInstance()
self.iGeometry.LoadFromXml(daeDocument, xmlNode)
#self.iGeometry = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_GEOMETRY, DaeGeometryInstance)
#print self.iGeometry
#print xmlNode.toxml()

def SaveToXml(self, daeDocument):
#node = super(DaeGeometryShape, self).SaveToXml(daeDocument)
#AppendChild(daeDocument, node, self.iGeometry)
return self.iGeometry.SaveToXml(daeDocument)

class DaePhysicsSyntax(object):
PHYSICS_SCENE = 'physics_scene'
PHYSICS_MODEL = 'physics_model'
PHYSICS_MATERIAL = 'physics_material'

RIGID_BODY = 'rigid_body'

INSTANCE_PHYSICS_MODEL = 'instance_physics_model'
INSTANCE_PHYSICS_MATERIAL = 'instance_physics_material'
INSTANCE_RIGID_BODY = 'instance_rigid_body'

RESTITUTION = 'restitution'
STATIC_FRICTION = 'static_friction'
DYNAMIC_FRICTION = 'dynamic_friction'

DYNAMIC = 'dynamic'
MASS = 'mass'
INERTIA = 'inertia'
SHAPE = 'shape'
DENSITY = 'density'
RADIUS = 'radius'
RADIUS1 = 'radius1'
RADIUS2 = 'radius2'


BOX = 'box'
PLANE = 'plane'
CYLINDER = 'cylinder'
SPHERE = 'sphere'
CAPSULE = 'capsule'
TAPERED_CAPSULE ='tapered_capsule'
TAPERED_CYLINDER = 'tapered_cylinder'

HALF_EXTENTS = 'half_extents'

#---Functions---
def CreateObjectsFromXml(colladaDocument, xmlNode, nodeType, objectType):
if xmlNode is None:
return None
objects = []
nodes = xmlUtils.FindElementsByTagName(xmlNode,nodeType)
for node in nodes:
object = objectType()
object.LoadFromXml(colladaDocument, node)
objects.append(object)
return objects

def CreateObjectFromXml(colladaDocument, xmlNode, nodeType, objectType, setSyntax = False):
if xmlNode is None:
return None
node = xmlUtils.FindElementByTagName(xmlNode, nodeType)
object = None
if setSyntax:
object = objectType(nodeType)
else:
object = objectType()
if node != None:
object.LoadFromXml(colladaDocument, node)
return object
return None

def CastFromXml(colladaDocument, xmlNode, nodeType, cast, default=None):
if xmlNode is None:
return default
node = xmlUtils.FindElementByTagName(xmlNode, nodeType)
if node != None:
textValue = xmlUtils.ReadContents(node)
if cast == bool:
if textValue.lower() == 'false':
return False
else:
return True
return cast(textValue)
return default

def CastAttributeFromXml(xmlNode, nodeType, cast, default=None):
if xmlNode is None:
return default
val = xmlUtils.ReadAttribute(xmlNode, nodeType)
if val != None and val != '':
return cast(val)
return default

def AppendChild(daeDocument, xmlNode, daeEntity):
if daeEntity is None or xmlNode is None:
return
else:
child = daeEntity.SaveToXml(daeDocument)
if child is None:
return
else :
xmlNode.appendChild(child)

def AppendChilds(daeDocument, xmlNode, daeEntities):
if daeEntities is None or xmlNode is None:
return

else:
for daeEntity in daeEntities:
AppendChild(daeDocument, xmlNode, daeEntity)

def AppendTextChild(xmlNode,syntax, object, default = None):
if object is None:
return
if default != None and object == default:
return
node = Element(syntax)
xmlNode.appendChild(node)
return AppendTextInChild(node, object)

def AppendTextInChild(xmlNode, object):
if object is None:
return
text = Text()
if type(object) == datetime:
text.data = object.isoformat()##xmlUtils.ToDateTime(object)
elif type(object) == list:
if len(object) == 0: return
if object[0] is not None and type(object[0]) == float:
object = RoundList(object, ROUND)
text.data = ListToString(object)
elif type(object) == float:
text.data = round(object, ROUND)
elif type(object) == bool:
text.data = str(object).lower()
elif type(object) == int:
text.data = str(object) #Doug: added Mar3008 - same as default below so should have no effect
else:
text.data = str(object)
xmlNode.appendChild(text)
return xmlNode

def SetAttribute(xmlNode,syntax, object):
if xmlNode is None or object is None or str(object) == '':
return
xmlNode.setAttribute(syntax,str(object))

def ReadNodeUrl(node):
attribute = xmlUtils.ReadAttribute(node,DaeSyntax.URL)
if attribute == None: return None
else :
attribute = str(attribute)
if attribute.startswith('#'):
return attribute[1:]
return None

def WriteNodeUrl(node, url):
node.setAttribute(DaeSyntax.URL, StripString('#'+url))

def IsVersionOk(version, curVersion):
versionAr = version.split('.')
curVersionAr = curVersion.split('.')
for i in range(len(curVersionAr)):
if versionAr[i] != curVersionAr[i]:
return False
return True

def StripString(text):
return text.replace(' ','_').replace('.','_')
  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 xml.dom.minidom import *
  26. import xmlUtils
  27. from cutils import *
  28. from datetime import *
  29.  
  30. # The number of decimals to export floats to
  31. ROUND = 5
  32.  
  33. # TODO: finish DaeDocument
  34. class DaeDocument(object):
  35.        
  36.         def __init__(self, debugM = False):
  37.                 global debugMode
  38.                 debugMode = debugM
  39.                
  40.                 self.colladaVersion = '1.4.0'
  41.                 self.version = ''
  42.                 self.xmlns = ''
  43.                 self.asset = DaeAsset()
  44.                 self.extras = []
  45.                
  46.                
  47.                 # create all the libraries
  48.                 self.animationsLibrary = DaeLibrary(DaeSyntax.LIBRARY_ANIMATIONS,DaeAnimation,DaeSyntax.ANIMATION)
  49.                 self.animationClipsLibrary = DaeLibrary(DaeSyntax.LIBRARY_ANIMATION_CLIPS,DaeAnimationClip,DaeSyntax.ANIMATION_CLIP)
  50.                 self.camerasLibrary = DaeLibrary(DaeSyntax.LIBRARY_CAMERAS,DaeCamera,DaeSyntax.CAMERA)
  51.                 self.controllersLibrary = DaeLibrary(DaeSyntax.LIBRARY_CONTROLLERS,DaeController,DaeSyntax.CONTROLLER)
  52.                 self.effectsLibrary = DaeLibrary(DaeSyntax.LIBRARY_EFFECTS,DaeFxEffect,DaeFxSyntax.EFFECT)
  53.                 self.geometriesLibrary = DaeLibrary(DaeSyntax.LIBRARY_GEOMETRIES,DaeGeometry,DaeSyntax.GEOMETRY)
  54.                 self.imagesLibrary = DaeLibrary(DaeSyntax.LIBRARY_IMAGES, DaeImage, DaeSyntax.IMAGE)
  55.                 self.lightsLibrary = DaeLibrary(DaeSyntax.LIBRARY_LIGHTS,DaeLight,DaeSyntax.LIGHT)
  56.                 self.materialsLibrary = DaeLibrary(DaeSyntax.LIBRARY_MATERIALS,DaeFxMaterial,DaeFxSyntax.MATERIAL)
  57.                 self.nodesLibrary = DaeLibrary(DaeSyntax.LIBRARY_NODES, DaeNode, DaeSyntax.NODE)
  58.                 self.visualScenesLibrary = DaeLibrary(DaeSyntax.LIBRARY_VISUAL_SCENES,DaeVisualScene,DaeSyntax.VISUAL_SCENE)
  59.                
  60.                 # Physics Support
  61.                 self.physicsMaterialsLibrary = DaeLibrary(DaeSyntax.LIBRARY_PHYSICS_MATERIALS, DaePhysicsMaterial, DaePhysicsSyntax.PHYSICS_MATERIAL)            
  62.                 self.physicsScenesLibrary = DaeLibrary(DaeSyntax.LIBRARY_PHYSICS_SCENES, DaePhysicsScene, DaePhysicsSyntax.PHYSICS_SCENE)                
  63.                
  64.                 self.physicsModelsLibrary = DaeLibrary(DaeSyntax.LIBRARY_PHYSICS_MODELS, DaePhysicsModel, DaePhysicsSyntax.PHYSICS_MODEL)
  65.                                
  66.                 self.scene = None
  67.                 self.physicsScene = None
  68.                
  69.         def LoadDocumentFromFile(self, filename):
  70.                 global debugMode
  71.                 # Build DOM tree
  72.                 doc = parse( filename )
  73.            
  74.                 # Get COLLADA element
  75.                 colladaNode = doc.documentElement       
  76.                                
  77.                 # Get Attributes               
  78.                 self.version = colladaNode.getAttribute(DaeSyntax.VERSION)
  79.                 if not IsVersionOk(self.version, self.colladaVersion):
  80.                         Debug.Debug('The version of the file (%s) is older then the version supported by this plugin(%s).'%(self.version, self.colladaVersion),'ERROR')
  81.                         doc.unlink()
  82.                         return
  83.                 self.xmlns = colladaNode.getAttribute(DaeSyntax.XMLNS)
  84.                
  85.                 # get the assets element
  86.                 self.asset.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.ASSET))
  87.                
  88.                 # get the extra elements
  89.                 self.extras = CreateObjectsFromXml(self,colladaNode,DaeSyntax.EXTRA,DaeExtra)
  90.                                
  91.                 # parse all the libraries
  92.                 self.imagesLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_IMAGES))
  93.                 self.animationsLibrary.LoadFromXml(self, xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_IMAGES))
  94.                 self.animationClipsLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_ANIMATION_CLIPS))
  95.                 self.camerasLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_CAMERAS))
  96.                 self.controllersLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_CONTROLLERS))
  97.                 self.effectsLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_EFFECTS))
  98.                 self.geometriesLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_GEOMETRIES))
  99.                 self.lightsLibrary.LoadFromXml(self, xmlUtils.FindElementByTagName(colladaNode, DaeSyntax.LIBRARY_LIGHTS))
  100.                 self.materialsLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_MATERIALS))
  101.                 self.nodesLibrary.LoadFromXml(self,xmlUtils.FindElementByTagName(colladaNode,DaeSyntax.LIBRARY_NODES))
  102.                 self.visualScenesLibrary.LoadFromXml(self, xmlUtils.FindElementByTagName(colladaNode, DaeSyntax.LIBRARY_VISUAL_SCENES))
  103.                
  104.                 self.physicsMaterialsLibrary.LoadFromXml(self, xmlUtils.FindElementByTagName(colladaNode, DaeSyntax.LIBRARY_PHYSICS_MATERIALS))
  105.                 self.physicsModelsLibrary.LoadFromXml(self, xmlUtils.FindElementByTagName(colladaNode, DaeSyntax.LIBRARY_PHYSICS_MODELS))
  106.                 self.physicsScenesLibrary.LoadFromXml(self, xmlUtils.FindElementByTagName(colladaNode, DaeSyntax.LIBRARY_PHYSICS_SCENES))
  107.                
  108.                 # Get the sceneNodes
  109.                 sceneNodes = colladaNode.getElementsByTagName(DaeSyntax.SCENE)
  110.                
  111.                 # Get the scene
  112.                 sceneNode = xmlUtils.FindElementByTagName(colladaNode, DaeSyntax.SCENE)
  113.                 if sceneNode != None:
  114.                         scene = DaeScene()
  115.                         scene.LoadFromXml(self, sceneNode)
  116.                         self.scene = scene
  117.                        
  118.                 doc.unlink()
  119.                
  120.                 if debugMode:
  121.                         Debug.Debug('Directly exporting this DaeDocument...','DEBUG')
  122.                         self.SaveDocumentToFile(filename+'_out.dae')
  123.                        
  124.         def SaveDocumentToFile(self, filename):
  125.                 self.version = '1.4.0'
  126.                 self.xmlns = 'http://www.collada.org/2005/11/COLLADASchema'
  127.                 colladaNode = Element(DaeSyntax.COLLADA)
  128.                 colladaNode.setAttribute(DaeSyntax.VERSION, self.version)
  129.                 colladaNode.setAttribute(DaeSyntax.XMLNS, self.xmlns)
  130.                
  131.                 colladaNode.appendChild(self.asset.SaveToXml(self))
  132.                
  133.                 # add the labraries
  134.                 AppendChild(self,colladaNode,self.animationsLibrary)
  135.                 AppendChild(self,colladaNode,self.animationClipsLibrary)
  136.                 AppendChild(self,colladaNode,self.camerasLibrary)
  137.                 AppendChild(self,colladaNode,self.controllersLibrary)
  138.                 AppendChild(self,colladaNode,self.effectsLibrary)
  139.                 AppendChild(self,colladaNode,self.geometriesLibrary)
  140.                 AppendChild(self,colladaNode,self.imagesLibrary)
  141.                 AppendChild(self,colladaNode,self.lightsLibrary)
  142.                 AppendChild(self,colladaNode,self.materialsLibrary)
  143.                 AppendChild(self,colladaNode,self.nodesLibrary)
  144.                 AppendChild(self,colladaNode,self.visualScenesLibrary)
  145.                 AppendChild(self,colladaNode,self.physicsMaterialsLibrary)
  146.                 AppendChild(self,colladaNode,self.physicsModelsLibrary)
  147.                 AppendChild(self,colladaNode,self.physicsScenesLibrary)            
  148.                
  149.                 AppendChild(self,colladaNode,self.scene)
  150.                
  151.                 # write xml to the file
  152.                 fileref = open(filename, 'w')
  153.                 fileref.write(xmlUtils.ToXml(colladaNode))
  154.                 fileref.flush()
  155.                 fileref.close()
  156.                 colladaNode.unlink()
  157.        
  158.         def GetItemCount(self):
  159.                 return (##self.animationClipsLibrary.GetItemCount()+
  160.         ##self.animationsLibrary.GetItemCount()+
  161.         ##self.camerasLibrary.GetItemCount()+
  162.         ##self.controllersLibrary.GetItemCount()+
  163.         ##self.effectsLibrary.GetItemCount()+
  164.         self.geometriesLibrary.GetItemCount()+
  165.         self.lightsLibrary.GetItemCount()+
  166.         ##self.materialsLibrary.GetItemCount()+
  167.         self.nodesLibrary.GetItemCount()##+
  168.         ##self.visualScenesLibrary.GetItemCount()
  169.         )
  170.        
  171.         def __str__(self):
  172.                 return '%s version: %s, xmlns: %s, asset: %s, extras: %s, scene: %s'%(type(self), self.version, self.xmlns, self.asset, self.extras, self.scene)
  173.                
  174. class DaeEntity(object):
  175.         def __init__(self):
  176.                 self.syntax = 'UNKNOWN'
  177.                
  178.         def LoadFromXml(self, daeDocument, xmlNode):
  179.                 Debug.Debug('DaeEntity: Override this method for %s'%(type(self)),'WARNING')
  180.        
  181.         def SaveToXml(self, daeDocument):
  182.                 node = Element(self.syntax)
  183.                 return node
  184.        
  185.         def GetType(self):
  186.                 return self.syntax
  187.                
  188. class DaeElement(DaeEntity):
  189.        
  190.         def __init__(self):
  191.                 super(DaeElement,self).__init__()
  192.                
  193.                 self.id = ''
  194.                 self.name = ''
  195.                
  196.        
  197.         def LoadFromXml(self,daeDocument, xmlNode):
  198.                 if xmlNode is None:
  199.                         return
  200.                
  201.                 self.id = xmlNode.getAttribute(DaeSyntax.ID)
  202.                 self.name = xmlNode.getAttribute(DaeSyntax.NAME)
  203.        
  204.         def SaveToXml(self, daeDocument):
  205.                 node = super(DaeElement,self).SaveToXml(daeDocument)
  206.                 SetAttribute(node,DaeSyntax.ID,StripString(self.id))
  207.                 SetAttribute(node,DaeSyntax.NAME, StripString(self.name))
  208.                 return node
  209.        
  210.         def __str__(self):
  211.                 return super(DaeElement,self).__str__()+'id: %s, name: %s'%(self.id, self.name)
  212.  
  213. # TODO: finish DaeLibrary
  214. class DaeLibrary(DaeElement):
  215.         def __init__(self, syntax, objectType, objectSyntax):
  216.                 super(DaeLibrary,self).__init__()
  217.                
  218.                 self.extras = []
  219.                 self.asset = None
  220.                 self.items = []
  221.                
  222.                 self.__objectSyntax = objectSyntax
  223.                
  224.                 self.syntax = syntax
  225.                 self.__objectType = objectType
  226.                
  227.         def LoadFromXml(self,daeDocument, xmlNode):
  228.                 if xmlNode is None:
  229.                         return
  230.                 super(DaeLibrary,self).LoadFromXml(daeDocument, xmlNode)
  231.                
  232.                 self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
  233.                 self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
  234.                 self.items =  CreateObjectsFromXml(daeDocument, xmlNode, self.__objectSyntax, self.__objectType)
  235.                
  236.         def SaveToXml(self,daeDocument):
  237.                 if len(self.items) > 0:
  238.                         node = super(DaeLibrary,self).SaveToXml(daeDocument)
  239.                         # Add the assets
  240.                         AppendChild(daeDocument,node,self.asset)
  241.                         # Add the library_items
  242.                         AppendChilds(daeDocument,node,self.items)
  243.                         # Add the extra's
  244.                         AppendChilds(self,node,self.extras)
  245.                         return node
  246.                 else:
  247.                         return None
  248.         def GetItemCount(self):
  249.                 return len(self.items)
  250.        
  251.         def FindObject(self,url):
  252.                 for i in self.items:
  253.                         if i.id == url:
  254.                                 return i
  255.                 return None
  256.        
  257.         def AddItem(self,item):
  258.                 self.items.append(item)
  259.                
  260.         def __str__(self):
  261.                 return super(DaeLibrary,self).__str__() + 'extras: %s, asset: %s, items: %s'%(self.extras, self.asset, self.items)
  262.                
  263. class DaeAsset(DaeEntity):
  264.         def __init__(self):
  265.                 super(DaeAsset,self).__init__()
  266.                 self.contributors = []
  267.                 self.created = None
  268.                 self.modified = None
  269.                 self.revision = None
  270.                 self.title = None
  271.                 self.subject = None
  272.                 self.keywords = []
  273.                 self.unit = DaeUnit()
  274.                 self.upAxis = 'Y_UP'
  275.                
  276.                 self.syntax = DaeSyntax.ASSET
  277.                
  278.         def LoadFromXml(self, daeDocument, xmlNode):
  279.                 if xmlNode is None:
  280.                         return
  281.                 # Get the contributor(s)
  282.                 self.contributors = CreateObjectsFromXml(daeDocument, xmlNode,DaeSyntax.CONTRIBUTOR,DaeContributor)
  283.                 # Get created
  284.                 self.created = xmlUtils.ReadDateTime(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.CREATED))
  285.                 # Get modified
  286.                 self.modified = xmlUtils.ReadDateTime(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.MODIFIED))
  287.                 # Get revision
  288.                 self.revision = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.REVISION))
  289.                 # Get title
  290.                 self.title = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.TITLE))
  291.                 # Get subject
  292.                 self.subject = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.SUBJECT))
  293.                 # Get keywords
  294.                 self.keywords = xmlUtils.GetStringArrayFromNodes(xmlNode.getElementsByTagName(DaeSyntax.KEYWORDS))
  295.                 # Get Unit
  296.                 self.unit.LoadFromXml(daeDocument, xmlUtils.FindElementByTagName(xmlNode, DaeSyntax.UNIT))
  297.                 # Get upAxis
  298.                 self.upAxis = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.UP_AXIS))
  299.        
  300.         def SaveToXml(self, daeDocument):
  301.                 node = Element(DaeSyntax.ASSET)
  302.                 AppendChilds(daeDocument,node, self.contributors)
  303.                 AppendTextChild(node, DaeSyntax.CREATED, self.created)
  304.                 AppendTextChild(node, DaeSyntax.MODIFIED, self.modified)
  305.                 AppendTextChild(node, DaeSyntax.REVISION, self.revision)
  306.                 AppendTextChild(node, DaeSyntax.TITLE, self.title)
  307.                 AppendTextChild(node, DaeSyntax.SUBJECT, self.subject)
  308.                 AppendChild(daeDocument, node, self.unit)
  309.                 AppendTextChild(node, DaeSyntax.UP_AXIS, self.upAxis)
  310.                
  311.                
  312.                
  313.                 return node
  314.                
  315.        
  316.         def __str__(self):
  317.                 return super(DaeAsset,self).__str__()+'contributors: %s, created: %s, modified: %s, revision: %s, title: %s, subject: %s, keywords: %s, unit: %s, upAxis: %s'%(self.contributors, self.created, self.modified, self.revision, self.title, self.subject, self.keywords, self.unit, self.upAxis)
  318.                
  319. # TODO: finish DaeScene
  320. class DaeScene(DaeEntity):
  321.         def __init__(self):
  322.                 super(DaeScene,self).__init__()
  323.                 self.extras = []
  324.                 self.iVisualScenes = []
  325.                 self.iPhysicsScenes = []
  326.  
  327.                 self.syntax = DaeSyntax.SCENE
  328.                
  329.         def LoadFromXml(self, daeDocument, xmlNode):
  330.                 if xmlNode is None:
  331.                         return
  332.                 self.iVisualScenes = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_VISUAL_SCENE, DaeVisualSceneInstance)
  333.                 self.iPhysicsScenes = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_PHYSICS_SCENE, DaePhysicsSceneInstance)
  334.        
  335.         def SaveToXml(self, daeDocument):
  336.                 node = super(DaeScene,self).SaveToXml(daeDocument)
  337.                 AppendChilds(daeDocument, node, self.iVisualScenes)
  338.                 AppendChilds(daeDocument, node, self.iPhysicsScenes)
  339.                 return node
  340.        
  341.         def GetVisualScenes(self):
  342.                 result = []
  343.                 for i in self.iVisualScenes:
  344.                         result.append(i.object)
  345.                 return result
  346.        
  347.         def GetPhysicsScenes(self):
  348.                 result = []
  349.                 for i in self.iPhysicsScenes:
  350.                         result.append(i.object)
  351.                 return result
  352.        
  353.         def __str__(self):
  354.                 return super(DaeScene,self).__str__()+'extras: %s, visualScenes: %s, physicsScenes: %s'%(self.extras, self.iVisualScenes, self.iPhysicsScenes)
  355.                
  356.  
  357. class DaeUnit(DaeEntity):
  358.         def __init__(self):
  359.                 super(DaeUnit,self).__init__()
  360.                 self.name = 'meter'
  361.                 self.meter = 1.0
  362.                
  363.                 self.syntax = DaeSyntax.UNIT
  364.                
  365.         def LoadFromXml(self, daeDocument, xmlNode):
  366.                 if xmlNode is None:
  367.                         return
  368.                 name = xmlNode.getAttribute(DaeSyntax.NAME)
  369.                 if name != '':
  370.                         self.name = name
  371.                        
  372.                 meter = xmlNode.getAttribute(DaeSyntax.METER)
  373.                 if meter != '':
  374.                         self.meter = float(meter)
  375.        
  376.         def SaveToXml(self,daeDocument):
  377.                 node = super(DaeUnit, self).SaveToXml(daeDocument)
  378.                 SetAttribute(node, DaeSyntax.METER, self.meter)
  379.                 SetAttribute(node, DaeSyntax.NAME, self.name)
  380.                 return node
  381.                                
  382.         def __str__(self):
  383.                 return super(DaeUnit, self).__str__()+' name: %s, meter: %s'%(self.name, self.meter)
  384.        
  385. class DaeContributor(DaeEntity):
  386.         def __init__(self):
  387.                 super(DaeContributor, self).__init__()
  388.                 self.author = ''
  389.                 self.authoringTool = ''
  390.                 self.comments = ''
  391.                 self.copyright = ''
  392.                 self.sourceData = ''
  393.                
  394.                 self.syntax = DaeSyntax.CONTRIBUTOR
  395.                
  396.         def LoadFromXml(self, daeDocument, xmlNode):
  397.                 self.author = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.AUTHOR))
  398.                 self.authoringTool = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.AUTHORING_TOOL))
  399.                 self.comments = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.COMMENTS))
  400.                 self.copyright = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.COPYRIGHT))
  401.                 self.sourceData = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.SOURCE_DATA))
  402.        
  403.         def SaveToXml(self, daeDocument):
  404.                 node = super(DaeContributor, self).SaveToXml(daeDocument)
  405.                 AppendTextChild(node, DaeSyntax.AUTHOR, self.author)
  406.                 AppendTextChild(node, DaeSyntax.AUTHORING_TOOL, self.authoringTool)
  407.                 AppendTextChild(node, DaeSyntax.COMMENTS, self.comments)
  408.                 AppendTextChild(node, DaeSyntax.COPYRIGHT, self.copyright)
  409.                 AppendTextChild(node, DaeSyntax.SOURCE_DATA, self.sourceData)
  410.                 return node
  411.                
  412.                
  413.         def __str__(self):
  414.                 return super(DaeContributor,self).__str__() + 'author: %s, authoring_tool: %s, comments: %s, copyright: %s, sourceData: %s'%(self.author, self.authoringTool, self.comments, self.copyright, self.sourceData)
  415.        
  416. class DaeAnimation(DaeElement):
  417.         pass   
  418. class DaeAnimationClip(DaeElement):
  419.         pass
  420. class DaeCamera(DaeElement):
  421.         def __init__(self):
  422.                 super(DaeCamera,self).__init__()
  423.                 self.asset = None
  424.                 self.extras = []
  425.                 self.optics = DaeOptics()
  426.                 self.imager = None
  427.                 self.syntax = DaeSyntax.CAMERA
  428.                
  429.         def LoadFromXml(self, daeDocument, xmlNode):
  430.                 super(DaeCamera, self).LoadFromXml(daeDocument, xmlNode)
  431.                 self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
  432.                 self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
  433.                 self.optics.LoadFromXml(daeDocument, xmlUtils.FindElementByTagName(xmlNode, DaeSyntax.OPTICS))
  434.                 self.imager = CreateObjectFromXml(daeDocument,xmlNode, DaeSyntax.IMAGER,DaeImager)
  435.                
  436.        
  437.         def SaveToXml(self, daeDocument):
  438.                 node = super(DaeCamera, self).SaveToXml(daeDocument)
  439.                 # Add the assets
  440.                 AppendChild(daeDocument,node,self.asset)
  441.                 # Add the optics
  442.                 node.appendChild(self.optics.SaveToXml(daeDocument))
  443.                 # Add the imager
  444.                 AppendChild(daeDocument,node,self.imager)
  445.                 # Add the extra's
  446.                 AppendChilds(self,node,self.extras)
  447.                 return node
  448.                
  449.         def __str__(self):
  450.                 return super(DaeCamera,self).__str__()+'asset: %s, optics: %s, imager: %s, extras: %s'%(self.asset, self.optics, self.imager, self.extras)
  451.  
  452. class DaeController(DaeElement):
  453.         pass
  454. class DaeImage(DaeElement):
  455.         def __init__(self):
  456.                 super(DaeImage,self).__init__()
  457.                 self.format = None
  458.                 self.height = None
  459.                 self.width = None
  460.                 self.depth = None
  461.                 self.initFrom = None
  462.                 self.syntax = DaeSyntax.IMAGE
  463.                
  464.         def LoadFromXml(self, daeDocument, xmlNode):
  465.                 super(DaeImage, self).LoadFromXml(daeDocument, xmlNode)
  466.                 self.format = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.FORMAT)
  467.                 self.height = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.HEIGHT)
  468.                 self.width = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.WIDTH)
  469.                 self.depth = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.DEPTH)
  470.                 self.initFrom = xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode, DaeSyntax.INIT_FROM))     
  471.                
  472.         def SaveToXml(self, daeDocument):
  473.                 node = super(DaeImage, self).SaveToXml(daeDocument)
  474.                 SetAttribute(node, DaeSyntax.FORMAT, self.format)
  475.                 SetAttribute(node, DaeSyntax.HEIGHT, self.height)
  476.                 SetAttribute(node, DaeSyntax.WIDTH, self.width)
  477.                 SetAttribute(node, DaeSyntax.DEPTH, self.depth)
  478.                 AppendTextChild(node, DaeSyntax.INIT_FROM,self.initFrom, None)
  479.                 return node
  480.        
  481. ##class DaeMaterial(DaeElement):
  482. ##        def __init__(self):
  483. ##                super(DaeMaterial,self).__init__()
  484. ##                self.asset = None
  485. ##                self.iEffects = []
  486. ##                self.extras = None
  487. ##                self.syntax = DaeSyntax.MATERIAL
  488. ##               
  489. ##        def LoadFromXml(self, daeDocument, xmlNode):
  490. ##                super(DaeMaterial, self).LoadFromXml(daeDocument, xmlNode)
  491. ##                self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
  492. ##                self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
  493. ##                self.iEffects = CreateObjectsFromXml(daeDocument,xmlNode, DaeSyntax.INSTANCE_EFFECT, DaeEffectInstance)
  494. ##       
  495. ##        def SaveToXml(self, daeDocument):
  496. ##                node = super(DaeMaterial, self).SaveToXml(daeDocument)
  497. ##                # Add the assets
  498. ##                AppendChild(daeDocument,node,self.asset)
  499. ##                # Add the effect instances
  500. ##                AppendChilds(daeDocument, node, self.iEffects)
  501. ##                # Add the extra's
  502. ##                AppendChilds(self,node,self.extras)
  503. ##                return node
  504. ##               
  505. ##        def __str__(self):
  506. ##                return super(DaeLight,self).__str__()+' assets: %s, data: %s, extras: %s'%(self.asset, self.data, self.extras)
  507.  
  508. class DaeGeometry(DaeElement):
  509.         def __init__(self):
  510.                 super(DaeGeometry,self).__init__()
  511.                 self.asset = None
  512.                 self.data = None
  513.                 self.extras = None
  514.                 self.syntax = DaeSyntax.GEOMETRY
  515.                
  516.         def LoadFromXml(self, daeDocument, xmlNode):
  517.                 super(DaeGeometry, self).LoadFromXml(daeDocument, xmlNode)
  518.                 self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
  519.                 self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
  520.                                
  521.                 self.data = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.MESH, DaeMesh)
  522.                 if self.data is None:
  523.                         self.data = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.CONVEX_MESH, DaeConvexMesh)
  524.                 if self.data is None:
  525.                         self.data = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.SPLINE, DaeSpline)
  526.        
  527.         def SaveToXml(self, daeDocument):
  528.                 node = super(DaeGeometry, self).SaveToXml(daeDocument)
  529.                 # Add the assets
  530.                 AppendChild(daeDocument,node,self.asset)
  531.                 # Add the data
  532.                 AppendChild(daeDocument, node, self.data)
  533.                 # Add the extra's
  534.                 AppendChilds(self,node,self.extras)
  535.                 return node
  536.                
  537.         def __str__(self):
  538.                 return super(DaeGeometry,self).__str__()+' assets: %s, data: %s, extras: %s'%(self.asset, self.data, self.extras)
  539.        
  540. class DaeConvexMesh(DaeEntity):
  541.         def __init__(self):
  542.                 super(DaeConvexMesh, self).__init__()
  543.                 self.syntax = DaeSyntax.CONVEX_MESH
  544.                 self.convexHullOf = None
  545.        
  546.         def LoadFromXml(self, daeDocument, xmlNode):
  547.                 self.convexHullOf = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.CONVEX_HULL_OF)
  548.                
  549.         def SaveToXml(self, daeDocument):
  550.                 node = super(DaeConvexMesh, self).SaveToXml(daeDocument)
  551.                 SetAttribute(node, DaeSyntax.CONVEX_HULL_OF, StripString(self.convexHullOf))
  552.                 return node
  553.        
  554. class DaeMesh(DaeEntity):
  555.         def __init__(self):
  556.                 super(DaeMesh, self).__init__()
  557.                 self.sources = []
  558.                 self.vertices = None
  559.                 self.primitives = []
  560.                 self.extras = []
  561.                 self.syntax = DaeSyntax.MESH
  562.                
  563.         def LoadFromXml(self, daeDocument, xmlNode):
  564.                 if xmlNode is None:
  565.                         return
  566.                 self.vertices = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.VERTICES, DaeVertices)               
  567.                 self.sources = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.SOURCE, DaeSource)
  568.                
  569.                 lines = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.LINES, DaeLines)
  570.                 linestrips = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.LINESTRIPS, DaeLineStrips)
  571.                 polygons = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.POLYGONS, DaePolygons)
  572.                 polylist = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.POLYLIST, DaePolylist)
  573.                 triangles = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.TRIANGLES, DaeTriangles)
  574.                 trifans = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.TRIFANS, DaeTriFans)
  575.                 tristrips = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.TRISTRIPS, DaeTriStrips)
  576.                 if lines != None: self.primitives += lines
  577.                 if linestrips != None: self.primitives += linestrips
  578.                 if polygons != None: self.primitives += polygons
  579.                 if polylist != None: self.primitives += polylist
  580.                 if triangles != None: self.primitives += triangles
  581.                 if trifans != None: self.primitives += trifans
  582.                 if tristrips != None: self.primitives += tristrips
  583.                
  584.                 self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
  585.                
  586.         def FindSource(self,input):
  587.                 for s in self.sources:
  588.                         if s.id == input.source:
  589.                                 return s
  590.                 return None
  591.                
  592.         def SaveToXml(self, daeDocument):
  593.                 node = super(DaeMesh, self).SaveToXml(daeDocument)
  594.                 AppendChilds(daeDocument, node, self.sources)
  595.                 AppendChild(daeDocument, node, self.vertices)
  596.                 AppendChilds(daeDocument, node, self.primitives)
  597.                 AppendChilds(daeDocument, node, self.extras)
  598.                 return node
  599. class DaeVertices(DaeElement):
  600.         def __init__(self):
  601.                 super(DaeVertices,self).__init__()
  602.                 self.inputs = []
  603.                 self.extras = []
  604.                
  605.                 self.syntax = DaeSyntax.VERTICES
  606.                
  607.         def LoadFromXml(self, daeDocument, xmlNode):
  608.                 super(DaeVertices,self).LoadFromXml(daeDocument, xmlNode)
  609.                 self.inputs = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INPUT, DaeInput)
  610.                 self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
  611.                
  612.         def SaveToXml(self, daeDocument):
  613.                 node = super(DaeVertices, self).SaveToXml(daeDocument)
  614.                 AppendChilds(daeDocument, node, self.inputs)
  615.                 AppendChilds(daeDocument, node, self.extras)
  616.                 return node
  617.        
  618.         def FindInput(self, semantic):
  619.                 for i in self.inputs:
  620.                         if i.semantic == semantic:
  621.                                 return i
  622.                 return None
  623.        
  624.         def __str__(self):
  625.                 return super(DaeVertices,self).__str__() + ' inputs: %s, extras: %s'%(self.inputs, self.extras)
  626.        
  627. class DaeInput(DaeEntity):
  628.         def __init__(self):
  629.                 super(DaeInput, self).__init__()
  630.                 self.offset = None
  631.                 self.semantic = ''
  632.                 self.source = ''
  633.                 self.set = ''
  634.                 self.syntax = DaeSyntax.INPUT
  635.                
  636.         def LoadFromXml(self, daeDocument, xmlNode):
  637.                 self.offset = CastAttributeFromXml(xmlNode, DaeSyntax.OFFSET, int)
  638.                 self.semantic = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.SEMANTIC)
  639.                 self.source = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.SOURCE)[1:]
  640.                 self.set = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.SET)
  641.                
  642.         def SaveToXml(self, daeDocument):
  643.                 node = super(DaeInput, self).SaveToXml(daeDocument)
  644.                 SetAttribute(node,DaeSyntax.OFFSET, self.offset)
  645.                 SetAttribute(node,DaeSyntax.SEMANTIC, self.semantic)
  646.                 SetAttribute(node,DaeSyntax.SOURCE, StripString('#'+self.source))
  647.                 SetAttribute(node,DaeSyntax.SET, self.set)
  648.                 return node
  649.  
  650. class DaeSource(DaeElement):
  651.         def __init__(self):
  652.                 super(DaeSource, self).__init__()
  653.                 self.source = DaeArray()
  654.                 self.vectors = []
  655.                 self.techniqueCommon = None
  656.                 self.techniques = []
  657.                
  658.                 self.syntax = DaeSyntax.SOURCE
  659.                
  660.         def LoadFromXml(self, daeDocument, xmlNode):
  661.                 super(DaeSource,self).LoadFromXml(daeDocument, xmlNode)
  662.                 if xmlNode is None:
  663.                         return
  664.                 bools = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.BOOL_ARRAY, DaeBoolArray)
  665.                 floats = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.FLOAT_ARRAY, DaeFloatArray)
  666.                 ints = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.INT_ARRAY, DaeIntArray)
  667.                 if bools != None:
  668.                         self.source = bools
  669.                 elif floats != None:
  670.                         self.source = floats
  671.                 elif ints != None:
  672.                         self.source = ints
  673.                
  674.                 self.techniqueCommon = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.TECHNIQUE_COMMON, DaeSource.DaeTechniqueCommon)
  675.                 self.techniques = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.TECHNIQUE,DaeTechnique)
  676.                
  677.                 for i in range(0,self.techniqueCommon.accessor.count):
  678.                         vec = []
  679.                         for j in range(0,self.techniqueCommon.accessor.stride):
  680.                                 vec.append(self.source.data[i*self.techniqueCommon.accessor.stride+j])
  681.                         self.vectors.append(vec)               
  682.                
  683.         def SaveToXml(self, daeDocument):
  684.                 node = super(DaeSource, self).SaveToXml(daeDocument)
  685. ##                if len(self.vectors) > 0:
  686. ##                        if type(self.vectors[0][0]) == float:
  687. ##                                self.source = DaeFloatArray()
  688. ##                                self.source.id = self.id+'-array'
  689. ##                               
  690. ##                for i in range(len(self.vectors)):
  691. ##                        for j in range(len(self.vectors[i])):
  692. ##                                self.source.data.append(self.vectors[i][j])
  693.                        
  694.                 # Add the source
  695.                 AppendChild(daeDocument, node, self.source)
  696.                 # Add the technique common               
  697.                 AppendChild(daeDocument,node,self.techniqueCommon)
  698.                 # Add the techniques
  699.                 AppendChilds(daeDocument, node, self.techniques)
  700.                 return node
  701.        
  702.         def __str__(self):
  703.                 return super(DaeSource,self).__str__()+' source: %s, techniqueCommon: %s, techniques: %s'%(self.source, self.techniqueCommon, self.techniques)
  704.  
  705.         class DaeTechniqueCommon(DaeEntity):
  706.                 def __init__(self):
  707.                         self.accessor = None
  708.                         self.syntax = DaeSyntax.TECHNIQUE_COMMON
  709.                        
  710.                 def LoadFromXml(self, daeDocument, xmlNode):
  711.                         self.accessor = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ACCESSOR, DaeAccessor)
  712.                            
  713.                 def SaveToXml(self, daeDocument):
  714.                         node = super(DaeSource.DaeTechniqueCommon,self).SaveToXml(daeDocument)
  715.                         AppendChild(daeDocument,node, self.accessor)
  716.                         return node
  717.                
  718.                 def __str__(self):
  719.                         return super(DaeSource.DaeTechniqueCommon,self).__str__()+' accessor: %s'%(self.accessor)
  720.                
  721. class DaeLight(DaeElement):
  722.         def __init__(self):
  723.                 super(DaeLight,self).__init__()
  724.                 self.asset = None
  725.                 self.techniqueCommon = DaeLight.DaeTechniqueCommon()
  726.                 self.techniques = []
  727.                 self.extras = None
  728.                 self.syntax = DaeSyntax.LIGHT
  729.                
  730.         def LoadFromXml(self, daeDocument, xmlNode):
  731.                 super(DaeLight, self).LoadFromXml(daeDocument, xmlNode)
  732.                 self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
  733.                 self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
  734.                 ##self.techniqueCommon.LoadFromXml(daeDocument, xmlUtils.FindElementByTagName(xmlNode, DaeSyntax.TECHNIQUE_COMMON))
  735.                 self.techniques = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.TECHNIQUE,DaeTechnique)
  736.                
  737.                 lightSourceNode = xmlUtils.RemoveWhiteSpaceNode(xmlUtils.FindElementByTagName(xmlNode, DaeSyntax.TECHNIQUE_COMMON)).firstChild
  738.                 lightSourceName = lightSourceNode.localName
  739.                 if lightSourceName == DaeSyntax.DIRECTIONAL:
  740.                         self.techniqueCommon = DaeLight.DaeDirectional()                       
  741.                 elif lightSourceName == DaeSyntax.SPOT:
  742.                         self.techniqueCommon = DaeLight.DaeSpot()
  743.                 elif lightSourceName == DaeSyntax.AMBIENT:
  744.                         self.techniqueCommon = DaeLight.DaeAmbient()
  745.                 elif lightSourceName == DaeSyntax.POINT:
  746.                         self.techniqueCommon = DaeLight.DaePoint()
  747.                 self.techniqueCommon.LoadFromXml(daeDocument,lightSourceNode)
  748.        
  749.         def SaveToXml(self, daeDocument):
  750.                 node = super(DaeLight, self).SaveToXml(daeDocument)
  751.                 # Add the assets
  752.                 AppendChild(daeDocument,node,self.asset)
  753.                 # Add the technique common               
  754.                 AppendChild(daeDocument,node,self.techniqueCommon)
  755.                 # Add the techniques
  756.                 AppendChilds(daeDocument, node, self.techniques)
  757.                 # Add the extra's
  758.                 AppendChilds(self,node,self.extras)
  759.                 return node
  760.        
  761.         def __str__(self):
  762.                 return super(DaeLight,self).__str__()+' techniqueCommon: %s, techniques: %s'%(self.techniqueCommon, self.techniques)
  763.                
  764.         class DaeTechniqueCommon(DaeEntity):
  765.                 def __init__(self):
  766.                         self.color = []
  767.                         self.lightSource = None
  768.                         self.syntax = DaeSyntax.TECHNIQUE_COMMON
  769.                        
  770.                 def LoadFromXml(self, daeDocument, xmlNode):
  771.                         self.color = ToFloat3(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.COLOR)))
  772.                
  773.                 def SaveToXml(self, daeDocument):
  774.                         node = Element(DaeSyntax.TECHNIQUE_COMMON)
  775.                         child = super(DaeLight.DaeTechniqueCommon,self).SaveToXml(daeDocument)
  776.                         AppendTextChild(child,DaeSyntax.COLOR, self.color)
  777.                         node.appendChild(child)
  778.                         return node
  779.                
  780.                 def __str__(self):
  781.                         return super(DaeLight.DaeTechniqueCommon,self).__str__()+' color: %s'%(self.color)
  782.                
  783.         class DaeAmbient(DaeTechniqueCommon):
  784.                 def __init__(self):
  785.                         super(DaeLight.DaeAmbient,self).__init__()
  786.                         self.syntax = DaeSyntax.AMBIENT
  787.                        
  788.                 def LoadFromXml(self, daeDocument, xmlNode):
  789.                         super(DaeLight.DaeAmbient,self).LoadFromXml(daeDocument, xmlNode)
  790.                
  791.                 def SaveToXml(self, daeDocument):
  792.                         node  = super(DaeLight.DaeAmbient,self).SaveToXml(daeDocument)
  793.                         return node
  794.                
  795.                 def __str__(self):
  796.                         return super(DaeLight.DaeAmbient,self).__str__()
  797.        
  798.         class DaeSpot(DaeTechniqueCommon):
  799.                 def __init__(self):
  800.                         super(DaeLight.DaeSpot,self).__init__()
  801.                         self.defConstantAttenuation = 0.0
  802.                         self.defLinearAttenuation = 0.0
  803.                         self.defQuadraticAttenuation = 0.0
  804.                         self.defFalloffAngle = 180.0
  805.                         self.defFalloffExponent = 0.0
  806.                        
  807.                         self.constantAttenuation = 0.0
  808.                         self.linearAttenuation = 0.0
  809.                         self.quadraticAttenuation = 0.0
  810.                         self.falloffAngle = 180.0
  811.                         self.falloffExponent = 0.0
  812.                         self.syntax = DaeSyntax.SPOT
  813.                        
  814.                 def LoadFromXml(self, daeDocument, xmlNode):
  815.                         super(DaeLight.DaeSpot,self).LoadFromXml(daeDocument, xmlNode)
  816.                         self.constantAttenuation = CastFromXml(daeDocument,xmlNode,DaeSyntax.CONSTANT_ATTENUATION, float, self.defConstantAttenuation)
  817.                         self.linearAttenuation = CastFromXml(daeDocument,xmlNode,DaeSyntax.LINEAR_ATTENUATION,float, self.defLinearAttenuation)
  818.                         self.quadraticAttenuation = CastFromXml(daeDocument, xmlNode,DaeSyntax.QUADRATIC_ATTENUATION, float, self.defQuadraticAttenuation)
  819.                         self.falloffAngle = CastFromXml(daeDocument, xmlNode, DaeSyntax.FALLOFF_ANGLE, float, self.defFalloffAngle)
  820.                         self.falloffExponent = CastFromXml(daeDocument, xmlNode, DaeSyntax.FALLOFF_EXPONENT, float, self.defFalloffExponent)
  821.                
  822.                 def SaveToXml(self, daeDocument):
  823.                         node = super(DaeLight.DaeSpot,self).SaveToXml(daeDocument)
  824.                         AppendTextChild(node.firstChild,DaeSyntax.CONSTANT_ATTENUATION, self.constantAttenuation, self.defConstantAttenuation)
  825.                         AppendTextChild(node.firstChild,DaeSyntax.LINEAR_ATTENUATION, self.linearAttenuation, self.defLinearAttenuation)
  826.                         AppendTextChild(node.firstChild,DaeSyntax.QUADRATIC_ATTENUATION, self.quadraticAttenuation, self.defQuadraticAttenuation)
  827.                         AppendTextChild(node.firstChild,DaeSyntax.FALLOFF_ANGLE, self.falloffAngle, self.defFalloffAngle)
  828.                         AppendTextChild(node.firstChild,DaeSyntax.FALLOFF_EXPONENT, self.falloffExponent, self.defFalloffExponent)
  829.                         return node
  830.                        
  831.                 def __str__(self):
  832.                         return super(DaeLight.DaeSpot,self).__str__()+' const.att: %s, lin.att: %s, quad.att: %s, falloffAngle: %s, falloffExponent: %s'%(self.constantAttenuation, self.linearAttenuation, self.quadraticAttenuation, self.falloffAngle, self.falloffExponent)
  833.                        
  834.         class DaeDirectional(DaeTechniqueCommon):
  835.                 # default direction is [0,0,-1] pointing down the -Z axis.
  836.                 # To change the direction, change the transform of the parent DaeNode
  837.                 def __init__(self):
  838.                         super(DaeLight.DaeDirectional,self).__init__()
  839.                         self.syntax = DaeSyntax.DIRECTIONAL
  840.                        
  841.                 def LoadFromXml(self, daeDocument, xmlNode):
  842.                         super(DaeLight.DaeDirectional,self).LoadFromXml(daeDocument, xmlNode)
  843.                
  844.                 def SaveToXml(self, daeDocument):
  845.                         node  = super(DaeLight.DaeDirectional,self).SaveToXml(daeDocument)
  846.                         return node
  847.                
  848.                 def __str__(self):
  849.                         return super(DaeLight.DaeDirectional,self).__str__()
  850.        
  851.         class DaePoint(DaeTechniqueCommon):
  852.                 def __init__(self):
  853.                         super(DaeLight.DaePoint,self).__init__()
  854.                         self.constantAttenuation = 0.0
  855.                         self.linearAttenuation = 0.0
  856.                         self.quadraticAttenuation = 0.0
  857.                         self.syntax = DaeSyntax.POINT
  858.                        
  859.                 def LoadFromXml(self, daeDocument, xmlNode):
  860.                         super(DaeLight.DaePoint,self).LoadFromXml(daeDocument, xmlNode)
  861.                         self.constantAttenuation = CastFromXml(daeDocument,xmlNode,DaeSyntax.CONSTANT_ATTENUATION, float)
  862.                         self.linearAttenuation = CastFromXml(daeDocument,xmlNode,DaeSyntax.LINEAR_ATTENUATION,float)
  863.                         self.quadraticAttenuation = CastFromXml(daeDocument, xmlNode,DaeSyntax.QUADRATIC_ATTENUATION, float)
  864.                
  865.                 def SaveToXml(self, daeDocument):
  866.                         node = super(DaeLight.DaePoint,self).SaveToXml(daeDocument)
  867.                         AppendTextChild(node.firstChild,DaeSyntax.CONSTANT_ATTENUATION, self.constantAttenuation)
  868.                         AppendTextChild(node.firstChild,DaeSyntax.LINEAR_ATTENUATION, self.linearAttenuation)
  869.                         AppendTextChild(node.firstChild,DaeSyntax.QUADRATIC_ATTENUATION, self.quadraticAttenuation)
  870.                         return node
  871.                
  872.                 def __str__(self):
  873.                         return super(DaeLight.DaePoint,self).__str__()+' const.att: %s, lin.att: %s, quad.att: %s'%(self.constantAttenuation, self.linearAttenuation, self.quadraticAttenuation)
  874.                        
  875. class DaeVisualScene(DaeElement):
  876.         def __init__(self):
  877.                 super(DaeVisualScene,self).__init__()
  878.                 self.asset = None
  879.                 self.extras = None
  880.                 self.nodes = []
  881.                 self.syntax = DaeSyntax.VISUAL_SCENE           
  882.                
  883.         def LoadFromXml(self, daeDocument, xmlNode):
  884.                 super(DaeVisualScene, self).LoadFromXml(daeDocument, xmlNode)
  885.                 self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
  886.                 self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
  887.                 self.nodes = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.NODE, DaeNode)
  888.                
  889.         def SaveToXml(self, daeDocument):
  890.                 node = super(DaeVisualScene, self).SaveToXml(daeDocument)
  891.                 # Add the assets
  892.                 AppendChild(daeDocument,node,self.asset)
  893.                 # Add the nodes
  894.                 AppendChilds(daeDocument, node, self.nodes)
  895.                 # Add the extra's
  896.                 AppendChilds(self,node,self.extras)
  897.                 return node
  898.        
  899.         def FindNode(self, nodeUrl):
  900.                 for n in self.nodes:
  901.                         if n.id == nodeUrl:
  902.                                 return n
  903.                 return None
  904.                
  905.                
  906.         def __str__(self):
  907.                 return super(DaeVisualScene,self).__str__()+' asset: %s, nodes: %s, extras: %s'%(self.asset, self.nodes, self.extras)
  908.        
  909. class DaeNode(DaeElement):
  910.        
  911.         NODE = 2
  912.         JOINT = 1       
  913.        
  914.         def __init__(self):
  915.                 super(DaeNode,self).__init__()
  916.                 self.sid = None
  917.                 self.type = DaeNode.NODE
  918.                 self.layer = None
  919.                 self.transforms = []
  920.                 self.nodes = []   #Doug: child nodes defined in nested xml
  921.  
  922.                 #Doug: instances - references to items defined elsewhere
  923.                 # ie iNode <instance_node url="#someothernode"/>
  924.                 self.iAnimations = []
  925.                 self.iCameras = []
  926.                 self.iControllers = []
  927.                 self.iGeometries = []
  928.                 self.iLights = []
  929.                 self.iNodes = []
  930.                 self.iVisualScenes = []
  931.                
  932.                 self.syntax = DaeSyntax.NODE
  933.                
  934.         def LoadFromXml(self, daeDocument, xmlNode):
  935.                 super(DaeNode, self).LoadFromXml(daeDocument, xmlNode)
  936.                 self.sid = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.SID)
  937.                 type = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.TYPE)
  938.                 if type == DaeSyntax.TYPE_JOINT:
  939.                         self.type = DaeNode.JOINT
  940.                 else:
  941.                         self.type = DaeNode.NODE                       
  942.                 self.layer = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.LAYER)
  943.                
  944.                 # Get transforms
  945.                 xmlUtils.RemoveWhiteSpaceNode(xmlNode)
  946.                 child = xmlNode.firstChild
  947.                 while child != None:
  948.                         name = child.localName
  949.                         if name == DaeSyntax.TRANSLATE:
  950.                                 self.transforms.append([name,ToFloatList(xmlUtils.ReadContents(child))])
  951.                         elif name == DaeSyntax.ROTATE:
  952.                                 self.transforms.append([name,ToFloatList(xmlUtils.ReadContents(child))])
  953.                         elif name == DaeSyntax.SCALE:
  954.                                 self.transforms.append([name,ToFloatList(xmlUtils.ReadContents(child))])
  955.                         elif name == DaeSyntax.SKEW:
  956.                                 self.transforms.append([name,ToFloatList(xmlUtils.ReadContents(child))])
  957.                         elif name == DaeSyntax.LOOKAT:
  958.                                 self.transforms.append([name,ToFloatList(xmlUtils.ReadContents(child))])
  959.                         elif name == DaeSyntax.MATRIX:
  960.                                 self.transforms.append([name,ToMatrix4(xmlUtils.ReadContents(child))])
  961.                                
  962.                         child = child.nextSibling
  963.                        
  964.                 # Get the instances
  965.                 self.iAnimations = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_ANIMATION, DaeAnimationInstance)
  966.                 self.iCameras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_CAMERA, DaeCameraInstance)
  967.                 self.iControllers = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_CONTROLLER, DaeControllerInstance)
  968.                 self.iGeometries = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_GEOMETRY, DaeGeometryInstance)
  969.                 self.iLights = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_LIGHT, DaeLightInstance)
  970.                 self.iNodes = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_NODE, DaeNodeInstance)
  971.                 self.iVisualScenes = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_VISUAL_SCENE, DaeVisualSceneInstance)
  972.  
  973.                 # Get childs nodes
  974.                 self.nodes = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.NODE, DaeNode)
  975.            
  976.         def SaveToXml(self, daeDocument):
  977.                 node = super(DaeNode, self).SaveToXml(daeDocument)
  978.                 SetAttribute(node, DaeSyntax.SID, self.sid)
  979.                 if self.type == DaeSyntax.TYPE_JOINT:
  980.                         SetAttribute(node, DaeSyntax.TYPE, DaeNode.GetType(self.type))
  981.                        
  982.                 SetAttribute(node, DaeSyntax.LAYER, self.layer)
  983.                 for i in self.transforms:
  984.                         writeTransform = False
  985.                         el = Element(i[0])
  986.                         val = i[1]
  987.                         if i[0] == DaeSyntax.MATRIX:
  988.                                 val = MatrixToString(val,ROUND)
  989.                                 AppendTextChild(node,i[0],val)
  990.                         else:
  991.                                 val = ListToString(RoundList(val, 5))
  992.                                 if i[0] == DaeSyntax.SCALE:
  993.                                         AppendTextChild(node,i[0],val,"1.0 1.0 1.0")
  994.                                 elif i[0] == DaeSyntax.TRANSLATE:
  995.                                         AppendTextChild(node,i[0],val,"0.0 0.0 0.0")
  996.                                 elif i[0] == DaeSyntax.ROTATE:
  997.                                         AppendTextChild(node,i[0],val,"0.0 0.0 0.0 0.0")
  998.                                 elif i[0] == DaeSyntax.SKEW:
  999.                                         AppendTextChild(node,i[0],val)
  1000.                                 elif i[0] == DaeSyntax.MATRIX or i[0] == DaeSyntax.LOOKAT:
  1001.                                         AppendTextChild(node,i[0],val)
  1002.                
  1003.                 AppendChilds(daeDocument, node, self.nodes)                
  1004.        
  1005.                 AppendChilds(daeDocument, node, self.iAnimations)
  1006.                 AppendChilds(daeDocument, node, self.iCameras)
  1007.                 AppendChilds(daeDocument, node, self.iControllers)
  1008.                 AppendChilds(daeDocument, node, self.iGeometries)
  1009.                 AppendChilds(daeDocument, node, self.iLights)
  1010.                 AppendChilds(daeDocument, node, self.iNodes)
  1011.                 AppendChilds(daeDocument, node, self.iVisualScenes)
  1012.                
  1013.                 return node
  1014.        
  1015.         def IsJoint(self):
  1016.                 return self.type == DaeNode.JOINT
  1017.        
  1018.         def GetType(type):
  1019.                 if type == DaeNode.JOINT:
  1020.                         return DaeSyntax.TYPE_JOINT
  1021.                 else:
  1022.                         return DaeSyntax.TYPE_NODE
  1023.         GetType = staticmethod(GetType)
  1024.                
  1025.         def GetInstances(self):
  1026.                 return []+self.iAnimations+self.iCameras+self.iControllers+self.iGeometries+self.iLights+self.iNodes
  1027.        
  1028.        
  1029.        
  1030. # TODO: finish DaeTechnique
  1031. class DaeTechnique(DaeEntity):
  1032.         def __init__(self):
  1033.                 super(DaeTechnique,self).__init__()
  1034.                 self.profile = ''
  1035.                 self.xmlns = ''
  1036.                 self.syntax = DaeSyntax.TECHNIQUE
  1037.                
  1038.         def LoadFromXml(self, daeDocument, xmlNode):
  1039.                 self.profile = xmlNode.getAttribute(DaeSyntax.PROFILE)
  1040.                 self.xmlns = xmlNode.getAttribute(DaeSyntax.XMLNS)
  1041.                
  1042.         def SaveToXml(self, daeDocument):
  1043.                 node = super(DaeTechnique,self).SaveToXml(daeDocument)
  1044.                 node.setAttribute(DaeSyntax.PROFILE, self.profile)
  1045.                 SetAttribute(node, DaeSyntax.XMLNS, self.xmlns)
  1046.                 return node
  1047.        
  1048. class DaeOptics(DaeEntity):
  1049.         def __init__(self):
  1050.                 super(DaeOptics,self).__init__()
  1051.                 self.techniqueCommon = DaeOptics.DaeTechniqueCommon()
  1052.                 self.techniques = []
  1053.                 self.extras = None
  1054.                 self.syntax = DaeSyntax.OPTICS
  1055.                
  1056.         def LoadFromXml(self, daeDocument, xmlNode):
  1057.                 self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
  1058.                 #self.techniqueCommon.LoadFromXml(daeDocument, xmlUtils.FindElementByTagName(xmlNode, DaeSyntax.TECHNIQUE_COMMON))
  1059.                 self.techniques = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.TECHNIQUE,DaeTechnique)
  1060.                
  1061.                 opticsSourceNode = xmlUtils.RemoveWhiteSpaceNode(xmlUtils.FindElementByTagName(xmlNode, DaeSyntax.TECHNIQUE_COMMON)).firstChild
  1062.                 opticsSourceName = opticsSourceNode.localName
  1063.                 if opticsSourceName == DaeSyntax.PERSPECTIVE:
  1064.                         self.techniqueCommon = DaeOptics.DaePerspective()
  1065.                 elif opticsSourceName == DaeSyntax.ORTHOGRAPHIC:
  1066.                         self.techniqueCommon = DaeOptics.DaeOrthoGraphic()
  1067.                 self.techniqueCommon.LoadFromXml(daeDocument,opticsSourceNode)
  1068.        
  1069.         def SaveToXml(self, daeDocument):
  1070.                 node = super(DaeOptics, self).SaveToXml(daeDocument)
  1071.                 # Add the technique common               
  1072.                 AppendChild(daeDocument,node,self.techniqueCommon)
  1073.                 # Add the techniques
  1074.                 AppendChilds(daeDocument, node, self.techniques)
  1075.                 # Add the extra's
  1076.                 AppendChilds(self,node,self.extras)
  1077.                 return node
  1078.                
  1079.         def __str__(self):
  1080.                 return super(DaeOptics,self).__str__()+' extras: %s, techniqueCommon: %s, techniques: %s'%(self.extras, self.techniqueCommon, self.techniques)
  1081.        
  1082.         class DaeTechniqueCommon(DaeEntity):
  1083.                 def __init__(self):
  1084.                         self.znear = 0.0
  1085.                         self.zfar = 0.0
  1086.                         self.aspectRatio = None
  1087.                        
  1088.                         self.syntax = DaeSyntax.TECHNIQUE_COMMON
  1089.                        
  1090.                 def LoadFromXml(self, daeDocument, xmlNode):
  1091.                         self.znear = ToFloat(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.ZNEAR)))
  1092.                         self.zfar = ToFloat(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.ZFAR)))
  1093.                         self.aspectRatio = ToFloat(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.ASPECT_RATIO)))
  1094.                
  1095.                 def SaveToXml(self, daeDocument):
  1096.                         node = Element(DaeSyntax.TECHNIQUE_COMMON)
  1097.                         child = super(DaeOptics.DaeTechniqueCommon,self).SaveToXml(daeDocument)
  1098. ##                        AppendTextChild(child,DaeSyntax.ZNEAR, self.znear)
  1099. ##                        AppendTextChild(child,DaeSyntax.ZFAR, self.zfar)
  1100. ##                        AppendTextChild(child,DaeSyntax.ASPECT_RATIO, self.aspectRatio)                        
  1101.                         node.appendChild(child)
  1102.                         return node
  1103.                
  1104.                 def SavePropertiesToXml(self, daeDocument, node):                        
  1105.                         AppendTextChild(node,DaeSyntax.ZNEAR, self.znear)
  1106.                         AppendTextChild(node,DaeSyntax.ZFAR, self.zfar)
  1107.                         AppendTextChild(node,DaeSyntax.ASPECT_RATIO, self.aspectRatio)
  1108.                
  1109.                 def __str__(self):
  1110.                         return super(DaeOptics.DaeTechniqueCommon,self).__str__()+' znear: %s, zfar: %s, aspectRatio: %s'%(self.znear, self.zfar, self.aspectRatio)
  1111.                
  1112.         class DaePerspective(DaeTechniqueCommon):
  1113.                 def __init__(self):
  1114.                         super(DaeOptics.DaePerspective,self).__init__()
  1115.                         self.xfov = None
  1116.                         self.yfov = None
  1117.                         self.syntax = DaeSyntax.PERSPECTIVE
  1118.                        
  1119.                 def LoadFromXml(self, daeDocument, xmlNode):
  1120.                         super(DaeOptics.DaePerspective,self).LoadFromXml(daeDocument, xmlNode)
  1121.                         self.xfov = ToFloat(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.XFOV)))
  1122.                         self.yfov = ToFloat(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.YFOV)))
  1123.                
  1124.                 def SaveToXml(self, daeDocument):
  1125.                         node  = super(DaeOptics.DaePerspective,self).SaveToXml(daeDocument)
  1126.                         AppendTextChild(node.firstChild,DaeSyntax.XFOV, self.xfov)
  1127.                         AppendTextChild(node.firstChild,DaeSyntax.YFOV, self.yfov)
  1128.                         super(DaeOptics.DaePerspective,self).SavePropertiesToXml(daeDocument, node.firstChild)
  1129.                         return node
  1130.                
  1131.                 def __str__(self):
  1132.                         return super(DaeOptics.DaePerspective,self).__str__()+' xfov: %s, yfov: %s'%(self.xfov, self.yfov)
  1133.                        
  1134.         class DaeOrthoGraphic(DaeTechniqueCommon):
  1135.                 def __init__(self):
  1136.                         super(DaeOptics.DaeOrthoGraphic,self).__init__()
  1137.                         self.xmag = None
  1138.                         self.ymag = None
  1139.                         self.syntax = DaeSyntax.ORTHOGRAPHIC
  1140.                        
  1141.                 def LoadFromXml(self, daeDocument, xmlNode):
  1142.                         super(DaeOptics.DaeOrthoGraphic,self).LoadFromXml(daeDocument, xmlNode)
  1143.                         self.xmag = ToFloat(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.XMAG)))
  1144.                         self.ymag = ToFloat(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.YMAG)))
  1145.                
  1146.                 def SaveToXml(self, daeDocument):
  1147.                         node  = super(DaeOptics.DaeOrthoGraphic,self).SaveToXml(daeDocument)
  1148.                         AppendTextChild(node.firstChild,DaeSyntax.XMAG, self.xmag)
  1149.                         AppendTextChild(node.firstChild,DaeSyntax.YMAG, self.ymag)
  1150.                         return node
  1151.                
  1152.                 def __str__(self):
  1153.                         return super(DaeOptics.DaeOrthoGraphic,self).__str__()+ 'xmag: %s, ymag: %s'%(self.xmag, self.ymag)
  1154.  
  1155. class DaeImager(DaeEntity):
  1156.         def __init__(self):
  1157.                 super(DaeImager,self).__init__()
  1158.                 self.techniques = []
  1159.                 self.extras = None
  1160.                 self.syntax = DaeSyntax.IMAGER
  1161.                
  1162.         def LoadFromXml(self, daeDocument, xmlNode):
  1163.                 super(DaeImager, self).LoadFromXml(daeDocument, xmlNode)
  1164.                 self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
  1165.                 self.techniques = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.TECHNIQUE,DaeTechnique)
  1166.        
  1167.         def SaveToXml(self, daeDocument):
  1168.                 node = super(DaeOptics, self).SaveToXml(daeDocument)
  1169.                 # Add the techniques
  1170.                 AppendChilds(daeDocument, node, self.techniques)
  1171.                 # Add the extra's
  1172.                 AppendChilds(self,node,self.extras)
  1173.                 return node
  1174.                
  1175.         def __str__(self):
  1176.                 return super(DaeImager,self).__str__()+' extras: %s, techniques: %s'%(self.techniqueCommon, self.techniques)
  1177.        
  1178.        
  1179. class DaeExtra(DaeEntity):
  1180.         def __init__(self):
  1181.                 super(DaeExtra,self).__init__()
  1182.                 self.type = None
  1183.                 self.techniques = []
  1184.                 self.syntax = DaeSyntax.EXTRA
  1185.                
  1186.         def LoadFromXml(self, daeDocument, xmlNode):
  1187.                 self.type = xmlNode.getAttribute(DaeSyntax.TYPE)
  1188.                 self.techniques = CreateObjectsFromXml(daeDocument, xmlNode,DaeSyntax.TECHNIQUE,DaeTechnique)
  1189.                
  1190.         def SaveToXml(self, daeDocument):
  1191.                 node = super(DaeExtra,self).SaveToXml(daeDocument)
  1192.                 AppendChilds(daeDocument, node, self.techniques)
  1193.                 return node
  1194.                
  1195.                
  1196.         def __str__(self):
  1197.                 return super(DaeExtra,self).__str__()+'techniques: %s'%(self.techniques)
  1198.        
  1199. class DaeAccessor(DaeEntity):
  1200.         def __init__(self):
  1201.                 super(DaeAccessor,self).__init__()
  1202.                 self.count = 0
  1203.                 self.offset = None
  1204.                 self.source = ''
  1205.                 self.stride = None
  1206.                 self.params = []
  1207.                
  1208.                 self.syntax = DaeSyntax.ACCESSOR
  1209.        
  1210.         def LoadFromXml(self,daeDocument, xmlNode):
  1211.                 self.count = CastAttributeFromXml(xmlNode, DaeSyntax.COUNT,int,0)
  1212.                 self.offset = CastAttributeFromXml(xmlNode, DaeSyntax.OFFSET,int)
  1213.                 self.source = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.SOURCE)
  1214.                 self.stride = CastAttributeFromXml(xmlNode, DaeSyntax.STRIDE,int)
  1215.                 self.params = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.PARAM, DaeParam)
  1216.                
  1217.         def SaveToXml(self, daeDocument):
  1218.                 node = super(DaeAccessor,self).SaveToXml(daeDocument)
  1219.                 node.setAttribute(DaeSyntax.COUNT, str(self.count))
  1220.                 SetAttribute(node,DaeSyntax.OFFSET, self.offset)
  1221.                 node.setAttribute(DaeSyntax.SOURCE, StripString('#'+self.source))
  1222.                 SetAttribute(node, DaeSyntax.STRIDE, len(self.params))
  1223.                 AppendChilds(daeDocument, node, self.params)
  1224.                 return node
  1225.        
  1226.         def AddParam(self, name, type):
  1227.                 param = DaeParam()
  1228.                 param.name = name
  1229.                 param.type = type
  1230.                 self.params.append(param)
  1231.        
  1232. class DaeParam(DaeEntity):
  1233.         def __init__(self):
  1234.                 super(DaeParam,self).__init__()
  1235.                 self.name = None
  1236.                 self.semantic = None
  1237.                 self.sid = None
  1238.                 self.type = ''   
  1239.                 self.syntax = DaeSyntax.PARAM
  1240.                
  1241.         def LoadFromXml(self, daeDocument, xmlNode):
  1242.                 self.semantic = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.SEMANTIC)
  1243.                 self.sid = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.SID)
  1244.                 self.name = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.NAME)
  1245.                 self.type = xmlNode.getAttribute(DaeSyntax.TYPE)
  1246.                
  1247.         def SaveToXml(self, daeDocument):
  1248.                 node = super(DaeParam,self).SaveToXml(daeDocument)
  1249.                 SetAttribute(node, DaeSyntax.SEMANTIC, self.semantic)
  1250.                 SetAttribute(node, DaeSyntax.SID, self.sid)
  1251.                 SetAttribute(node, DaeSyntax.NAME, self.name)
  1252.                 node.setAttribute(DaeSyntax.TYPE, self.type)
  1253.                 return node
  1254.        
  1255. class DaeArray(DaeElement):
  1256.         def __init__(self):
  1257.                 super(DaeArray, self).__init__()
  1258.                 self.count = 0
  1259.                 self.data = []
  1260.                
  1261.         def LoadFromXml(self, daeDocument, xmlNode):
  1262.                 super(DaeArray, self).LoadFromXml(daeDocument, xmlNode)
  1263.                 self.count = ToInt(xmlUtils.ReadAttribute(xmlNode, DaeSyntax.COUNT))
  1264.                 self.data = ToList(xmlUtils.ReadContents(xmlNode))
  1265.                
  1266.         def SaveToXml(self, daeDocument):
  1267.                 node = super(DaeArray,self).SaveToXml(daeDocument)
  1268.                 SetAttribute(node, DaeSyntax.COUNT, len(self.data))
  1269.                 AppendTextInChild(node, self.data)
  1270.                 return node
  1271.        
  1272.         def __str__(self):
  1273.                 return super(DaeArray,self).__str__()+' count: %s'%(self.count)
  1274.                
  1275.        
  1276. class DaeFloatArray(DaeArray):
  1277.         def __init__(self):
  1278.                 super(DaeFloatArray, self).__init__()
  1279.                 self.syntax = DaeSyntax.FLOAT_ARRAY
  1280.                
  1281.         def LoadFromXml(self, daeDocument, xmlNode):
  1282.                 super(DaeFloatArray, self).LoadFromXml(daeDocument, xmlNode)
  1283.                 self.data = ToFloatList(self.data)
  1284.                
  1285.        
  1286. class DaeIntArray(DaeArray):
  1287.         def __init__(self):
  1288.                 super(DaeIntArray, self).__init__()
  1289.                 self.syntax = DaeSyntax.INT_ARRAY
  1290.                
  1291.         def LoadFromXml(self, daeDocument, xmlNode):
  1292.                 super(DaeIntArray, self).LoadFromXml(daeDocument, xmlNode)
  1293.                 self.data = ToIntList(self.data)
  1294.        
  1295. class DaeBoolArray(DaeArray):
  1296.         def __init__(self):
  1297.                 super(DaeBoolArray, self).__init__()
  1298.                 self.syntax = DaeSyntax.BOOL_ARRAY
  1299.                
  1300.         def LoadFromXml(self, daeDocument, xmlNode):
  1301.                 super(DaeBoolArray, self).LoadFromXml(daeDocument, xmlNode)
  1302.                 self.data = ToBoolList(self.data)
  1303.        
  1304. class DaeNameArray(DaeArray):
  1305.         def __init__(self):
  1306.                 super(DaeNameArray, self).__init__()
  1307.                 self.syntax = DaeSyntax.NAME_ARRAY
  1308.                
  1309.         def LoadFromXml(self, daeDocument, xmlNode):
  1310.                 super(DaeNameArray, self).LoadFromXml(daeDocument, xmlNode)
  1311.                 ##self.data = ToFloatList(self.data)
  1312.        
  1313. class DaeIDREFArray(DaeArray):
  1314.         def __init__(self):
  1315.                 super(DaeIDREFArray, self).__init__()
  1316.                 self.syntax = DaeSyntax.IDREF_ARRAY
  1317.                
  1318.         def LoadFromXml(self, daeDocument, xmlNode):
  1319.                 super(DaeIDREFArray, self).LoadFromXml(daeDocument, xmlNode)
  1320.                 ##self.data = ToFloatList(self.data)
  1321.  
  1322.  
  1323. #---Primitive Classes---
  1324. class DaePrimitive(DaeEntity):
  1325.         def __init__(self):
  1326.                 super(DaePrimitive, self).__init__()
  1327.                 self.name = None
  1328.                 self.count = 0
  1329.                 self.material = ''               
  1330.                 self.inputs = []
  1331.                
  1332.         def LoadFromXml(self, daeDocument, xmlNode):
  1333.                 self.name = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.NAME)
  1334.                 self.count = int(xmlUtils.ReadAttribute(xmlNode, DaeSyntax.COUNT))
  1335.                 self.material = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.MATERIAL)
  1336.                
  1337.         def SaveToXml(self, daeDocument):
  1338.                 node = super(DaePrimitive, self).SaveToXml(daeDocument)
  1339.                 SetAttribute(node, DaeSyntax.NAME, self.name)
  1340.                 SetAttribute(node, DaeSyntax.MATERIAL, StripString(self.material))
  1341.                 node.setAttribute(DaeSyntax.COUNT, str(self.count))
  1342.                 return node
  1343.        
  1344.         def GetMaxOffset(self):
  1345.                 if self.inputs != []:
  1346.                         return max([i.offset for i in self.inputs])
  1347.                 else:
  1348.                         return None
  1349.                
  1350.         def FindInput(self, semantic):
  1351.                 for i in self.inputs:
  1352.                         if i.semantic == semantic:
  1353.                                 return i
  1354.                 return None
  1355.                
  1356. class DaeLines(DaePrimitive):
  1357.         def __init__(self):
  1358.                 super(DaeLines, self).__init__()
  1359.                 self.syntax = DaeSyntax.LINES
  1360.                 self.lines = []
  1361.                
  1362.         def LoadFromXml(self, daeDocument, xmlNode):
  1363.                 super(DaeLines,self).LoadFromXml(daeDocument, xmlNode)
  1364.                 self.syntax = DaeSyntax.LINES
  1365.                 self.inputs = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INPUT, DaeInput)
  1366.                 self.lines = ToIntList(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.P)))
  1367.        
  1368.         def SaveToXml(self, daeDocument):
  1369.                 node = super(DaeLines,self).SaveToXml(daeDocument)
  1370.                 AppendChilds(daeDocument, node, self.inputs)
  1371.                 AppendTextChild(node, DaeSyntax.P, self.lines)
  1372.                 return node
  1373.        
  1374. class DaeLineStrips(DaePrimitive):
  1375.         def __init__(self):
  1376.                 super(DaeLineStrips, self).__init__()
  1377.                 self.syntax = DaeSyntax.LINESTRIPS
  1378.                
  1379.         def LoadFromXml(self, daeDocument, xmlNode):
  1380.                 super(DaeLineStrips,self).LoadFromXml(daeDocument, xmlNode)
  1381.                
  1382.                
  1383.  
  1384. class DaePolygons(DaePrimitive):
  1385.         def __init__(self):
  1386.                 super(DaePolygons, self).__init__()
  1387.                 self.syntax = DaeSyntax.POLYGONS
  1388.                 self.polygons = []
  1389.                 self.holedPolygons = []
  1390.                
  1391.         def LoadFromXml(self, daeDocument, xmlNode):
  1392.                 super(DaePolygons,self).LoadFromXml(daeDocument, xmlNode)
  1393.                 self.polygons = xmlUtils.GetListFromNodes(xmlNode.getElementsByTagName(DaeSyntax.P), int)
  1394.                 self.inputs = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INPUT, DaeInput)
  1395.                
  1396.         def SaveToXml(self, daeDocument):
  1397.                 node = super(DaePolygons,self).SaveToXml(daeDocument)
  1398.                 AppendChilds(daeDocument, node, self.inputs)
  1399.                 xmlUtils.AppendChilds(node, DaeSyntax.P, self.polygons)
  1400.                 return node        
  1401.        
  1402. class DaePolylist(DaePrimitive):
  1403.         def __init__(self):
  1404.                 super(DaePolylist, self).__init__()
  1405.                 self.syntax = DaeSyntax.POLYLIST
  1406.                
  1407.         def LoadFromXml(self, daeDocument, xmlNode):
  1408.                 super(DaePolylist,self).LoadFromXml(daeDocument, xmlNode)
  1409.        
  1410. class DaeTriangles(DaePrimitive):
  1411.         def __init__(self):
  1412.                 super(DaeTriangles, self).__init__()
  1413.                 self.triangles = []
  1414.                 self.syntax = DaeSyntax.TRIANGLES
  1415.                
  1416.         def LoadFromXml(self, daeDocument, xmlNode):
  1417.                 super(DaeTriangles,self).LoadFromXml(daeDocument, xmlNode)
  1418.                 self.triangles = ToIntList(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaeSyntax.P)))
  1419.                 self.inputs = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INPUT, DaeInput)
  1420.                
  1421.         def SaveToXml(self, daeDocument):
  1422.                 node = super(DaeTriangles,self).SaveToXml(daeDocument)
  1423.                 AppendChilds(daeDocument, node, self.inputs)
  1424.                 AppendTextChild(node, DaeSyntax.P, self.triangles)
  1425.                 return node
  1426.        
  1427. class DaeTriFans(DaePrimitive):
  1428.         def __init__(self):
  1429.                 super(DaeTriFans, self).__init__()
  1430.                 self.syntax = DaeSyntax.TRIFANS
  1431.                
  1432.         def LoadFromXml(self, daeDocument, xmlNode):
  1433.                 super(DaeTriFans,self).LoadFromXml(daeDocument, xmlNode)
  1434.        
  1435. class DaeTriStrips(DaePrimitive):
  1436.         def __init__(self):
  1437.                 super(DaeTriStrips, self).__init__()
  1438.                 self.syntax = DaeSyntax.TRISTRIPS
  1439.        
  1440.         def LoadFromXml(self, daeDocument, xmlNode):
  1441.                 super(DaeTriStrips,self).LoadFromXml(daeDocument, xmlNode)
  1442. #---instance Classes---
  1443. class DaeInstance(DaeEntity):
  1444.         def __init__(self):
  1445.                 super(DaeInstance, self).__init__()
  1446.                 self.url = ''
  1447.                 self.extras = []               
  1448.                 self.object = None
  1449.                
  1450.         def LoadFromXml(self, daeDocument, xmlNode):
  1451.                 self.url = ReadNodeUrl(xmlNode)
  1452.                 self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
  1453.                
  1454.         def SaveToXml(self, daeDocument):
  1455.                 node = super(DaeInstance,self).SaveToXml(daeDocument)
  1456.                 AppendChilds(daeDocument, node, self.extras)
  1457.                 WriteNodeUrl(node, self.object.id)
  1458.                 return node
  1459.        
  1460. class DaeAnimationInstance(DaeInstance):
  1461.         def __init__(self):
  1462.                 super(DaeAnimationInstance, self).__init__()           
  1463.                 self.syntax = DaeSyntax.INSTANCE_ANIMATION
  1464.                
  1465.         def LoadFromXml(self, daeDocument, xmlNode):
  1466.                 super(DaeAnimationInstance,self).LoadFromXml(daeDocument, xmlNode)
  1467.                 self.object = daeDocument.animationsLibrary.FindObject(self.url)
  1468.                
  1469.         def SaveToXml(self, daeDocument):
  1470.                 node = super(DaeAnimationInstance,self).SaveToXml(daeDocument)
  1471.                 return node
  1472.        
  1473. class DaeCameraInstance(DaeInstance):
  1474.         def __init__(self):
  1475.                 super(DaeCameraInstance, self).__init__()                
  1476.                 self.syntax = DaeSyntax.INSTANCE_CAMERA
  1477.                
  1478.         def LoadFromXml(self, daeDocument, xmlNode):
  1479.                 super(DaeCameraInstance,self).LoadFromXml(daeDocument, xmlNode)
  1480.                 self.object = daeDocument.camerasLibrary.FindObject(self.url)
  1481.                
  1482.         def SaveToXml(self, daeDocument):
  1483.                 node = super(DaeCameraInstance,self).SaveToXml(daeDocument)
  1484.                 return node
  1485.        
  1486. class DaeControllerInstance(DaeInstance):
  1487.         def __init__(self):
  1488.                 super(DaeControllerInstance, self).__init__()            
  1489.                 self.skeletons = []
  1490.                 self.bindMaterials = []
  1491.                 self.syntax = DaeSyntax.INSTANCE_CONTROLLER
  1492.                
  1493.         def LoadFromXml(self, daeDocument, xmlNode):
  1494.                 super(DaeControllerInstance,self).LoadFromXml(daeDocument, xmlNode)
  1495.                 self.skeletons = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.SKELETON, DaeSkeleton)
  1496.                 self.bindMaterials = CreateObjectsFromXml(daeDocument, xmlNode, DaeFxSyntax.BIND_MATERIAL, DaeFxBindMaterial)
  1497.                 self.object = daeDocument.controllersLibrary.FindObject(self.url)
  1498.                
  1499.         def SaveToXml(self, daeDocument):
  1500.                 node = super(DaeControllerInstance,self).SaveToXml(daeDocument)
  1501.                 AppendChilds(daeDocument, node, self.skeletons)
  1502.                 AppendChilds(daeDocument, node, self.bindMaterials)
  1503.                 return node
  1504.        
  1505. # TODO: finish DaeEffectInstance
  1506. class DaeEffectInstance(DaeInstance):
  1507.         def __init__(self):
  1508.                 super(DaeEffectInstance, self).__init__()                
  1509.                
  1510.                 self.syntax = DaeSyntax.INSTANCE_EFFECT
  1511.                
  1512.         def LoadFromXml(self, daeDocument, xmlNode):
  1513.                 super(DaeEffectInstance,self).LoadFromXml(daeDocument, xmlNode)
  1514.                 self.object = daeDocument.effectsLibrary.FindObject(self.url)
  1515.                
  1516.         def SaveToXml(self, daeDocument):
  1517.                 node = super(DaeEffectInstance,self).SaveToXml(daeDocument)
  1518.                 return node
  1519.        
  1520. class DaeGeometryInstance(DaeInstance):
  1521.         def __init__(self):
  1522.                 super(DaeGeometryInstance, self).__init__()
  1523.                 self.bindMaterials = []
  1524.                 self.syntax = DaeSyntax.INSTANCE_GEOMETRY
  1525.                
  1526.         def LoadFromXml(self, daeDocument, xmlNode):
  1527.                 super(DaeGeometryInstance,self).LoadFromXml(daeDocument, xmlNode)
  1528.                 self.bindMaterials = CreateObjectsFromXml(daeDocument, xmlNode, DaeFxSyntax.BIND_MATERIAL, DaeFxBindMaterial)
  1529.                 self.object = daeDocument.geometriesLibrary.FindObject(self.url)
  1530.                
  1531.         def SaveToXml(self, daeDocument):
  1532.                 node = super(DaeGeometryInstance,self).SaveToXml(daeDocument)
  1533.                 AppendChilds(daeDocument, node, self.bindMaterials)
  1534.                 return node
  1535.        
  1536. class DaeLightInstance(DaeInstance):
  1537.         def __init__(self):
  1538.                 super(DaeLightInstance, self).__init__()                   
  1539.                 self.syntax = DaeSyntax.INSTANCE_LIGHT
  1540.                
  1541.         def LoadFromXml(self, daeDocument, xmlNode):
  1542.                 super(DaeLightInstance,self).LoadFromXml(daeDocument, xmlNode)
  1543.                 self.object = daeDocument.lightsLibrary.FindObject(self.url)
  1544.                
  1545.         def SaveToXml(self, daeDocument):
  1546.                 node = super(DaeLightInstance,self).SaveToXml(daeDocument)
  1547.                 return node
  1548.        
  1549. class DaeNodeInstance(DaeInstance):
  1550.         def __init__(self):
  1551.                 super(DaeNodeInstance, self).__init__()            
  1552.                 self.syntax = DaeSyntax.INSTANCE_NODE
  1553.                
  1554.         def LoadFromXml(self, daeDocument, xmlNode):
  1555.                 super(DaeNodeInstance,self).LoadFromXml(daeDocument, xmlNode)
  1556.                 self.object = daeDocument.nodesLibrary.FindObject(self.url)
  1557.                
  1558.         def SaveToXml(self, daeDocument):
  1559.                 node = super(DaeNodeInstance,self).SaveToXml(daeDocument)
  1560.                 return node
  1561.  
  1562. class DaeVisualSceneInstance(DaeInstance):
  1563.         def __init__(self):
  1564.                 super(DaeVisualSceneInstance, self).__init__()           
  1565.                 self.syntax = DaeSyntax.INSTANCE_VISUAL_SCENE
  1566.                
  1567.         def LoadFromXml(self, daeDocument, xmlNode):
  1568.                 super(DaeVisualSceneInstance,self).LoadFromXml(daeDocument, xmlNode)
  1569.                 self.object = daeDocument.visualScenesLibrary.FindObject(self.url)
  1570.                
  1571.         def SaveToXml(self, daeDocument):
  1572.                 node = super(DaeVisualSceneInstance,self).SaveToXml(daeDocument)
  1573.                 return node
  1574.                
  1575.        
  1576. class DaeSkeleton(DaeEntity):
  1577.         def __init__(self):
  1578.                 super(DaeSkeleton,self).__init__()
  1579.                 self.iControllers = []
  1580.        
  1581.         def LoadFromXml(self, daeDocument, xmlNode):
  1582.                 self.iControllers = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_CONTROLLER, DaeControllerInstance)
  1583.                
  1584.         def SaveToXml(self, daeDocument):
  1585.                 node = super(DaeSkeleton, self).SaveToXml(daeDocument)
  1586.                 AppendChilds(daeDocument, node, self.iControllers)
  1587.                 return node
  1588.  
  1589.  
  1590. class DaeSyntax(object):
  1591.        
  1592.         #---collada---
  1593.         COLLADA = 'COLLADA'
  1594.         VERSION = 'version'
  1595.         XMLNS = 'xmlns'
  1596.        
  1597.         BODY = 'body'
  1598.         TARGET = 'target'
  1599.        
  1600.         ASSET = 'asset'
  1601.        
  1602.         ID = 'id'
  1603.         NAME = 'name'
  1604.         URL = 'url'
  1605.        
  1606.         COUNT = 'count'
  1607.         OFFSET = 'offset'
  1608.         STRIDE = 'stride'
  1609.        
  1610.         METER = 'meter'
  1611.         SID = 'sid'
  1612.         SEMANTIC = 'semantic'
  1613.         PARAM = 'param'
  1614.        
  1615.         PROFILE = 'profile'
  1616.         TECHNIQUE = 'technique'
  1617.         TECHNIQUE_COMMON = 'technique_common'
  1618.        
  1619.         ##BIND_MATERIAL = 'bind_material'
  1620.         SKELETON = 'skeleton'
  1621.        
  1622.         P = 'p'
  1623.         PH = 'ph'
  1624.         H = 'h'
  1625.        
  1626.        
  1627.         INPUT = 'input'
  1628.         SET  = 'set'
  1629.        
  1630.         #---light---
  1631.         COLOR = 'color'
  1632.         AMBIENT = 'ambient'
  1633.         SPOT = 'spot'
  1634.         DIRECTIONAL = 'directional'
  1635.         POINT = 'point'
  1636.        
  1637.         CONSTANT_ATTENUATION = 'constant_attenuation'
  1638.         LINEAR_ATTENUATION = 'linear_attenuation'
  1639.         QUADRATIC_ATTENUATION = 'quadratic_attenuation'
  1640.        
  1641.         FALLOFF_ANGLE = 'falloff_angle'
  1642.         FALLOFF_EXPONENT = 'falloff_exponent'
  1643.        
  1644.         #---camera--
  1645.         OPTICS = 'optics'
  1646.         PERSPECTIVE = 'perspective'
  1647.         ORTHOGRAPHIC = 'orthographic'
  1648.         IMAGER = 'imager'
  1649.         ZNEAR = 'znear'
  1650.         ZFAR = 'zfar'
  1651.         XFOV = 'xfov'
  1652.         YFOV = 'yfov'
  1653.         XMAG = 'xmag'
  1654.         YMAG ='ymag'
  1655.         ASPECT_RATIO = 'aspect_ratio'
  1656.  
  1657.         #---geometry---
  1658.         MESH = 'mesh'
  1659.         CONVEX_MESH ='convex_mesh'
  1660.         SPLINE = 'spline'
  1661.         SOURCE  ='source'
  1662.         VERTICES = 'vertices'
  1663.         ACCESSOR = 'accessor'
  1664.        
  1665.         CONVEX_HULL_OF = 'convex_hull_of'
  1666.  
  1667.         #---primitives---
  1668.         LINES = 'lines'
  1669.         LINESTRIPS = 'linestrips'
  1670.         POLYGONS = 'polygons'
  1671.         POLYLIST = 'polylist'
  1672.         TRIANGLES = 'triangles'
  1673.         TRIFANS = 'trifans'
  1674.         TRISTRIPS = 'tristrips'
  1675.        
  1676.         #---libraries---
  1677.         LIBRARY_ANIMATIONS = 'library_animations'
  1678.         LIBRARY_ANIMATION_CLIPS = 'library_animation_clips'
  1679.         LIBRARY_CAMERAS = 'library_cameras'
  1680.         LIBRARY_CONTROLLERS = 'library_controllers'
  1681.         LIBRARY_EFFECTS = 'library_effects'
  1682.         LIBRARY_FORCE_FIELDS = 'library_force_fields'
  1683.         LIBRARY_GEOMETRIES = 'library_geometries'
  1684.         LIBRARY_IMAGES = 'library_images'
  1685.         LIBRARY_LIGHTS = 'library_lights'
  1686.         LIBRARY_MATERIALS = 'library_materials'
  1687.         #LIBRARY_NODES = 'library_NODES'   #Doug: looks funny - should be library_nodes?
  1688.         LIBRARY_NODES = 'library_nodes'
  1689.         LIBRARY_PHYSICS_MATERIALS = 'library_physics_materials'
  1690.         LIBRARY_PHYSICS_MODELS = 'library_physics_models'
  1691.         LIBRARY_PHYSICS_SCENES = 'library_physics_scenes'
  1692.         LIBRARY_VISUAL_SCENES = 'library_visual_scenes'
  1693.        
  1694.         SCENE = 'scene'
  1695.         EXTRA = 'extra'
  1696.         TYPE = 'type'
  1697.         LIGHT = 'light'
  1698.         CAMERA = 'camera'
  1699.         ANIMATION = 'animation'
  1700.         ANIMATION_CLIP = 'animation_clip'
  1701.         GEOMETRY = 'geometry'
  1702.         IMAGE = 'image'
  1703.         ##EFFECT = 'effect'
  1704.         VISUAL_SCENE = 'visual_scene'
  1705.         CONTROLLER = 'controller'
  1706.         MATERIAL = 'material'
  1707.        
  1708.         #---asset---
  1709.         CONTRIBUTOR = 'contributor'
  1710.         CREATED = 'created'
  1711.         MODIFIED = 'modified'
  1712.         REVISION = 'revision'
  1713.         TITLE = 'title'
  1714.         SUBJECT = 'subject'
  1715.         KEYWORDS = 'keywords'
  1716.         UNIT = 'unit'
  1717.         UP_AXIS = 'up_axis'
  1718.        
  1719.         Y_UP = 'Y_UP'
  1720.         Z_UP = 'Z_UP'
  1721.        
  1722.         #---contributor---
  1723.         AUTHOR = 'author'
  1724.         AUTHORING_TOOL = 'authoring_tool'
  1725.         COMMENTS = 'comments'
  1726.         COPYRIGHT = 'copyright'
  1727.         SOURCE_DATA = 'source_data'
  1728.        
  1729.         #---array---
  1730.         FLOAT_ARRAY = 'float_array'
  1731.         NAME_ARRAY = 'name_array'
  1732.         BOOL_ARRAY = 'bool_array'
  1733.         INT_ARRAY = 'int_array'
  1734.         IDREF_ARRAY = 'IDREF_array'
  1735.        
  1736.         #---node---
  1737.         NODE = 'node'
  1738.         TYPE_JOINT = 'JOINT'
  1739.         TYPE_NODE = 'NODE'
  1740.         LAYER = 'layer'
  1741.        
  1742.         #---transforms---
  1743.         TRANSLATE = 'translate'
  1744.         ROTATE = 'rotate'
  1745.         SCALE = 'scale'
  1746.         SKEW = 'skew'
  1747.         MATRIX = 'matrix'
  1748.         LOOKAT = 'lookat'
  1749.        
  1750.         #---instances---
  1751.         INSTANCE_ANIMATION = 'instance_animation'
  1752.         INSTANCE_CAMERA = 'instance_camera'
  1753.         INSTANCE_CONTROLLER = 'instance_controller'
  1754.         ##INSTANCE_EFFECT = 'instance_effect'
  1755.         INSTANCE_GEOMETRY = 'instance_geometry'
  1756.         INSTANCE_LIGHT = 'instance_light'
  1757.         INSTANCE_NODE = 'instance_node'
  1758.         INSTANCE_VISUAL_SCENE = 'instance_visual_scene'
  1759.         INSTANCE_PHYSICS_SCENE = 'instance_physics_scene'
  1760.        
  1761.         #---image---
  1762.         FORMAT = 'format'
  1763.         DEPTH = 'depth'
  1764.         HEIGHT = 'height'
  1765.         WIDTH = 'width'
  1766.         INIT_FROM = 'init_from'
  1767.  
  1768. class DaeFxBindMaterial(DaeEntity):
  1769.         def __init__(self):
  1770.                 super(DaeFxBindMaterial, self).__init__()
  1771.                 self.syntax = DaeFxSyntax.BIND_MATERIAL
  1772.                 self.techniqueCommon = DaeFxBindMaterial.DaeFxTechniqueCommon()            
  1773.                
  1774.         def LoadFromXml(self, daeDocument, xmlNode):
  1775.                 self.techniqueCommon = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.TECHNIQUE_COMMON, DaeFxBindMaterial.DaeFxTechniqueCommon)
  1776.                
  1777.         def SaveToXml(self, daeDocument):
  1778.                 node = super(DaeFxBindMaterial,self).SaveToXml(daeDocument)
  1779.                 AppendChild(daeDocument, node, self.techniqueCommon)
  1780.                 return node
  1781.                
  1782.         class DaeFxTechniqueCommon(DaeEntity):
  1783.                 def __init__(self):                
  1784.                         self.syntax = DaeFxSyntax.TECHNIQUE_COMMON
  1785.                         self.iMaterials = []
  1786.                        
  1787.                 def LoadFromXml(self, daeDocument, xmlNode):
  1788.                         self.iMaterials = CreateObjectsFromXml(daeDocument, xmlNode, DaeFxSyntax.INSTANCE_MATERIAL, DaeFxMaterialInstance)
  1789.                        
  1790.                 def SaveToXml(self, daeDocument):
  1791.                         node = super(DaeFxBindMaterial.DaeFxTechniqueCommon,self).SaveToXml(daeDocument)
  1792.                         AppendChilds(daeDocument, node, self.iMaterials)
  1793.                         return node
  1794.                
  1795.                 def __str__(self):
  1796.                         return super(DaeFxBindMaterial.DaeFxTechniqueCommon,self).__str__()
  1797.  
  1798.                
  1799. class DaeFxMaterialInstance(DaeEntity):
  1800.         def __init__(self):
  1801.                 super(DaeFxMaterialInstance, self).__init__()
  1802.                 self.target = ''
  1803.                 self.symbol = ''
  1804.                 self.object = None
  1805.                 self.syntax = DaeFxSyntax.INSTANCE_MATERIAL
  1806.                
  1807.         def LoadFromXml(self, daeDocument, xmlNode):
  1808.                 self.target = xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.TARGET)[1:]
  1809.                 self.symbol = xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.SYMBOL)
  1810.                 self.object = daeDocument.materialsLibrary.FindObject(self.target)
  1811.                
  1812.         def SaveToXml(self, daeDocument):
  1813.                 node = super(DaeFxMaterialInstance,self).SaveToXml(daeDocument)
  1814.                 SetAttribute(node, DaeFxSyntax.TARGET, StripString('#'+self.object.id))
  1815.                 SetAttribute(node, DaeFxSyntax.SYMBOL, StripString(self.object.id))
  1816.                 return node
  1817.                
  1818. class DaeFxMaterial(DaeElement):
  1819.         def __init__(self):
  1820.                 super(DaeFxMaterial, self).__init__()
  1821.                 self.asset = None
  1822.                 self.iEffects = []
  1823.                 self.extras = None
  1824.                 self.syntax = DaeFxSyntax.MATERIAL
  1825.                
  1826.         def LoadFromXml(self, daeDocument, xmlNode):
  1827.                 super(DaeFxMaterial, self).LoadFromXml(daeDocument, xmlNode)
  1828.                 self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
  1829.                 self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
  1830.                 self.iEffects = CreateObjectsFromXml(daeDocument,xmlNode, DaeFxSyntax.INSTANCE_EFFECT, DaeFxEffectInstance)
  1831.                
  1832.         def SaveToXml(self, daeDocument):
  1833.                 node = super(DaeFxMaterial,self).SaveToXml(daeDocument)
  1834.                 # Add the assets
  1835.                 AppendChild(daeDocument,node,self.asset)
  1836.                 # Add the effect instances
  1837.                 AppendChilds(daeDocument, node, self.iEffects)
  1838.                 # Add the extra's
  1839.                 AppendChilds(self,node,self.extras)
  1840.                 return node
  1841.                
  1842.         def __str__(self):
  1843.                 return super(DaeFxMaterial,self).__str__()+' assets: %s, iEffects: %s, extras: %s'%(self.asset, self.iEffects, self.extras)
  1844.  
  1845. class DaeFxEffectInstance(DaeEntity):
  1846.         def __init__(self):
  1847.                 super(DaeFxEffectInstance, self).__init__()
  1848.                 self.url = ''
  1849.                 self.syntax = DaeFxSyntax.INSTANCE_EFFECT
  1850.        
  1851.         def LoadFromXml(self, daeDocument, xmlNode):
  1852.                 self.url = xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.URL)[1:]
  1853.                 self.object = daeDocument.effectsLibrary.FindObject(self.url)
  1854.                
  1855.         def SaveToXml(self, daeDocument):
  1856.                 node = super(DaeFxEffectInstance,self).SaveToXml(daeDocument)
  1857.                 SetAttribute(node, DaeFxSyntax.URL, StripString('#'+self.object.id))
  1858.                 return node
  1859.        
  1860. class DaeFxEffect(DaeElement):
  1861.         def __init__(self):
  1862.                 super(DaeFxEffect, self).__init__()
  1863.                 self.profileCommon = DaeFxProfileCommon()
  1864.                 self.syntax = DaeFxSyntax.EFFECT
  1865.                
  1866.        
  1867.         def LoadFromXml(self, daeDocument, xmlNode):
  1868.                 super(DaeFxEffect, self).LoadFromXml(daeDocument, xmlNode)
  1869.                 self.profileCommon = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.PROFILE_COMMON, DaeFxProfileCommon)
  1870.                
  1871.         def SaveToXml(self, daeDocument):
  1872.                 node = super(DaeFxEffect,self).SaveToXml(daeDocument)
  1873.                 AppendChild(daeDocument, node, self.profileCommon)
  1874.                 return node
  1875.        
  1876.         def __str__(self):
  1877.                 return super(DaeFxEffect, self).__str__() + ', profileCommon: %s' % (self.profileCommon)
  1878.        
  1879.         def AddShader(self, daeShader):
  1880.                 self.profileCommon.technique.shader = daeShader
  1881.         def AddDoubleSided(self, val):
  1882.                 if self.profileCommon.extra == None:
  1883.                         self.profileCommon.AddExtra()
  1884.                 self.profileCommon.extra.technique.AddDoubleSided(val)
  1885.        
  1886. class DaeFxProfileCommon(DaeEntity):
  1887.         def __init__(self):
  1888.                 super(DaeFxProfileCommon, self).__init__()
  1889.                 self.technique = DaeFxTechnique()
  1890.                 self.images = []
  1891.                 self.newParams = []
  1892.                 self.syntax = DaeFxSyntax.PROFILE_COMMON
  1893.                 self.extra = None   #Doug: added Mar3008
  1894.                
  1895.        
  1896.         def LoadFromXml(self, daeDocument, xmlNode):
  1897.                 self.images = CreateObjectsFromXml(daeDocument, xmlNode, DaeFxSyntax.IMAGE, DaeFxImage)
  1898.                 self.newParams = CreateObjectsFromXml(daeDocument, xmlNode, DaeFxSyntax.NEWPARAM, DaeFxNewParam)
  1899.                 self.technique = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.TECHNIQUE, DaeFxTechnique)
  1900.                 self.extra = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.EXTRA, DaeFxExtra) #Doug: added Mar3008
  1901.                
  1902.         def SaveToXml(self, daeDocument):
  1903.                 node = super(DaeFxProfileCommon,self).SaveToXml(daeDocument)
  1904.                 AppendChilds(daeDocument, node, self.images)
  1905.                 AppendChilds(daeDocument, node, self.newParams)
  1906.                 AppendChild(daeDocument, node, self.technique)
  1907.                 AppendChild(daeDocument, node, self.extra)   #Doug: added Mar3008
  1908.                 return node
  1909.         def AddExtra(self):
  1910.                 if not self.extra:
  1911.                         self.extra = DaeFxExtra()
  1912.        
  1913.         def __str__(self):
  1914.                 return super(DaeFxProfileCommon, self).__str__() + ', technique: %s, images: %s, newParams: %s' % (self.technique, self.images, self.newParams)
  1915.  
  1916. class DaeFxExtra(DaeEntity):  #Doug: added Mar3008  - there is a DaeExtra which could be used instead or for guidance
  1917.         def __init__(self):
  1918.                 super(DaeFxExtra, self).__init__()
  1919.                 self.technique = DaeFxTechnique()
  1920.                 #self.images = []
  1921.                 #self.newParams = []
  1922.                 self.syntax = DaeFxSyntax.EXTRA
  1923.                 #self.extra = []   #Doug: added Mar3008
  1924.                
  1925.        
  1926.         def LoadFromXml(self, daeDocument, xmlNode):
  1927.                 #self.images = CreateObjectsFromXml(daeDocument, xmlNode, DaeFxSyntax.IMAGE, DaeFxImage)
  1928.                 #self.newParams = CreateObjectsFromXml(daeDocument, xmlNode, DaeFxSyntax.NEWPARAM, DaeFxNewParam)
  1929.                 self.technique = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.TECHNIQUE, DaeFxTechnique)
  1930.                 #self.extra = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.EXTRA, DaeFxExtra)
  1931.                
  1932.         def SaveToXml(self, daeDocument):
  1933.                 node = super(DaeFxExtra,self).SaveToXml(daeDocument)
  1934.                 #AppendChilds(daeDocument, node, self.images)
  1935.                 #AppendChilds(daeDocument, node, self.newParams)
  1936.                 AppendChild(daeDocument, node, self.technique)
  1937.                 return node
  1938.        
  1939.         def __str__(self):
  1940.                 #return super(DaeFxExtra, self).__str__() + ', technique: %s, images: %s, newParams: %s' % (self.technique, self.images, self.newParams)
  1941.                 return super(DaeFxExtra, self).__str__() + ', technique: %s' % (self.technique)
  1942.        
  1943. class DaeFxImage(DaeEntity):
  1944.         def __init__(self):
  1945.                 super(DaeFxImage, self).__init__()
  1946.                 self.syntax = DaeFxSyntax.IMAGE
  1947.                
  1948.         def LoadFromXml(self, daeDocument, xmlNode):
  1949.                 super(DaeFxImage, self).LoadFromXml(daeDocument, xmlNode)
  1950.                
  1951.         def SaveToXml(self, daeDocument):
  1952.                 node = super(DaeFxImage,self).SaveToXml(daeDocument)
  1953.                 return node
  1954.        
  1955. class DaeFxNewParam(DaeEntity):
  1956.         def __init__(self):
  1957.                 super(DaeFxNewParam, self).__init__()
  1958.                 self.syntax = DaeFxSyntax.NEWPARAM
  1959.                
  1960.         def LoadFromXml(self, daeDocument, xmlNode):
  1961.                 super(DaeFxNewParam, self).LoadFromXml(daeDocument, xmlNode)
  1962.                
  1963.         def SaveToXml(self, daeDocument):
  1964.                 node = super(DaeFxNewParam,self).SaveToXml(daeDocument)
  1965.                 return node
  1966.        
  1967. class DaeFxTechnique(DaeEntity):
  1968.         def __init__(self):
  1969.                 super(DaeFxTechnique, self).__init__()
  1970.                 self.syntax = DaeFxSyntax.TECHNIQUE
  1971.                 self.shader = DaeFxShadeConstant()
  1972.                 self.sid = ''
  1973.                 self.doubleside = DaeFxDoubleSided()  #Doug: added Mar3008
  1974.                
  1975.         def LoadFromXml(self, daeDocument, xmlNode):
  1976.                 # TODO: add asset and extra?
  1977.                 self.sid = xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.SID)
  1978.                 #Doug: added Mar3008 the following 5 lines about googleearth profile and doublesided
  1979.                 profile = xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.PROFILE)
  1980.                 if profile == DaeFxSyntax.GOOGLEEARTH:
  1981.                         lightSourceNode = xmlUtils.FindElementByTagName(xmlNode, DaeFxSyntax.DOUBLESIDED)
  1982.                         if lightSourceNode:
  1983.                                 self.doubleside = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.DOUBLE_SIDED, DaeFxDoubleSided)
  1984.                 else:
  1985.                         lightSourceNode = xmlUtils.FindElementByTagName(xmlNode, DaeFxSyntax.CONSTANT)
  1986.                         if lightSourceNode:
  1987.                                 self.shader = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.CONSTANT, DaeFxShadeConstant)                        
  1988.                         else:
  1989.                                 lightSourceNode = xmlUtils.FindElementByTagName(xmlNode, DaeFxSyntax.LAMBERT)
  1990.                                 if lightSourceNode:
  1991.                                         self.shader = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.LAMBERT, DaeFxShadeLambert)
  1992.                                 else:
  1993.                                         lightSourceNode = xmlUtils.FindElementByTagName(xmlNode, DaeFxSyntax.BLINN)
  1994.                                         if lightSourceNode:
  1995.                                                 self.shader = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.BLINN, DaeFxShadeBlinn)
  1996.                                         else:
  1997.                                                 lightSourceNode = xmlUtils.FindElementByTagName(xmlNode, DaeFxSyntax.PHONG)
  1998.                                                 self.shader = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.PHONG, DaeFxShadePhong)
  1999.                
  2000.                
  2001.         def SaveToXml(self, daeDocument):
  2002.                 node = super(DaeFxTechnique,self).SaveToXml(daeDocument)
  2003.                 if self.doubleside.value:
  2004.                         node.setAttribute(DaeFxSyntax.PROFILE, DaeFxSyntax.GOOGLEEARTH)
  2005.                         AppendChild(daeDocument, node, self.doubleside)
  2006.                 else:
  2007.                         node.setAttribute(DaeFxSyntax.SID, self.sid)
  2008.                         AppendChild(daeDocument, node, self.shader)
  2009.                 return node
  2010.        
  2011.         def AddDoubleSided(self, val):  #Doug: added Mar3008
  2012.                 self.doubleside.AddValue(val)
  2013.        
  2014.         def __str__(self):
  2015.                 if self.doubleside.doublesided:
  2016.                         return super(DaeFxTechnique,self).__str__()+' doublesided: %s'%(self.doubleside)
  2017.                 else:
  2018.                         return super(DaeFxTechnique,self).__str__()+' shader: %s'%(self.shader)
  2019.  
  2020. class DaeFxDoubleSided(DaeEntity):  #Doug: added Mar3008
  2021.         def __init__(self):
  2022.                 super(DaeFxDoubleSided, self).__init__()
  2023.                 self.value = None
  2024.                 self.syntax = DaeFxSyntax.DOUBLE_SIDED
  2025.                
  2026.         def LoadFromXml(self, daeDocument, xmlNode):
  2027.                 #self.value = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.DOUBLE_SIDED, DaeFxCommonContainer, True)
  2028.                 self.value = CastFromXml(daeDocument, xmlNode, self.syntax, int)
  2029.                
  2030.         def SaveToXml(self, daeDocument):
  2031.                 node = super(DaeFxDoubleSided,self).SaveToXml(daeDocument)
  2032.                 #def AppendTextInChild(xmlNode, object):
  2033.                 AppendTextInChild(node,int(self.value))
  2034.                 #AppendTextChild(node, self.syntax, int(self.value)) #not quie the right thing- dont need syntax again
  2035.                 return node
  2036.        
  2037.         def AddValue(self, val):
  2038.                 self.value = int(val)
  2039.        
  2040. class DaeFxShadeConstant(DaeEntity):
  2041.         def __init__(self):
  2042.                 super(DaeFxShadeConstant, self).__init__()
  2043.                 self.emission = None
  2044.                 self.reflective = None
  2045.                 self.reflectivity = None
  2046.                 self.transparent = None
  2047.                 self.transparency = None
  2048.                 self.indexOfRefraction = None
  2049.                        
  2050.                 self.syntax = DaeFxSyntax.CONSTANT
  2051.                
  2052.         def LoadFromXml(self, daeDocument, xmlNode):
  2053.                 self.emission = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.EMISSION, DaeFxCommonColorAndTextureContainer, True)
  2054.                 self.reflective = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.REFLECTIVE, DaeFxCommonColorAndTextureContainer, True)
  2055.                 self.reflectivity = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.REFLECTIVITY, DaeFxCommonFloatAndParamContainer, True)
  2056.                 self.transparent = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.TRANSPARENT, DaeFxCommonColorAndTextureContainer, True)
  2057.                 self.transparency = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.TRANSPARENCY, DaeFxCommonFloatAndParamContainer, True)
  2058.                 self.indexOfRefraction = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.INDEXOFREFRACTION, DaeFxCommonFloatAndParamContainer, True)
  2059.                
  2060.         def SaveToXml(self, daeDocument):
  2061.                 node = super(DaeFxShadeConstant,self).SaveToXml(daeDocument)
  2062.                 AppendChild(daeDocument, node, self.emission)
  2063.                 if isinstance(self, DaeFxShadeLambert):
  2064.                         AppendChild(daeDocument, node, self.ambient)
  2065.                         AppendChild(daeDocument, node, self.diffuse)
  2066.                         if isinstance(self,DaeFxShadeBlinn):
  2067.                                 AppendChild(daeDocument, node, self.specular)
  2068.                                 AppendChild(daeDocument, node, self.shininess)
  2069.                 AppendChild(daeDocument, node, self.reflective)
  2070.                 AppendChild(daeDocument, node, self.reflectivity)
  2071.                 AppendChild(daeDocument, node, self.transparent)
  2072.                 AppendChild(daeDocument, node, self.transparency)
  2073.                 AppendChild(daeDocument, node, self.indexOfRefraction)
  2074.                 return node
  2075.        
  2076.         def AddValue(self, type, val):
  2077.                 col = DaeFxColor()
  2078.                 col.rgba = val
  2079.                 if type == DaeFxSyntax.EMISSION:
  2080.                         if not self.emission:
  2081.                                 self.emission = DaeFxCommonColorAndTextureContainer(type)
  2082.                         self.emission.color = col
  2083.                 elif type == DaeFxSyntax.REFLECTIVE:
  2084.                         if not self.reflective:
  2085.                                 self.reflective = DaeFxCommonColorAndTextureContainer(type)
  2086.                         self.reflective.color = col
  2087.                 elif type == DaeFxSyntax.REFLECTIVITY:
  2088.                         if not self.reflectivity:
  2089.                                 self.reflectivity = DaeFxCommonFloatAndParamContainer(type)
  2090.                         self.reflectivity.float = val
  2091.                 elif type == DaeFxSyntax.TRANSPARENT:
  2092.                         if not self.transparent:
  2093.                                 self.transparent = DaeFxCommonColorAndTextureContainer(type)
  2094.                         self.transparent.color = col
  2095.                 elif type == DaeFxSyntax.TRANSPARENCY:
  2096.                         if not self.transparency:
  2097.                                 self.transparency = DaeFxCommonFloatAndParamContainer(type)
  2098.                         self.transparency.float = val
  2099.                 elif type == DaeFxSyntax.INDEXOFREFRACTION:
  2100.                         if not self.indexOfRefraction:
  2101.                                 self.indexOfRefraction = DaeFxCommonFloatAndParamContainer(type)
  2102.                         self.indexOfRefraction.float = val
  2103.                 else:
  2104.                         Debug.Debug('DaeFxShadeConstant: type: %s not recognised'%(type),'ERROR')
  2105.  
  2106.                
  2107.        
  2108. class DaeFxShadeLambert(DaeFxShadeConstant):
  2109.         def __init__(self):
  2110.                 super(DaeFxShadeLambert, self).__init__()
  2111.                 self.ambient = None
  2112.                 self.diffuse = None
  2113.                 self.syntax = DaeFxSyntax.LAMBERT
  2114.                
  2115.         def LoadFromXml(self, daeDocument, xmlNode):
  2116.                 super(DaeFxShadeLambert, self).LoadFromXml(daeDocument, xmlNode)
  2117.                 self.ambient = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.AMBIENT, DaeFxCommonColorAndTextureContainer, True)
  2118.                 self.diffuse = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.DIFFUSE, DaeFxCommonColorAndTextureContainer, True)
  2119.                
  2120.                
  2121.         def SaveToXml(self, daeDocument):
  2122.                 node = super(DaeFxShadeLambert,self).SaveToXml(daeDocument)
  2123.                 #AppendChild(daeDocument, node, self.ambient)
  2124.                 #AppendChild(daeDocument, node, self.diffuse)
  2125.                 return node
  2126.        
  2127.         def AddValue(self, type, val):
  2128.                 col = DaeFxColor()
  2129.                 col.rgba = val
  2130.                 if type == DaeFxSyntax.DIFFUSE:
  2131.                         if not self.diffuse:
  2132.                                 self.diffuse = DaeFxCommonColorAndTextureContainer(type)
  2133.                         if isinstance(val, DaeFxTexture): # its a texture
  2134.                                 self.diffuse.texture = val
  2135.                         else: # it's a color
  2136.                                 self.diffuse.color = col
  2137.                 elif type == DaeFxSyntax.AMBIENT:
  2138.                         if not self.ambient:
  2139.                                 self.ambient = DaeFxCommonColorAndTextureContainer(type)
  2140.                         self.ambient.color = col
  2141.                 else:
  2142.                         super(DaeFxShadeLambert,self).AddValue(type, val)
  2143.                        
  2144. class DaeFxShadeBlinn(DaeFxShadeLambert):
  2145.         def __init__(self):
  2146.                 super(DaeFxShadeBlinn, self).__init__()
  2147.                 self.specular = None
  2148.                 self.shininess = None
  2149.                 self.syntax = DaeFxSyntax.BLINN
  2150.                
  2151.         def LoadFromXml(self, daeDocument, xmlNode):
  2152.                 super(DaeFxShadeBlinn, self).LoadFromXml(daeDocument, xmlNode)
  2153.                 self.specular = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.SPECULAR, DaeFxCommonColorAndTextureContainer, True)
  2154.                 self.shininess = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.SHININESS, DaeFxCommonFloatAndParamContainer, True)
  2155.                
  2156.                
  2157.         def SaveToXml(self, daeDocument):
  2158.                 node = super(DaeFxShadeBlinn,self).SaveToXml(daeDocument)
  2159.                 #AppendChild(daeDocument, node, self.specular)
  2160.                 #AppendChild(daeDocument, node, self.shininess)
  2161.                 return node
  2162.        
  2163.         def AddValue(self, type, val):
  2164.                 col = DaeFxColor()
  2165.                 col.rgba = val
  2166.                 if type == DaeFxSyntax.SPECULAR:
  2167.                         if not self.specular:
  2168.                                 self.specular = DaeFxCommonColorAndTextureContainer(type)
  2169.                         self.specular.color = col
  2170.                 elif type == DaeFxSyntax.SHININESS:
  2171.                         if not self.shininess:
  2172.                                 self.shininess = DaeFxCommonFloatAndParamContainer(type)
  2173.                         self.shininess.float = val
  2174.                 else:
  2175.                         super(DaeFxShadeBlinn,self).AddValue(type, val)
  2176.                        
  2177. class DaeFxShadePhong(DaeFxShadeBlinn):
  2178.         def __init__(self):
  2179.                 super(DaeFxShadePhong, self).__init__()
  2180.                 self.syntax = DaeFxSyntax.PHONG
  2181.        
  2182. class DaeFxCommonColorAndTextureContainer(DaeEntity):
  2183.         def __init__(self, syntax='UNKNOWN'):
  2184.                 super(DaeFxCommonColorAndTextureContainer, self).__init__()
  2185.                 self.color = None
  2186.                 self.texture = None
  2187.                 self.syntax = syntax
  2188.                
  2189.         def LoadFromXml(self, daeDocument, xmlNode):
  2190.                 self.color = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.COLOR, DaeFxColor)
  2191.                 self.texture = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.TEXTURE, DaeFxTexture)
  2192.                
  2193.         def SaveToXml(self, daeDocument):
  2194.                 node = super(DaeFxCommonColorAndTextureContainer,self).SaveToXml(daeDocument)
  2195.                 AppendChild(daeDocument, node, self.color)
  2196.                 AppendChild(daeDocument, node, self.texture)
  2197.                 return node
  2198.        
  2199. class DaeFxCommonFloatAndParamContainer(DaeEntity):
  2200.         def __init__(self, syntax = 'UNKNOWN'):
  2201.                 super(DaeFxCommonFloatAndParamContainer, self).__init__()
  2202.                 self.float = None
  2203.                 self.param = None
  2204.                 self.syntax = syntax
  2205.                
  2206.         def LoadFromXml(self, daeDocument, xmlNode):
  2207.                 self.float = CastFromXml(daeDocument, xmlNode, DaeFxSyntax.FLOAT, float)
  2208.                 ##self.param = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.PARAM, DaeFxParam)
  2209.                
  2210.         def SaveToXml(self, daeDocument):
  2211.                 node = super(DaeFxCommonFloatAndParamContainer,self).SaveToXml(daeDocument)
  2212.                 AppendTextChild(node, DaeFxSyntax.FLOAT, self.float)
  2213.                 AppendChild(daeDocument, node, self.param)
  2214.                 return node
  2215.        
  2216. class DaeFxCommonContainer(DaeEntity): #Doug: added Mar3008
  2217.         def __init__(self, cast = str):
  2218.                 super(DaeFxCommonContainer, self).__init__()
  2219.                 self.value = None
  2220.                 self.cast = cast
  2221.                 self.syntax = syntax
  2222.                
  2223.         def LoadFromXml(self, daeDocument, xmlNode):
  2224.                 self.value = CastFromXml(daeDocument, xmlNode, self.syntax, self.cast)
  2225.                 #def CastFromXml(colladaDocument, xmlNode, nodeType, cast, default=None):
  2226.                 ##self.param = CreateObjectFromXml(daeDocument, xmlNode, DaeFxSyntax.PARAM, DaeFxParam)
  2227.                
  2228.         def SaveToXml(self, daeDocument):
  2229.                 node = super(DaeFxCommonContainer,self).SaveToXml(daeDocument)
  2230.                 AppendTextChild(node, self.syntax, self.cast(self.value))
  2231.                 #def AppendTextChild(xmlNode,syntax, object, default = None):
  2232.                 #AppendChild(daeDocument, node, false)
  2233.                 return node
  2234.  
  2235. class DaeFxColor(DaeEntity):
  2236.         def __init__(self):
  2237.                 super(DaeFxColor, self).__init__()
  2238.                 self.sid = ''
  2239.                 self.rgba = []
  2240.                 self.syntax = DaeFxSyntax.COLOR
  2241.                
  2242.         def LoadFromXml(self, daeDocument, xmlNode):
  2243.                 self.sid = xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.SID)
  2244.                 self.rgba = ToFloatList(xmlUtils.ReadContents(xmlNode))
  2245.                
  2246.         def SaveToXml(self, daeDocument):
  2247.                 node = super(DaeFxColor,self).SaveToXml(daeDocument)
  2248.                 SetAttribute(node, DaeFxSyntax.SID, self.sid)
  2249.                 AppendTextInChild(node, self.rgba)
  2250.                 return node
  2251.        
  2252. class DaeFxTexture(DaeEntity):
  2253.         def __init__(self):
  2254.                 super(DaeFxTexture, self).__init__()
  2255.                 self.texture = ''
  2256.                 self.textCoord = ''
  2257.                 self.syntax = DaeFxSyntax.TEXTURE
  2258.                
  2259.         def LoadFromXml(self, daeDocument, xmlNode):
  2260.                 self.texture = daeDocument.imagesLibrary.FindObject(xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.TEXTURE))
  2261.                 self.textCoord = xmlUtils.ReadAttribute(xmlNode, DaeFxSyntax.TEXCOORD)
  2262.                
  2263.         def SaveToXml(self, daeDocument):
  2264.                 node = super(DaeFxTexture,self).SaveToXml(daeDocument)
  2265.                 SetAttribute(node, DaeFxSyntax.TEXTURE, StripString(self.texture))
  2266.                 SetAttribute(node, DaeFxSyntax.TEXCOORD, self.textCoord)
  2267.                 return node
  2268.        
  2269. class DaeFxSyntax(object):
  2270.         COLOR = 'color'  
  2271.         INSTANCE_MATERIAL = 'instance_material'
  2272.         INSTANCE_EFFECT = 'instance_effect'
  2273.         TECHNIQUE_COMMON = 'technique_common'
  2274.         SID = 'sid'
  2275.         EMISSION = 'emission'
  2276.         REFLECTIVE ='reflective'
  2277.         REFLECTIVITY = 'reflectivity'   
  2278.         TRANSPARENT = 'transparent'
  2279.         TRANSPARENCY = 'transparency'
  2280.         INDEXOFREFRACTION = 'index_of_refraction'
  2281.         TEXTURE = 'texture'
  2282.         TEXCOORD = 'texcoord'
  2283.         AMBIENT = 'ambient'
  2284.         DIFFUSE = 'diffuse'    
  2285.        
  2286.         BIND_MATERIAL ='bind_material'
  2287.         PROFILE_COMMON = 'profile_COMMON'
  2288.         SYMBOL = 'symbol'
  2289.         MATERIAL = 'material'
  2290.         EFFECT = 'effect'
  2291.        
  2292.         TARGET = 'target'
  2293.         URL = 'url'
  2294.         SYMBOL = 'symbol'
  2295.        
  2296.         BLINN = 'blinn'
  2297.         SHININESS = 'shininess'
  2298.         SPECULAR = 'specular'
  2299.         PHONG = 'phong'
  2300.        
  2301.         IMAGE = 'image'
  2302.         NEWPARAM = 'newparam'
  2303.         TECHNIQUE = 'technique'
  2304.         EXTRA = 'extra'                 #Doug: added Mar3008
  2305.         DOUBLE_SIDED = 'double_sided'   #Doug: added Mar3008
  2306.         PROFILE = 'profile'             #Doug: added Mar3008
  2307.         GOOGLEEARTH = 'GOOGLEEARTH'   #Doug: added Mar3008
  2308.        
  2309.         CONSTANT = 'constant'
  2310.         LAMBERT = 'lambert'
  2311.        
  2312.         FLOAT ='float'
  2313. #---COLLADA PHYSICS---
  2314. class DaePhysicsScene(DaeElement):
  2315.         def __init__(self):
  2316.                 super(DaePhysicsScene,self).__init__()
  2317.                 self.asset = None
  2318.                 self.extras = None
  2319.                 self.iPhysicsModels = []
  2320.                 self.syntax = DaePhysicsSyntax.PHYSICS_SCENE       
  2321.                
  2322.         def LoadFromXml(self, daeDocument, xmlNode):
  2323.                 super(DaePhysicsScene, self).LoadFromXml(daeDocument, xmlNode)
  2324.                 self.extras = CreateObjectsFromXml(daeDocument, xmlNode, DaeSyntax.EXTRA, DaeExtra)
  2325.                 self.asset = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.ASSET, DaeAsset)
  2326.                 self.iPhysicsModels = CreateObjectsFromXml(daeDocument, xmlNode, DaePhysicsSyntax.INSTANCE_PHYSICS_MODEL, DaePhysicsModelInstance)
  2327.                
  2328.         def SaveToXml(self, daeDocument):
  2329.                 node = super(DaePhysicsScene, self).SaveToXml(daeDocument)
  2330.                 # Add the assets
  2331.                 AppendChild(daeDocument,node,self.asset)
  2332.                 # Add the phyics models
  2333.                 AppendChilds(daeDocument, node, self.iPhysicsModels)
  2334.                 # Add the extra's
  2335.                 AppendChilds(self,node,self.extras)
  2336.                 return node
  2337.                
  2338.         def __str__(self):
  2339.                 return super(DaePhysicsScene,self).__str__()+' asset: %s, iPhysicsModels: %s, extras: %s'%(self.asset, self.iPhysicsModels, self.extras)
  2340.  
  2341. class DaePhysicsModelInstance(DaeInstance):
  2342.         def __init__(self):
  2343.                 super(DaePhysicsModelInstance, self).__init__()            
  2344.                 self.syntax = DaePhysicsSyntax.INSTANCE_PHYSICS_MODEL
  2345.                 self.iRigidBodies = []
  2346.                
  2347.         def LoadFromXml(self, daeDocument, xmlNode):
  2348.                 super(DaePhysicsModelInstance,self).LoadFromXml(daeDocument, xmlNode)
  2349.                 self.object = daeDocument.physicsModelsLibrary.FindObject(self.url)
  2350.                 self.iRigidBodies = self.CreateInstanceRigidBodies(daeDocument, xmlNode, self.object)
  2351.                
  2352.         def SaveToXml(self, daeDocument):
  2353.                 node = super(DaePhysicsModelInstance,self).SaveToXml(daeDocument)
  2354.                 AppendChilds(daeDocument, node, self.iRigidBodies)
  2355.                 return node
  2356.        
  2357.         def CreateInstanceRigidBodies(self, daeDocument, xmlNode, physicsModel):
  2358.                 objects = []
  2359.                 CreateObjectsFromXml(daeDocument, xmlNode, DaePhysicsSyntax.INSTANCE_RIGID_BODY, DaeRigidBodyInstance)
  2360.                 nodes = xmlUtils.FindElementsByTagName(xmlNode,DaePhysicsSyntax.INSTANCE_RIGID_BODY)
  2361.                 for node in nodes:
  2362.                         object = DaeRigidBodyInstance()
  2363.                         object.LoadFromXml(daeDocument, node)
  2364.                         object.body = physicsModel.FindRigidBody(object.bodyString)
  2365.                         n = None
  2366.                         for visualScene in daeDocument.visualScenesLibrary.items:
  2367.                                 n = visualScene.FindNode(object.targetString)
  2368.                                 if not (n is None):
  2369.                                         break
  2370.                         object.target = n
  2371.                         objects.append(object)
  2372.                 return objects
  2373.                
  2374.        
  2375. class DaePhysicsSceneInstance(DaeInstance):
  2376.         def __init__(self):
  2377.                 super(DaePhysicsSceneInstance, self).__init__()
  2378.                 self.syntax = DaeSyntax.INSTANCE_PHYSICS_SCENE
  2379.                
  2380.         def LoadFromXml(self, daeDocument, xmlNode):
  2381.                 super(DaePhysicsSceneInstance,self).LoadFromXml(daeDocument, xmlNode)
  2382.                 self.object = daeDocument.physicsScenesLibrary.FindObject(self.url)
  2383.                
  2384.         def SaveToXml(self, daeDocument):
  2385.                 node = super(DaePhysicsSceneInstance,self).SaveToXml(daeDocument)
  2386.                 return node
  2387.        
  2388. class DaePhysicsMaterialInstance(DaeInstance):
  2389.         def __init__(self):
  2390.                 super(DaePhysicsMaterialInstance, self).__init__()               
  2391.                 self.syntax = DaePhysicsSyntax.INSTANCE_PHYSICS_MATERIAL
  2392.                
  2393.         def LoadFromXml(self, daeDocument, xmlNode):           
  2394.                 super(DaePhysicsMaterialInstance,self).LoadFromXml(daeDocument, xmlNode)
  2395.                 self.object = daeDocument.physicsMaterialsLibrary.FindObject(self.url)
  2396.                
  2397.         def SaveToXml(self, daeDocument):
  2398.                 node = super(DaePhysicsMaterialInstance,self).SaveToXml(daeDocument)
  2399.                 return node
  2400.        
  2401. class DaeRigidBodyInstance(DaeEntity):
  2402.         def __init__(self):
  2403.                 super(DaeRigidBodyInstance, self).__init__()           
  2404.                 self.syntax = DaePhysicsSyntax.INSTANCE_RIGID_BODY
  2405.                 self.body = None
  2406.                 self.target = None
  2407.                 self.bodyString = ''
  2408.                 self.targetString = ''
  2409.                
  2410.         def LoadFromXml(self, daeDocument, xmlNode):           
  2411.                 self.bodyString = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.BODY)
  2412.                 self.targetString = xmlUtils.ReadAttribute(xmlNode, DaeSyntax.TARGET)[1:]
  2413.                
  2414.         def SaveToXml(self, daeDocument):
  2415.                 node = super(DaeRigidBodyInstance,self).SaveToXml(daeDocument)
  2416.                 SetAttribute(node, DaeSyntax.BODY, StripString(self.body.name))
  2417.                 SetAttribute(node, DaeSyntax.TARGET, StripString('#'+self.target.id))            
  2418.                 return node
  2419.        
  2420. class DaePhysicsModel(DaeElement):
  2421.         def __init__(self):
  2422.                 super(DaePhysicsModel,self).__init__()
  2423.                 self.syntax = DaePhysicsSyntax.PHYSICS_MODEL
  2424.                 self.rigidBodies = []
  2425.        
  2426.         def LoadFromXml(self, daeDocument, xmlNode):
  2427.                 super(DaePhysicsModel, self).LoadFromXml(daeDocument, xmlNode)
  2428.                 self.rigidBodies = CreateObjectsFromXml(daeDocument, xmlNode, DaePhysicsSyntax.RIGID_BODY, DaeRigidBody)               
  2429.                
  2430.         def SaveToXml(self, daeDocument):
  2431.                 node = super(DaePhysicsModel, self).SaveToXml(daeDocument)
  2432.                 # Add the rigid bodies
  2433.                 AppendChilds(daeDocument, node, self.rigidBodies)
  2434.                 return node
  2435.        
  2436.         def FindRigidBody(self, url):
  2437.                 for rigidBody in self.rigidBodies:
  2438.                         if rigidBody.sid == url:
  2439.                                 return rigidBody
  2440.                 return None
  2441.  
  2442. class DaePhysicsMaterial(DaeElement):
  2443.         def __init__(self):
  2444.                 super(DaePhysicsMaterial,self).__init__()
  2445.                 self.syntax = DaePhysicsSyntax.PHYSICS_MATERIAL
  2446.                 self.techniqueCommon = DaePhysicsMaterial.DaeTechniqueCommon()
  2447.        
  2448.         def LoadFromXml(self, daeDocument, xmlNode):
  2449.                 super(DaePhysicsMaterial, self).LoadFromXml(daeDocument, xmlNode)
  2450.                 self.techniqueCommon = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.TECHNIQUE_COMMON, DaePhysicsMaterial.DaeTechniqueCommon)        
  2451.                
  2452.         def SaveToXml(self, daeDocument):
  2453.                 node = super(DaePhysicsMaterial, self).SaveToXml(daeDocument)
  2454.                 AppendChild(daeDocument,node,self.techniqueCommon)
  2455.                 return node
  2456.        
  2457.         class DaeTechniqueCommon(DaeEntity):
  2458.                 def __init__(self):
  2459.                         super(DaePhysicsMaterial.DaeTechniqueCommon,self).__init__()
  2460.                         self.syntax = DaeSyntax.TECHNIQUE_COMMON
  2461.                         self.dynamicFriction = 0
  2462.                         self.restitution = 0
  2463.                         self.staticFriction = 0
  2464.                        
  2465.                 def LoadFromXml(self, daeDocument, xmlNode):
  2466.                         self.dynamicFriction = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.DYNAMIC_FRICTION, float, 0)
  2467.                         self.restitution = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.RESTITUTION,      float, 0)
  2468.                         self.staticFriction = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.STATIC_FRICTION, float, 0)
  2469.                
  2470.                 def SaveToXml(self, daeDocument):
  2471.                         node = super(DaePhysicsMaterial.DaeTechniqueCommon,self).SaveToXml(daeDocument)
  2472.                         AppendTextChild(node, DaePhysicsSyntax.DYNAMIC_FRICTION, self.dynamicFriction, None)
  2473.                         AppendTextChild(node, DaePhysicsSyntax.RESTITUTION, self.restitution, None)
  2474.                         AppendTextChild(node, DaePhysicsSyntax.STATIC_FRICTION, self.staticFriction, None)
  2475.                         return node
  2476.                
  2477.                 def __str__(self):
  2478.                         return super(DaePhysicsMaterial.DaeTechniqueCommon,self).__str__()
  2479.        
  2480. class DaeRigidBody(DaeEntity):
  2481.         def __init__(self):
  2482.                 super(DaeRigidBody, self).__init__()
  2483.                 self.syntax = DaePhysicsSyntax.RIGID_BODY
  2484.                 self.name = ''
  2485.                 self.sid = ''
  2486.                 self.techniqueCommon = DaeRigidBody.DaeTechniqueCommon()
  2487.        
  2488.         def LoadFromXml(self, daeDocument, xmlNode):
  2489.                 self.name = xmlNode.getAttribute(DaeSyntax.NAME)
  2490.                 self.sid = xmlNode.getAttribute(DaeSyntax.SID)
  2491.                 self.techniqueCommon = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.TECHNIQUE_COMMON, DaeRigidBody.DaeTechniqueCommon)            
  2492.                
  2493.         def SaveToXml(self, daeDocument):
  2494.                 node = super(DaeRigidBody, self).SaveToXml(daeDocument)
  2495.                 SetAttribute(node,DaeSyntax.NAME, StripString(self.name))
  2496.                 SetAttribute(node,DaeSyntax.SID, StripString(self.name))
  2497.                 AppendChild(daeDocument,node,self.techniqueCommon)
  2498.                 return node
  2499.        
  2500.         class DaeTechniqueCommon(DaeEntity):
  2501.                 def __init__(self):
  2502.                         super(DaeRigidBody.DaeTechniqueCommon, self).__init__()
  2503.                         self.syntax = DaeSyntax.TECHNIQUE_COMMON
  2504.                         self.iPhysicsMaterial = None
  2505.                         self.physicsMaterial = None
  2506.                         self.dynamic = True
  2507.                         self.mass = None
  2508.                         self.inertia = None
  2509.                         self.shapes = []
  2510.                        
  2511.                 def LoadFromXml(self, daeDocument, xmlNode):
  2512.                         self.iPhysicsMaterial = CreateObjectFromXml(daeDocument, xmlNode, DaePhysicsSyntax.INSTANCE_PHYSICS_MATERIAL, DaePhysicsMaterialInstance)                
  2513.                         self.physicsMaterial = CreateObjectFromXml(daeDocument, xmlNode, DaePhysicsSyntax.PHYSICS_MATERIAL, DaePhysicsMaterial)            
  2514.                         self.dynamic = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.DYNAMIC,bool,True)
  2515.                         self.mass = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.MASS, float, 1)
  2516.                         self.inertia = ToFloat3(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaePhysicsSyntax.INERTIA)))
  2517.                        
  2518.                         shapeNodes = xmlUtils.FindElementsByTagName(xmlNode, DaePhysicsSyntax.SHAPE)
  2519.                         for shapeNode in shapeNodes:
  2520.                                 s = xmlUtils.FindElementByTagName(shapeNode, DaePhysicsSyntax.BOX)
  2521.                                 b = None
  2522.                                 if not (s is None):
  2523.                                         b = DaeBoxShape()
  2524.                                 else:
  2525.                                         s = xmlUtils.FindElementByTagName(shapeNode, DaePhysicsSyntax.SPHERE)
  2526.                                         if not (s is None):
  2527.                                                 b = DaeSphereShape()
  2528.                                         else:
  2529.                                                 s = xmlUtils.FindElementByTagName(shapeNode, DaePhysicsSyntax.PLANE)
  2530.                                                 if not (s is None):
  2531.                                                         b = DaePlaneShape()
  2532.                                                 else:
  2533.                                                         s = xmlUtils.FindElementByTagName(shapeNode, DaeSyntax.INSTANCE_GEOMETRY)
  2534.                                                         if not (s is None):
  2535.                                                                 b = DaeGeometryShape()
  2536.                                                         else:
  2537.                                                                 s = xmlUtils.FindElementByTagName(shapeNode, DaePhysicsSyntax.CYLINDER)
  2538.                                                                 if not (s is None):
  2539.                                                                         b = DaeCylinderShape()
  2540.                                                                 else:
  2541.                                                                         s = xmlUtils.FindElementByTagName(shapeNode, DaePhysicsSyntax.TAPERED_CYLINDER)
  2542.                                                                         if not (s is None):
  2543.                                                                                 b = DaeTaperedCylinderShape()
  2544.                                                                         else:
  2545.                                                                                 s = xmlUtils.FindElementByTagName(shapeNode, DaePhysicsSyntax.CAPSULE)
  2546.                                                                                 if not (s is None):
  2547.                                                                                         b = DaeCapsule()
  2548.                                                                                 else: # TAPERED_CAPSULE
  2549.                                                                                         b = DaeTaperedCapsuleShape()
  2550.                                 b.LoadFromXml(daeDocument, s)
  2551.                                 self.shapes.append(b)
  2552.                
  2553.                 def SaveToXml(self, daeDocument):
  2554.                         node = super(DaeRigidBody.DaeTechniqueCommon,self).SaveToXml(daeDocument)
  2555.                         AppendChild(daeDocument,node,self.iPhysicsMaterial)
  2556.                         AppendChild(daeDocument,node,self.physicsMaterial)
  2557.                         shapes = Element(DaePhysicsSyntax.SHAPE)
  2558.                         AppendChilds(daeDocument, shapes, self.shapes)
  2559.                         node.appendChild(shapes)
  2560.                         AppendTextChild(node, DaePhysicsSyntax.DYNAMIC, self.dynamic, None)
  2561.                         AppendTextChild(node, DaePhysicsSyntax.MASS, self.mass, None)
  2562.                         AppendTextChild(node, DaePhysicsSyntax.INERTIA, self.inertia, None)
  2563.                         return node
  2564.                
  2565.                 def GetPhysicsMaterial(self):
  2566.                         if not (self.physicsMaterial is None):
  2567.                                 return self.physicsMaterial
  2568.                         else:
  2569.                                 return self.iPhysicsMaterial.object
  2570.                
  2571.                 def __str__(self):
  2572.                         return super(DaeRigidBody.DaeTechniqueCommon,self).__str__()
  2573.                
  2574. class DaeShape(DaeEntity):
  2575.         def __init__(self):
  2576.                 super(DaeShape, self).__init__()
  2577.                 self.mass = None
  2578.                 self.density = None
  2579.                 self.syntax = DaePhysicsSyntax.SHAPE
  2580.                
  2581.         def LoadFromXml(self, daeDocument, xmlNode):
  2582.                 self.iGeometry = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_GEOMETRY,DaeGeometryInstance)
  2583.                 self.mass = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.MASS, float, None)
  2584.                 self.density = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.DENSITY, float, None)
  2585.                
  2586.         def SaveToXml(self, daeDocument):
  2587.                 node = super(DaeShape, self).SaveToXml(daeDocument)
  2588.                 AppendTextChild(node, DaePhysicsSyntax.MASS, self.mass, None)
  2589.                 AppendTextChild(node, DaePhysicsSyntax.DENSITY, self.density, None)
  2590.                 return node
  2591.  
  2592. class DaeBoxShape(DaeShape):
  2593.         def __init__(self):
  2594.                 super(DaeBoxShape, self).__init__()
  2595.                 self.halfExtents = []
  2596.                 self.syntax = DaePhysicsSyntax.BOX
  2597.                
  2598.         def LoadFromXml(self, daeDocument, xmlNode):
  2599.                 super(DaeBoxShape, self).LoadFromXml(daeDocument, xmlNode)
  2600.                 self.halfExtents = ToFloat3(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaePhysicsSyntax.HALF_EXTENTS)))
  2601.                
  2602.         def SaveToXml(self, daeDocument):
  2603.                 node = super(DaeBoxShape, self).SaveToXml(daeDocument)
  2604.                 AppendTextChild(node, DaePhysicsSyntax.HALF_EXTENTS, self.halfExtents)
  2605.                 return node
  2606.  
  2607. class DaeSphereShape(DaeShape):
  2608.         def __init__(self):
  2609.                 super(DaeSphereShape, self).__init__()
  2610.                 self.radius = None
  2611.                 self.syntax = DaePhysicsSyntax.SPHERE
  2612.                
  2613.         def LoadFromXml(self, daeDocument, xmlNode):
  2614.                 super(DaeSphereShape, self).LoadFromXml(daeDocument, xmlNode)
  2615.                 self.radius = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.RADIUS, float)
  2616.                
  2617.         def SaveToXml(self, daeDocument):
  2618.                 node = super(DaeSphereShape, self).SaveToXml(daeDocument)
  2619.                 AppendTextChild(node, DaePhysicsSyntax.RADIUS, self.radius)
  2620.                 return node
  2621.        
  2622. class DaeCylinderShape(DaeShape):
  2623.         def __init__(self):
  2624.                 super(DaeCylinderShape, self).__init__()
  2625.                 self.radius = [1 , 1]
  2626.                 self.height = None
  2627.                 self.syntax = DaePhysicsSyntax.CYLINDER
  2628.                
  2629.         def LoadFromXml(self, daeDocument, xmlNode):
  2630.                 super(DaeCylinderShape, self).LoadFromXml(daeDocument, xmlNode)
  2631.                 self.radius = ToFloat2(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode, DaePhysicsSyntax.RADIUS)),'Not a valid radius found. Must consist of 2 floats')
  2632.                 self.height = CastFromXml(daeDocument, xmlNode, DaeSyntax.HEIGHT, float)
  2633.                
  2634.         def SaveToXml(self, daeDocument):
  2635.                 node = super(DaeCylinderShape, self).SaveToXml(daeDocument)
  2636.                 AppendTextChild(node, DaePhysicsSyntax.RADIUS, self.radius)
  2637.                 AppendTextChild(node, DaeSyntax.HEIGHT, self.height)
  2638.                 return node
  2639.        
  2640. class DaeTaperedCylinderShape(DaeShape):
  2641.         def __init__(self):
  2642.                 super(DaeTaperedCylinderShape, self).__init__()
  2643.                 self.radius1 = [1 , 1]
  2644.                 self.radius2 = [1 , 1]
  2645.                 self.height = None
  2646.                 self.syntax = DaePhysicsSyntax.TAPERED_CYLINDER
  2647.                
  2648.         def LoadFromXml(self, daeDocument, xmlNode):
  2649.                 super(DaeTaperedCylinderShape, self).LoadFromXml(daeDocument, xmlNode)
  2650.                 self.radius1 = ToFloat2(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode, DaePhysicsSyntax.RADIUS1)),'Not a valid radius found. Must consist of 2 floats')
  2651.                 self.radius2 = ToFloat2(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode, DaePhysicsSyntax.RADIUS2)), 'Not a valid radius found. Must consist of 2 floats')
  2652.                 self.height = CastFromXml(daeDocument, xmlNode, DaeSyntax.HEIGHT, float)
  2653.                
  2654.         def SaveToXml(self, daeDocument):
  2655.                 node = super(DaeTaperedCylinderShape, self).SaveToXml(daeDocument)
  2656.                 AppendTextChild(node, DaePhysicsSyntax.RADIUS1, self.radius1)
  2657.                 AppendTextChild(node, DaePhysicsSyntax.RADIUS2, self.radius2)
  2658.                 AppendTextChild(node, DaeSyntax.HEIGHT, self.height)
  2659.                 return node
  2660.        
  2661. class DaePlaneShape(DaeShape):
  2662.         def __init__(self):
  2663.                 super(DaePlaneShape, self).__init__()
  2664.                 self.equation = []
  2665.                 self.syntax = DaePhysicsSyntax.PLANE
  2666.                
  2667.         def LoadFromXml(self, daeDocument, xmlNode):
  2668.                 super(DaePlaneShape, self).LoadFromXml(daeDocument, xmlNode)
  2669.                 self.equation = ToFloat4(xmlUtils.ReadContents(xmlUtils.FindElementByTagName(xmlNode,DaePhysicsSyntax.EQUATION)))
  2670.        
  2671.         def SaveToXml(self, daeDocument):
  2672.                 node = super(DaePlaneShape, self).SaveToXml(daeDocument)
  2673.                 AppendTextChild(node, DaePhysicsSyntax.EQUATION, self.equation)
  2674.                 return node
  2675.  
  2676. class DaeCapsuleShape(DaeShape):
  2677.         def __init__(self):
  2678.                 super(DaeCapsuleShape, self).__init__()
  2679.                 self.radius = None
  2680.                 self.height = None
  2681.                 self.syntax = DaePhysicsSyntax.CAPSULE
  2682.                
  2683.         def LoadFromXml(self, daeDocument, xmlNode):
  2684.                 super(DaeCapsuleShape, self).LoadFromXml(daeDocument, xmlNode)
  2685.                 self.radius = CastFromXml(daeDocument, xmlNode, DaePhysicsSyntax.RADIUS, float)
  2686.                 self.height = CastFromXml(daeDocument, xmlNode, DaeSyntax.HEIGHT, float)
  2687.                
  2688.         def SaveToXml(self, daeDocument):
  2689.                 node = super(DaeCapsuleShape, self).SaveToXml(daeDocument)
  2690.                 AppendTextChild(node, DaePhysicsSyntax.RADIUS, self.radius)
  2691.                 AppendTextChild(node, DaeSyntax.HEIGHT, self.height)
  2692.                 return node
  2693.  
  2694. class DaeGeometryShape(DaeShape):
  2695.         def __init__(self):
  2696.                 super(DaeGeometryShape, self).__init__()
  2697.                 self.iGeometry = None
  2698.                
  2699.         def LoadFromXml(self, daeDocument, xmlNode):
  2700.                 super(DaeGeometryShape, self).LoadFromXml(daeDocument, xmlNode)
  2701.                 self.iGeometry = DaeGeometryInstance()
  2702.                 self.iGeometry.LoadFromXml(daeDocument, xmlNode)
  2703.                 #self.iGeometry = CreateObjectFromXml(daeDocument, xmlNode, DaeSyntax.INSTANCE_GEOMETRY, DaeGeometryInstance)
  2704.                 #print self.iGeometry
  2705.                 #print xmlNode.toxml()
  2706.                
  2707.         def SaveToXml(self, daeDocument):
  2708.                 #node = super(DaeGeometryShape, self).SaveToXml(daeDocument)
  2709.                 #AppendChild(daeDocument, node, self.iGeometry)
  2710.                 return self.iGeometry.SaveToXml(daeDocument)
  2711.        
  2712. class DaePhysicsSyntax(object):
  2713.         PHYSICS_SCENE = 'physics_scene'
  2714.         PHYSICS_MODEL = 'physics_model'
  2715.         PHYSICS_MATERIAL = 'physics_material'
  2716.        
  2717.         RIGID_BODY = 'rigid_body'
  2718.        
  2719.         INSTANCE_PHYSICS_MODEL = 'instance_physics_model'
  2720.         INSTANCE_PHYSICS_MATERIAL = 'instance_physics_material'
  2721.         INSTANCE_RIGID_BODY = 'instance_rigid_body'
  2722.        
  2723.         RESTITUTION = 'restitution'
  2724.         STATIC_FRICTION = 'static_friction'
  2725.         DYNAMIC_FRICTION = 'dynamic_friction'
  2726.        
  2727.         DYNAMIC = 'dynamic'
  2728.         MASS = 'mass'
  2729.         INERTIA = 'inertia'
  2730.         SHAPE = 'shape'
  2731.         DENSITY = 'density'
  2732.         RADIUS = 'radius'
  2733.         RADIUS1 = 'radius1'
  2734.         RADIUS2 = 'radius2'
  2735.        
  2736.        
  2737.         BOX = 'box'
  2738.         PLANE = 'plane'
  2739.         CYLINDER = 'cylinder'
  2740.         SPHERE = 'sphere'
  2741.         CAPSULE = 'capsule'
  2742.         TAPERED_CAPSULE ='tapered_capsule'
  2743.         TAPERED_CYLINDER = 'tapered_cylinder'
  2744.        
  2745.         HALF_EXTENTS = 'half_extents'
  2746.  
  2747. #---Functions---
  2748. def CreateObjectsFromXml(colladaDocument, xmlNode, nodeType, objectType):
  2749.         if xmlNode is None:
  2750.                 return None
  2751.         objects = []
  2752.         nodes = xmlUtils.FindElementsByTagName(xmlNode,nodeType)
  2753.         for node in nodes:
  2754.                 object = objectType()
  2755.                 object.LoadFromXml(colladaDocument, node)
  2756.                 objects.append(object)
  2757.         return objects
  2758.  
  2759. def CreateObjectFromXml(colladaDocument, xmlNode, nodeType, objectType, setSyntax = False):
  2760.         if xmlNode is None:
  2761.                 return None
  2762.         node = xmlUtils.FindElementByTagName(xmlNode, nodeType)  
  2763.         object = None
  2764.         if setSyntax:
  2765.                 object = objectType(nodeType)
  2766.         else:
  2767.                 object = objectType()
  2768.         if node != None:
  2769.                 object.LoadFromXml(colladaDocument, node)
  2770.                 return object
  2771.         return None
  2772.  
  2773. def CastFromXml(colladaDocument, xmlNode, nodeType, cast, default=None):
  2774.         if xmlNode is None:
  2775.                 return default
  2776.         node = xmlUtils.FindElementByTagName(xmlNode, nodeType)
  2777.         if node != None:
  2778.                 textValue = xmlUtils.ReadContents(node)
  2779.                 if cast == bool:
  2780.                         if textValue.lower() == 'false':
  2781.                                 return False
  2782.                         else:
  2783.                                 return True
  2784.                 return cast(textValue)
  2785.         return default
  2786.                
  2787. def CastAttributeFromXml(xmlNode, nodeType, cast, default=None):
  2788.         if xmlNode is None:
  2789.                 return default
  2790.         val = xmlUtils.ReadAttribute(xmlNode, nodeType)
  2791.         if val != None and val != '':
  2792.                 return cast(val)
  2793.         return default
  2794.        
  2795. def AppendChild(daeDocument, xmlNode, daeEntity):
  2796.         if daeEntity is None or xmlNode is None:
  2797.                 return
  2798.         else:
  2799.                 child = daeEntity.SaveToXml(daeDocument)
  2800.                 if child is None:
  2801.                         return
  2802.                 else :
  2803.                         xmlNode.appendChild(child)
  2804.                
  2805. def AppendChilds(daeDocument, xmlNode, daeEntities):
  2806.         if daeEntities is None or xmlNode is None:
  2807.                 return
  2808.        
  2809.         else:
  2810.                 for daeEntity in daeEntities:
  2811.                         AppendChild(daeDocument, xmlNode, daeEntity)
  2812.                        
  2813. def AppendTextChild(xmlNode,syntax, object, default = None):
  2814.         if object is None:
  2815.                 return
  2816.         if default != None and object == default:
  2817.                 return
  2818.         node = Element(syntax)
  2819.         xmlNode.appendChild(node)
  2820.         return AppendTextInChild(node, object)
  2821.  
  2822. def AppendTextInChild(xmlNode, object):
  2823.         if object is None:
  2824.                 return
  2825.         text = Text()
  2826.         if type(object) == datetime:
  2827.                 text.data = object.isoformat()##xmlUtils.ToDateTime(object)
  2828.         elif type(object) == list:
  2829.                 if len(object) == 0: return
  2830.                 if object[0] is not None and type(object[0]) == float:
  2831.                         object = RoundList(object, ROUND)
  2832.                 text.data = ListToString(object)
  2833.         elif type(object) == float:
  2834.                 text.data = round(object, ROUND)
  2835.         elif type(object) == bool:
  2836.                 text.data = str(object).lower()
  2837.         elif type(object) == int:
  2838.                 text.data = str(object) #Doug: added Mar3008 - same as default below so should have no effect
  2839.         else:
  2840.                 text.data = str(object)
  2841.         xmlNode.appendChild(text)
  2842.         return xmlNode
  2843.  
  2844. def SetAttribute(xmlNode,syntax, object):
  2845.         if xmlNode is None or object is None or str(object) == '':
  2846.                 return
  2847.         xmlNode.setAttribute(syntax,str(object))
  2848.  
  2849. def ReadNodeUrl(node):
  2850.         attribute = xmlUtils.ReadAttribute(node,DaeSyntax.URL)
  2851.         if attribute == None: return None
  2852.         else :           
  2853.                 attribute = str(attribute)
  2854.                 if attribute.startswith('#'):
  2855.                         return attribute[1:]     
  2856.         return None
  2857.  
  2858. def WriteNodeUrl(node, url):
  2859.         node.setAttribute(DaeSyntax.URL, StripString('#'+url))
  2860.        
  2861. def IsVersionOk(version, curVersion):
  2862.         versionAr = version.split('.')
  2863.         curVersionAr = curVersion.split('.')
  2864.         for i in range(len(curVersionAr)):
  2865.                 if versionAr[i] != curVersionAr[i]:
  2866.                         return False
  2867.         return True
  2868.  
  2869. def StripString(text):
  2870.         return text.replace(' ','_').replace('.','_')
  2871.  
go to heaven