# -*- coding: utf-8 -*-
import maya.cmds as cmds
import webbrowser
def lcRig_open_help_url(*_):
webbrowser.open("https://www.google.com/")
def lcRig_get_parent():
items = cmds.textScrollList("lcRig_parentList", q=True, allItems=True) or []
return items[0] if items else ""
def lcRig_get_children():
items = cmds.textScrollList("lcRig_childList", q=True, allItems=True)
return [i.strip() for i in items] if items else []
def lcRig_update_display_parent(*_):
sel = cmds.ls(sl=True)
if not sel or len(sel) != 1:
cmds.warning(u"親は1つだけ選択してください。")
return
cmds.textScrollList("lcRig_parentList", e=True, removeAll=True)
cmds.textScrollList("lcRig_parentList", e=True, append=sel[0])
def lcRig_update_display_children(*_):
sel = cmds.ls(sl=True)
if not sel:
cmds.warning(u"子オブジェクトを1つ以上選択してください。")
return
existing = cmds.textScrollList("lcRig_childList", q=True, allItems=True) or []
for s in sel:
if s not in existing:
cmds.textScrollList("lcRig_childList", e=True, append=s)
def lcRig_reset_selection(*_):
cmds.textScrollList("lcRig_parentList", e=True, removeAll=True)
cmds.textScrollList("lcRig_childList", e=True, removeAll=True)
def lcRig_is_locked_or_hidden(obj, attrs):
for attr in attrs:
full_attr = f"{obj}.{attr}"
if not cmds.objExists(full_attr):
continue
if cmds.getAttr(full_attr, lock=True):
return True
if not cmds.getAttr(full_attr, keyable=True) and not cmds.getAttr(full_attr, channelBox=True):
return True
return False
def lcRig_lock_attrs(obj, attrs):
for attr in attrs:
if cmds.objExists(f"{obj}.{attr}"):
cmds.setAttr(f"{obj}.{attr}", lock=True, keyable=False, channelBox=False)
def lcRig_match_transform(target, source):
pos = cmds.xform(source, q=True, ws=True, t=True)
rot = cmds.xform(source, q=True, ws=True, ro=True)
cmds.xform(target, ws=True, t=pos)
cmds.xform(target, ws=True, ro=rot)
def lcRig_create_unique_name(base_name):
if not cmds.objExists(base_name):
return base_name
i = 1
while cmds.objExists(f"{base_name}{i}"):
i += 1
return f"{base_name}{i}"
def lcRig_create_control_pair(common_parent, child_obj):
skip_t = lcRig_is_locked_or_hidden(child_obj, ["translateX", "translateY", "translateZ"])
skip_r = lcRig_is_locked_or_hidden(child_obj, ["rotateX", "rotateY", "rotateZ"])
locator_trans = None
if not skip_t:
loc_d = f"TH_{child_obj}_translrig"
if cmds.objExists(loc_d):
cmds.delete(loc_d)
locator_trans = cmds.spaceLocator(name=loc_d)[0]
cmds.delete(cmds.pointConstraint(child_obj, locator_trans))
cmds.parent(locator_trans, common_parent)
pc = cmds.pointConstraint(child_obj, locator_trans, mo=False)[0]
start = cmds.playbackOptions(q=True, min=True)
end = cmds.playbackOptions(q=True, max=True)
cmds.bakeResults(locator_trans, t=(start, end), at=["translate"], simulation=True, preserveOutsideKeys=True)
cmds.delete(pc)
lcRig_lock_attrs(locator_trans, ["rotateX", "rotateY", "rotateZ", "scaleX", "scaleY", "scaleZ"])
if not skip_r:
loc_e = f"TH_{child_obj}_orientrig"
if cmds.objExists(loc_e):
cmds.delete(loc_e)
locator_rot = cmds.spaceLocator(name=loc_e)[0]
lcRig_match_transform(locator_rot, child_obj)
cmds.parent(locator_rot, locator_trans if locator_trans else common_parent)
lcRig_lock_attrs(locator_rot, ["translateX", "translateY", "translateZ", "scaleX", "scaleY", "scaleZ"])
oc = cmds.orientConstraint(child_obj, locator_rot, mo=False)[0]
start = cmds.playbackOptions(q=True, min=True)
end = cmds.playbackOptions(q=True, max=True)
cmds.bakeResults(locator_rot, t=(start, end), at=["rotate"], simulation=True, preserveOutsideKeys=True)
cmds.delete(oc)
cmds.orientConstraint(locator_rot, child_obj, mo=True)
if locator_trans:
cmds.pointConstraint(locator_trans, child_obj, mo=True)
print(f"[OK] {child_obj} → ローカル制御構造 作成完了")
def lcRig_execute_all(*_):
parent = lcRig_get_parent()
children = lcRig_get_children()
if not parent or not children:
cmds.warning(u"親と子オブジェクトを選択してください。")
return
if parent in children:
cmds.confirmDialog(
title="エラー",
message="親と子に同じオブジェクトが含まれています。\n修正してください。",
button=["OK"]
)
return
raw_parent_name = f"TH_{parent}_pivot_parent"
unique_parent_name = lcRig_create_unique_name(raw_parent_name)
common_parent = cmds.spaceLocator(name=unique_parent_name)[0]
cmds.delete(cmds.pointConstraint(parent, common_parent))
cmds.parentConstraint(parent, common_parent, mo=False)
lcRig_lock_attrs(common_parent, [
"translateX", "translateY", "translateZ",
"rotateX", "rotateY", "rotateZ",
"scaleX", "scaleY", "scaleZ"
])
for child in children:
lcRig_create_control_pair(common_parent, child)
cmds.inViewMessage(amg=u"ローカル制御リグ構築完了", pos="midCenter", fade=True)
lcRig_reset_selection()
def lcRig_build_ui():
win = "lc_localControlRigUI"
if cmds.window(win, exists=True):
cmds.deleteUI(win)
cmds.window(win, title=u"ローカル制御リグ構築", sizeable=False, menuBar=True)
cmds.menu(label=u"ヘルプ", helpMenu=True)
cmds.menuItem(label=u"ドキュメントを開く", command=lcRig_open_help_url)
cmds.columnLayout(adjustableColumn=True, rowSpacing=10, columnAttach=("both", 2), columnOffset=("both", 2))
cmds.separator(h=1)
cmds.textScrollList("lcRig_parentList", allowMultiSelection=False, height=30)
cmds.button(label=u"親を登録", command=lcRig_update_display_parent)
cmds.separator(h=8)
cmds.textScrollList("lcRig_childList", allowMultiSelection=True, height=80)
cmds.button(label=u"子を登録(追加入力)", command=lcRig_update_display_children)
cmds.separator(h=10)
cmds.button(label=u"実行(ローカル制御構築)", command=lcRig_execute_all, bgc=(0.2, 0.5, 0.3))
cmds.rowLayout(numberOfColumns=1, columnAlign1="left")
cmds.button(label=u"選択をリセット", width=100, command=lcRig_reset_selection, bgc=(0.3, 0.3, 0.3))
cmds.setParent('..')
cmds.showWindow(win)
# 起動
lcRig_build_ui()
- 前ページ
- 次ページ