示例#1
0
def get_keyframes(armature):
    '''Get each bone location and rotation for each frame.'''
    location_list = []
    rotation_list = []

    for frame in range(bpy.context.scene.frame_start,
                       bpy.context.scene.frame_end + 1):
        bpy.context.scene.frame_set(frame)

        locations = {}
        rotations = {}

        for bone in armature.pose.bones:
            bone_matrix = transform_animation_matrix(bone.matrix)
            if bone.parent and bone.parent.parent:
                parent_matrix = transform_animation_matrix(bone.parent.matrix)
                bone_matrix = parent_matrix.inverted() * bone_matrix
            elif not bone.parent:
                bone_matrix = Matrix()

            loc, rot, scl = bone_matrix.decompose()

            locations[bone.name] = loc
            rotations[bone.name] = rot.to_euler()

        location_list.append(locations.copy())
        rotation_list.append(rotations.copy())

        del locations
        del rotations

    bcPrint("Keyframes have been appended to lists.")

    return location_list, rotation_list
示例#2
0
def generate_mtl_files(_config, materials=None):
    print()
    if materials is None:
        materials = get_materials(_config.export_selected_nodes)

    for node in get_material_groups(materials):
        _doc = Document()
        parent_material = _doc.createElement('Material')
        parent_material.setAttribute("MtlFlags", "524544")
        parent_material.setAttribute("vertModifType", "0")
        sub_material = _doc.createElement('SubMaterials')
        parent_material.appendChild(sub_material)
        set_public_params(_doc, None, parent_material)

        for material, material_name in materials.items():
            if material_name.split('__')[0] != node:
                continue

            material_node = _doc.createElement('Material')

            set_material_attributes(material, material_name, material_node)
            add_textures(_doc, material, material_node, _config)
            set_public_params(_doc, material, material_node)

            sub_material.appendChild(material_node)

        _doc.appendChild(parent_material)

        filename = "{!s}.mtl".format(node)
        filepath = os.path.join(os.path.dirname(_config.filepath), filename)
        utils.generate_xml(filepath, _doc, True, 1)
        utils.clear_xml_header(filepath)

        bcPrint("'{}' material file has been generated.".format(filename))
示例#3
0
    def __remove_tmp_files(self):
        for tmp_image in self.__tmp_images:
            try:
                bcPrint("Removing tmp image: {!r}".format(tmp_image), 'debug')
                os.remove(tmp_image)
            except FileNotFoundError:
                pass

        os.removedirs(self.__tmp_dir)
        self.__tmp_images.clear()
示例#4
0
def fix_weights():
    for object_ in get_type("skins"):
        override = get_3d_context(object_)
        try:
            bpy.ops.object.vertex_group_normalize_all(override,
                                                      lock_active=False)
        except:
            raise exceptions.BCryException(
                "Please fix weightless vertices first.")
    bcPrint("Weights Corrected.")
示例#5
0
    def _process_bone_weights(self, object_, armature, skin_node):

        bones = utils.get_bones(armature)
        group_weights = []
        vw = ""
        vertex_groups_lengths = ""
        vertex_count = 0
        bone_list = {}

        for bone_id, bone in enumerate(bones):
            bone_list[bone.name] = bone_id

        for vertex in object_.data.vertices:
            vertex_group_count = 0
            for group in vertex.groups:
                group_name = object_.vertex_groups[group.group].name
                if (group.weight == 0 or
                        group_name not in bone_list):
                    continue
                if vertex_group_count == 8:
                    bcPrint("Too many bone references in {}:{} vertex group"
                            .format(object_.name, group_name))
                    continue
                group_weights.append(group.weight)
                vw = "{}{} {} ".format(vw, bone_list[group_name], vertex_count)
                vertex_count += 1
                vertex_group_count += 1

            vertex_groups_lengths = "{}{} ".format(vertex_groups_lengths,
                                                   vertex_group_count)

        id_ = "{!s}_{!s}-weights".format(armature.name, object_.name)
        source = utils.write_source(id_, "float", group_weights, [])
        skin_node.appendChild(source)

        vertex_weights = self._doc.createElement("vertex_weights")
        vertex_weights.setAttribute("count", str(len(object_.data.vertices)))

        id_ = "{!s}_{!s}".format(armature.name, object_.name)
        input = utils.write_input(id_, 0, "joints", "JOINT")
        vertex_weights.appendChild(input)
        input = utils.write_input(id_, 1, "weights", "WEIGHT")
        vertex_weights.appendChild(input)

        vcount = self._doc.createElement("vcount")
        vcount_text = self._doc.createTextNode(vertex_groups_lengths)
        vcount.appendChild(vcount_text)
        vertex_weights.appendChild(vcount)

        v = self._doc.createElement("v")
        v_text = self._doc.createTextNode(vw)
        v.appendChild(v_text)
        vertex_weights.appendChild(v)

        skin_node.appendChild(vertex_weights)
