work
update amznchartools
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
"""Operator definitions for AMZN Character Tools."""
|
||||
import importlib
|
||||
from pathlib import Path
|
||||
import runpy
|
||||
import traceback
|
||||
@@ -8,6 +9,7 @@ from bpy.types import Operator
|
||||
|
||||
|
||||
OPS_DIR = Path(__file__).parent.parent / "ops"
|
||||
BASE_PACKAGE = (__package__ or "").rsplit(".", 1)[0]
|
||||
|
||||
|
||||
def run_script(script_name: str) -> None:
|
||||
@@ -25,6 +27,15 @@ def run_script(script_name: str) -> None:
|
||||
runpy.run_path(str(script_path), run_name="__main__")
|
||||
|
||||
|
||||
def _import_ops_module(module_name: str):
|
||||
"""Import and reload an ops module from this addon package."""
|
||||
if not BASE_PACKAGE:
|
||||
raise RuntimeError("Cannot resolve addon base package for module imports")
|
||||
full_name = f"{BASE_PACKAGE}.ops.{module_name}"
|
||||
module = importlib.import_module(full_name)
|
||||
return importlib.reload(module)
|
||||
|
||||
|
||||
# Icon mapping from old indices to icon names
|
||||
ICON_MAP = {
|
||||
144: "PREFERENCES", # Settings/configuration operations
|
||||
@@ -86,6 +97,15 @@ OP_SPECS = [
|
||||
"icon": "FILE_REFRESH",
|
||||
"panel": "devices",
|
||||
},
|
||||
{
|
||||
"name": "RemoveDevicesSettings",
|
||||
"id": "remove_devices_settings",
|
||||
"desc": "Removes the 'Devices' custom property from SettingsBone",
|
||||
"script": "RemoveDevicesSettings.py",
|
||||
"button": "Remove Devices Settings",
|
||||
"icon": "CANCEL",
|
||||
"panel": "devices",
|
||||
},
|
||||
{
|
||||
"name": "GeoSeparator",
|
||||
"id": "geo_separator",
|
||||
@@ -122,6 +142,15 @@ OP_SPECS = [
|
||||
"icon": "PREFERENCES",
|
||||
"panel": "geo",
|
||||
},
|
||||
{
|
||||
"name": "AddVestAmbassadorColor",
|
||||
"id": "add_vest_ambassador_color",
|
||||
"desc": "Adds blue (ambassador) vest color option to active object's vest color node group",
|
||||
"script": "vest_ambassador_color.py",
|
||||
"button": "Add Vest Ambassador Color",
|
||||
"icon": "MATERIAL",
|
||||
"panel": "vest",
|
||||
},
|
||||
{
|
||||
"name": "HHSpawn",
|
||||
"id": "hh_spawn",
|
||||
@@ -192,7 +221,65 @@ def _make_operator(spec: dict) -> type[Operator]:
|
||||
"""Create an operator class from a specification dictionary."""
|
||||
def _execute(self, context):
|
||||
try:
|
||||
run_script(spec["script"])
|
||||
# Special handling for operators that need result capture
|
||||
if spec["script"] == "replace_cel_with_bsdf.py":
|
||||
script_path = OPS_DIR / spec["script"]
|
||||
if script_path.exists():
|
||||
module = _import_ops_module("replace_cel_with_bsdf")
|
||||
materials_mapped, users_remapped = module.replace_cel_materials()
|
||||
self.report({"INFO"}, f"Replaced CEL: {materials_mapped} materials, {users_remapped} users remapped")
|
||||
else:
|
||||
run_script(spec["script"])
|
||||
self.report({"INFO"}, f"{spec['button']} complete")
|
||||
elif spec["script"] == "vest_ambassador_color.py":
|
||||
script_path = OPS_DIR / spec["script"]
|
||||
if script_path.exists():
|
||||
module = _import_ops_module("vest_ambassador_color")
|
||||
result = module.add_vest_ambassador_color()
|
||||
success = bool(result.get("success")) if isinstance(result, dict) else bool(result)
|
||||
reason = result.get("reason") if isinstance(result, dict) else ""
|
||||
if success:
|
||||
self.report({"INFO"}, f"{spec['button']} complete")
|
||||
else:
|
||||
if reason == "NO_NODE_GROUP":
|
||||
self.report({"INFO"}, "No vest color node group found on active object")
|
||||
elif reason == "NO_ACTIVE_OBJECT":
|
||||
self.report({"INFO"}, "No active object selected")
|
||||
elif reason == "NO_MENU_SWITCH":
|
||||
self.report({"INFO"}, "No vest menu switch node found in vest color node group")
|
||||
else:
|
||||
self.report({"WARNING"}, "Vest-blue material linked but menu item was not added")
|
||||
else:
|
||||
run_script(spec["script"])
|
||||
self.report({"INFO"}, f"{spec['button']} complete")
|
||||
elif spec["script"] == "BodyMasker.py":
|
||||
script_path = OPS_DIR / spec["script"]
|
||||
if script_path.exists():
|
||||
module = _import_ops_module("BodyMasker")
|
||||
result = module.add_body_masks()
|
||||
if isinstance(result, dict):
|
||||
if result.get("success"):
|
||||
self.report({"INFO"}, f"{spec['button']} complete")
|
||||
else:
|
||||
reason = result.get("reason")
|
||||
if reason == "NO_BODY":
|
||||
self.report({"ERROR"}, "CC_Base_Body not found in scene")
|
||||
else:
|
||||
self.report({"WARNING"}, f"{spec['button']} incomplete: {reason}")
|
||||
else:
|
||||
# Unexpected return type; fall back to running the script for side-effects
|
||||
run_script(spec["script"])
|
||||
self.report({"INFO"}, f"{spec['button']} complete")
|
||||
elif spec.get("id") == "remove_devices_settings":
|
||||
# Pre-check: ensure CC_Base_Body exists in the scene. If not, inform the user.
|
||||
if "CC_Base_Body" not in bpy.data.objects:
|
||||
self.report({"ERROR"}, "CC_Base_Body not found in scene")
|
||||
return {"CANCELLED"}
|
||||
run_script(spec["script"])
|
||||
self.report({"INFO"}, f"{spec['button']} complete")
|
||||
else:
|
||||
run_script(spec["script"])
|
||||
self.report({"INFO"}, f"{spec['button']} complete")
|
||||
except Exception as exc: # pragma: no cover - best effort logging
|
||||
traceback.print_exc()
|
||||
self.report({"ERROR"}, f"{spec['button']} failed: {exc}")
|
||||
|
||||
Reference in New Issue
Block a user