Merge branch 'main' into cleanup-p2

This commit is contained in:
Onan Chew
2024-10-18 18:04:52 -04:00
committed by GitHub
4 changed files with 68 additions and 56 deletions
+1
View File
@@ -40,6 +40,7 @@ import_types: dict[str, typing.Callable[[str, list[dict[str,str]], str], None]]
"x3d": (lambda directory, files, filepath : bpy.ops.import_scene.x3d(files=files, directory=directory, filepath=filepath)), "x3d": (lambda directory, files, filepath : bpy.ops.import_scene.x3d(files=files, directory=directory, filepath=filepath)),
"wrl": (lambda directory, files, filepath : bpy.ops.import_scene.x3d(files=files, directory=directory, filepath=filepath)), "wrl": (lambda directory, files, filepath : bpy.ops.import_scene.x3d(files=files, directory=directory, filepath=filepath)),
"vmd": (lambda directory, files, filepath : import_multi_files(directory=directory, files=files, filepath=filepath, method = (lambda directory, filepath: bpy.ops.tuxedo.import_mmd_animation(directory=directory, filepath=filepath)))), "vmd": (lambda directory, files, filepath : import_multi_files(directory=directory, files=files, filepath=filepath, method = (lambda directory, filepath: bpy.ops.tuxedo.import_mmd_animation(directory=directory, filepath=filepath)))),
"vrm": (lambda directory, files, filepath: bpy.ops.import_scene.vrm(filepath=filepath)),
"pmx": (lambda directory, files, filepath : import_pmx(filepath)), "pmx": (lambda directory, files, filepath : import_pmx(filepath)),
"pmd": (lambda directory, files, filepath : import_pmd(filepath)), "pmd": (lambda directory, files, filepath : import_pmd(filepath)),
} }
+53 -51
View File
@@ -3,11 +3,13 @@ from bpy.types import Operator
from bpy_extras.io_utils import ImportHelper from bpy_extras.io_utils import ImportHelper
from ..core.register import register_wrap from ..core.register import register_wrap
from ..core.importer import imports, import_types from ..core.importer import imports, import_types
from ..core.common import remove_default_objects, open_web_after_delay_multi_threaded from ..core.common import remove_default_objects
from ..functions.translations import t from ..functions.translations import t
import pathlib import pathlib
import os import os
VRM_IMPORTER_URL = "https://github.com/saturday06/VRM_Addon_for_Blender"
@register_wrap @register_wrap
class AvatarToolKit_OT_ImportAnyModel(Operator, ImportHelper): class AvatarToolKit_OT_ImportAnyModel(Operator, ImportHelper):
bl_idname = 'avatar_toolkit.import_any_model' bl_idname = 'avatar_toolkit.import_any_model'
@@ -16,71 +18,71 @@ class AvatarToolKit_OT_ImportAnyModel(Operator, ImportHelper):
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
files: bpy.props.CollectionProperty(type=bpy.types.OperatorFileListElement, options={'HIDDEN', 'SKIP_SAVE'}) files: bpy.props.CollectionProperty(type=bpy.types.OperatorFileListElement, options={'HIDDEN', 'SKIP_SAVE'})
filter_glob: bpy.props.StringProperty(default = imports, options={'HIDDEN','SKIP_SAVE'}) filter_glob: bpy.props.StringProperty(default=imports, options={'HIDDEN', 'SKIP_SAVE'})
directory: bpy.props.StringProperty(maxlen=1024, subtype='FILE_PATH', options={'HIDDEN', 'SKIP_SAVE'}) directory: bpy.props.StringProperty(maxlen=1024, subtype='FILE_PATH', options={'HIDDEN', 'SKIP_SAVE'})
# since I wrote this myself, a bit more efficient than cats. mostly - @989onan
#since I wrote this myself, a bit more efficent than cats. mostly - @989onan
def execute(self, context: bpy.types.Context): def execute(self, context: bpy.types.Context):
file_grouping_dict: dict[str, list[dict[str,str]]] = dict()#group our files so our importers can import them together. in the case of OBJ+MTL and others that need grouped files, this is extremely important. file_grouping_dict: dict[str, list[dict[str, str]]] = dict() # group our files so our importers can import them together. in the case of OBJ+MTL and others that need grouped files, this is extremely important.
remove_default_objects() remove_default_objects()
#check if we are importing multiple files # check if we are importing multiple files
is_multi = False is_multi = len(self.files) > 0
try:
if is_multi:
for file in self.files: for file in self.files:
pass fullpath = os.path.join(self.directory, os.path.basename(file.name))
is_multi = True name = pathlib.Path(fullpath).suffix.replace(".", "")
except Exception as e: # this makes sure our imports that should be grouped stay together.
is_multi = False # basically the method checks for if the first value has a lambda with the same bytecode as another lambda, then it will use that value's key (ex:"obj"<->"mtl" or "fbx"), keeping same importers together
print(e) if name not in file_grouping_dict:
file_grouping_dict[name] = []
file_grouping_dict[name].append({"name": os.path.basename(file.name)}) # emulate passing a list of files.
#put the files together into lists of same importers
if(is_multi):
for file in self.files:
fullpath = os.path.join(self.directory,os.path.basename(file.name))
name = pathlib.Path(fullpath).suffix.replace(".","")
#this makes sure our imports that should be grouped stay together.
#basically the method checks for if the first value has a lambda with the same bytecode as another lambda, then it will use that value's key (ex:"obj"<->"mtl" or "fbx"), keeping same importers together
try:
name2 = next(key for key,value in import_types.items() if value.__code__.co_code == import_types[name].__code__.co_code)
print(name +" is the same importer as "+name2+", grouping.")
name = name2
except Exception as e:
print("error when trying to find a value of the same value in the kinds of importers. May just be an import type that's a singlet:")
print(e)
if name not in file_grouping_dict: file_grouping_dict[name] = []
file_grouping_dict[name].append({"name": os.path.basename(file.name)}) #emulate passing a list of files.
else: else:
fullpath: str = os.path.join(os.path.dirname(self.filepath),os.path.basename(self.filepath)) fullpath: str = os.path.join(os.path.dirname(self.filepath), os.path.basename(self.filepath))
name = pathlib.Path(fullpath).suffix.replace(".","") name = pathlib.Path(fullpath).suffix.replace(".", "")
if name not in file_grouping_dict: file_grouping_dict[name] = [] if name not in file_grouping_dict:
file_grouping_dict[name].append({"name": fullpath}) #emulate passing a list of files. file_grouping_dict[name] = []
file_grouping_dict[name].append({"name": fullpath}) # emulate passing a list of files.
#import the files together to make sure things like obj import together. This is important # import the files together to make sure things like obj import together. This is important
for file_group_name,files in file_grouping_dict.items(): for file_group_name, files in file_grouping_dict.items():
try: try:
if(self.directory): # Check for VRM importer availability
print(files) if file_group_name == "vrm" and not hasattr(bpy.ops.import_scene, "vrm"):
import_types[file_group_name](self.directory,files,self.filepath) bpy.ops.wm.vrm_importer_popup('INVOKE_DEFAULT')
return {'CANCELLED'}
if self.directory:
import_types[file_group_name](self.directory, files, self.filepath)
else: else:
import_types[file_group_name]("",files,self.filepath) #give an empty directory, works just fine for 90% import_types[file_group_name]("", files, self.filepath) # give an empty directory, works just fine for 90%
except AttributeError as e: except AttributeError as e:
print("Warning, you may not have the required importer for extension type \"{extension}\"!".format(extension = file_group_name)) if file_group_name == "vrm":
bpy.ops.wm.vrm_importer_popup('INVOKE_DEFAULT')
open_web_after_delay_multi_threaded(delay=12, url=t('Importing.importer_search_term').format(extension = file_group_name)) else:
self.report({'ERROR'}, t('Importing.need_importer').format(extension=file_group_name))
self.report({'ERROR'},t('Importing.need_importer').format(extension = file_group_name)) print("Importer error:", e)
return {'CANCELLED'}
print("importer error was:")
print(e)
self.report({'INFO'}, t('Quick_Access.import_success')) self.report({'INFO'}, t('Quick_Access.import_success'))
return {'FINISHED'} return {'FINISHED'}
@register_wrap
class VRMImporterPopup(Operator):
bl_idname = "wm.vrm_importer_popup"
bl_label = "VRM Importer Not Installed"
def execute(self, context):
return {'FINISHED'}
def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self, width=300)
def draw(self, context):
layout = self.layout
layout.label(text="VRM importer plugin is not installed.")
layout.label(text="Please install it to import VRM files.")
layout.operator("wm.url_open", text="Get VRM Importer").url = VRM_IMPORTER_URL
#TODO: This needs to be done with our own MMD importer. #TODO: This needs to be done with our own MMD importer.
""" """
+13 -3
View File
@@ -18,7 +18,6 @@ class AvatarToolKit_OT_RemoveDoublesSafelyAdvanced(Operator):
bl_description = t("Optimization.remove_doubles_safely_advanced.desc") bl_description = t("Optimization.remove_doubles_safely_advanced.desc")
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
merge_distance: bpy.props.FloatProperty(default=0.0001) merge_distance: bpy.props.FloatProperty(default=0.0001)
@classmethod @classmethod
@@ -26,9 +25,20 @@ class AvatarToolKit_OT_RemoveDoublesSafelyAdvanced(Operator):
armature = get_selected_armature(context) armature = get_selected_armature(context)
return armature is not None and is_valid_armature(armature) return armature is not None and is_valid_armature(armature)
def draw(self, context):
layout = self.layout
layout.label(text="This process may take a long time.")
layout.label(text="Blender may seem unresponsive during this operation.")
layout.label(text="Please be patient and wait for it to complete.")
def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)
def execute(self, context: Context): def execute(self, context: Context):
bpy.ops.avatar_toolkit.remove_doubles_safely('INVOKE_DEFAULT',advanced=True,merge_distance=self.merge_distance) bpy.ops.avatar_toolkit.remove_doubles_safely('INVOKE_DEFAULT', advanced=True, merge_distance=self.merge_distance)
return {'FINISHED'} return {'RUNNING_MODAL'}
@register_wrap @register_wrap
class AvatarToolKit_OT_RemoveDoublesSafely(Operator): class AvatarToolKit_OT_RemoveDoublesSafely(Operator):
bl_idname = "avatar_toolkit.remove_doubles_safely" bl_idname = "avatar_toolkit.remove_doubles_safely"
-1
View File
@@ -36,7 +36,6 @@ class AvatarToolkit_PT_OptimizationPanel(bpy.types.Panel):
row.scale_y = 1.2 row.scale_y = 1.2
row.operator(AvatarToolKit_OT_RemoveDoublesSafely.bl_idname, text=t("Optimization.remove_doubles_safely.label"), icon='SNAP_VERTEX') row.operator(AvatarToolKit_OT_RemoveDoublesSafely.bl_idname, text=t("Optimization.remove_doubles_safely.label"), icon='SNAP_VERTEX')
row.operator(AvatarToolKit_OT_RemoveDoublesSafelyAdvanced.bl_idname, text=t("Optimization.remove_doubles_safely_advanced.label"), icon="ACTION") row.operator(AvatarToolKit_OT_RemoveDoublesSafelyAdvanced.bl_idname, text=t("Optimization.remove_doubles_safely_advanced.label"), icon="ACTION")
layout.separator(factor=1.0) layout.separator(factor=1.0)
layout.label(text=t("Optimization.joinmeshes.label"), icon='OBJECT_DATA') layout.label(text=t("Optimization.joinmeshes.label"), icon='OBJECT_DATA')