示例#6
0
def set_keyframes(armature, location_list, rotation_list):
    '''Insert each keyframe from lists.'''

    bpy.context.scene.frame_set(bpy.context.scene.frame_start)

    for frame in range(bpy.context.scene.frame_start,
                       bpy.context.scene.frame_end + 1):
        set_keyframe(armature, frame, location_list, rotation_list)

    bpy.context.scene.frame_set(bpy.context.scene.frame_start)
    bcPrint("Keyframes have been inserted to armature fakebones.")
示例#7
0
def apply_modifiers(just_selected=False):
    print()
    for node in get_export_nodes(just_selected):
        for object_ in node.objects:
            bpy.context.scene.objects.active = object_
            for modifier in object_.modifiers:
                if modifier.type == 'ARMATURE':
                    continue
                mod_name = modifier.name
                bpy.ops.object.modifier_apply(apply_as='DATA',
                                              modifier=mod_name)

        bcPrint("Modifiers are applied for {} node.".format(node.name))
示例#8
0
    def __load(self, current_configuration):
        new_configuration = {}
        new_configuration.update(self.__DEFAULT_CONFIGURATION)
        new_configuration.update(current_configuration)

        if os.path.isfile(self.__CONFIG_FILEPATH):
            try:
                with open(self.__CONFIG_FILEPATH, 'rb') as f:
                    new_configuration.update(pickle.load(f))
                    bcPrint('Configuration file loaded.')
            except:
                bcPrint("[IO] can not read: {}".format(self.__CONFIG_FILEPATH),
                        'error')

        return new_configuration
示例#9
0
    def _write_uvs(self, object_, bmesh_, mesh_node, geometry_name):
        uv_layer = bmesh_.loops.layers.uv.active
        if object_.data.uv_layers.active is None:
            bcPrint(
                "{} object has no a UV map, creating a default UV...".format(
                    object_.name))
            uv_layer = bmesh_.loops.layers.uv.new()

        float_uvs = []

        for face in bmesh_.faces:
            for loop in face.loops:
                float_uvs.extend(loop[uv_layer].uv)

        id_ = "{!s}-uvs".format(geometry_name)
        source = utils.write_source(id_, "float", float_uvs, "ST")
        mesh_node.appendChild(source)
示例#10
0
    def _create_physic_proxy_for_bone(self, object_, bone):
        extra = None
        try:
            bonePhys = object_.pose.bones[bone.name]['phys_proxy']
            bcPrint(bone.name + " physic proxy is " + bonePhys)

            extra = self._doc.createElement("extra")
            techcry = self._doc.createElement("technique")
            techcry.setAttribute("profile", "CryEngine")
            prop2 = self._doc.createElement("properties")

            cryprops = self._doc.createTextNode(bonePhys)
            prop2.appendChild(cryprops)
            techcry.appendChild(prop2)
            extra.appendChild(techcry)
        except:
            pass

        return extra
示例#11
0
    def save(self):
        bcPrint("Saving configuration file.", 'debug')

        if os.path.isdir(self.__CONFIG_PATH):
            try:
                with open(self.__CONFIG_FILEPATH, 'wb') as f:
                    pickle.dump(self.__CONFIG, f, -1)
                    bcPrint("Configuration file saved.")

                bcPrint('Saved {}'.format(self.__CONFIG_FILEPATH))

            except:
                bcPrint(
                    "[IO] can not write: {}".format(self.__CONFIG_FILEPATH),
                    'error')

        else:
            bcPrint(
                "Configuration file path is missing {}".format(
                    self.__CONFIG_PATH), 'error')
