Skip to content

Commit

Permalink
Merge pull request #269 from Dragorn421/quick_import
Browse files Browse the repository at this point in the history
[OoT] Add Quick Import button
  • Loading branch information
sauraen authored Dec 29, 2023
2 parents 289b307 + 20b2501 commit 1eaef22
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 0 deletions.
38 changes: 38 additions & 0 deletions fast64_internal/oot/tools/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from ...utility import parentObject, setOrigin
from ..cutscene.motion.utility import setupCutscene, createNewCameraShot
from ..oot_utility import getNewPath
from .quick_import import QuickImportAborted, quick_import_exec


class OOT_AddWaterBox(AddWaterBox):
Expand Down Expand Up @@ -255,3 +256,40 @@ def execute(self, context: Context):
return {"FINISHED"}
except:
return {"CANCELLED"}


class OOTQuickImport(Operator):
bl_idname = "object.oot_quick_import"
bl_label = "Quick Import"
bl_options = {"REGISTER", "UNDO"}
bl_description = (
"Import (almost) anything by inputting a symbol name from an object."
" This operator automatically finds the file to import from (within objects)"
)

sym_name: StringProperty(
name="Symbol name",
description=(
"Which symbol to import."
" This may be a display list (e.g. gBoomerangDL), "
"a skeleton (e.g. object_daiku_Skel_007958), "
"an animation (with the appropriate skeleton selected, e.g. object_daiku_Anim_008164)"
),
)

def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)

def draw(self, context):
self.layout.prop(self, "sym_name", text="Symbol")

def execute(self, context: Context):
try:
quick_import_exec(
context,
self.sym_name,
)
except QuickImportAborted as e:
self.report({"ERROR"}, e.message)
return {"CANCELLED"}
return {"FINISHED"}
3 changes: 3 additions & 0 deletions fast64_internal/oot/tools/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
OOT_AddCutscene,
OOT_AddPath,
OOTClearTransformAndLock,
OOTQuickImport,
)


Expand All @@ -24,6 +25,7 @@ def draw(self, context):
col.operator(OOT_AddCutscene.bl_idname)
col.operator(OOT_AddPath.bl_idname)
col.operator(OOTClearTransformAndLock.bl_idname)
col.operator(OOTQuickImport.bl_idname)


oot_operator_panel_classes = [
Expand All @@ -38,6 +40,7 @@ def draw(self, context):
OOT_AddCutscene,
OOT_AddPath,
OOTClearTransformAndLock,
OOTQuickImport,
]


Expand Down
115 changes: 115 additions & 0 deletions fast64_internal/oot/tools/quick_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
from pathlib import Path
import os
import re

import bpy

from ..f3d.properties import OOTDLImportSettings
from ..skeleton.properties import OOTSkeletonImportSettings
from ..animation.properties import OOTAnimImportSettingsProperty


class QuickImportAborted(Exception):
def __init__(self, message):
super().__init__(message)
self.message = message


def quick_import_exec(context: bpy.types.Context, sym_name: str):
sym_name = sym_name.strip()
if sym_name == "":
raise QuickImportAborted("No symbol name given")
if not all(
(
"a" <= c <= "z"
or "A" <= c <= "Z"
or "0" <= c <= "9"
or c
in {
"_",
}
)
for c in sym_name
):
raise QuickImportAborted("Symbol names only have characters a-zA-Z0-9_")

sym_def_pattern = re.compile(rf"([^\s]+)\s+{sym_name}\s*(\[[^\]]*\])?\s*=")

base_dir_p = Path(context.scene.ootDecompPath)
assets_objects_dir_p = base_dir_p / "assets" / "objects"

all_found_defs: dict[Path, list[tuple[str, str]]] = dict()

for dirpath, dirnames, filenames in os.walk(assets_objects_dir_p):
dirpath_p = Path(dirpath)
for filename in filenames:
file_p = dirpath_p / filename
# Only look into C files
if file_p.suffix != ".c":
continue
source = file_p.read_text()
# Simple check to see if we should look into this file any further
if sym_name not in source:
continue
found_defs = sym_def_pattern.findall(source)
print(file_p, f"{found_defs=}")
all_found_defs[file_p] = found_defs

# Ideally if for example sym_name was gLinkAdultHookshotTipDL,
# all_found_defs now contains:
# {Path('.../assets/objects/object_link_boy/object_link_boy.c'): [('Gfx', '[]')]}
# or with gButterflySkel:
# {Path('.../assets/objects/gameplay_field_keep/gameplay_field_keep.c'): [('SkeletonHeader', '')]}

if len(all_found_defs) == 0:
raise QuickImportAborted(f"Couldn't find a definition of {sym_name}")
if len(all_found_defs) > 1:
raise QuickImportAborted(
f"Found definitions of {sym_name} in several files: "
+ ", ".join(str(p.relative_to(assets_objects_dir_p)) for p in all_found_defs.keys())
)
assert len(all_found_defs) == 1
sym_file_p, sym_defs = list(all_found_defs.items())[0]
if len(sym_defs) > 1:
raise QuickImportAborted(
f"Found several definitions of {sym_name} in {sym_file_p.relative_to(assets_objects_dir_p)}"
)

# We found a single definition of the symbol
sym_def_type, sym_def_array_decl = sym_defs[0]
is_array = sym_def_array_decl != ""
object_name = sym_file_p.relative_to(assets_objects_dir_p).parts[0]

if sym_def_type == "Gfx" and is_array:
settings: OOTDLImportSettings = context.scene.fast64.oot.DLImportSettings
settings.name = sym_name
settings.folder = object_name
settings.actorOverlayName = ""
settings.isCustom = False
bpy.ops.object.oot_import_dl()
elif sym_def_type in {"SkeletonHeader", "FlexSkeletonHeader"} and not is_array:
settings: OOTSkeletonImportSettings = context.scene.fast64.oot.skeletonImportSettings
settings.isCustom = False
if sym_name == "gLinkAdultSkel":
settings.mode = "Adult Link"
elif sym_name == "gLinkChildSkel":
settings.mode = "Child Link"
else:
settings.mode = "Generic"
settings.name = sym_name
settings.folder = object_name
settings.actorOverlayName = ""
bpy.ops.object.oot_import_skeleton()
elif sym_def_type == "AnimationHeader" and not is_array:
settings: OOTAnimImportSettingsProperty = context.scene.fast64.oot.animImportSettings
settings.isCustom = False
settings.isLink = False
settings.animName = sym_name
settings.folderName = object_name
bpy.ops.object.oot_import_anim()
else:
raise QuickImportAborted(
f"Don't know how to import {sym_def_type}"
+ ("[]" if is_array else "")
+ f" (symbol found in {object_name})"
)

0 comments on commit 1eaef22

Please sign in to comment.