Пример #1
0
def export_fbx(operator, context, objects, name, kwargs):
    """
    Exports objects to fbx, with the given name and parameters,
    under the scene export path\t\t
    :param operator: the operator though which we report messages\t
    :param context: the context to use\t
    :param objects: the list of objects to include in the exported file\t\t
    :param name: the base name of the file to export\t
    :param kwargs: a dict containing any additional parameters\t
    :returns: nothing
    """

    file_name = str(name) + ".fbx"
    file_path = join(str(context.scene.export_path), file_name)
    file_exists = exists(file_path)

    if file_exists and not operator.overwrite:
        operator.report({"ERROR"}, "File exists: " + file_name)
        return

    export_fbx_bin.save_single(operator,
                               context.scene,
                               filepath=file_path,
                               context_objects=objects,
                               **kwargs)
    operator.report({"INFO"},
                    "File " + ("overwritten" if file_exists else "exported") +
                    ": " + file_name)
Пример #2
0
def export_fbx_meshes(filepath, scene, depsgraph):
    # Not sure what the "operator" is supposed to be, but passing a dummy seems to work fine.
    class DummyOp:
        def report(self, *args, **kwargs):
            print(*args)

    save_single(DummyOp(),
                scene,
                depsgraph,
                filepath,
                object_types={"MESH"},
                context_objects=depsgraph.objects,
                use_tspace=False,
                axis_forward='Z',
                axis_up='Y')