示例#12
0
def trim_path_to(path, trim_to):
    path_normalized = normalize_path(path)
    components = path_normalized.split("/")
    for index, component in enumerate(components):
        if component == trim_to:
            bcPrint("FOUND AN INSTANCE")
            break
    bcPrint(index)
    components_trimmed = components[index:]
    bcPrint(components_trimmed)
    path_trimmed = build_path(*components_trimmed)
    bcPrint(path_trimmed)
    return path_trimmed
示例#13
0
    def __call__(self):
        for image in self.__images_to_convert:
            rc_params = self.__get_rc_params(image.filepath)
            tiff_image_path = self.__get_temp_tiff_image_path(image)

            tiff_image_for_rc = utils.get_absolute_path_for_rc(tiff_image_path)
            bcPrint(tiff_image_for_rc)

            try:
                self.__create_normal_texture()
            except:
                bcPrint("Failed to invert green channel")

            rc_process = run_rc(self.__config.texture_rc_path,
                                tiff_image_for_rc,
                                rc_params)

            # re-save the original image after running the RC to
            # prevent the original one from getting lost
            try:
                if ("_ddn" in image.name):
                    image.save()
            except:
                bcPrint("Failed to invert green channel")

            rc_process.wait()

        if self.__config.texture_rc_path:
            self.__save_tiffs()

        self.__remove_tmp_files()
示例#14
0
    def __get_temp_tiff_image_path(self, image):
        # check if the image already is a .tif
        image_extension = utils.get_extension_from_path(image.filepath)
        bcPrint(image_extension)

        if ".tif" == image_extension:
            bcPrint(
                "Image {!r} is already a tif, not converting".format(
                    image.name), 'debug')
            return image.filepath

        tiff_image_path = utils.get_path_with_new_extension(image.filepath,
                                                            "tif")
        tiff_image_absolute_path = utils.get_absolute_path(tiff_image_path)
        tiff_file_name = os.path.basename(tiff_image_path)

        tmp_file_path = os.path.join(self.__tmp_dir, tiff_file_name)

        if tiff_image_path != image.filepath:
            self.__save_as_tiff(image, tmp_file_path)
            self.__tmp_images[tmp_file_path] = (tiff_image_absolute_path)

        return tmp_file_path
示例#15
0
def add_textures(_doc, material, material_node, _config):
    textures_node = _doc.createElement("Textures")

    diffuse = get_diffuse_texture(material)
    specular = get_specular_texture(material)
    normal = get_normal_texture(material)

    if diffuse:
        texture_node = _doc.createElement('Texture')
        texture_node.setAttribute("Map", "Diffuse")
        path = get_image_path_for_game(diffuse, _config.game_dir)
        texture_node.setAttribute("File", path)
        textures_node.appendChild(texture_node)
        bcPrint("Diffuse Path: {}.".format(path))
    else:
        if "physProxyNoDraw" != get_material_physic(material.name):
            texture_node = _doc.createElement('Texture')
            texture_node.setAttribute("Map", "Diffuse")
            path = "textures/defaults/white.dds"
            texture_node.setAttribute("File", path)
            textures_node.appendChild(texture_node)
            bcPrint("Diffuse Path: {}.".format(path))
    if specular:
        texture_node = _doc.createElement('Texture')
        texture_node.setAttribute("Map", "Specular")
        path = get_image_path_for_game(specular, _config.game_dir)
        texture_node.setAttribute("File", path)
        textures_node.appendChild(texture_node)
        bcPrint("Specular Path: {}.".format(path))
    if normal:
        texture_node = _doc.createElement('Texture')
        texture_node.setAttribute("Map", "Normal")
        path = get_image_path_for_game(normal, _config.game_dir)
        texture_node.setAttribute("File", path)
        textures_node.appendChild(texture_node)
        bcPrint("Normal Path: {}.".format(path))

    if _config.convert_textures:
        convert_image_to_dds([diffuse, specular, normal], _config)

    material_node.appendChild(textures_node)
示例#16
0
def run_rc(rc_path, files_to_process, params=None):
    bcPrint("RC Path: {}".format(os.path.abspath(rc_path)), newline=True)
    process_params = [rc_path]

    if isinstance(files_to_process, list):
        process_params.extend(files_to_process)
    else:
        process_params.append(files_to_process)

    process_params.extend(params)

    bcPrint("RC Parameters: {}".format(params))
    bcPrint("Processing File: {}".format(files_to_process))

    try:
        run_object = subprocess.Popen(process_params)
    except:
        raise exceptions.NoRcSelectedException

    print()
    return run_object
