def set_texcoord_sourceset(self, t): if len(t) != len(self._texcoord_sourceset): raise DaeMalformedError('Wrong number of texcoord sources') try: self._texcoordset = tuple([ checkSource(self.sourceById[c], ('S', 'T'), self.maxtexcoordsetindex[i]).data for i,c in enumerate(t)]) except KeyError, ex: raise DaeBrokenRefError('Setting missing texcoord source in triangle set') self._texcoord_sourceset = tuple(t)
def __init__(self, sourcebyid, bind_shape_matrix, joint_source, joint_matrix_source, weight_source, weight_joint_source, vcounts, vertex_weight_index, offsets, geometry, controller_node=None, skin_node=None): """Create a skin. :Parameters: sourceById A dict mapping id's to a collada source bind_shape_matrix A numpy array of floats (pre-shape) joint_source The string id for the joint source joint_matrix_source The string id for the joint matrix source weight_source The string id for the weight source weight_joint_source The string id for the joint source of weights vcounts A list with the number of influences on each vertex vertex_weight_index An array with the indexes as they come from <v> array offsets A list with the offsets in the weight index array for each source in (joint, weight) geometry The source geometry this should be applied to (geometry.Geometry) controller_node XML node of the <controller> tag which is the parent of this skin_node XML node of the <skin> tag if this is from there """ self.sourcebyid = sourcebyid self.bind_shape_matrix = bind_shape_matrix self.joint_source = joint_source self.joint_matrix_source = joint_matrix_source self.weight_source = weight_source self.weight_joint_source = weight_joint_source self.vcounts = vcounts self.vertex_weight_index = vertex_weight_index self.offsets = offsets self.geometry = geometry self.controller_node = controller_node self.skin_node = skin_node self.xmlnode = controller_node if not type(self.geometry) is Geometry: raise DaeMalformedError('Invalid reference geometry in skin') self.id = controller_node.get('id') if self.id is None: raise DaeMalformedError('Controller node requires an ID') self.nindices = max(self.offsets) + 1 if len(bind_shape_matrix) != 16: raise DaeMalformedError('Corrupted bind shape matrix in skin') self.bind_shape_matrix.shape = (4,4) if not(joint_source in sourcebyid and joint_matrix_source in sourcebyid): raise DaeBrokenRefError("Input in joints not found") if not(type(sourcebyid[joint_source]) is source.NameSource or type(sourcebyid[joint_source]) is source.IDRefSource): raise DaeIncompleteError("Could not find joint name input for skin") if not type(sourcebyid[joint_matrix_source]) is source.FloatSource: raise DaeIncompleteError("Could not find joint matrix source for skin") joint_names = [j for j in sourcebyid[joint_source]] joint_matrices = sourcebyid[joint_matrix_source].data joint_matrices.shape = (-1,4,4) if len(joint_names) != len(joint_matrices): raise DaeMalformedError("Skin joint and matrix inputs must be same length") self.joint_matrices = {} for n,m in zip(joint_names, joint_matrices): self.joint_matrices[n] = m if not(weight_source in sourcebyid and weight_joint_source in sourcebyid): raise DaeBrokenRefError("Weights input in joints not found") if not type(sourcebyid[weight_source]) is source.FloatSource: raise DaeIncompleteError("Could not find weight inputs for skin") if not(type(sourcebyid[weight_joint_source]) is source.NameSource or type(sourcebyid[weight_joint_source]) is source.IDRefSource): raise DaeIncompleteError("Could not find weight joint source input for skin") self.weights = sourcebyid[weight_source] self.weight_joints = sourcebyid[weight_joint_source] try: newshape = [] at = 0 for ct in self.vcounts: this_set = self.vertex_weight_index[self.nindices*at:self.nindices*(at+ct)] this_set.shape = (ct, self.nindices) newshape.append(numpy.array(this_set)) at+=ct self.index = newshape except: raise DaeMalformedError('Corrupted vcounts or index in skin weights') try: self.joint_index = [influence[:, self.offsets[0]] for influence in self.index] self.weight_index = [influence[:, self.offsets[1]] for influence in self.index] except: raise DaeMalformedError('Corrupted joint or weight index in skin') self.max_joint_index = numpy.max( [numpy.max(joint) if len(joint) > 0 else 0 for joint in self.joint_index] ) self.max_weight_index = numpy.max( [numpy.max(weight) if len(weight) > 0 else 0 for weight in self.weight_index] ) checkSource(self.weight_joints, ('JOINT',), self.max_joint_index) checkSource(self.weights, ('WEIGHT',), self.max_weight_index)
def __init__(self, sources, material, index, xmlnode=None): """A LineSet should not be created manually. Instead, call the :meth:`collada.geometry.Geometry.createLineSet` method after creating a geometry instance. """ if len(sources) == 0: raise DaeIncompleteError('A line set needs at least one input for vertex positions') if not 'VERTEX' in sources: raise DaeIncompleteError('Line set requires vertex input') #find max offset max_offset = max([ max([input[0] for input in input_type_array]) for input_type_array in sources.itervalues() if len(input_type_array) > 0]) self.sources = sources self.material = material self.index = index self.indices = self.index self.nindices = max_offset + 1 self.index.shape = (-1, 2, self.nindices) self.nlines = len(self.index) if len(self.index) > 0: self._vertex = sources['VERTEX'][0][4].data self._vertex_index = self.index[:,:, sources['VERTEX'][0][0]] self.maxvertexindex = numpy.max( self._vertex_index ) checkSource(sources['VERTEX'][0][4], ('X', 'Y', 'Z'), self.maxvertexindex) else: self._vertex = None self._vertex_index = None self.maxvertexindex = -1 if 'NORMAL' in sources and len(sources['NORMAL']) > 0 and len(self.index) > 0: self._normal = sources['NORMAL'][0][4].data self._normal_index = self.index[:,:, sources['NORMAL'][0][0]] self.maxnormalindex = numpy.max( self._normal_index ) checkSource(sources['NORMAL'][0][4], ('X', 'Y', 'Z'), self.maxnormalindex) else: self._normal = None self._normal_index = None self.maxnormalindex = -1 if 'TEXCOORD' in sources and len(sources['TEXCOORD']) > 0 and len(self.index) > 0: self._texcoordset = tuple([texinput[4].data for texinput in sources['TEXCOORD']]) self._texcoord_indexset = tuple([ self.index[:,:, sources['TEXCOORD'][i][0]] for i in xrange(len(sources['TEXCOORD'])) ]) self.maxtexcoordsetindex = [ numpy.max( tex_index ) for tex_index in self._texcoord_indexset ] for i, texinput in enumerate(sources['TEXCOORD']): checkSource(texinput[4], ('S', 'T'), self.maxtexcoordsetindex[i]) else: self._texcoordset = tuple() self._texcoord_indexset = tuple() self.maxtexcoordsetindex = -1 if xmlnode is not None: self.xmlnode = xmlnode """ElementTree representation of the line set.""" else: self.index.shape = (-1) acclen = len(self.index) txtindices = ' '.join(map(str, self.index.tolist())) self.index.shape = (-1, 2, self.nindices) self.xmlnode = E.lines(count=str(self.nlines), material=self.material) all_inputs = [] for semantic_list in self.sources.itervalues(): all_inputs.extend(semantic_list) for offset, semantic, sourceid, set, src in all_inputs: inpnode = E.input(offset=str(offset), semantic=semantic, source=sourceid) if set is not None: inpnode.set('set', str(set)) self.xmlnode.append(inpnode) self.xmlnode.append(E.p(txtindices))
def __init__(self, sources, material, index, xmlnode=None): """Create a triangle set. :Parameters: sources A dict mapping source types to an array of tuples in the form: {input_type: (offset, semantic, sourceid, set, Source)} Example: {'VERTEX': (0, 'VERTEX', '#vertex-inputs', '0', <collada.source.FloatSource>)} material A string with the symbol of the material index An array with the indexes as they come from the collada file xmlnode An xml node in case this is loaded from there """ if len(sources) == 0: raise DaeIncompleteError('A triangle set needs at least one input for vertex positions') if not 'VERTEX' in sources: raise DaeIncompleteError('Triangle set requires vertex input') #find max offset max_offset = max([ max([input[0] for input in input_type_array]) for input_type_array in sources.itervalues() if len(input_type_array) > 0]) self.material = material self.index = index self.indices = self.index self.nindices = max_offset + 1 self.index.shape = (-1, 3, self.nindices) self.ntriangles = len(self.index) self._vertex = sources['VERTEX'][0][4].data self._vertex_index = self.index[:,:, sources['VERTEX'][0][0]] self.maxvertexindex = numpy.max( self._vertex_index ) checkSource(sources['VERTEX'][0][4], ('X', 'Y', 'Z'), self.maxvertexindex) if 'NORMAL' in sources and len(sources['NORMAL']) > 0: self._normal = sources['NORMAL'][0][4].data self._normal_index = self.index[:,:, sources['NORMAL'][0][0]] self.maxnormalindex = numpy.max( self._normal_index ) checkSource(sources['NORMAL'][0][4], ('X', 'Y', 'Z'), self.maxnormalindex) else: self._normal = None self._normal_index = None self.maxnormalindex = -1 if 'TEXCOORD' in sources and len(sources['TEXCOORD']) > 0: self._texcoordset = tuple([texinput[4].data for texinput in sources['TEXCOORD']]) self._texcoord_indexset = tuple([ self.index[:,:, sources['TEXCOORD'][i][0]] for i in xrange(len(sources['TEXCOORD'])) ]) self.maxtexcoordsetindex = [ numpy.max( tex_index ) for tex_index in self._texcoord_indexset ] for i, texinput in enumerate(sources['TEXCOORD']): checkSource(texinput[4], ('S', 'T'), self.maxtexcoordsetindex[i]) else: self._texcoordset = tuple() self._texcoord_indexset = tuple() self.maxtexcoordsetindex = -1 if xmlnode is not None: self.xmlnode = xmlnode else: self.xmlnode = ElementTree.fromstring("<triangles> <p></p> </triangles>")
def set_normal_source(self, c): try: self._normal = checkSource(self.sourceById[c], ('X', 'Y', 'Z'), self.maxnormalindex).data except KeyError, ex: raise DaeBrokenRefError('Setting missing normal source in triangle set') self._normal_source = c
def set_vertex_source(self, c): try: self._vertex = checkSource(self.sourceById[c], ('X', 'Y', 'Z'), self.maxvertexindex).data except KeyError, ex: raise DaeBrokenRefError('Setting missing vertex source in triangle set') self._vertex_source = c
def __init__(self, sources, material, index, vcounts, xmlnode=None): """Create a polygon list. :Parameters: sources A dict mapping source types to an array of tuples in the form: {input_type: (offset, semantic, sourceid, set, Source)} Example: {'VERTEX': (0, 'VERTEX', '#vertex-inputs', '0', <collada.source.FloatSource>)} material A string with the symbol of the material index An array with the indexes as they come from the collada file vcounts A list with the lengths of each individual polygon xmlnode An xml node in case this is loaded from there """ if len(sources) == 0: raise DaeIncompleteError('A polylist set needs at least one input for vertex positions') if not 'VERTEX' in sources: raise DaeIncompleteError('Polylist requires vertex input') #find max offset max_offset = max([ max([input[0] for input in input_type_array]) for input_type_array in sources.itervalues() if len(input_type_array) > 0]) self.material = material self.index = index self.indices = self.index self.nindices = max_offset + 1 self.vcounts = vcounts self.nvertices = 0 try: newshape = [] at = 0 for ct in self.vcounts: thispoly = self.index[self.nindices*at:self.nindices*(at+ct)] thispoly.shape = (ct, self.nindices) self.nvertices += ct newshape.append(numpy.array(thispoly)) at+=ct self.index = newshape except: raise DaeMalformedError('Corrupted vcounts or index in polylist') self.npolygons = len(self.index) self._vertex = sources['VERTEX'][0][4].data self._vertex_index = [poly[:,sources['VERTEX'][0][0]] for poly in self.index] self.maxvertexindex = numpy.max( [numpy.max(poly) for poly in self._vertex_index] ) checkSource(sources['VERTEX'][0][4], ('X', 'Y', 'Z'), self.maxvertexindex) if 'NORMAL' in sources and len(sources['NORMAL']) > 0: self._normal = sources['NORMAL'][0][4].data self._normal_index = [poly[:,sources['NORMAL'][0][0]] for poly in self.index] self.maxnormalindex = numpy.max( [numpy.max(poly) for poly in self._normal_index] ) checkSource(sources['NORMAL'][0][4], ('X', 'Y', 'Z'), self.maxnormalindex) else: self._normal = None self._normal_index = None self.maxnormalindex = -1 if 'TEXCOORD' in sources and len(sources['TEXCOORD']) > 0: self._texcoordset = tuple([texinput[4].data for texinput in sources['TEXCOORD']]) self._texcoord_indexset = tuple([ [poly[:,sources['TEXCOORD'][i][0]] for poly in self.index] for i in xrange(len(sources['TEXCOORD'])) ]) self.maxtexcoordsetindex = [ numpy.max([ numpy.max([p for p in poly]) for poly in each ]) for each in self._texcoord_indexset ] for i, texinput in enumerate(sources['TEXCOORD']): checkSource(texinput[4], ('S', 'T'), self.maxtexcoordsetindex[i]) else: self._texcoordset = tuple() self._texcoord_indexset = tuple() self.maxtexcoordsetindex = -1 if xmlnode is not None: self.xmlnode = xmlnode else: self.xmlnode = ElementTree.fromstring("<polylist> <vcount></vcount> <p></p> </polylist>")
def __init__(self, sources, material, index, xmlnode=None): """A TriangleSet should not be created manually. Instead, call the :meth:`collada.geometry.Geometry.createTriangleSet` method after creating a geometry instance. """ if len(sources) == 0: raise DaeIncompleteError('A triangle set needs at least one input for vertex positions') if not 'VERTEX' in sources: raise DaeIncompleteError('Triangle set requires vertex input') max_offset = max([ max([input[0] for input in input_type_array]) for input_type_array in sources.itervalues() if len(input_type_array) > 0]) self.material = material self.index = index self.indices = self.index self.nindices = max_offset + 1 self.index.shape = (-1, 3, self.nindices) self.ntriangles = len(self.index) self.sources = sources if len(self.index) > 0: self._vertex = sources['VERTEX'][0][4].data self._vertex_index = self.index[:,:, sources['VERTEX'][0][0]] self.maxvertexindex = numpy.max( self._vertex_index ) checkSource(sources['VERTEX'][0][4], ('X', 'Y', 'Z'), self.maxvertexindex) else: self._vertex = None self._vertex_index = None self.maxvertexindex = -1 if 'NORMAL' in sources and len(sources['NORMAL']) > 0 and len(self.index) > 0: self._normal = sources['NORMAL'][0][4].data self._normal_index = self.index[:,:, sources['NORMAL'][0][0]] self.maxnormalindex = numpy.max( self._normal_index ) checkSource(sources['NORMAL'][0][4], ('X', 'Y', 'Z'), self.maxnormalindex) else: self._normal = None self._normal_index = None self.maxnormalindex = -1 if 'TEXCOORD' in sources and len(sources['TEXCOORD']) > 0 and len(self.index) > 0: self._texcoordset = tuple([texinput[4].data for texinput in sources['TEXCOORD']]) self._texcoord_indexset = tuple([ self.index[:,:, sources['TEXCOORD'][i][0]] for i in xrange(len(sources['TEXCOORD'])) ]) self.maxtexcoordsetindex = [ numpy.max( tex_index ) for tex_index in self._texcoord_indexset ] for i, texinput in enumerate(sources['TEXCOORD']): checkSource(texinput[4], ('S', 'T'), self.maxtexcoordsetindex[i]) else: self._texcoordset = tuple() self._texcoord_indexset = tuple() self.maxtexcoordsetindex = -1 if 'TEXTANGENT' in sources and len(sources['TEXTANGENT']) > 0 and len(self.index) > 0: self._textangentset = tuple([texinput[4].data for texinput in sources['TEXTANGENT']]) self._textangent_indexset = tuple([ self.index[:,:, sources['TEXTANGENT'][i][0]] for i in xrange(len(sources['TEXTANGENT'])) ]) self.maxtextangentsetindex = [ numpy.max( tex_index ) for tex_index in self._textangent_indexset ] for i, texinput in enumerate(sources['TEXTANGENT']): checkSource(texinput[4], ('X', 'Y', 'Z'), self.maxtextangentsetindex[i]) else: self._textangentset = tuple() self._textangent_indexset = tuple() self.maxtextangentsetindex = -1 if 'TEXBINORMAL' in sources and len(sources['TEXBINORMAL']) > 0 and len(self.index) > 0: self._texbinormalset = tuple([texinput[4].data for texinput in sources['TEXBINORMAL']]) self._texbinormal_indexset = tuple([ self.index[:,:, sources['TEXBINORMAL'][i][0]] for i in xrange(len(sources['TEXBINORMAL'])) ]) self.maxtexbinormalsetindex = [ numpy.max( tex_index ) for tex_index in self._texbinormal_indexset ] for i, texinput in enumerate(sources['TEXBINORMAL']): checkSource(texinput[4], ('X', 'Y', 'Z'), self.maxtexbinormalsetindex[i]) else: self._texbinormalset = tuple() self._texbinormal_indexset = tuple() self.maxtexbinormalsetindex = -1 if xmlnode is not None: self.xmlnode = xmlnode else: self._recreateXmlNode()