Пример #3
0
def do_fbx_export(self, actions):
    context = bpy.context
    forward = 'Y'
    up = 'Z'

    export_fbx_bin.save_single(self,
                               context.scene,
                               self.filepath,
                               context_objects=context.selected_objects,
                               axis_forward=forward,
                               axis_up=up,
                               version='BIN7400',
                               ui_tab='MAIN',
                               use_selection=True,
                               global_scale=0.01,
                               apply_unit_scale=True,
                               bake_space_transform=False,
                               object_types={'MESH', 'ARMATURE'},
                               use_mesh_modifiers=True,
                               mesh_smooth_type='OFF',
                               use_mesh_edges=True,
                               use_tspace=True,
                               use_custom_props=False,
                               add_leaf_bones=False,
                               primary_bone_axis='Y',
                               secondary_bone_axis='X',
                               use_armature_deform_only=False,
                               bake_anim=actions,
                               bake_anim_use_all_bones=actions,
                               bake_anim_use_nla_strips=actions,
                               bake_anim_use_all_actions=actions,
                               bake_anim_force_startend_keying=actions,
                               bake_anim_step=1.0,
                               bake_anim_simplify_factor=0.0,
                               use_anim=actions,
                               use_anim_action_all=actions,
                               use_default_take=actions,
                               use_anim_optimize=actions,
                               anim_optimize_precision=6.0,
                               path_mode='AUTO',
                               embed_textures=False,
                               batch_mode='OFF',
                               use_batch_own_dir=True)
    def execute(self, context):
        if not self.filepath:
            raise Exception("filepath not set")

        # Create save system to save current selection, mode, and active object
        state = SaveState(context)

        # Evaluate selected objects to export
        source_data = evaluate_and_get_source_data(context.selected_objects)

        # If evaluate returns string it means error
        if type(source_data) is str:
            state.load(context)
            self.report({'ERROR'}, source_data)
            return {'CANCELLED'}

        # Get export rig
        if self.remove_unused_bones:
            export_rig_ob = extract_export_rig(context,
                                               source_data.rigify_object,
                                               self.global_scale,
                                               source_data.mesh_objects)
        else:
            export_rig_ob = extract_export_rig(context,
                                               source_data.rigify_object,
                                               self.global_scale)

        # If returns string it means error
        if type(export_rig_ob) is str:
            state.load(context)
            self.report({'ERROR'}, export_rig_ob)
            return {'CANCELLED'}

        # Get export mesh objects
        export_mesh_objs = extract_export_meshes(context, source_data,
                                                 export_rig_ob,
                                                 self.global_scale)

        # Set to object mode
        if context.mode != 'OBJECT':
            bpy.ops.object.mode_set(mode='OBJECT')

        # Select export objects
        export_rig_ob.select = True
        for obj in export_mesh_objs:
            obj.select = True

        # Retarget bone name
        if self.use_humanoid_name:
            retarget_bone_name(export_rig_ob)

        # Set Global Matrix
        forward = '-Y'
        up = 'Z'
        global_matrix = (Matrix.Scale(1.0, 4) * axis_conversion(
            to_forward=forward,
            to_up=up,
        ).to_4x4())

        # EXPORT!
        export_fbx_bin.save_single(self,
                                   context.scene,
                                   self.filepath,
                                   global_matrix=global_matrix,
                                   axis_up=up,
                                   axis_forward=forward,
                                   context_objects=context.selected_objects,
                                   object_types={'ARMATURE', 'MESH'},
                                   use_mesh_modifiers=True,
                                   mesh_smooth_type='EDGE',
                                   use_armature_deform_only=False,
                                   bake_anim=False,
                                   bake_anim_use_all_bones=True,
                                   bake_anim_use_nla_strips=True,
                                   bake_anim_use_all_actions=True,
                                   bake_anim_step=1.0,
                                   bake_anim_simplify_factor=1.0,
                                   add_leaf_bones=False,
                                   primary_bone_axis='Y',
                                   secondary_bone_axis='X',
                                   use_metadata=True,
                                   path_mode='AUTO',
                                   use_mesh_edges=True,
                                   use_tspace=True,
                                   embed_textures=False,
                                   use_custom_props=False,
                                   bake_space_transform=False)

        # Delete exported objects
        bpy.ops.object.delete()

        # Bring back original selection
        state.load(context)

        # Failed export objects
        #if any(source_data.failed_mesh_objects):
        #    obj_names = ''
        #    for i, obj in enumerate(source_data.failed_mesh_objects):
        #        obj_names += obj.name
        #        if i != len(source_data.failed_mesh_objects) - 1:
        #            obj_names += ', '
        #
        #    self.report({'INFO'}, "INFO: Cannot export mesh [" + obj_names + "] because of reasons")

        self.report({'INFO'}, "INFO: What does the fox say?")

        return {'FINISHED'}
    def execute(self, context):
        if not self.filepath:
            raise Exception("filepath not set")

        # Create save system to save current selection, mode, and active object
        state = SaveState(context)

        scene = context.scene

        # Active object is source rigify object
        rig_obj = context.object

        # Go to object mode first
        #bpy.ops.object.mode_set(mode='OBJECT')

        # Check action
        action = rig_obj.animation_data.action

        if not action:
            self.report(
                {'ERROR'},
                "FAILED! Please activate an action you want to export.")
            return {'CANCELLED'}

        # Extract export rig from rigify
        if self.remove_unused_bones:
            # If using linked lib
            mesh_objects = []
            if rig_obj.proxy_group:
                for obj in rig_obj.proxy_group.dupli_group.objects:
                    if obj.type == 'MESH':
                        mesh_objects.append(obj)
            else:
                mesh_objects = get_objects_using_rig(rig_obj)
            export_rig_ob = extract_export_rig(context, rig_obj,
                                               self.global_scale, mesh_objects)
        else:
            export_rig_ob = extract_export_rig(context, rig_obj,
                                               self.global_scale)

        # Scale original rig
        rig_obj.scale *= self.global_scale

        # Make constraint
        make_constraint(context, rig_obj, export_rig_ob)

        # Select only export rig
        bpy.ops.object.select_all(action='DESELECT')
        export_rig_ob.select = True
        scene.objects.active = export_rig_ob

        # Set timeframe
        #if self.timeframe == 'SCENE':
        #    start = scene.frame_start
        #    end = scene.frame_end
        #else:
        if self.timeframe != 'SCENE':
            scene.frame_start = action.frame_range[0]
            scene.frame_end = action.frame_range[1]
            if self.timeframe == 'ACTION_MINUS_ONE':
                scene.frame_end -= 1

        # Manual bake action if want to edit root bone
        if self.hip_to_root:
            move_root(scene, export_rig_ob)

        # Retarget bone name
        if self.use_humanoid_name:
            retarget_bone_name(export_rig_ob)

        # Set Global Matrix
        forward = '-Y'
        up = 'Z'
        global_matrix = (Matrix.Scale(1.0, 4) * axis_conversion(
            to_forward=forward,
            to_up=up,
        ).to_4x4())

        # EXPORT!
        export_fbx_bin.save_single(self,
                                   scene,
                                   self.filepath,
                                   global_matrix=global_matrix,
                                   axis_up=up,
                                   axis_forward=forward,
                                   context_objects=context.selected_objects,
                                   object_types={'ARMATURE', 'MESH'},
                                   use_mesh_modifiers=True,
                                   mesh_smooth_type='EDGE',
                                   use_armature_deform_only=False,
                                   bake_anim=True,
                                   bake_anim_use_all_bones=True,
                                   bake_anim_use_nla_strips=False,
                                   bake_anim_use_all_actions=False,
                                   bake_anim_step=1.0,
                                   bake_anim_simplify_factor=0.0,
                                   add_leaf_bones=False,
                                   primary_bone_axis='Y',
                                   secondary_bone_axis='X',
                                   use_metadata=True,
                                   path_mode='AUTO',
                                   use_mesh_edges=True,
                                   use_tspace=True,
                                   embed_textures=False,
                                   use_custom_props=False,
                                   bake_space_transform=False)

        # Delete exported object
        bpy.ops.object.delete()

        # Descale original rig
        rig_obj.scale /= self.global_scale

        # Load original state
        state.load(context)

        return {'FINISHED'}