示例#17
0
def apply_animation_scale(armature):
    '''Apply Animation Scale.'''
    scene = bpy.context.scene
    remove_unused_meshes()

    if armature is None or armature.type != "ARMATURE":
        return

    skeleton = armature.data
    empties = []

    deselect_all()
    scene.frame_set(scene.frame_start)
    for pose_bone in armature.pose.bones:
        bmatrix = pose_bone.bone.head_local
        bpy.ops.object.empty_add(type='PLAIN_AXES', radius=0.1)
        empty = bpy.context.active_object
        empty.name = pose_bone.name

        bpy.ops.object.constraint_add(type='CHILD_OF')
        bpy.data.objects[
            empty.name].constraints['Child Of'].use_scale_x = False
        bpy.data.objects[
            empty.name].constraints['Child Of'].use_scale_y = False
        bpy.data.objects[
            empty.name].constraints['Child Of'].use_scale_z = False

        bpy.data.objects[empty.name].constraints['Child Of'].target = armature
        bpy.data.objects[
            empty.name].constraints['Child Of'].subtarget = pose_bone.name

        bcPrint("Baking animation on " + empty.name + "...")
        bpy.ops.nla.bake(frame_start=scene.frame_start,
                         frame_end=scene.frame_end,
                         step=1,
                         only_selected=True,
                         visual_keying=True,
                         clear_constraints=True,
                         clear_parents=False,
                         bake_types={'OBJECT'})

        empties.append(empty)

    for empty in empties:
        empty.select = True

    bcPrint("Baked Animation successfully on empties.")
    deselect_all()

    set_active(armature)
    armature.select = True
    bpy.ops.anim.keyframe_clear_v3d()

    bpy.ops.object.transform_apply(rotation=True, scale=True)

    bpy.ops.object.mode_set(mode='POSE')
    bpy.ops.pose.user_transforms_clear()

    for pose_bone in armature.pose.bones:
        pose_bone.constraints.new(type='COPY_LOCATION')
        pose_bone.constraints.new(type='COPY_ROTATION')

        for empty in empties:
            if empty.name == pose_bone.name:
                pose_bone.constraints['Copy Location'].target = empty
                pose_bone.constraints['Copy Rotation'].target = empty
                break

        pose_bone.bone.select = True

    bcPrint("Baking Animation on skeleton...")
    bpy.ops.nla.bake(frame_start=scene.frame_start,
                     frame_end=scene.frame_end,
                     step=1,
                     only_selected=True,
                     visual_keying=True,
                     clear_constraints=True,
                     clear_parents=False,
                     bake_types={'POSE'})

    bpy.ops.object.mode_set(mode='OBJECT')

    deselect_all()

    bcPrint("Clearing empty data...")
    for empty in empties:
        empty.select = True

    bpy.ops.object.delete()

    bcPrint("Apply Animation was completed.")
示例#18
0
    def _export_library_geometries(self, parent_element):
        libgeo = self._doc.createElement("library_geometries")
        parent_element.appendChild(libgeo)
        for group in utils.get_mesh_export_nodes(
                self._config.export_selected_nodes):
            for object_ in group.objects:
                if object_.type != 'MESH':
                    continue

                bmesh_, layer_state, scene_layer = utils.get_bmesh(object_)
                geometry_node = self._doc.createElement("geometry")
                geometry_name = utils.get_geometry_name(group, object_)
                geometry_node.setAttribute("id", geometry_name)
                mesh_node = self._doc.createElement("mesh")

                print()
                bcPrint('"{}" object is being processed...'.format(
                    object_.name))

                start_time = clock()
                self._write_positions(bmesh_, mesh_node, geometry_name)
                bcPrint('Positions have been writed {:.4f} seconds.'.format(
                    clock() - start_time))

                start_time = clock()
                self._write_normals(object_, bmesh_, mesh_node, geometry_name)
                bcPrint('Normals have been writed {:.4f} seconds.'.format(
                    clock() - start_time))

                start_time = clock()
                self._write_uvs(object_, bmesh_, mesh_node, geometry_name)
                bcPrint(
                    'UVs have been writed {:.4f} seconds.'.format(clock() -
                                                                  start_time))

                start_time = clock()
                self._write_vertex_colors(object_, bmesh_, mesh_node,
                                          geometry_name)
                bcPrint(
                    'Vertex colors have been writed {:.4f} seconds.'.format(
                        clock() - start_time))

                start_time = clock()
                self._write_vertices(mesh_node, geometry_name)
                bcPrint('Vertices have been writed {:.4f} seconds.'.format(
                    clock() - start_time))

                start_time = clock()
                self._write_triangle_list(object_, bmesh_, mesh_node,
                                          geometry_name)
                bcPrint(
                    'Triangle list have been writed {:.4f} seconds.'.format(
                        clock() - start_time))

                extra = self._create_double_sided_extra("MAYA")
                mesh_node.appendChild(extra)
                geometry_node.appendChild(mesh_node)
                libgeo.appendChild(geometry_node)

                utils.clear_bmesh(object_, layer_state, scene_layer)
                bcPrint('"{}" object has been processed for "{}" node.'.format(
                    object_.name, group.name))
