def save_obj(self): s = '# Wavefront OBJ exported with ABMATT v1.2.0\n\nmtllib ' + self.mtllib + '\n\n' vertex_index = 1 normal_index = 1 normal_offset = -1 texcoord_index = 1 smooth = False for geometry in self.geometries: s += '#\n# object ' + geometry.name + '\n#\n\n' vertex_count = len(geometry.vertices) for vert in geometry.vertices: s += 'v ' + ' '.join(float_to_str(x) for x in vert) + '\n' s += '# {} vertices\n\n'.format(vertex_count) if geometry.normals: normal_count = len(geometry.normals) for normal in geometry.normals: s += 'vn ' + ' '.join(float_to_str(x) for x in normal) + '\n' s += '# {} normals\n\n'.format(normal_count) else: normal_count = 0 if geometry.texcoords: texcoord_count = len(geometry.texcoords) for texcoord in geometry.texcoords: s += 'vt ' + ' '.join(float_to_str(x) for x in texcoord) + '\n' s += '# {} texture coordinates\n\n'.format(texcoord_count) texcoord_offset = 1 else: texcoord_offset = -1 # now adjust the tri indices tris = np.copy(geometry.triangles) tris[:, :, 0] = tris[:, :, 0] + vertex_index if texcoord_offset > 0: tris[:, :, texcoord_offset] = tris[:, :, texcoord_offset] + texcoord_index if normal_count: tris[:, :, normal_offset] = tris[:, :, normal_offset] + normal_index # start the group of indices s += 'o {}\ng {}\n'.format(geometry.name, geometry.name) s += 'usemtl {}\n'.format(geometry.material_name) if geometry.smooth != smooth: s += 's off\n' if not geometry.smooth else 's\n' smooth = geometry.smooth joiner = '/' if geometry.texcoords else '//' for tri in tris: s += 'f ' + ' '.join( [joiner.join([str(x) for x in fp]) for fp in tri]) + '\n' s += '# {} triangles\n\n'.format(len(tris)) # now increase the indices vertex_index += vertex_count normal_index += normal_count if geometry.texcoords: texcoord_index += texcoord_count with open(self.filename, 'w') as f: f.write(s)
def __get_default_shader_color(name, iterable=(0.0, 0.0, 0.0, 1.0)): shader_color = XMLNode(name) text = ' '.join([float_to_str(x) for x in iterable]) color = XMLNode('color', text) color.attrib['sid'] = name shader_color.append(color) return shader_color
def add_node(self, node, parent=None): if parent is None: parent = self.scene xml_node = XMLNode('node', id=node.name, name=node.name, parent=parent) if node.attrib: att = node.attrib for key in att: xml_node.attrib[key] = att[key] xml_node.attrib['sid'] = node.name if node.matrix is not None: matrix_xml = XMLNode( 'matrix', ' '.join([float_to_str(x) for x in node.matrix.flatten()]), parent=xml_node) matrix_xml.attrib['sid'] = 'matrix' if node.extra is not None: xml_node.append(node.extra) if node.controller is not None: controller_node = XMLNode('instance_controller', parent=xml_node) controller_node.attrib['url'] = '#' + get_id( self.add_skin_controller(node.controller)) self.__bind_material(controller_node, node.controller.geometry.material_name) elif node.geometries: for geometry in node.geometries: geometry_node = XMLNode('instance_geometry', parent=xml_node) geometry_node.attrib['url'] = '#' + get_id( self.add_geometry(geometry)) self.__bind_material(geometry_node, geometry.material_name) for n in node.nodes: self.add_node(n, xml_node) return xml_node
def get_save_str(self): s = 'newmtl ' + self.name + '\n\tNs ' + str(self.specular_highlight) + \ '\n\tNi ' + str(self.optical_density) + '\n\td ' + str(self.dissolve) + \ '\n\tTr ' + str(1 - self.dissolve) + '\n\tillum ' + str(self.illumination) +\ '\n\tKa ' + ' '.join([float_to_str(x) for x in self.ambient_color]) + \ '\n\tKd ' + ' '.join([float_to_str(x) for x in self.diffuse_color]) + \ '\n\tKs ' + ' '.join([float_to_str(x) for x in self.specular_color]) if self.ambient_map: s += '\n\tmap_Ka ' + self.ambient_map if self.diffuse_map: s += '\n\tmap_Kd ' + self.diffuse_map if self.specular_map: s += '\n\tmap_Ks ' + self.specular_map if self.specular_highlight_map: s += '\n\tmap_Ns ' + self.specular_highlight_map if self.alpha_map: s += '\n\tmap_d ' + self.alpha_map return s + '\n'
def add_skin_controller(self, controller): controller_id = controller.name + '-controller' xml_controller = XMLNode('controller', id=controller_id, parent=self.controllers) xml_skin = XMLNode('skin', parent=xml_controller) xml_skin.attrib['source'] = '#' + get_id(self.add_geometry(controller.geometry)) bind_shape_matrix = XMLNode('bind_shape_matrix', ' '.join([float_to_str(x) for \ x in controller.bind_shape_matrix.flatten()]), parent=xml_skin) joint_source_id = controller_id + '-joints' joint_source = XMLNode('source', id=joint_source_id, parent=xml_skin) name_array_id = joint_source_id + '-array' name_array = XMLNode('Name_array', ' '.join(controller.bones), id=name_array_id, parent=joint_source) bone_len = len(controller.bones) name_array.attrib['count'] = str(bone_len) self.__create_technique_common(name_array_id, bone_len, 'name', joint_source) matrices_source_id = controller_id + '-matrices' matrices_source = XMLNode('source', id=matrices_source_id, parent=xml_skin) matrices_array_id = matrices_source_id + '-array' inv_bind_matrix = controller.inv_bind_matrix.flatten() float_array = XMLNode('float_array', ' '.join([float_to_str(x) for x in inv_bind_matrix]), id=matrices_array_id, parent=matrices_source) float_array.attrib['count'] = str(16 * bone_len) self.__create_technique_common(matrices_array_id, bone_len, 'float4x4', matrices_source, 16) weight_source_id = controller_id + '-weights' weight_source = XMLNode('source', id=weight_source_id, parent=xml_skin) float_array_id = weight_source_id + '-array' float_array = XMLNode('float_array', ' '.join([float_to_str(x) for x in controller.weights.flatten()]), id=float_array_id, parent=weight_source) weight_count = len(controller.weights) float_array.attrib['count'] = str(weight_count) # todo, vertex count or total weight? self.__create_technique_common(float_array_id, weight_count, 'float', weight_source) joints = XMLNode('joints', parent=xml_skin) self.__create_input_node('JOINT', joint_source_id, parent=joints) self.__create_input_node('INV_BIND_MATRIX', matrices_source_id, parent=joints) vertex_weights = XMLNode('vertex_weights', parent=xml_skin) vertex_weights.attrib['count'] = str(len(controller.vertex_weight_counts)) self.__create_input_node('JOINT', joint_source_id, 0, vertex_weights) self.__create_input_node('WEIGHT', weight_source_id, 1, vertex_weights) vcount = XMLNode('vcount', ' '.join([str(x) for x in controller.vertex_weight_counts]), parent=vertex_weights) vw_data = XMLNode('v', ' '.join([str(x) for x in controller.vertex_weight_indices.flatten()]), parent=vertex_weights) return xml_controller
def __create_source(name, data_collection, params): source = XMLNode('source', id=name) text = '' for x in data_collection: text += ' '.join([float_to_str(y) for y in x.flatten()]) + ' ' source_array = XMLNode('float_array', text, id=name + '-array', parent=source) technique_common = XMLNode('technique_common', parent=source) accessor = XMLNode('accessor', parent=technique_common) accessor.attrib['source'] = '#' + name + '-array' point_len = len(data_collection) accessor.attrib['count'] = str(point_len) stride = len(data_collection[0]) accessor.attrib['stride'] = str(stride) for letter in params: param = XMLNode('param', name=letter, parent=accessor) param.attrib['type'] = 'float' source_array.attrib['count'] = str(stride * point_len) return source
def __get_default_shader_float(name, fl=0.0): node = XMLNode(name) fl = XMLNode('float', float_to_str(fl), parent=node) fl.attrib['sid'] = name return node