前回の「UVの傾きを計算して水平・垂直にする!! part1」の続き、今度はプログラムに落とし込んでいきます!
選択の取得
まずは、選択の取得です。今回は2つのUVを選択してもらい処理を開始したいので、「filterExpand」を使って取得します。選択がない場合、2つのUV選択でない場合は、処理を続行しないようにしましょう。
import math from maya import cmds def main(): uvs = cmds.filterExpand(sm=35) if not uvs or len(uvs) != 2: return False
UVの座標を取得
UVの座標を取得するには、「polyEditUV」をクエリーモードで実行すればOKです!それぞれ変数「pointA」「pointB」に代入します。
import math from maya import cmds def main(): uvs = cmds.filterExpand(sm=35) if not uvs or len(uvs) != 2: return False pointA = cmds.polyEditUV(uvs[0], q=True) pointB = cmds.polyEditUV(uvs[1], q=True)
2点のベクトルを求める
取得した座標を元に、2点のベクトルを求めていきます。計算は終点の座標から始点の座標を引き算するだけですが、ちょっと問題があります。
filterExpandを使って取得したコンポーネントのリストは、インデックスが若い順番になってしまいます。。。っということは、、、
どちらの向きでベクトルができるかわからなくなってしまいます、、、後々の計算を簡単にを楽にするために、「-90°~90°」の範囲に制限して計算を行いたいと思いました。
コレをやるには、「Uの座標が大きい点を終点」っとしてすることで可能になります。画像にすると、このようになります。
これがどのように役立つかは、後ほどわかります!(`・ω・´)ゞ
import math from maya import cmds def main(): uvs = cmds.filterExpand(sm=35) if not uvs or len(uvs) != 2: return False pointA = cmds.polyEditUV(uvs[0], q=True) pointB = cmds.polyEditUV(uvs[1], q=True) if pointA[0] >= pointB[0]: u = pointA[0] - pointB[0] v = pointA[1] - pointB[1] else: u = pointB[0] - pointA[0] v = pointB[1] - pointA[1]
角度を求める
前回の記事で考えたように、「atan2」を使ってやっていきたいと思います。厳密には(-90°~90°)に制限しているので「atan」でいいのですが、0の割り算の対応が面倒なので「atan2」にしました。
import math from maya import cmds def main(): uvs = cmds.filterExpand(sm=35) if not uvs or len(uvs) != 2: return False pointA = cmds.polyEditUV(uvs[0], q=True) pointB = cmds.polyEditUV(uvs[1], q=True) if pointA[0] >= pointB[0]: u = pointA[0] - pointB[0] v = pointA[1] - pointB[1] else: u = pointB[0] - pointA[0] v = pointB[1] - pointA[1] angle = math.degrees(math.atan2(v, u))#(1)
atan2の角度は、「ラジアル」と言われる単位で返って来るので、馴染みのある「度」に変換して、変数「angle」に代入します(1)。
水平・垂直にする角度を求める
UVの傾きがわかったところで、UVを水平にするのか、垂直にするのか考える必要があります。
そこで、今回は、「45°」「-45°」を境目に水平か、垂直にするか決めたいと思います。コレをシンプルにやるために、先程「-90°~90°」の範囲に制限しました!
import math from maya import cmds def main(): uvs = cmds.filterExpand(sm=35) if not uvs or len(uvs) != 2: return False pointA = cmds.polyEditUV(uvs[0], q=True) pointB = cmds.polyEditUV(uvs[1], q=True) if pointA[0] >= pointB[0]: u = pointA[0] - pointB[0] v = pointA[1] - pointB[1] else: u = pointB[0] - pointA[0] v = pointB[1] - pointA[1] angle = math.degrees(math.atan2(v, u)) if angle > -45 and angle < 45:#(1) angle = - angle elif angle > 45 and angle < 90:#(2) angle = 90 - angle elif angle < -45 and angle > -90:#(3) angle = 90 + angle angle = -angle
傾きが「-45°~45°」の場合は、傾きの逆値になるように変数「angle」を補正します。傾きが30°なら-30°回転することで水平になる!っということです(1)。
傾きが「45°~89.999999°」の場合は、「90°」から傾きの角度を引き算して、三角形の残りの角度を求めます(2)。
「-45°~-89.999999°」の場合は、「90°」に傾きを足し算して、逆値にします(3)。
UVシェルの取得
傾きを直したいのはUVのシェルになりますが、選択してもらったのは2点のUVだけです。なので、この2点のUVをシェルに変更し、回転させるUVを見つけておきます。
コチラについては、以前の「選択したコンポーネントのShellを取得する!!」をご覧ください。
import math from maya import cmds def main(): uvs = cmds.filterExpand(sm=35) if not uvs or len(uvs) != 2: return False pointA = cmds.polyEditUV(uvs[0], q=True) pointB = cmds.polyEditUV(uvs[1], q=True) if pointA[0] >= pointB[0]: u = pointA[0] - pointB[0] v = pointA[1] - pointB[1] else: u = pointB[0] - pointA[0] v = pointB[1] - pointA[1] angle = math.degrees(math.atan2(v, u)) if angle > -45 and angle < 45: angle = - angle elif angle > 45 and angle < 90: angle = 90 - angle elif angle < -45 and angle > -90: angle = 90 + angle angle = -angle cmds.polySelectConstraint(mode=2, shell=True) cmds.polySelectConstraint(bo=0, mode=0, shell=False) shell = cmds.ls(sl=True, fl=True)
回転の起点を求める
始点か、終点を中心に回転してもいいのですが、今回はUVシェルのBoundingBoxのセンターで回転させてたいと思います。
import math from maya import cmds def main(): uvs = cmds.filterExpand(sm=35) if not uvs or len(uvs) != 2: return False pointA = cmds.polyEditUV(uvs[0], q=True) pointB = cmds.polyEditUV(uvs[1], q=True) if pointA[0] >= pointB[0]: u = pointA[0] - pointB[0] v = pointA[1] - pointB[1] else: u = pointB[0] - pointA[0] v = pointB[1] - pointA[1] angle = math.degrees(math.atan2(v, u)) if angle > -45 and angle < 45: angle = - angle elif angle > 45 and angle < 90: angle = 90 - angle elif angle < -45 and angle > -90: angle = 90 + angle angle = -angle cmds.polySelectConstraint(mode=2, shell=True) cmds.polySelectConstraint(bo=0, mode=0, shell=False) shell = cmds.ls(sl=True, fl=True) boudingBox = cmds.polyEvaluate(bc2=True)#(1) centerU = (boudingBox[0][0] + boudingBox[0][1]) / 2 centerV = (boudingBox[1][0] + boudingBox[1][1]) / 2#(2)
UVのシェルを取得するために、Maya上で選択が変わっている状態になっているので「polyEvaluate」を使えば、UVの最小値、最大値を簡単に取得することができます(1)。
それぞれ最小値と最大値を足し算し、2で割ることで、UVシェルのセンターを取得することができます(2)。
傾きを修正する
import math from maya import cmds def main(): uvs = cmds.filterExpand(sm=35) if not uvs or len(uvs) != 2: return False pointA = cmds.polyEditUV(uvs[0], q=True) pointB = cmds.polyEditUV(uvs[1], q=True) if pointA[0] >= pointB[0]: u = pointA[0] - pointB[0] v = pointA[1] - pointB[1] else: u = pointB[0] - pointA[0] v = pointB[1] - pointA[1] angle = math.degrees(math.atan2(v, u)) if angle > -45 and angle < 45: angle = - angle elif angle > 45 and angle < 90: angle = 90 - angle elif angle < -45 and angle > -90: angle = 90 + angle angle = -angle cmds.polySelectConstraint(mode=2, shell=True) cmds.polySelectConstraint(bo=0, mode=0, shell=False) shell = cmds.ls(sl=True, fl=True) boudingBox = cmds.polyEvaluate(bc2=True) centerU = (boudingBox[0][0] + boudingBox[0][1]) / 2 centerV = (boudingBox[1][0] + boudingBox[1][1]) / 2 cmds.polyEditUV(angle=angle, pivotU=centerU, pivotV=centerV)#(1) cmds.select(uvs)#(2)
最後に計算して求めた角度と、UVのセンターを指定して回転させて傾きを修正します(1)。
このまま終わってしまうとUVシェルが選択された状態になってしまうので、もともと選択されていたUVに選択を戻して終わりです(2)。
あれこれ色々やりましたが、コード自体は40行ほどで思ったよりシンプルになりました。これでキッチリUVの傾きを調整できるので、几帳面な人にも、めんどくさがり屋の人にもモッテコイなのではないでしょうか!?(*´ω`*)
この記事がイイネ!っと思ったら、ぜひSNSで拡散お願い致します!