Holy shit this was a pain
- Truly fixes PMX Import lol, i messed up completely - Updated MMD Tools to use Cats One
This commit is contained in:
@@ -1,90 +1,82 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2014 MMD Tools authors
|
||||
# This file was originally part of the MMD Tools add-on for Blender
|
||||
# You can find MMD Tools here: https://github.com/MMD-Blender/blender_mmd_tools
|
||||
# Neoneko has modified this file to work with Avatar Toolkit and may of made changes or improvements.
|
||||
# MMD Tools is licensed under the terms of the GNU General Public License version 3 (GPLv3) same as Avatar Toolkit.
|
||||
# This file is part of MMD Tools.
|
||||
|
||||
import bpy
|
||||
from typing import Optional, Set, Dict, Any, List, Tuple, Union, Type
|
||||
|
||||
from .. import utils
|
||||
from ..core import material
|
||||
from ..core.material import FnMaterial
|
||||
from ..core.model import FnModel
|
||||
from . import patch_library_overridable
|
||||
from ....core.logging_setup import logger
|
||||
|
||||
|
||||
def _mmd_material_update_ambient_color(prop: "MMDMaterial", _context: bpy.types.Context) -> None:
|
||||
def _mmd_material_update_ambient_color(prop: "MMDMaterial", _context):
|
||||
FnMaterial(prop.id_data).update_ambient_color()
|
||||
|
||||
|
||||
def _mmd_material_update_diffuse_color(prop: "MMDMaterial", _context: bpy.types.Context) -> None:
|
||||
def _mmd_material_update_diffuse_color(prop: "MMDMaterial", _context):
|
||||
FnMaterial(prop.id_data).update_diffuse_color()
|
||||
|
||||
|
||||
def _mmd_material_update_alpha(prop: "MMDMaterial", _context: bpy.types.Context) -> None:
|
||||
def _mmd_material_update_alpha(prop: "MMDMaterial", _context):
|
||||
FnMaterial(prop.id_data).update_alpha()
|
||||
|
||||
|
||||
def _mmd_material_update_specular_color(prop: "MMDMaterial", _context: bpy.types.Context) -> None:
|
||||
def _mmd_material_update_specular_color(prop: "MMDMaterial", _context):
|
||||
FnMaterial(prop.id_data).update_specular_color()
|
||||
|
||||
|
||||
def _mmd_material_update_shininess(prop: "MMDMaterial", _context: bpy.types.Context) -> None:
|
||||
def _mmd_material_update_shininess(prop: "MMDMaterial", _context):
|
||||
FnMaterial(prop.id_data).update_shininess()
|
||||
|
||||
|
||||
def _mmd_material_update_is_double_sided(prop: "MMDMaterial", _context: bpy.types.Context) -> None:
|
||||
def _mmd_material_update_is_double_sided(prop: "MMDMaterial", _context):
|
||||
FnMaterial(prop.id_data).update_is_double_sided()
|
||||
|
||||
|
||||
def _mmd_material_update_sphere_texture_type(prop: "MMDMaterial", context: bpy.types.Context) -> None:
|
||||
def _mmd_material_update_sphere_texture_type(prop: "MMDMaterial", context):
|
||||
FnMaterial(prop.id_data).update_sphere_texture_type(context.active_object)
|
||||
|
||||
|
||||
def _mmd_material_update_toon_texture(prop: "MMDMaterial", _context: bpy.types.Context) -> None:
|
||||
def _mmd_material_update_toon_texture(prop: "MMDMaterial", _context):
|
||||
FnMaterial(prop.id_data).update_toon_texture()
|
||||
|
||||
|
||||
def _mmd_material_update_enabled_drop_shadow(prop: "MMDMaterial", _context: bpy.types.Context) -> None:
|
||||
def _mmd_material_update_enabled_drop_shadow(prop: "MMDMaterial", _context):
|
||||
FnMaterial(prop.id_data).update_drop_shadow()
|
||||
|
||||
|
||||
def _mmd_material_update_enabled_self_shadow_map(prop: "MMDMaterial", _context: bpy.types.Context) -> None:
|
||||
def _mmd_material_update_enabled_self_shadow_map(prop: "MMDMaterial", _context):
|
||||
FnMaterial(prop.id_data).update_self_shadow_map()
|
||||
|
||||
|
||||
def _mmd_material_update_enabled_self_shadow(prop: "MMDMaterial", _context: bpy.types.Context) -> None:
|
||||
def _mmd_material_update_enabled_self_shadow(prop: "MMDMaterial", _context):
|
||||
FnMaterial(prop.id_data).update_self_shadow()
|
||||
|
||||
|
||||
def _mmd_material_update_enabled_toon_edge(prop: "MMDMaterial", _context: bpy.types.Context) -> None:
|
||||
def _mmd_material_update_enabled_toon_edge(prop: "MMDMaterial", _context):
|
||||
FnMaterial(prop.id_data).update_enabled_toon_edge()
|
||||
|
||||
|
||||
def _mmd_material_update_edge_color(prop: "MMDMaterial", _context: bpy.types.Context) -> None:
|
||||
def _mmd_material_update_edge_color(prop: "MMDMaterial", _context):
|
||||
FnMaterial(prop.id_data).update_edge_color()
|
||||
|
||||
|
||||
def _mmd_material_update_edge_weight(prop: "MMDMaterial", _context: bpy.types.Context) -> None:
|
||||
def _mmd_material_update_edge_weight(prop: "MMDMaterial", _context):
|
||||
FnMaterial(prop.id_data).update_edge_weight()
|
||||
|
||||
|
||||
def _mmd_material_get_name_j(prop: "MMDMaterial") -> str:
|
||||
def _mmd_material_get_name_j(prop: "MMDMaterial"):
|
||||
return prop.get("name_j", "")
|
||||
|
||||
|
||||
def _mmd_material_set_name_j(prop: "MMDMaterial", value: str) -> None:
|
||||
def _mmd_material_set_name_j(prop: "MMDMaterial", value: str):
|
||||
prop_value = value
|
||||
if prop_value and prop_value != prop.get("name_j"):
|
||||
root = FnModel.find_root_object(bpy.context.active_object)
|
||||
if root is None:
|
||||
logger.debug(f"No root object found, using unique name for material: {value}")
|
||||
prop_value = utils.unique_name(value, {mat.mmd_material.name_j for mat in bpy.data.materials})
|
||||
else:
|
||||
logger.debug(f"Root object found, using unique name for material within model: {value}")
|
||||
prop_value = utils.unique_name(value, {mat.mmd_material.name_j for mat in FnModel.iterate_materials(root)})
|
||||
|
||||
prop["name_j"] = prop_value
|
||||
@@ -279,15 +271,13 @@ class MMDMaterial(bpy.types.PropertyGroup):
|
||||
description="Comment",
|
||||
)
|
||||
|
||||
def is_id_unique(self) -> bool:
|
||||
def is_id_unique(self):
|
||||
return self.material_id < 0 or not next((m for m in bpy.data.materials if m.mmd_material != self and m.mmd_material.material_id == self.material_id), None)
|
||||
|
||||
@staticmethod
|
||||
def register() -> None:
|
||||
logger.debug("Registering MMD material properties")
|
||||
def register():
|
||||
bpy.types.Material.mmd_material = patch_library_overridable(bpy.props.PointerProperty(type=MMDMaterial))
|
||||
|
||||
@staticmethod
|
||||
def unregister() -> None:
|
||||
logger.debug("Unregistering MMD material properties")
|
||||
def unregister():
|
||||
del bpy.types.Material.mmd_material
|
||||
|
||||
@@ -1,38 +1,34 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2014 MMD Tools authors
|
||||
# This file was originally part of the MMD Tools add-on for Blender
|
||||
# You can find MMD Tools here: https://github.com/MMD-Blender/blender_mmd_tools
|
||||
# Neoneko has modified this file to work with Avatar Toolkit and may of made changes or improvements.
|
||||
# MMD Tools is licensed under the terms of the GNU General Public License version 3 (GPLv3) same as Avatar Toolkit.
|
||||
# Copyright 2015 MMD Tools authors
|
||||
# This file is part of MMD Tools.
|
||||
|
||||
import bpy
|
||||
from typing import Optional, List, Dict, Any, Set, Tuple, Union, TypeVar, Type
|
||||
from bpy.types import PropertyGroup, Object, ShapeKey
|
||||
|
||||
from .. import utils
|
||||
from ..core.bone import FnBone
|
||||
from ..core.material import FnMaterial
|
||||
from ..core.model import FnModel, Model
|
||||
from ..core.morph import FnMorph
|
||||
from ....core.logging_setup import logger
|
||||
|
||||
|
||||
def _morph_base_get_name(prop: "_MorphBase") -> str:
|
||||
return prop.get("name", "")
|
||||
|
||||
|
||||
def _morph_base_set_name(prop: "_MorphBase", value: str) -> None:
|
||||
def _morph_base_set_name(prop: "_MorphBase", value: str):
|
||||
mmd_root = prop.id_data.mmd_root
|
||||
morph_type = "%s_morphs" % prop.bl_rna.identifier[:-5].lower()
|
||||
# morph_type = mmd_root.active_morph_type
|
||||
morph_type = f"{prop.bl_rna.identifier[:-5].lower()}_morphs"
|
||||
# assert(prop.bl_rna.identifier.endswith('Morph'))
|
||||
# logging.debug('_set_name: %s %s %s', prop, value, morph_type)
|
||||
prop_name = prop.get("name", None)
|
||||
if prop_name == value:
|
||||
return
|
||||
|
||||
used_names: Set[str] = {x.name for x in getattr(mmd_root, morph_type) if x != prop}
|
||||
used_names = {x.name for x in getattr(mmd_root, morph_type) if x != prop}
|
||||
value = utils.unique_name(value, used_names)
|
||||
if prop_name is not None:
|
||||
if morph_type == "vertex_morphs":
|
||||
kb_list: Dict[str, List[ShapeKey]] = {}
|
||||
kb_list = {}
|
||||
for mesh in FnModel.iterate_mesh_objects(prop.id_data):
|
||||
for kb in getattr(mesh.data.shape_keys, "key_blocks", ()):
|
||||
kb_list.setdefault(kb.name, []).append(kb)
|
||||
@@ -43,7 +39,7 @@ def _morph_base_set_name(prop: "_MorphBase", value: str) -> None:
|
||||
kb.name = value
|
||||
|
||||
elif morph_type == "uv_morphs":
|
||||
vg_list: Dict[str, List[Any]] = {}
|
||||
vg_list = {}
|
||||
for mesh in FnModel.iterate_mesh_objects(prop.id_data):
|
||||
for vg, n, x in FnMorph.get_uv_morph_vertex_groups(mesh):
|
||||
vg_list.setdefault(n, []).append(vg)
|
||||
@@ -72,7 +68,6 @@ def _morph_base_set_name(prop: "_MorphBase", value: str) -> None:
|
||||
kb.name = value
|
||||
|
||||
prop["name"] = value
|
||||
logger.debug(f"Renamed morph from '{prop_name}' to '{value}'")
|
||||
|
||||
|
||||
class _MorphBase:
|
||||
@@ -101,12 +96,16 @@ class _MorphBase:
|
||||
)
|
||||
|
||||
|
||||
def _bone_morph_data_update_bone_id(prop: "BoneMorphData", context: bpy.types.Context):
|
||||
pass # Empty function is sufficient to trigger UI update
|
||||
|
||||
|
||||
def _bone_morph_data_get_bone(prop: "BoneMorphData") -> str:
|
||||
bone_id: int = prop.get("bone_id", -1)
|
||||
bone_id = prop.get("bone_id", -1)
|
||||
if bone_id < 0:
|
||||
return ""
|
||||
root_object: Object = prop.id_data
|
||||
armature_object: Optional[Object] = FnModel.find_armature_object(root_object)
|
||||
root_object = prop.id_data
|
||||
armature_object = FnModel.find_armature_object(root_object)
|
||||
if armature_object is None:
|
||||
return ""
|
||||
pose_bone = FnBone.find_pose_bone_by_bone_id(armature_object, bone_id)
|
||||
@@ -115,9 +114,9 @@ def _bone_morph_data_get_bone(prop: "BoneMorphData") -> str:
|
||||
return pose_bone.name
|
||||
|
||||
|
||||
def _bone_morph_data_set_bone(prop: "BoneMorphData", value: str) -> None:
|
||||
root: Object = prop.id_data
|
||||
arm: Optional[Object] = FnModel.find_armature_object(root)
|
||||
def _bone_morph_data_set_bone(prop: "BoneMorphData", value: str):
|
||||
root = prop.id_data
|
||||
arm = FnModel.find_armature_object(root)
|
||||
|
||||
# Load the library_override file. This function is triggered when loading, but the arm obj cannot be found.
|
||||
# The arm obj is exist, but the relative relationship has not yet been established.
|
||||
@@ -125,14 +124,13 @@ def _bone_morph_data_set_bone(prop: "BoneMorphData", value: str) -> None:
|
||||
return
|
||||
|
||||
if value not in arm.pose.bones.keys():
|
||||
prop["bone_id"] = -1
|
||||
prop.bone_id = -1
|
||||
return
|
||||
pose_bone = arm.pose.bones[value]
|
||||
prop["bone_id"] = FnBone.get_or_assign_bone_id(pose_bone)
|
||||
logger.debug(f"Set bone morph data bone to '{value}' with ID {prop['bone_id']}")
|
||||
prop.bone_id = FnBone.get_or_assign_bone_id(pose_bone)
|
||||
|
||||
|
||||
def _bone_morph_data_update_location_or_rotation(prop: "BoneMorphData", _context: bpy.types.Context) -> None:
|
||||
def _bone_morph_data_update_location_or_rotation(prop: "BoneMorphData", _context):
|
||||
if not prop.name.startswith("mmd_bind"):
|
||||
return
|
||||
arm = FnModel(prop.id_data).morph_slider.dummy_armature
|
||||
@@ -141,12 +139,9 @@ def _bone_morph_data_update_location_or_rotation(prop: "BoneMorphData", _context
|
||||
if bone:
|
||||
bone.location = prop.location
|
||||
bone.rotation_quaternion = prop.rotation.__class__(*prop.rotation.to_axis_angle()) # Fix for consistency
|
||||
logger.debug(f"Updated bone morph data location/rotation for '{prop.name}'")
|
||||
|
||||
|
||||
class BoneMorphData(bpy.types.PropertyGroup):
|
||||
""" """
|
||||
|
||||
bone: bpy.props.StringProperty(
|
||||
name="Bone",
|
||||
description="Target bone",
|
||||
@@ -156,6 +151,7 @@ class BoneMorphData(bpy.types.PropertyGroup):
|
||||
|
||||
bone_id: bpy.props.IntProperty(
|
||||
name="Bone ID",
|
||||
update=_bone_morph_data_update_bone_id,
|
||||
)
|
||||
|
||||
location: bpy.props.FloatVectorProperty(
|
||||
@@ -191,61 +187,53 @@ class BoneMorph(_MorphBase, bpy.types.PropertyGroup):
|
||||
)
|
||||
|
||||
|
||||
def _material_morph_data_get_material(prop: "MaterialMorphData") -> str:
|
||||
mat_p = prop.get("material_data", None)
|
||||
if mat_p is not None:
|
||||
return mat_p.name
|
||||
def _material_morph_data_get_material(prop: "MaterialMorphData"):
|
||||
mat_data = prop.get("material_data", None)
|
||||
if mat_data is not None:
|
||||
return mat_data.name
|
||||
return ""
|
||||
|
||||
|
||||
def _material_morph_data_set_material(prop: "MaterialMorphData", value: str) -> None:
|
||||
def _material_morph_data_set_material(prop: "MaterialMorphData", value: str):
|
||||
if value not in bpy.data.materials:
|
||||
prop["material_data"] = None
|
||||
prop["material_id"] = -1
|
||||
logger.debug(f"Material '{value}' not found, setting material_data to None")
|
||||
prop.material_data = None
|
||||
prop.material_id = -1
|
||||
else:
|
||||
mat = bpy.data.materials[value]
|
||||
fnMat = FnMaterial(mat)
|
||||
prop["material_data"] = mat
|
||||
prop["material_id"] = fnMat.material_id
|
||||
logger.debug(f"Set material morph data material to '{value}' with ID {fnMat.material_id}")
|
||||
prop.material_data = mat
|
||||
prop.material_id = fnMat.material_id
|
||||
|
||||
|
||||
def _material_morph_data_set_related_mesh(prop: "MaterialMorphData", value: str) -> None:
|
||||
def _material_morph_data_set_related_mesh(prop: "MaterialMorphData", value: str):
|
||||
mesh = FnModel.find_mesh_object_by_name(prop.id_data, value)
|
||||
if mesh is not None:
|
||||
prop["related_mesh_data"] = mesh.data
|
||||
logger.debug(f"Set material morph data related mesh to '{value}'")
|
||||
prop.related_mesh_data = mesh.data
|
||||
else:
|
||||
prop["related_mesh_data"] = None
|
||||
logger.debug(f"Mesh '{value}' not found, setting related_mesh_data to None")
|
||||
prop.related_mesh_data = None
|
||||
|
||||
|
||||
def _material_morph_data_get_related_mesh(prop: "MaterialMorphData") -> str:
|
||||
mesh_p = prop.get("related_mesh_data", None)
|
||||
if mesh_p is not None:
|
||||
return mesh_p.name
|
||||
def _material_morph_data_get_related_mesh(prop):
|
||||
mesh_data = prop.get("related_mesh_data", None)
|
||||
if mesh_data is not None:
|
||||
return mesh_data.name
|
||||
return ""
|
||||
|
||||
|
||||
def _material_morph_data_update_modifiable_values(prop: "MaterialMorphData", _context: bpy.types.Context) -> None:
|
||||
def _material_morph_data_update_modifiable_values(prop: "MaterialMorphData", _context):
|
||||
if not prop.name.startswith("mmd_bind"):
|
||||
return
|
||||
from ..core.shader import _MaterialMorph
|
||||
|
||||
mat = prop["material_data"]
|
||||
if mat is not None:
|
||||
_MaterialMorph.update_morph_inputs(mat, prop)
|
||||
logger.debug(f"Updated material morph modifiable values for '{prop.name}'")
|
||||
mat_data = prop.get("material_data", None)
|
||||
if mat_data is not None:
|
||||
_MaterialMorph.update_morph_inputs(mat_data, prop)
|
||||
else:
|
||||
for mat in FnModel(prop.id_data).materials():
|
||||
_MaterialMorph.update_morph_inputs(mat, prop)
|
||||
logger.debug(f"Updated material morph modifiable values for all materials")
|
||||
for mat_data in FnModel(prop.id_data).materials():
|
||||
_MaterialMorph.update_morph_inputs(mat_data, prop)
|
||||
|
||||
|
||||
class MaterialMorphData(bpy.types.PropertyGroup):
|
||||
""" """
|
||||
|
||||
related_mesh: bpy.props.StringProperty(
|
||||
name="Related Mesh",
|
||||
description="Stores a reference to the mesh where this morph data belongs to",
|
||||
@@ -416,6 +404,9 @@ class UVMorphOffset(bpy.types.PropertyGroup):
|
||||
name="UV Offset",
|
||||
description="UV offset",
|
||||
size=4,
|
||||
# min=-1,
|
||||
# max=1,
|
||||
# precision=3,
|
||||
step=0.1,
|
||||
default=[0, 0, 0, 0],
|
||||
)
|
||||
|
||||
@@ -1,37 +1,31 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2014 MMD Tools authors
|
||||
# This file was originally part of the MMD Tools add-on for Blender
|
||||
# You can find MMD Tools here: https://github.com/MMD-Blender/blender_mmd_tools
|
||||
# Neoneko has modified this file to work with Avatar Toolkit and may of made changes or improvements.
|
||||
# MMD Tools is licensed under the terms of the GNU General Public License version 3 (GPLv3) same as Avatar Toolkit.
|
||||
# This file is part of MMD Tools.
|
||||
|
||||
from typing import cast
|
||||
|
||||
from typing import cast, Optional, Any, Union
|
||||
import bpy
|
||||
from bpy.types import Context, PropertyGroup, PoseBone, Object, Armature
|
||||
|
||||
from ..core.bone import FnBone
|
||||
from . import patch_library_overridable
|
||||
from ....core.logging_setup import logger
|
||||
|
||||
|
||||
def _mmd_bone_update_additional_transform(prop: "MMDBone", context: Context) -> None:
|
||||
prop["is_additional_transform_dirty"] = True
|
||||
def _mmd_bone_update_additional_transform(prop: "MMDBone", context: bpy.types.Context):
|
||||
prop.is_additional_transform_dirty = True
|
||||
# Apply additional transform (Assembly -> Bone button) (Very Slow)
|
||||
p_bone = context.active_pose_bone
|
||||
if p_bone and p_bone.mmd_bone.as_pointer() == prop.as_pointer():
|
||||
logger.debug(f"Applying additional transformation for {p_bone.name}")
|
||||
FnBone.apply_additional_transformation(prop.id_data)
|
||||
|
||||
|
||||
def _mmd_bone_update_additional_transform_influence(prop: "MMDBone", context: Context) -> None:
|
||||
def _mmd_bone_update_additional_transform_influence(prop: "MMDBone", context: bpy.types.Context):
|
||||
pose_bone = context.active_pose_bone
|
||||
if pose_bone and pose_bone.mmd_bone.as_pointer() == prop.as_pointer():
|
||||
logger.debug(f"Updating additional transform influence for {pose_bone.name}")
|
||||
FnBone.update_additional_transform_influence(pose_bone)
|
||||
else:
|
||||
prop["is_additional_transform_dirty"] = True
|
||||
prop.is_additional_transform_dirty = True
|
||||
|
||||
|
||||
def _mmd_bone_get_additional_transform_bone(prop: "MMDBone") -> str:
|
||||
def _mmd_bone_get_additional_transform_bone(prop: "MMDBone"):
|
||||
arm = prop.id_data
|
||||
bone_id = prop.get("additional_transform_bone_id", -1)
|
||||
if bone_id < 0:
|
||||
@@ -42,17 +36,57 @@ def _mmd_bone_get_additional_transform_bone(prop: "MMDBone") -> str:
|
||||
return pose_bone.name
|
||||
|
||||
|
||||
def _mmd_bone_set_additional_transform_bone(prop: "MMDBone", value: str) -> None:
|
||||
def _mmd_bone_set_additional_transform_bone(prop: "MMDBone", value: str):
|
||||
arm = prop.id_data
|
||||
prop["is_additional_transform_dirty"] = True
|
||||
prop.is_additional_transform_dirty = True
|
||||
|
||||
if value not in arm.pose.bones.keys():
|
||||
prop["additional_transform_bone_id"] = -1
|
||||
prop.additional_transform_bone_id = -1
|
||||
return
|
||||
|
||||
pose_bone = arm.pose.bones[value]
|
||||
prop["additional_transform_bone_id"] = FnBone.get_or_assign_bone_id(pose_bone)
|
||||
target_bone_id = FnBone.get_or_assign_bone_id(pose_bone)
|
||||
|
||||
if prop.bone_id == target_bone_id:
|
||||
prop.additional_transform_bone_id = -1
|
||||
return
|
||||
|
||||
prop.additional_transform_bone_id = target_bone_id
|
||||
|
||||
|
||||
class MMDBone(PropertyGroup):
|
||||
def _mmd_bone_update_display_connection(prop: "MMDBone", context: bpy.types.Context):
|
||||
pass # Empty function is sufficient to trigger UI update
|
||||
|
||||
|
||||
def _mmd_bone_get_display_connection_bone(prop: "MMDBone"):
|
||||
arm = prop.id_data
|
||||
bone_id = prop.get("display_connection_bone_id", -1)
|
||||
if bone_id < 0:
|
||||
return ""
|
||||
pose_bone = FnBone.find_pose_bone_by_bone_id(arm, bone_id)
|
||||
if pose_bone is None:
|
||||
return ""
|
||||
return pose_bone.name
|
||||
|
||||
|
||||
def _mmd_bone_set_display_connection_bone(prop: "MMDBone", value: str):
|
||||
arm = prop.id_data
|
||||
|
||||
if value not in arm.pose.bones.keys():
|
||||
prop.display_connection_bone_id = -1
|
||||
return
|
||||
|
||||
pose_bone = arm.pose.bones[value]
|
||||
target_bone_id = FnBone.get_or_assign_bone_id(pose_bone)
|
||||
|
||||
if prop.bone_id == target_bone_id:
|
||||
prop.display_connection_bone_id = -1
|
||||
return
|
||||
|
||||
prop.display_connection_bone_id = target_bone_id
|
||||
|
||||
|
||||
class MMDBone(bpy.types.PropertyGroup):
|
||||
name_j: bpy.props.StringProperty(
|
||||
name="Name",
|
||||
description="Japanese Name",
|
||||
@@ -188,12 +222,35 @@ class MMDBone(PropertyGroup):
|
||||
|
||||
is_additional_transform_dirty: bpy.props.BoolProperty(name="", default=True)
|
||||
|
||||
def is_id_unique(self) -> bool:
|
||||
display_connection_bone: bpy.props.StringProperty(
|
||||
name="Display Connection Bone",
|
||||
description="Target bone for display connection",
|
||||
set=_mmd_bone_set_display_connection_bone,
|
||||
get=_mmd_bone_get_display_connection_bone,
|
||||
)
|
||||
|
||||
display_connection_bone_id: bpy.props.IntProperty(
|
||||
name="Display Connection Bone ID",
|
||||
description="Bone ID for display connection (PMX displayConnection)",
|
||||
default=-1,
|
||||
update=_mmd_bone_update_display_connection,
|
||||
)
|
||||
|
||||
display_connection_type: bpy.props.EnumProperty(
|
||||
name="Display Connection Type",
|
||||
description="Type of display connection",
|
||||
items=[
|
||||
("BONE", "Bone", "Connected to a bone"),
|
||||
("OFFSET", "Offset", "Connected to an offset position"),
|
||||
],
|
||||
default="OFFSET",
|
||||
)
|
||||
|
||||
def is_id_unique(self):
|
||||
return self.bone_id < 0 or not next((b for b in self.id_data.pose.bones if b.mmd_bone != self and b.mmd_bone.bone_id == self.bone_id), None)
|
||||
|
||||
@staticmethod
|
||||
def register() -> None:
|
||||
logger.debug("Registering MMDBone properties")
|
||||
def register():
|
||||
bpy.types.PoseBone.mmd_bone = patch_library_overridable(bpy.props.PointerProperty(type=MMDBone))
|
||||
bpy.types.PoseBone.is_mmd_shadow_bone = patch_library_overridable(bpy.props.BoolProperty(name="is_mmd_shadow_bone", default=False))
|
||||
bpy.types.PoseBone.mmd_shadow_bone_type = patch_library_overridable(bpy.props.StringProperty(name="mmd_shadow_bone_type"))
|
||||
@@ -203,25 +260,24 @@ class MMDBone(PropertyGroup):
|
||||
description="MMD IK toggle is used to import/export animation of IK on-off",
|
||||
update=_pose_bone_update_mmd_ik_toggle,
|
||||
default=True,
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def unregister() -> None:
|
||||
logger.debug("Unregistering MMDBone properties")
|
||||
def unregister():
|
||||
del bpy.types.PoseBone.mmd_ik_toggle
|
||||
del bpy.types.PoseBone.mmd_shadow_bone_type
|
||||
del bpy.types.PoseBone.is_mmd_shadow_bone
|
||||
del bpy.types.PoseBone.mmd_bone
|
||||
|
||||
|
||||
def _pose_bone_update_mmd_ik_toggle(prop: PoseBone, _context: Any) -> None:
|
||||
def _pose_bone_update_mmd_ik_toggle(prop: bpy.types.PoseBone, _context):
|
||||
v = prop.mmd_ik_toggle
|
||||
armature_object = cast(Object, prop.id_data)
|
||||
armature_object = cast("bpy.types.Object", prop.id_data)
|
||||
for b in armature_object.pose.bones:
|
||||
for c in b.constraints:
|
||||
if c.type == "IK" and c.subtarget == prop.name:
|
||||
logger.debug(f"Updating IK toggle for {b.name} {c.name}")
|
||||
# logging.debug(' %s %s', b.name, c.name)
|
||||
c.influence = v
|
||||
b = b if c.use_tail else b.parent
|
||||
for b in ([b] + b.parent_recursive)[: c.chain_count]:
|
||||
|
||||
@@ -1,42 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2014 MMD Tools authors
|
||||
# This file was originally part of the MMD Tools add-on for Blender
|
||||
# You can find MMD Tools here: https://github.com/MMD-Blender/blender_mmd_tools
|
||||
# Neoneko has modified this file to work with Avatar Toolkit and may of made changes or improvements.
|
||||
# MMD Tools is licensed under the terms of the GNU General Public License version 3 (GPLv3) same as Avatar Toolkit.
|
||||
# This file is part of MMD Tools.
|
||||
|
||||
"""Properties for rigid bodies and joints"""
|
||||
|
||||
import bpy
|
||||
from typing import Optional, Any, Set, List, Dict, Tuple, Union
|
||||
from bpy.types import Context, Object, PropertyGroup, Material
|
||||
|
||||
from .. import bpyutils
|
||||
from ..core import rigid_body
|
||||
from ..core.rigid_body import RigidBodyMaterial, FnRigidBody
|
||||
from ..core.model import FnModel
|
||||
from ..core.rigid_body import FnRigidBody, RigidBodyMaterial
|
||||
from . import patch_library_overridable
|
||||
from ....core.logging_setup import logger
|
||||
|
||||
|
||||
def _updateCollisionGroup(prop: PropertyGroup, _context: Context) -> None:
|
||||
obj: Object = prop.id_data
|
||||
materials: List[Material] = obj.data.materials
|
||||
def _updateCollisionGroup(prop, _context):
|
||||
obj = prop.id_data
|
||||
materials = obj.data.materials
|
||||
if len(materials) == 0:
|
||||
materials.append(RigidBodyMaterial.getMaterial(prop.collision_group_number))
|
||||
else:
|
||||
obj.material_slots[0].material = RigidBodyMaterial.getMaterial(prop.collision_group_number)
|
||||
|
||||
|
||||
def _updateType(prop: PropertyGroup, _context: Context) -> None:
|
||||
obj: Object = prop.id_data
|
||||
def _updateType(prop, _context):
|
||||
obj = prop.id_data
|
||||
rb = obj.rigid_body
|
||||
if rb:
|
||||
rb.kinematic = int(prop.type) == rigid_body.MODE_STATIC
|
||||
|
||||
|
||||
def _updateShape(prop: PropertyGroup, _context: Context) -> None:
|
||||
obj: Object = prop.id_data
|
||||
def _updateShape(prop, _context):
|
||||
obj = prop.id_data
|
||||
|
||||
if len(obj.data.vertices) > 0:
|
||||
size = prop.size
|
||||
@@ -47,8 +40,8 @@ def _updateShape(prop: PropertyGroup, _context: Context) -> None:
|
||||
rb.collision_shape = prop.shape
|
||||
|
||||
|
||||
def _get_bone(prop: PropertyGroup) -> str:
|
||||
obj: Object = prop.id_data
|
||||
def _get_bone(prop):
|
||||
obj = prop.id_data
|
||||
relation = obj.constraints.get("mmd_tools_rigid_parent", None)
|
||||
if relation:
|
||||
arm = relation.target
|
||||
@@ -58,9 +51,9 @@ def _get_bone(prop: PropertyGroup) -> str:
|
||||
return prop.get("bone", "")
|
||||
|
||||
|
||||
def _set_bone(prop: PropertyGroup, value: str) -> None:
|
||||
bone_name: str = value
|
||||
obj: Object = prop.id_data
|
||||
def _set_bone(prop, value):
|
||||
bone_name = value
|
||||
obj = prop.id_data
|
||||
relation = obj.constraints.get("mmd_tools_rigid_parent", None)
|
||||
if relation is None:
|
||||
relation = obj.constraints.new("CHILD_OF")
|
||||
@@ -81,21 +74,24 @@ def _set_bone(prop: PropertyGroup, value: str) -> None:
|
||||
prop["bone"] = bone_name
|
||||
|
||||
|
||||
def _get_size(prop: PropertyGroup) -> Tuple[float, float, float]:
|
||||
def _get_size(prop):
|
||||
if prop.id_data.mmd_type != "RIGID_BODY":
|
||||
return (0, 0, 0)
|
||||
return FnRigidBody.get_rigid_body_size(prop.id_data)
|
||||
|
||||
|
||||
def _set_size(prop: PropertyGroup, value: Tuple[float, float, float]) -> None:
|
||||
obj: Object = prop.id_data
|
||||
def _set_size(prop, value):
|
||||
obj = prop.id_data
|
||||
assert obj.mode == "OBJECT" # not support other mode yet
|
||||
shape: str = prop.shape
|
||||
shape = prop.shape
|
||||
|
||||
mesh = obj.data
|
||||
rb = obj.rigid_body
|
||||
|
||||
if len(mesh.vertices) == 0 or rb is None or rb.collision_shape != shape:
|
||||
current_size = FnRigidBody.get_rigid_body_size(obj)
|
||||
is_zero_size = all(abs(s) < 1e-6 for s in current_size)
|
||||
|
||||
if len(mesh.vertices) == 0 or rb is None or rb.collision_shape != shape or is_zero_size:
|
||||
if shape == "SPHERE":
|
||||
bpyutils.makeSphere(
|
||||
radius=value[0],
|
||||
@@ -149,15 +145,15 @@ def _set_size(prop: PropertyGroup, value: Tuple[float, float, float]) -> None:
|
||||
mesh.update()
|
||||
|
||||
|
||||
def _get_rigid_name(prop: PropertyGroup) -> str:
|
||||
def _get_rigid_name(prop):
|
||||
return prop.get("name", "")
|
||||
|
||||
|
||||
def _set_rigid_name(prop: PropertyGroup, value: str) -> None:
|
||||
def _set_rigid_name(prop, value):
|
||||
prop["name"] = value
|
||||
|
||||
|
||||
class MMDRigidBody(PropertyGroup):
|
||||
class MMDRigidBody(bpy.types.PropertyGroup):
|
||||
name_j: bpy.props.StringProperty(
|
||||
name="Name",
|
||||
description="Japanese Name",
|
||||
@@ -230,18 +226,16 @@ class MMDRigidBody(PropertyGroup):
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def register() -> None:
|
||||
logger.debug("Registering MMDRigidBody property")
|
||||
def register():
|
||||
bpy.types.Object.mmd_rigid = patch_library_overridable(bpy.props.PointerProperty(type=MMDRigidBody))
|
||||
|
||||
@staticmethod
|
||||
def unregister() -> None:
|
||||
logger.debug("Unregistering MMDRigidBody property")
|
||||
def unregister():
|
||||
del bpy.types.Object.mmd_rigid
|
||||
|
||||
|
||||
def _updateSpringLinear(prop: PropertyGroup, context: Context) -> None:
|
||||
obj: Object = prop.id_data
|
||||
def _updateSpringLinear(prop, context):
|
||||
obj = prop.id_data
|
||||
rbc = obj.rigid_body_constraint
|
||||
if rbc:
|
||||
rbc.spring_stiffness_x = prop.spring_linear[0]
|
||||
@@ -249,8 +243,8 @@ def _updateSpringLinear(prop: PropertyGroup, context: Context) -> None:
|
||||
rbc.spring_stiffness_z = prop.spring_linear[2]
|
||||
|
||||
|
||||
def _updateSpringAngular(prop: PropertyGroup, context: Context) -> None:
|
||||
obj: Object = prop.id_data
|
||||
def _updateSpringAngular(prop, context):
|
||||
obj = prop.id_data
|
||||
rbc = obj.rigid_body_constraint
|
||||
if rbc and hasattr(rbc, "use_spring_ang_x"):
|
||||
rbc.spring_stiffness_ang_x = prop.spring_angular[0]
|
||||
@@ -258,7 +252,7 @@ def _updateSpringAngular(prop: PropertyGroup, context: Context) -> None:
|
||||
rbc.spring_stiffness_ang_z = prop.spring_angular[2]
|
||||
|
||||
|
||||
class MMDJoint(PropertyGroup):
|
||||
class MMDJoint(bpy.types.PropertyGroup):
|
||||
name_j: bpy.props.StringProperty(
|
||||
name="Name",
|
||||
description="Japanese Name",
|
||||
@@ -292,12 +286,9 @@ class MMDJoint(PropertyGroup):
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def register() -> None:
|
||||
logger.debug("Registering MMDJoint property")
|
||||
def register():
|
||||
bpy.types.Object.mmd_joint = patch_library_overridable(bpy.props.PointerProperty(type=MMDJoint))
|
||||
|
||||
@staticmethod
|
||||
def unregister() -> None:
|
||||
logger.debug("Unregistering MMDJoint property")
|
||||
def unregister():
|
||||
del bpy.types.Object.mmd_joint
|
||||
|
||||
|
||||
+87
-56
@@ -1,16 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2014 MMD Tools authors
|
||||
# This file was originally part of the MMD Tools add-on for Blender
|
||||
# You can find MMD Tools here: https://github.com/MMD-Blender/blender_mmd_tools
|
||||
# Neoneko has modified this file to work with Avatar Toolkit and may of made changes or improvements.
|
||||
# MMD Tools is licensed under the terms of the GNU General Public License version 3 (GPLv3) same as Avatar Toolkit.
|
||||
# This file is part of MMD Tools.
|
||||
|
||||
"""Properties for MMD model root object"""
|
||||
|
||||
import bpy
|
||||
from typing import Optional, List, Dict, Any, Set, Tuple, Union, Type, TypeVar, cast
|
||||
|
||||
from .. import utils
|
||||
from ..bpyutils import FnContext
|
||||
from ..core.material import FnMaterial
|
||||
from ..core.model import FnModel
|
||||
@@ -18,18 +12,19 @@ from ..core.sdef import FnSDEF
|
||||
from . import patch_library_overridable
|
||||
from .morph import BoneMorph, GroupMorph, MaterialMorph, UVMorph, VertexMorph
|
||||
from .translations import MMDTranslation
|
||||
from ....core.logging_setup import logger
|
||||
|
||||
IS_BLENDER_50_UP = bpy.app.version >= (5, 0)
|
||||
|
||||
|
||||
def __driver_variables(constraint: bpy.types.Constraint, path: str, index: int = -1) -> Tuple[bpy.types.Driver, Any]:
|
||||
def __driver_variables(constraint: bpy.types.Constraint, path: str, index=-1):
|
||||
d = constraint.driver_add(path, index)
|
||||
variables = d.driver.variables
|
||||
for x in variables:
|
||||
for x in reversed(variables):
|
||||
variables.remove(x)
|
||||
return d.driver, variables
|
||||
|
||||
|
||||
def __add_single_prop(variables: Any, id_obj: bpy.types.Object, data_path: str, prefix: str) -> Any:
|
||||
def __add_single_prop(variables, id_obj, data_path, prefix):
|
||||
var = variables.new()
|
||||
var.name = prefix + str(len(variables))
|
||||
var.type = "SINGLE_PROP"
|
||||
@@ -40,18 +35,17 @@ def __add_single_prop(variables: Any, id_obj: bpy.types.Object, data_path: str,
|
||||
return var
|
||||
|
||||
|
||||
def _toggleUsePropertyDriver(self: "MMDRoot", _context: bpy.types.Context) -> None:
|
||||
def _toggleUsePropertyDriver(self: "MMDRoot", _context):
|
||||
root_object: bpy.types.Object = self.id_data
|
||||
armature_object = FnModel.find_armature_object(root_object)
|
||||
|
||||
if armature_object is None:
|
||||
ik_map: Dict[Any, Tuple[Any, Any]] = {}
|
||||
ik_map = {}
|
||||
else:
|
||||
bones = armature_object.pose.bones
|
||||
ik_map = {bones[c.subtarget]: (b, c) for b in bones for c in b.constraints if c.type == "IK" and c.is_valid and c.subtarget in bones}
|
||||
|
||||
if self.use_property_driver:
|
||||
logger.debug("Enabling property drivers for %s", root_object.name)
|
||||
for ik, (b, c) in ik_map.items():
|
||||
driver, variables = __driver_variables(c, "influence")
|
||||
driver.expression = "%s" % __add_single_prop(variables, ik.id_data, ik.path_from_id("mmd_ik_toggle"), "use_ik").name
|
||||
@@ -66,7 +60,6 @@ def _toggleUsePropertyDriver(self: "MMDRoot", _context: bpy.types.Context) -> No
|
||||
driver, variables = __driver_variables(i, prop_hide)
|
||||
driver.expression = "not %s" % __add_single_prop(variables, root_object, "mmd_root.show_meshes", "show").name
|
||||
else:
|
||||
logger.debug("Disabling property drivers for %s", root_object.name)
|
||||
for ik, (b, c) in ik_map.items():
|
||||
c.driver_remove("influence")
|
||||
b = b if c.use_tail else b.parent
|
||||
@@ -84,35 +77,31 @@ def _toggleUsePropertyDriver(self: "MMDRoot", _context: bpy.types.Context) -> No
|
||||
# ===========================================
|
||||
|
||||
|
||||
def _toggleUseToonTexture(self: "MMDRoot", _context: bpy.types.Context) -> None:
|
||||
def _toggleUseToonTexture(self: "MMDRoot", _context):
|
||||
use_toon = self.use_toon_texture
|
||||
logger.debug("Toggling toon texture to %s for %s", use_toon, self.id_data.name)
|
||||
for i in FnModel.iterate_mesh_objects(self.id_data):
|
||||
for m in i.data.materials:
|
||||
if m:
|
||||
FnMaterial(m).use_toon_texture(use_toon)
|
||||
|
||||
|
||||
def _toggleUseSphereTexture(self: "MMDRoot", _context: bpy.types.Context) -> None:
|
||||
def _toggleUseSphereTexture(self: "MMDRoot", _context):
|
||||
use_sphere = self.use_sphere_texture
|
||||
logger.debug("Toggling sphere texture to %s for %s", use_sphere, self.id_data.name)
|
||||
for i in FnModel.iterate_mesh_objects(self.id_data):
|
||||
for m in i.data.materials:
|
||||
if m:
|
||||
FnMaterial(m).use_sphere_texture(use_sphere, i)
|
||||
|
||||
|
||||
def _toggleUseSDEF(self: "MMDRoot", _context: bpy.types.Context) -> None:
|
||||
def _toggleUseSDEF(self: "MMDRoot", _context):
|
||||
mute_sdef = not self.use_sdef
|
||||
logger.debug("Toggling SDEF to %s for %s", not mute_sdef, self.id_data.name)
|
||||
for i in FnModel.iterate_mesh_objects(self.id_data):
|
||||
FnSDEF.mute_sdef_set(i, mute_sdef)
|
||||
|
||||
|
||||
def _toggleVisibilityOfMeshes(self: "MMDRoot", context: bpy.types.Context) -> None:
|
||||
def _toggleVisibilityOfMeshes(self: "MMDRoot", context: bpy.types.Context):
|
||||
root = self.id_data
|
||||
hide = not self.show_meshes
|
||||
logger.debug("Toggling mesh visibility to %s for %s", not hide, root.name)
|
||||
for i in FnModel.iterate_mesh_objects(self.id_data):
|
||||
i.hide_set(hide)
|
||||
i.hide_render = hide
|
||||
@@ -120,30 +109,27 @@ def _toggleVisibilityOfMeshes(self: "MMDRoot", context: bpy.types.Context) -> No
|
||||
FnContext.set_active_object(context, root)
|
||||
|
||||
|
||||
def _toggleVisibilityOfRigidBodies(self: "MMDRoot", context: bpy.types.Context) -> None:
|
||||
def _toggleVisibilityOfRigidBodies(self: "MMDRoot", context: bpy.types.Context):
|
||||
root = self.id_data
|
||||
hide = not self.show_rigid_bodies
|
||||
logger.debug("Toggling rigid body visibility to %s for %s", not hide, root.name)
|
||||
for i in FnModel.iterate_rigid_body_objects(root):
|
||||
i.hide_set(hide)
|
||||
if hide and context.active_object is None:
|
||||
FnContext.set_active_object(context, root)
|
||||
|
||||
|
||||
def _toggleVisibilityOfJoints(self: "MMDRoot", context: bpy.types.Context) -> None:
|
||||
def _toggleVisibilityOfJoints(self: "MMDRoot", context):
|
||||
root_object = self.id_data
|
||||
hide = not self.show_joints
|
||||
logger.debug("Toggling joint visibility to %s for %s", not hide, root_object.name)
|
||||
for i in FnModel.iterate_joint_objects(root_object):
|
||||
i.hide_set(hide)
|
||||
if hide and context.active_object is None:
|
||||
FnContext.set_active_object(context, root_object)
|
||||
|
||||
|
||||
def _toggleVisibilityOfTemporaryObjects(self: "MMDRoot", context: bpy.types.Context) -> None:
|
||||
def _toggleVisibilityOfTemporaryObjects(self: "MMDRoot", context: bpy.types.Context):
|
||||
root_object: bpy.types.Object = self.id_data
|
||||
hide = not self.show_temporary_objects
|
||||
logger.debug("Toggling temporary object visibility to %s for %s", not hide, root_object.name)
|
||||
with FnContext.temp_override_active_layer_collection(context, root_object):
|
||||
for i in FnModel.iterate_temporary_objects(root_object):
|
||||
i.hide_set(hide)
|
||||
@@ -151,48 +137,45 @@ def _toggleVisibilityOfTemporaryObjects(self: "MMDRoot", context: bpy.types.Cont
|
||||
FnContext.set_active_object(context, root_object)
|
||||
|
||||
|
||||
def _toggleShowNamesOfRigidBodies(self: "MMDRoot", _context: bpy.types.Context) -> None:
|
||||
def _toggleShowNamesOfRigidBodies(self: "MMDRoot", _context):
|
||||
root = self.id_data
|
||||
show_names = root.mmd_root.show_names_of_rigid_bodies
|
||||
logger.debug("Toggling rigid body names to %s for %s", show_names, root.name)
|
||||
for i in FnModel.iterate_rigid_body_objects(root):
|
||||
i.show_name = show_names
|
||||
|
||||
|
||||
def _toggleShowNamesOfJoints(self: "MMDRoot", _context: bpy.types.Context) -> None:
|
||||
def _toggleShowNamesOfJoints(self: "MMDRoot", _context):
|
||||
root = self.id_data
|
||||
show_names = root.mmd_root.show_names_of_joints
|
||||
logger.debug("Toggling joint names to %s for %s", show_names, root.name)
|
||||
for i in FnModel.iterate_joint_objects(root):
|
||||
i.show_name = show_names
|
||||
|
||||
|
||||
def _setVisibilityOfMMDRigArmature(prop: "MMDRoot", v: bool) -> None:
|
||||
def _setVisibilityOfMMDRigArmature(prop: "MMDRoot", v: bool):
|
||||
root = prop.id_data
|
||||
arm = FnModel.find_armature_object(root)
|
||||
if arm is None:
|
||||
return
|
||||
if not v and bpy.context.active_object == arm:
|
||||
FnContext.set_active_object(bpy.context, root)
|
||||
logger.debug("Setting armature visibility to %s for %s", v, root.name)
|
||||
arm.hide_set(not v)
|
||||
|
||||
|
||||
def _getVisibilityOfMMDRigArmature(prop: "MMDRoot") -> bool:
|
||||
def _getVisibilityOfMMDRigArmature(prop: "MMDRoot"):
|
||||
if prop.id_data.mmd_type != "ROOT":
|
||||
return False
|
||||
arm = FnModel.find_armature_object(prop.id_data)
|
||||
return arm and not arm.hide_get()
|
||||
return arm is not None and not arm.hide_get()
|
||||
|
||||
|
||||
def _setActiveRigidbodyObject(prop: "MMDRoot", v: int) -> None:
|
||||
def _setActiveRigidbodyObject(prop: "MMDRoot", v: int):
|
||||
obj = FnContext.get_scene_objects(bpy.context)[v]
|
||||
if FnModel.is_rigid_body_object(obj):
|
||||
FnContext.set_active_and_select_single_object(bpy.context, obj)
|
||||
prop["active_rigidbody_object_index"] = v
|
||||
|
||||
|
||||
def _getActiveRigidbodyObject(prop: "MMDRoot") -> int:
|
||||
def _getActiveRigidbodyObject(prop: "MMDRoot"):
|
||||
context = bpy.context
|
||||
active_obj = FnContext.get_active_object(context)
|
||||
if FnModel.is_rigid_body_object(active_obj):
|
||||
@@ -200,14 +183,14 @@ def _getActiveRigidbodyObject(prop: "MMDRoot") -> int:
|
||||
return prop.get("active_rigidbody_object_index", 0)
|
||||
|
||||
|
||||
def _setActiveJointObject(prop: "MMDRoot", v: int) -> None:
|
||||
def _setActiveJointObject(prop: "MMDRoot", v: int):
|
||||
obj = FnContext.get_scene_objects(bpy.context)[v]
|
||||
if FnModel.is_joint_object(obj):
|
||||
FnContext.set_active_and_select_single_object(bpy.context, obj)
|
||||
prop["active_joint_object_index"] = v
|
||||
|
||||
|
||||
def _getActiveJointObject(prop: "MMDRoot") -> int:
|
||||
def _getActiveJointObject(prop: "MMDRoot"):
|
||||
context = bpy.context
|
||||
active_obj = FnContext.get_active_object(context)
|
||||
if FnModel.is_joint_object(active_obj):
|
||||
@@ -215,26 +198,26 @@ def _getActiveJointObject(prop: "MMDRoot") -> int:
|
||||
return prop.get("active_joint_object_index", 0)
|
||||
|
||||
|
||||
def _setActiveMorph(prop: "MMDRoot", v: bool) -> None:
|
||||
def _setActiveMorph(prop: "MMDRoot", v: bool):
|
||||
if "active_morph_indices" not in prop:
|
||||
prop["active_morph_indices"] = [0] * 5
|
||||
prop["active_morph_indices"][prop.get("active_morph_type", 3)] = v
|
||||
|
||||
|
||||
def _getActiveMorph(prop: "MMDRoot") -> int:
|
||||
def _getActiveMorph(prop: "MMDRoot"):
|
||||
if "active_morph_indices" in prop:
|
||||
return prop["active_morph_indices"][prop.get("active_morph_type", 3)]
|
||||
return 0
|
||||
|
||||
|
||||
def _setActiveMeshObject(prop: "MMDRoot", v: int) -> None:
|
||||
def _setActiveMeshObject(prop: "MMDRoot", v: int):
|
||||
obj = FnContext.get_scene_objects(bpy.context)[v]
|
||||
if FnModel.is_mesh_object(obj):
|
||||
FnContext.set_active_and_select_single_object(bpy.context, obj)
|
||||
prop["active_mesh_index"] = v
|
||||
|
||||
|
||||
def _getActiveMeshObject(prop: "MMDRoot") -> int:
|
||||
def _getActiveMeshObject(prop: "MMDRoot"):
|
||||
context = bpy.context
|
||||
active_obj = FnContext.get_active_object(context)
|
||||
if FnModel.is_mesh_object(active_obj):
|
||||
@@ -393,6 +376,18 @@ class MMDRoot(bpy.types.PropertyGroup):
|
||||
update=_toggleShowNamesOfJoints,
|
||||
)
|
||||
|
||||
show_japanese_name: bpy.props.BoolProperty(
|
||||
name="Japanese name",
|
||||
description="Toggle Japanese name display",
|
||||
default=True,
|
||||
)
|
||||
|
||||
show_english_name: bpy.props.BoolProperty(
|
||||
name="English name",
|
||||
description="Toggle English name display",
|
||||
default=True,
|
||||
)
|
||||
|
||||
use_toon_texture: bpy.props.BoolProperty(
|
||||
name="Use Toon Texture",
|
||||
description="Use toon texture",
|
||||
@@ -453,6 +448,15 @@ class MMDRoot(bpy.types.PropertyGroup):
|
||||
default=0,
|
||||
)
|
||||
|
||||
# *************************
|
||||
# Bone
|
||||
# *************************
|
||||
active_bone_index: bpy.props.IntProperty(
|
||||
name="Active Bone Index",
|
||||
description="Index of the active bone in the armature",
|
||||
default=0,
|
||||
)
|
||||
|
||||
# *************************
|
||||
# Morph
|
||||
# *************************
|
||||
@@ -513,29 +517,40 @@ class MMDRoot(bpy.types.PropertyGroup):
|
||||
|
||||
@staticmethod
|
||||
def __get_select(prop: bpy.types.Object) -> bool:
|
||||
utils.warn_deprecation("Object.select", "v4.0.0", "Use Object.select_get() method instead")
|
||||
# TODO: Object.select is deprecated since v4.0.0, use Object.select_get() method instead
|
||||
# utils.warn_deprecation("Object.select", "v4.0.0", "Use Object.select_get() method instead")
|
||||
return prop.select_get()
|
||||
|
||||
@staticmethod
|
||||
def __set_select(prop: bpy.types.Object, value: bool) -> None:
|
||||
utils.warn_deprecation("Object.select", "v4.0.0", "Use Object.select_set() method instead")
|
||||
# TODO: Object.select is deprecated since v4.0.0, use Object.select_set() method instead
|
||||
# utils.warn_deprecation("Object.select", "v4.0.0", "Use Object.select_set() method instead")
|
||||
prop.select_set(value)
|
||||
|
||||
@staticmethod
|
||||
def __get_hide(prop: bpy.types.Object) -> bool:
|
||||
utils.warn_deprecation("Object.hide", "v4.0.0", "Use Object.hide_get() method instead")
|
||||
# TODO: Object.hide is deprecated since v4.0.0, use Object.hide_get() method instead
|
||||
# utils.warn_deprecation("Object.hide", "v4.0.0", "Use Object.hide_get() method instead")
|
||||
return prop.hide_get()
|
||||
|
||||
@staticmethod
|
||||
def __set_hide(prop: bpy.types.Object, value: bool) -> None:
|
||||
utils.warn_deprecation("Object.hide", "v4.0.0", "Use Object.hide_set() method instead")
|
||||
# TODO: Object.hide is deprecated since v4.0.0, use Object.hide_set() method instead
|
||||
# utils.warn_deprecation("Object.hide", "v4.0.0", "Use Object.hide_set() method instead")
|
||||
prop.hide_set(value)
|
||||
if prop.hide_viewport != value:
|
||||
prop.hide_viewport = value
|
||||
|
||||
@staticmethod
|
||||
def register() -> None:
|
||||
logger.debug("Registering MMDRoot property group")
|
||||
def __get_pose_bone_select(prop: bpy.types.PoseBone) -> bool:
|
||||
return prop.bone.select
|
||||
|
||||
@staticmethod
|
||||
def __set_pose_bone_select(prop: bpy.types.PoseBone, value: bool) -> None:
|
||||
prop.bone.select = value
|
||||
|
||||
@staticmethod
|
||||
def register():
|
||||
bpy.types.Object.mmd_type = patch_library_overridable(
|
||||
bpy.props.EnumProperty(
|
||||
name="Type",
|
||||
@@ -557,7 +572,7 @@ class MMDRoot(bpy.types.PropertyGroup):
|
||||
("SPRING_CONSTRAINT", "Spring Constraint", "", 53),
|
||||
("SPRING_GOAL", "Spring Goal", "", 54),
|
||||
],
|
||||
)
|
||||
),
|
||||
)
|
||||
bpy.types.Object.mmd_root = patch_library_overridable(bpy.props.PointerProperty(type=MMDRoot))
|
||||
|
||||
@@ -570,7 +585,7 @@ class MMDRoot(bpy.types.PropertyGroup):
|
||||
"ANIMATABLE",
|
||||
"LIBRARY_EDITABLE",
|
||||
},
|
||||
)
|
||||
),
|
||||
)
|
||||
bpy.types.Object.hide = patch_library_overridable(
|
||||
bpy.props.BoolProperty(
|
||||
@@ -581,13 +596,29 @@ class MMDRoot(bpy.types.PropertyGroup):
|
||||
"ANIMATABLE",
|
||||
"LIBRARY_EDITABLE",
|
||||
},
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
if not IS_BLENDER_50_UP:
|
||||
bpy.types.PoseBone.select = patch_library_overridable(
|
||||
bpy.props.BoolProperty(
|
||||
name="Select",
|
||||
description="Pose bone selection state (compatibility layer for Blender 4.x, forwards to bone.select)",
|
||||
get=MMDRoot.__get_pose_bone_select,
|
||||
set=MMDRoot.__set_pose_bone_select,
|
||||
options={
|
||||
"SKIP_SAVE",
|
||||
"ANIMATABLE",
|
||||
"LIBRARY_EDITABLE",
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def unregister() -> None:
|
||||
logger.debug("Unregistering MMDRoot property group")
|
||||
def unregister():
|
||||
del bpy.types.Object.hide
|
||||
del bpy.types.Object.select
|
||||
del bpy.types.Object.mmd_root
|
||||
del bpy.types.Object.mmd_type
|
||||
if not IS_BLENDER_50_UP:
|
||||
del bpy.types.PoseBone.select
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2014 MMD Tools authors
|
||||
# This file was originally part of the MMD Tools add-on for Blender
|
||||
# You can find MMD Tools here: https://github.com/MMD-Blender/blender_mmd_tools
|
||||
# Neoneko has modified this file to work with Avatar Toolkit and may of made changes or improvements.
|
||||
# MMD Tools is licensed under the terms of the GNU General Public License version 3 (GPLv3) same as Avatar Toolkit.
|
||||
# Copyright 2021 MMD Tools authors
|
||||
# This file is part of MMD Tools.
|
||||
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
|
||||
Reference in New Issue
Block a user