Пример #6
0
    def execute(self, context):
        if not self.filepath:
            raise Exception("filepath not set")

        # Create save system to save current selection, mode, and active object
        state = SaveState(context)

        # Evaluate selected objects to export
        rig_object, mesh_objects, failed_mesh_objects, error_messages = evaluate_and_get_source_data(
                context.scene, context.selected_objects)

        # If valid mesh isn't found
        #if not mesh_objects:
        if error_messages != '':
            state.load(context)
            self.report({'ERROR'}, error_messages)
            return{'CANCELLED'}

        # Scale of the objects
        rig_props = rig_object.data.ue4h_props
        scale = ABS_SCALE * rig_props.global_scale

        # Check if armature using rigify
        use_rigify = check_use_rigify(rig_object.data)
        #if not use_rigify:
        #    state.load(context)
        #    self.report({'ERROR'}, 'This addon only works with Blender 2.78 Rigify! (More support coming soon!)')
        #    return{'CANCELLED'}

        # Get export rig
        #if self.remove_unused_bones:
        #    export_rig_ob = extract_export_rig(context, rig_object, scale, mesh_objects)
        #else: export_rig_ob = extract_export_rig(context, rig_object, scale)
        export_rig_ob = extract_export_rig(context, rig_object, scale, use_rigify)

        # If returns string it means error
        #if type(export_rig_ob) is str:
        #    state.load(context)
        #    self.report({'ERROR'}, export_rig_ob)
        #    return{'CANCELLED'}

        # Get export mesh objects
        export_mesh_objs = extract_export_meshes(context, mesh_objects, export_rig_ob, scale)

        # Set to object mode
        if context.mode != 'OBJECT':
            bpy.ops.object.mode_set(mode='OBJECT')

        # Select export objects
        export_rig_ob.select = True
        for obj in export_mesh_objs:
            obj.select = True

        # Retarget bone name and vertex groups (RIGIFY ONLY)
        if use_rigify:
            if rig_props.use_humanoid_name:
                convert_to_unreal_humanoid(rig_object, export_rig_ob, scale, export_mesh_objs)

            if rig_props.unparent_ik_bones:
                unparent_ik_related_bones(rig_props.use_humanoid_name, rig_object, export_rig_ob)

        #return {'FINISHED'}

        # Set Global Matrix
        forward = '-Y'
        up = 'Z'
        #global_matrix = (Matrix.Scale(1.0, 4) * axis_conversion(to_forward=forward, to_up=up,).to_4x4()) 
        # Descale global matrix because Unreal always multiply object by 100 points when importing
        global_matrix = (Matrix.Scale(1.0/ABS_SCALE, 4) * axis_conversion(to_forward=forward, to_up=up,).to_4x4()) 

        # EXPORT!
        export_fbx_bin.save_single(self, context.scene, self.filepath,
                global_matrix=global_matrix,
                axis_up=up,
                axis_forward=forward,
                context_objects=context.selected_objects,
                object_types={'ARMATURE', 'MESH'},
                use_mesh_modifiers=True,
                mesh_smooth_type='EDGE',
                use_armature_deform_only=False,
                bake_anim=False,
                bake_anim_use_all_bones=True,
                bake_anim_use_nla_strips=True,
                bake_anim_use_all_actions=True,
                bake_anim_force_startend_keying=True,
                bake_anim_step=1.0,
                bake_anim_simplify_factor=1.0,
                add_leaf_bones=False,
                primary_bone_axis='Y',
                secondary_bone_axis='X',
                use_metadata=True,
                path_mode='AUTO',
                use_mesh_edges=True,
                use_tspace=True,
                embed_textures=False,
                use_custom_props=False,
                bake_space_transform=False
                ) 

        # Delete exported objects
        bpy.ops.object.delete()

        # Bring back original selection
        state.load(context)

        # Failed export objects
        if any(failed_mesh_objects):
            obj_names = ''
            for i, obj in enumerate(failed_mesh_objects):
                obj_names += obj.name
                if i != len(failed_mesh_objects) - 1:
                    obj_names += ', '
            
            self.report({'INFO'}, "INFO: Cannot export mesh [" + obj_names + "] because of reasons")

        #self.report({'INFO'}, "INFO: Export successful!")

        return {'FINISHED'}