示例#19
0
    def export(self):
        self._prepare_for_export()

        root_element = self._doc.createElement('collada')
        root_element.setAttribute(
            "xmlns", "http://www.collada.org/2005/11/COLLADASchema")
        root_element.setAttribute("version", "1.4.1")
        self._doc.appendChild(root_element)
        self._create_file_header(root_element)

        libanmcl = self._doc.createElement("library_animation_clips")
        libanm = self._doc.createElement("library_animations")
        root_element.appendChild(libanmcl)
        root_element.appendChild(libanm)

        lib_visual_scene = self._doc.createElement("library_visual_scenes")
        visual_scene = self._doc.createElement("visual_scene")
        visual_scene.setAttribute("id", "scene")
        visual_scene.setAttribute("name", "scene")
        lib_visual_scene.appendChild(visual_scene)
        root_element.appendChild(lib_visual_scene)

        initial_frame_active = bpy.context.scene.frame_current
        initial_frame_start = bpy.context.scene.frame_start
        initial_frame_end = bpy.context.scene.frame_end

        ALLOWED_NODE_TYPES = ("i_caf", "anm")
        for group in utils.get_animation_export_nodes():

            node_type = utils.get_node_type(group)
            node_name = utils.get_node_name(group)

            if node_type in ALLOWED_NODE_TYPES:
                object_ = None
                layers = None

                if node_type == 'i_caf':
                    object_ = utils.get_armature_from_node(group)
                    layers = utils.activate_all_bone_layers(object_)
                elif node_type == 'anm':
                    object_ = group.objects[0]

                frame_start, frame_end = utils.get_animation_node_range(
                    object_, node_name, initial_frame_start, initial_frame_end)
                bpy.context.scene.frame_start = frame_start
                bpy.context.scene.frame_end = frame_end

                print('')
                bcPrint(group.name)
                bcPrint("Animation is being preparing to process.")
                bcPrint("Animation frame range are [{} - {}]".format(
                    frame_start, frame_end))

                if node_type == 'i_caf':
                    utils.add_fakebones(group)
                try:
                    self._export_library_animation_clips_and_animations(
                        libanmcl, libanm, group)
                    self._export_library_visual_scenes(visual_scene, group)
                except RuntimeError:
                    pass
                finally:
                    if node_type == 'i_caf':
                        utils.remove_fakebones()
                        utils.recover_bone_layers(object_, layers)

                    bcPrint("Animation has been processed.")

        bpy.context.scene.frame_current = initial_frame_active
        bpy.context.scene.frame_start = initial_frame_start
        bpy.context.scene.frame_end = initial_frame_end
        print('')

        self._export_scene(root_element)

        converter = RCInstance(self._config)
        converter.convert_dae(self._doc)
示例#20
0
def write_material_information(material_name):
    parts = material_name.split('__')
    bcPrint("Subname: '{}'  -  Index: '{}'  -  Physic Type: '{}'".format(
        parts[2], parts[1], parts[3]))
示例#21
0
 def __save_tiffs(self):
     for tmp_image, dest_image in self.__tmp_images.items():
         bcPrint("Moving tmp image: {!r} to {!r}".format(tmp_image,
                                                         dest_image),
                 'debug')
         shutil.move(tmp_image, dest_image)