def save(self): """Saves the light's properties back to :attr:`xmlnode`""" self.xmlnode.set('id', self.id) self.xmlnode.set('name', self.id) colornode = self.xmlnode.find( '%s/%s/%s'%(tag('technique_common'),tag('directional'), tag('color') ) ) colornode.text = ' '.join(map(str, self.color))
def __init__(self, controller, materials, xmlnode=None): """Creates a controller node :param collada.controller.Controller controller: A controller to instantiate in the scene :param list materials: A list containing items of type :class:`collada.scene.MaterialNode`. Each of these represents a material that the controller should be bound to. :param xmlnode: When loaded, the xmlnode it comes from """ self.controller = controller """ An object of type :class:`collada.controller.Controller` representing the controller being instantiated in the scene""" self.materials = materials """A list containing items of type :class:`collada.scene.MaterialNode`. Each of these represents a material that the controller is bound to.""" if xmlnode != None: self.xmlnode = xmlnode """ElementTree representation of the controller node.""" else: self.xmlnode = ElementTree.Element( tag('instance_controller') ) bindnode = ElementTree.Element( tag('bind_material') ) technode = ElementTree.Element( tag('technique_common') ) bindnode.append( technode ) self.xmlnode.append( bindnode ) for mat in materials: technode.append( mat.xmlnode )
def load( collada, localscope, node ): sourceid = node.get('id') arraynode = node.find(tag('float_array')) if arraynode is None: raise DaeIncompleteError('No float_array in source node') if arraynode.text is None: data = numpy.array([], dtype=numpy.float32) else: try: data = numpy.fromstring(arraynode.text, dtype=numpy.float32, sep=' ') except ValueError: raise DaeMalformedError('Corrupted float array') data[numpy.isnan(data)] = 0 paramnodes = node.findall('%s/%s/%s'%(tag('technique_common'), tag('accessor'), tag('param'))) if not paramnodes: raise DaeIncompleteError('No accessor info in source node') components = [ param.get('name') for param in paramnodes ] if len(components) == 2 and components[0] == 'U' and components[1] == 'V': #U,V is used for "generic" arguments - convert to S,T components = ['S', 'T'] if len(components) == 3 and components[0] == 'S' and components[1] == 'T' and components[2] == 'P': components = ['S', 'T'] data.shape = (-1, 3) #remove 3d texcoord dimension because we don't support it #TODO data = numpy.array(zip(data[:,0], data[:,1])) data.shape = (-1) return FloatSource( sourceid, data, tuple(components), xmlnode=node )
def load(collada, localscope, node): colornode = node.find( '%s/%s/%s'%(tag('technique_common'),tag('directional'), tag('color') ) ) if colornode is None: raise DaeIncompleteError('Missing color for directional light') try: color = tuple( [ float(v) for v in colornode.text.split() ] ) except ValueError, ex: raise DaeMalformedError('Corrupted color values in light definition')
def __init__(self, id, path, collada = None, xmlnode = None): """Create an image object. :Parameters: id Id of the image node for later reference path Path in the [zae, kmz] file space collada The Collada class instance containing this for file access xmlnode If loaded from xml, the node this data comes from """ self.id = id self.path = path self.collada = collada self._data = None self._pilimage = None self._uintarray = None self._floatarray = None if xmlnode != None: self.xmlnode = xmlnode else: self.xmlnode = ElementTree.Element( tag('image') ) initnode = ElementTree.Element( tag('init_from') ) initnode.text = path self.xmlnode.append(initnode) self.xmlnode.set('id', id) self.xmlnode.set('name', id)
def __init__(self, symbol, target, inputs, xmlnode = None): """Create a MaterialNode. :Parameters: symbol The symbol string (inside the geometry object) we are defining target The id of the material to assign to the symbol inputs A list of tuples (semantic, input_semantic, set) mapping geometry texcoords or other inputs to material input channels (semantic) xmlnode If loaded from XML, the node it comes from """ self.symbol = symbol """The symbol string (inside the geometry object) we are defining.""" self.target = target """The id of the material to assign to the symbol.""" self.inputs = inputs """A list of tuples (semantic, input_semantic, set) mapping material inputs.""" if xmlnode is not None: self.xmlnode = xmlnode else: self.xmlnode = ElementTree.Element( tag('instance_material') ) self.xmlnode.set('symbol', symbol) self.xmlnode.set('target', '#' + target.id) for sem, input_sem, set in inputs: inputnode = ElementTree.ElementTree( tag('bind_vertex_input') ) inputnode.set('semantic', sem) inputnode.set('input_semantic', input_sem) inputnode.set('input_set', set) self.xmlnode.append( inputnode )
def __init__(self, controller, materials, xmlnode=None): """Creates a controller node :param collada.controller.Controller controller: A controller to instantiate in the scene :param list materials: A list containing items of type :class:`collada.scene.MaterialNode`. Each of these represents a material that the controller should be bound to. :param xmlnode: When loaded, the xmlnode it comes from """ self.controller = controller """ An object of type :class:`collada.controller.Controller` representing the controller being instantiated in the scene""" self.materials = materials """A list containing items of type :class:`collada.scene.MaterialNode`. Each of these represents a material that the controller is bound to.""" if xmlnode != None: self.xmlnode = xmlnode """ElementTree representation of the controller node.""" else: self.xmlnode = ElementTree.Element( collada.tag('instance_controller')) bindnode = ElementTree.Element(collada.tag('bind_material')) technode = ElementTree.Element(collada.tag('technique_common')) bindnode.append(technode) self.xmlnode.append(bindnode) for mat in materials: technode.append(mat.xmlnode)
def save(self): """Saves the geometry node back to :attr:`xmlnode`""" self.xmlnode.set('url', "#%s" % self.geometry.id) for m in self.materials: m.save() matparent = self.xmlnode.find('%s/%s'%( tag('bind_material'), tag('technique_common') ) ) if matparent is None and len(self.materials)==0: return elif matparent is None: matparent = E.technique_common() self.xmlnode.append(E.bind_material(matparent)) elif len(self.materials) == 0 and matparent is not None: bindnode = self.xmlnode.find('%s' % tag('bind_material')) self.xmlnode.remove(bindnode) return for m in self.materials: if m.xmlnode not in matparent: matparent.append(m.xmlnode) xmlnodes = [m.xmlnode for m in self.materials] for n in matparent: if n not in xmlnodes: matparent.remove(n)
def load( collada, localscope, node ): indexnode = node.find(tag('p')) if indexnode is None: raise DaeIncompleteError('Missing index in polylist') vcountnode = node.find(tag('vcount')) if vcountnode is None: raise DaeIncompleteError('Missing vcount in polylist') try: if vcountnode.text is None: vcounts = numpy.array([], dtype=numpy.int32) else: vcounts = numpy.fromstring(vcountnode.text, dtype=numpy.int32, sep=' ') vcounts[numpy.isnan(vcounts)] = 0 except ValueError, ex: raise DaeMalformedError('Corrupted vcounts in polylist') all_inputs = primitive.Primitive._getInputs(collada, localscope, node.findall(tag('input'))) try: if indexnode.text is None: index = numpy.array([], dtype=numpy.int32) else: index = numpy.fromstring(indexnode.text, dtype=numpy.int32, sep=' ') index[numpy.isnan(index)] = 0 except: raise DaeMalformedError('Corrupted index in polylist') polylist = Polylist(all_inputs, node.get('material'), index, vcounts, node) return polylist
def findInput(self, semantic): """Return the xml node assigning something to `semantic`.""" for node in self.xmlnode.findall(tag('bind_vertex_input')): if node.get('semantic') == semantic: return node node = ElementTree.Element(tag('bind_vertex_input')) node.set('semantic', semantic) self.xmlnode.append( node ) return node
def load(collada, localscope, node): colornode = node.find("%s/%s/%s" % (tag("technique_common"), tag("directional"), tag("color"))) if colornode is None: raise DaeIncompleteError("Missing color for directional light") try: color = tuple([float(v) for v in colornode.text.split()]) except ValueError, ex: raise DaeMalformedError("Corrupted color values in light definition")
def save(self): surfacenode = self.xmlnode.find( tag('surface') ) initnode = surfacenode.find( tag('init_from') ) if self.format: formatnode = surfacenode.find( tag('format') ) formatnode.text = self.format initnode.text = self.image.id self.xmlnode.set('sid', self.id)
def save(self): #TODO: Update this with new sourceById format for ch in self.sources: ch.save() vnode = self.xmlnode.find(tag('mesh')).find(tag('vertices')) vinput = vnode.find(tag('input')) vnode.set('id', self.vertexsource) vinput.set('source', '#'+self.sourceById[self.vertexsource].id) for t in self._primitives: t.save() self.xmlnode.set('id', self.id) self.xmlnode.set('name', self.id)
def load( collada, node ): url = node.get('url') if not url.startswith('#'): raise DaeMalformedError('Invalid url in geometry instance') geometry = collada.geometryById.get(url[1:]) if not geometry: raise DaeBrokenRefError('Geometry %s not found in library'%url) matnodes = node.findall('%s/%s/%s'%( tag('bind_material'), tag('technique_common'), tag('instance_material') ) ) materials = [] for matnode in matnodes: materials.append( MaterialNode.load(collada, matnode) ) return GeometryNode( geometry, materials, xmlnode=node)
def load( collada, node ): url = node.get('url') if not url.startswith('#'): raise DaeMalformedError('Invalid url in controller instance') controller = collada.controllerById.get(url[1:]) if not controller: raise DaeBrokenRefError('Controller %s not found in library'%url) matnodes = node.findall('%s/%s/%s'%( tag('bind_material'), tag('technique_common'), tag('instance_material') ) ) materials = [] for matnode in matnodes: materials.append( MaterialNode.load(collada, matnode) ) return ControllerNode( controller, materials, xmlnode=node)
def save(self): samplernode = self.xmlnode.find( tag('sampler2D') ) sourcenode = samplernode.find( tag('source') ) if self.minfilter: minnode = samplernode.find( tag('minfilter') ) minnode.text = self.minfilter if self.maxfilter: maxnode = samplernode.find( tag('maxfilter') ) maxnode.text = self.maxfilter sourcenode.text = self.surface.id self.xmlnode.set('sid', self.id)
def load(collada, localscope, node): tecnode = node.find( '%s/%s' % (tag('optics'),tag('technique_common')) ) if tecnode is None or len(tecnode) == 0: raise DaeIncompleteError('Missing common technique in camera') camnode = tecnode[0] if camnode.tag == tag('perspective'): return PerspectiveCamera.load( collada, localscope, node ) elif camnode.tag == tag('orthographic'): return OrthographicCamera.load( collada, localscope, node ) else: raise DaeUnsupportedError('Unrecognized camera type: %s'%camnode.tag)
def save(self): """Saves the light's properties back to :attr:`xmlnode`""" self.xmlnode.set('id', self.id) self.xmlnode.set('name', self.id) pnode = self.xmlnode.find( '%s/%s'%(tag('technique_common'),tag('point')) ) colornode = pnode.find( tag('color') ) colornode.text = ' '.join(map(str, self.color ) ) Light._correctValInNode(pnode, 'constant_attenuation', self.constant_att) Light._correctValInNode(pnode, 'linear_attenuation', self.linear_att) Light._correctValInNode(pnode, 'quadratic_attenuation', self.quad_att) Light._correctValInNode(pnode, 'zfar', self.zfar)
def save(self): txtdata = ' '.join([ f for f in self.data ]) node = self.xmlnode.find(tag('Name_array')) node.text = txtdata node.set('count', str(len(self.data))) node.set('id', self.id+'-array' ) node = self.xmlnode.find('%s/%s'%(tag('technique_common'), tag('accessor'))) node.set('count', str(len(self.components))) node.set('source', '#'+self.id+'-array') node.set('stride', str(len(self.components))) self.xmlnode.set('id', self.id )
def save(self): """Saves the light's properties back to :attr:`xmlnode`""" self.xmlnode.set("id", self.id) self.xmlnode.set("name", self.id) pnode = self.xmlnode.find("%s/%s" % (tag("technique_common"), tag("point"))) colornode = pnode.find(tag("color")) colornode.text = " ".join(map(str, self.color)) _correctValInNode(pnode, "constant_attenuation", self.constant_att) _correctValInNode(pnode, "linear_attenuation", self.linear_att) _correctValInNode(pnode, "quadratic_attenuation", self.quad_att) _correctValInNode(pnode, "zfar", self.zfar)
def load( collada, localscope, node ): indexnodes = node.findall(tag('p')) if indexnodes is None: raise DaeIncompleteError('Missing indices in polygons') polygon_indices = [] for indexnode in indexnodes: polygon_indices.append(numpy.fromstring(indexnode.text, dtype=numpy.int32, sep=' ')) all_inputs = primitive.Primitive._getInputs(localscope, node.findall(tag('input'))) polygons = Polygons(all_inputs, node.get('material'), polygon_indices, node) return polygons
def save(self): """Saves the surface data back to :attr:`xmlnode`""" surfacenode = self.xmlnode.find( tag('surface') ) initnode = surfacenode.find( tag('init_from') ) if self.format: formatnode = surfacenode.find( tag('format') ) if formatnode is None: surfacenode.append(E.format(self.format)) else: formatnode.text = self.format initnode.text = self.image.id self.xmlnode.set('sid', self.id)
def save(self): """Saves the sampler data back to :attr:`xmlnode`""" samplernode = self.xmlnode.find( tag('sampler2D') ) sourcenode = samplernode.find( tag('source') ) if self.minfilter: minnode = samplernode.find( tag('minfilter') ) minnode.text = self.minfilter if self.magfilter: maxnode = samplernode.find( tag('magfilter') ) maxnode.text = self.magfilter sourcenode.text = self.surface.id self.xmlnode.set('sid', self.id)
def load(collada, localscope, node): author = node.find( tag('author') ) authoring_tool = node.find( tag('authoring_tool') ) comments = node.find( tag('comments') ) copyright = node.find( tag('copyright') ) source_data = node.find( tag('source_data') ) if author is not None: author = author.text if authoring_tool is not None: authoring_tool = authoring_tool.text if comments is not None: comments = comments.text if copyright is not None: copyright = copyright.text if source_data is not None: source_data = source_data.text return Contributor(author=author, authoring_tool=authoring_tool, comments=comments, copyright=copyright, source_data=source_data, xmlnode=node)
def load( collada, localscope, node ): indexnode = node.find(tag('p')) if indexnode is None: raise DaeIncompleteError('Missing index in triangle set') source_array = primitive.Primitive.getInputs(localscope, node.findall(tag('input'))) try: index = numpy.array([float(v) for v in indexnode.text.split()], dtype=numpy.int32) except: raise DaeMalformedError('Corrupted index in triangleset') triset = TriangleSet(source_array, node.get('material'), index) triset.xmlnode = node return triset
def load(collada, localscope, node): tecnode = node.find(tag("technique_common")) if tecnode is None or len(tecnode) == 0: raise DaeIncompleteError("Missing common technique in light") lightnode = tecnode[0] if lightnode.tag == tag("directional"): return SunLight.load(collada, localscope, node) elif lightnode.tag == tag("point"): return PointLight.load(collada, localscope, node) elif lightnode.tag == tag("ambient"): return AmbientLight.load(collada, localscope, node) else: raise DaeUnsupportedError("Unrecognized light type: %s" % lightnode.tag)
def load( collada, localscope, node ): surfacenode = node.find( tag('surface') ) if surfacenode is None: raise DaeIncompleteError('No surface found in newparam') if surfacenode.get('type') != '2D': raise DaeMalformedError('Hard to imagine a non-2D surface, isn\'t it?') initnode = surfacenode.find( tag('init_from') ) if initnode is None: raise DaeIncompleteError('No init image found in surface') formatnode = surfacenode.find( tag('format') ) if formatnode is None: format = None #raise Exception('No format found in surface') else: format = formatnode.text imgid = initnode.text id = node.get('sid') img = collada.imageById.get(imgid) if img is None: raise DaeBrokenRefError('Missing image ' + imgid) return Surface(id, img, format, xmlnode=node)
def load( collada, localscope, node ): sourceid = node.get('id') arraynode = node.find(tag('Name_array')) if arraynode is None: raise DaeIncompleteError('No Name_array in source node') if arraynode.text is None: values = [] else: try: values = [v for v in arraynode.text.split()] except ValueError: raise DaeMalformedError('Corrupted Name array') data = numpy.array( values, dtype=numpy.string_ ) paramnodes = node.findall('%s/%s/%s'%(tag('technique_common'), tag('accessor'), tag('param'))) if not paramnodes: raise DaeIncompleteError('No accessor info in source node') components = [ param.get('name') for param in paramnodes ] return NameSource( sourceid, data, tuple(components), xmlnode=node )
def save(self): self.data.shape = (-1,) txtdata = ' '.join([ str(f) for f in self.data ])#str(self.data)[1:-1] rawlen = len( self.data ) self.data.shape = (-1, len(self.components) ) acclen = len( self.data ) node = self.xmlnode.find(tag('float_array')) node.text = txtdata node.set('count', str(rawlen)) node.set('id', self.id+'-array' ) node = self.xmlnode.find('%s/%s'%(tag('technique_common'), tag('accessor'))) node.set('count', str(acclen)) node.set('source', '#'+self.id+'-array') node.set('stride', str(len(self.components))) self.xmlnode.set('id', self.id )
def load(collada, localscope, node): tecnode = node.find( tag('technique_common') ) if tecnode is None or len(tecnode) == 0: raise DaeIncompleteError('Missing common technique in light') lightnode = tecnode[0] if lightnode.tag == tag('directional'): return DirectionalLight.load( collada, localscope, node ) elif lightnode.tag == tag('point'): return PointLight.load( collada, localscope, node ) elif lightnode.tag == tag('ambient'): return AmbientLight.load( collada, localscope, node ) elif lightnode.tag == tag('spot'): return SpotLight.load( collada, localscope, node ) else: raise DaeUnsupportedError('Unrecognized light type: %s'%lightnode.tag)
def load(collada, localscope, node): sourceid = node.get('id') arraynode = node.find(tag('float_array')) if not arraynode is None: return FloatSource.load(collada, localscope, node) arraynode = node.find(tag('IDREF_array')) if not arraynode is None: return IDRefSource.load(collada, localscope, node) arraynode = node.find(tag('Name_array')) if not arraynode is None: return NameSource.load(collada, localscope, node) if arraynode is None: raise DaeIncompleteError('No array found in source %s' % sourceid)
def load(collada, node): url = node.get('url') if not url.startswith('#'): raise DaeMalformedError('Invalid url in controller instance %s' % url) controller = collada.controllers.get(url[1:]) if not controller: raise DaeBrokenRefError('Controller %s not found in library' % url) matnodes = node.findall( '%s/%s/%s' % (collada.tag('bind_material'), collada.tag('technique_common'), collada.tag('instance_material'))) materials = [] for matnode in matnodes: materials.append(MaterialNode.load(collada, matnode)) return ControllerNode(controller, materials, xmlnode=node)
def load(collada, node): url = node.get('url') if not url.startswith('#'): raise DaeMalformedError('Invalid url in geometry instance %s' % url) geometry = collada.geometries.get(url[1:]) if not geometry: raise DaeBrokenRefError('Geometry %s not found in library' % url) matnodes = node.findall( '%s/%s/%s' % (collada.tag('bind_material'), collada.tag('technique_common'), collada.tag('instance_material'))) materials = [] for matnode in matnodes: materials.append(MaterialNode.load(collada, matnode)) return GeometryNode(geometry, materials, xmlnode=node)
def load(collada, node): inputs = [] for inputnode in node.findall(collada.tag('bind_vertex_input')): inputs.append( (inputnode.get('semantic'), inputnode.get('input_semantic'), inputnode.get('input_set'))) targetid = node.get('target') if not targetid.startswith('#'): raise DaeMalformedError('Incorrect target id in material ' + targetid) target = collada.materials.get(targetid[1:]) if not target: raise DaeBrokenRefError('Material %s not found' % targetid) return MaterialNode(node.get('symbol'), target, inputs, xmlnode=node)
def load(collada, node): id = node.get('id') nodes = [] tried_loading = [] succeeded = False localscope = {} for nodenode in node.findall(collada.tag('node')): try: N = loadNode(collada, nodenode, localscope) except DaeInstanceNotLoadedError as ex: tried_loading.append((nodenode, ex)) except DaeError as ex: collada.handleError(ex) else: if N is not None: nodes.append(N) if N.id and N.id not in localscope: localscope[N.id] = N succeeded = True while len(tried_loading) > 0 and succeeded: succeeded = False next_tried = [] for nodenode, ex in tried_loading: try: N = loadNode(collada, nodenode, localscope) except DaeInstanceNotLoadedError as ex: next_tried.append((nodenode, ex)) except DaeError as ex: collada.handleError(ex) else: if N is not None: nodes.append(N) succeeded = True tried_loading = next_tried if len(tried_loading) > 0: for nodenode, ex in tried_loading: raise DaeBrokenRefError(ex.msg) return Scene(id, nodes, xmlnode=node, collada=collada)
def loadNode(collada, node, localscope): """Generic scene node loading from an xml `node` and a `collada` object. Knowing the supported nodes, create the appropriate class for the given node and return it. """ if node.tag == collada.tag('node'): return Node.load(collada, node, localscope) elif node.tag == collada.tag('translate'): return TranslateTransform.load(collada, node) elif node.tag == collada.tag('rotate'): return RotateTransform.load(collada, node) elif node.tag == collada.tag('scale'): return ScaleTransform.load(collada, node) elif node.tag == collada.tag('matrix'): return MatrixTransform.load(collada, node) elif node.tag == collada.tag('lookat'): return LookAtTransform.load(collada, node) elif node.tag == collada.tag('instance_geometry'): return GeometryNode.load(collada, node) elif node.tag == collada.tag('instance_camera'): return CameraNode.load(collada, node) elif node.tag == collada.tag('instance_light'): return LightNode.load(collada, node) elif node.tag == collada.tag('instance_controller'): return ControllerNode.load(collada, node) elif node.tag == collada.tag('instance_node'): return NodeNode.load(collada, node, localscope) elif node.tag == collada.tag('extra'): return ExtraNode.load(collada, node) elif node.tag == collada.tag('asset'): return None else: raise DaeUnsupportedError('Unknown scene node %s' % str(node.tag))