Пример #7
0
    def execute(self, context):
        if not self.filepath:
            raise Exception("filepath not set")

        # Create save system to save current selection, mode, and active object
        state = SaveState(context)

        scene = context.scene

        # Active object is source rigify object
        rig_obj = context.object
        rig_props = rig_obj.data.ue4h_props

        # Check if using rigify by checking the widget of root bone
        use_rigify = check_use_rigify(rig_obj.data)
        #if not use_rigify:
        #    state.load(context)
        #    self.report({'ERROR'}, 'This addon only works with Blender 2.78 Rigify! (More support coming soon!)')
        #    return{'CANCELLED'}

        # Check action
        action = rig_obj.animation_data.action
        action_props = action.ue4h_props

        # Scale of the objects
        scale = ABS_SCALE * rig_props.global_scale

        if not action:
            self.report({'ERROR'}, "FAILED! Please activate an action you want to export.")
            return{'CANCELLED'}

        # Extract export rig from rigify
        export_rig_ob = extract_export_rig(context, rig_obj, scale, use_rigify)

        # Scale original rig
        rig_obj.scale *= scale

        # Set timeframe
        if action_props.timeframe != 'SCENE':
            scene.frame_start = action.frame_range[0]
            scene.frame_end = action.frame_range[1]
            if action_props.timeframe == 'ACTION_MINUS_ONE':
                scene.frame_end -= 1

        if use_rigify and rig_props.use_humanoid_name:
            # Retarget bone name
            convert_to_unreal_humanoid(rig_obj, export_rig_ob, scale)

            # Make humanoid constraint
            make_humanoid_constraint(context, rig_obj, export_rig_ob)

        else:
            # Make constraint
            make_constraint(context, rig_obj, export_rig_ob)

            # Manual bake action if want to edit root bone
            #if action_props.hip_to_root:
            #    move_root(scene, export_rig_ob)

        if use_rigify and rig_props.unparent_ik_bones:
            unparent_ik_related_bones(rig_props.use_humanoid_name, rig_obj, export_rig_ob)

        # Select only export rig
        bpy.ops.object.select_all(action='DESELECT')
        export_rig_ob.select = True
        scene.objects.active = export_rig_ob

        #return {'FINISHED'}

        # Set Global Matrix
        forward = '-Y'
        up = 'Z'
        global_matrix = (Matrix.Scale(1.0/ABS_SCALE, 4) * axis_conversion(to_forward=forward, to_up=up,).to_4x4()) 

        ## EXPORT!
        export_fbx_bin.save_single(self, scene, self.filepath,
                global_matrix=global_matrix,
                axis_up=up,
                axis_forward=forward,
                context_objects=context.selected_objects,
                object_types={'ARMATURE', 'MESH'},
                use_mesh_modifiers=True,
                mesh_smooth_type='EDGE',
                use_armature_deform_only=False,
                bake_anim=True,
                bake_anim_use_all_bones=True,
                bake_anim_use_nla_strips=False,
                bake_anim_use_all_actions=False,
                bake_anim_force_startend_keying=True,
                bake_anim_step=1.0,
                bake_anim_simplify_factor=0.0,
                add_leaf_bones=False,
                primary_bone_axis='Y',
                secondary_bone_axis='X',
                use_metadata=True,
                path_mode='AUTO',
                use_mesh_edges=True,
                use_tspace=True,
                embed_textures=False,
                use_custom_props=False,
                bake_space_transform=False
                ) 

        # Delete exported object
        bpy.ops.object.delete()

        # Delete temporary rig
        for arm in bpy.data.armatures:
            if arm.name.startswith('__TEMP__'):
                bpy.data.armatures.remove(arm, True)

        # Descale original rig
        rig_obj.scale /= scale

        # Load original state
        state.load(context)

        return {'FINISHED'}