Lopiii

Roblox Modifiers Animation

May 19th, 2021 (edited)
1,820
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.17 KB | None | 0 0
  1. # my original pastebin is: https://pastebin.com/B4XXey6V, I upload this again bc the original I uploaded it without an accound
  2. # Lopi_light
  3. # 16/05/2021
  4.  
  5. import bpy
  6. from bpy import props, utils
  7. from bpy_extras.io_utils import ExportHelper
  8. from bpy.types import Operator, TOPBAR_MT_file_export
  9. from os.path import  join
  10.  
  11. ROBLOX_SCALE = 0.01 # blender scale to roblox scale
  12. ROBLOX_TRIS_LIMIT = 50000 # tris limit to import a fbx
  13. EXPORT_NAME = 'rbxmanim' # default
  14. EXPORT_EXT = 'fbx'
  15.  
  16. register_class = utils.register_class
  17. unregister_class = utils.unregister_class
  18.  
  19. bl_info = {
  20.     'author': 'Lopy',
  21.     'name': 'Modifiers Animation',
  22.     'category': 'Animation',
  23.     'blender': (2, 92, 0)
  24. }
  25.  
  26.  
  27. def clear_animation_data(object):
  28.     object.animation_data_clear()
  29.  
  30.     try:
  31.         object.select_set(True)
  32.         bpy.ops.anim.clear_animation_animall() # AnimAll compatibility
  33.     except:
  34.         pass
  35.     finally:
  36.         object.select_set(False)
  37.  
  38.  
  39. def get_tris_of(object=None):
  40.     if object is None:
  41.         return 0
  42.  
  43.     tris = 0
  44.     for polygon in object.evaluated_get(bpy.context.evaluated_depsgraph_get()).to_mesh().polygons:
  45.         tris += len(polygon.vertices) - 2
  46.  
  47.     return tris
  48.  
  49.  
  50. def get_total_tris_of(list=None):
  51.     if list is None:
  52.         return 0
  53.  
  54.     tris = 0
  55.     for object in list:
  56.         tris += get_tris_of(object)
  57.  
  58.     return tris
  59.  
  60.  
  61. class ExportFiles(Operator, ExportHelper):
  62.     '''Select a file to export fbx'''
  63.     bl_label = 'Export Animation'
  64.     bl_idname = 'modifiers_animation.select_file'
  65.  
  66.     filename_ext = '.' + EXPORT_EXT
  67.     directory: props.StringProperty(subtype='FILE_PATH')
  68.     filename: props.StringProperty(options={'HIDDEN'}, subtype='FILE_NAME')
  69.     filter_glob = props.StringProperty(default=f'*{EXPORT_EXT};', options={'HIDDEN'})
  70.  
  71.  
  72.     def get_filepath(self, index):
  73.         if index == 0:
  74.             index = ''
  75.         return join(self.directory, str(self.filename).replace(self.filename_ext, str(index) + self.filename_ext))
  76.  
  77.  
  78.     def execute(self, context):
  79.         to_export = [[]]
  80.         scene = context.scene
  81.         frame_current = scene.frame_current
  82.         target_obj = self.target_obj
  83.  
  84.         for frame in range(scene.frame_start, scene.frame_end + 1):
  85.             scene.frame_set(frame)
  86.             duplicated = target_obj.copy()
  87.             duplicated.data = target_obj.data.copy()
  88.             duplicated.name = str(int(frame))
  89.             scene.collection.objects.link(duplicated)
  90.             clear_animation_data(duplicated)
  91.  
  92.             list = to_export[len(to_export) - 1]
  93.  
  94.             if get_total_tris_of(list) + get_tris_of(duplicated) > ROBLOX_TRIS_LIMIT:
  95.                 to_export.append([])
  96.                 list = to_export[len(to_export) - 1]
  97.  
  98.             list.append(duplicated)
  99.  
  100.         scene.frame_current = frame_current
  101.  
  102.         for objs in to_export:
  103.             index = 0
  104.             bpy.ops.object.select_all(action='DESELECT')
  105.  
  106.             if len(to_export) > 1:
  107.                 index = to_export.index(objs) + 1
  108.  
  109.             for obj in objs:
  110.                 if get_tris_of(obj) != 0:
  111.                     obj.select_set(True)
  112.  
  113.             bpy.ops.export_scene.fbx(filepath=self.get_filepath(index), use_selection=True, global_scale=ROBLOX_SCALE)
  114.  
  115.             for obj in objs:
  116.                 bpy.data.objects.remove(obj, do_unlink=True)
  117.  
  118.         target_obj.select_set(True)
  119.  
  120.         del to_export
  121.         del scene
  122.         del frame_current
  123.         del target_obj
  124.  
  125.         return {'FINISHED'}
  126.  
  127.     def invoke(self, context, _):
  128.         self.filepath = EXPORT_NAME
  129.         self.target_obj = context.selected_objects[0]
  130.  
  131.         bpy.ops.object.select_all(action='DESELECT')
  132.         context.window_manager.fileselect_add(self)
  133.  
  134.         return {'RUNNING_MODAL'}
  135.  
  136.  
  137. def export_option(self, _):
  138.     self.layout.operator('modifiers_animation.select_file', text='Roblox Modifiers Animation (.fbx)')
  139.  
  140.  
  141. def register():
  142.     register_class(ExportFiles)
  143.     TOPBAR_MT_file_export.append(export_option)
  144.  
  145.  
  146. def unregister():
  147.     unregister_class(ExportFiles)
  148.     TOPBAR_MT_file_export.remove(export_option)
  149.  
  150.  
  151. if __name__ == '__main__':
  152.     register()
  153.  
Add Comment
Please, Sign In to add comment