Skip to content

Instantly share code, notes, and snippets.

@FryPotato893
Last active April 25, 2023 21:51
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save FryPotato893/932a983ce4e3a6f98e6840bb15f94b2a to your computer and use it in GitHub Desktop.
Save FryPotato893/932a983ce4e3a6f98e6840bb15f94b2a to your computer and use it in GitHub Desktop.
【Maya Python API2.0】 選択したNurbsCurve上にLocatorを作成。
# -*- coding:utf-8 -*-
import maya.cmds as cmds
import maya.api.OpenMaya as om
def setLocatorOnNurbsCurve(value, connect=True):
u"""
概要:
選択したNurbsCurve上にLocatorを作成。
引数:
value(int) : 作成するロケーターの数。
connect(bool) : カーブにロケータをコネクト。
戻り値:
string[] : 作成されたロケーター名。
"""
# 選択したNurbsCurveをMFnに格納
sel = om.MGlobal.getActiveSelectionList()
dagPath = sel.getDagPath(0)
curveFn = om.MFnNurbsCurve(dagPath)
# CVの数を取得
val = value
cvs = curveFn.length()
locList = []
for i in range(int(val)):
param = curveFn.findParamFromLength(cvs / (val - 1) * i)
# ワールドスペースを宣言
space = om.MSpace.kWorld
# CVのポジション、タンジェント、ノーマル情報を取得
position = curveFn.getPointAtParam(param, space)
tangent = curveFn.tangent(param, space)
# 何故かノーマルだけエラーが出たので、最初と最後だけパラメーター値をずらす
if i == 0:
normal = curveFn.normal(param + 0.0001, space)
elif (i + 1) == val:
normal = curveFn.normal(param - 0.0001, space)
else:
normal = curveFn.normal(param, space)
# タンジェント、ノーマルの外積を求める
binormal = tangent ^ normal
# 求めたベクトル情報をマトリックスへ変換
worldMatrix = [tangent.x, tangent.y, tangent.z, 0,
normal.x, normal.y, normal.z, 0,
binormal.x, binormal.y, binormal.z, 0,
position.x, position.y, position.z, 0, ]
# ロケーターを作成し、位置回転情報を代入
loc = cmds.spaceLocator()
cmds.xform(loc, matrix=worldMatrix)
locList.append(loc[0])
if connect:
# ノード作成
poci = cmds.createNode("pointOnCurveInfo")
vecX = cmds.createNode("vectorProduct")
vecZ = cmds.createNode("vectorProduct")
mat = cmds.createNode("fourByFourMatrix")
dec = cmds.createNode("decomposeMatrix")
# セット
cmds.setAttr(poci + ".parameter", param)
cmds.setAttr(vecX + ".input1Y", 1)
cmds.setAttr(cmds.listRelatives(loc[0], s=True)[0]+".localScale", 10, 10, 10)
# コネクト
cmds.connectAttr(curveFn.fullPathName() + ".worldSpace[0]",
poci + ".inputCurve")
cmds.connectAttr(poci + ".tangent", vecX + ".input2")
cmds.connectAttr(vecX + ".output", vecZ + ".input2")
cmds.connectAttr(poci + ".tangent", vecZ + ".input1")
cmds.connectAttr(poci + ".tangentX", mat + ".in00")
cmds.connectAttr(poci + ".tangentY", mat + ".in01")
cmds.connectAttr(poci + ".tangentZ", mat + ".in02")
cmds.connectAttr(vecZ + ".outputX", mat + ".in10")
cmds.connectAttr(vecZ + ".outputY", mat + ".in11")
cmds.connectAttr(vecZ + ".outputZ", mat + ".in12")
cmds.connectAttr(vecX + ".outputX", mat + ".in20")
cmds.connectAttr(vecX + ".outputY", mat + ".in21")
cmds.connectAttr(vecX + ".outputZ", mat + ".in22")
cmds.connectAttr(poci + ".positionX", mat + ".in30")
cmds.connectAttr(poci + ".positionY", mat + ".in31")
cmds.connectAttr(poci + ".positionZ", mat + ".in32")
cmds.connectAttr(mat + ".output", dec + ".inputMatrix")
cmds.connectAttr(dec + ".outputTranslate", loc[0] + ".t")
cmds.connectAttr(dec + ".outputRotate", loc[0] + ".r")
return locList
setLocatorOnNurbsCurve(4, connect=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment