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)
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')
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'}
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'}
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'}