mayaでnurbsCurveをアニメーションさせたい

nurbsCurveをアニメーションさせたいなぁと

たとえば　左から右のように形状を変化させたい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/bb408209-4820-c0a3-8ac1-137ef9fbc485.png)

CV数が一致してたらCVにキーフレームを打ってしまってお終いなのですが、
任意のCV数同士のカーブをうまい事アニメーションさせたい。

別件で気づいた
-
別のことやってて気づいたのですが、
nurbsCurveのloftってCV数違ってもつながってくれるんですよね。
format = CVs で実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/9b36fffe-e1ce-81ae-9b29-b3466b5740d6.png)

あれはCV数はどうやって解決してるんだろうとみてみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/d36f0fa4-2be9-b4f4-c5fc-7c558689d7e7.png)

イイ感じに増やしてくれてるなぁ


loftに頼る
-
loftに頼ってみよう

- キーポーズのカーブを定義
- カーブ同士をloftでつなげる（rebuild)
- キーポーズと同一の場所のCVを取得
- アニメーション

こんな流れでできるか？


キーポーズのカーブを定義
-
はい　定義
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/532c9c9e-cb0a-bb45-fa6d-b7b7b302839e.png)

カーブ同士をloftでつなげる
-

```python
curves = ["curve1","curve2","curve3"]

##loftノード作る
loftNode = cmds.createNode("loft")
cmds.setAttr(loftNode + ".degree",1)
cmds.setAttr(loftNode + ".uniform",1)
cmds.setAttr(loftNode + ".reverseSurfaceNormals",0)
cmds.setAttr(loftNode + ".autoReverse",0)

for i in range(0,len(curves)):
    sourcePlug = curves[i] + ".worldSpace[0]"
    targetPlug = loftNode + ".inputCurve["+str(i)+"]"
    cmds.connectAttr(sourcePlug,targetPlug,f =True)
```

ちょっと結果が判りづらいので、一時的にnurbsSurfaceを追加

```python
curves = ["curve1","curve2","curve3"]

##出力用srf
outputSrf = cmds.createNode("transform", name = "output_srf")
cmds.createNode("nurbsSurface", name = "output_srfShape", p = outputSrf)

##loftノード作る
loftNode = cmds.createNode("loft")
cmds.connectAttr(loftNode + ".outputSurface",outputSrf + ".create")
cmds.setAttr(loftNode + ".degree",1)
cmds.setAttr(loftNode + ".uniform",1)
cmds.setAttr(loftNode + ".reverseSurfaceNormals",0)
cmds.setAttr(loftNode + ".autoReverse",0)

for i in range(0,len(curves)):
    sourcePlug = curves[i] + ".worldSpace[0]"
    targetPlug = loftNode + ".inputCurve["+str(i)+"]"
    cmds.connectAttr(sourcePlug,targetPlug,f =True)
```

びろーん
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/bcc9e0d7-cf74-b495-480f-7f97b5355a5f.png)


キーポーズと同一の場所のCVを取得
-
キーポーズと同一の場所のCV・・・
同一の場所・・・
うーん・・・

```
select -r output_srf.cv[0][29] ;
select -tgl output_srf.cv[1][29] ;
select -tgl output_srf.cv[2][29] ;
```

なるほど 1つ目のindexを考えれば良いか。

```python
curves = ["curve1","curve2","curve3"]

##出力用srf
outputSrf = cmds.createNode("transform", name = "output_srf")
cmds.createNode("nurbsSurface", name = "output_srfShape", p = outputSrf)

##loftノード作る
loftNode = cmds.createNode("loft")
cmds.connectAttr(loftNode + ".outputSurface",outputSrf + ".create")
cmds.setAttr(loftNode + ".degree",1)
cmds.setAttr(loftNode + ".uniform",1)
cmds.setAttr(loftNode + ".reverseSurfaceNormals",0)
cmds.setAttr(loftNode + ".autoReverse",0)

for i in range(0,len(curves)):
    sourcePlug = curves[i] + ".worldSpace[0]"
    targetPlug = loftNode + ".inputCurve["+str(i)+"]"
    cmds.connectAttr(sourcePlug,targetPlug,f =True)

##rebuild後のCV位置を取得
sellist = om.MGlobal.getSelectionListByName(outputSrf)        
outputSrfFnShape = om.MFnNurbsSurface(sellist.getDagPath(0))
CVNum_V = outputSrfFnShape.numCVsInV
rebuildCVs = []
for i in range(0,len(curves)):
    rebuildCV = []
    for param in range(0,CVNum_V):
        position = outputSrfFnShape.cvPosition(i,param)
        rebuildCV.append([position[0],position[1],position[2]])
    rebuildCVs.append(rebuildCV)


```

アニメーション
-
アニメーションさせる為のカーブを新しく用意しなくてはならんかった。
CV数がrebuild後と一致してるカーブをどうすっかなぁ
そもそもloftしたsurfaceのカーブってどうなってんだろ？
isoparamからカーブに変換できなかったっけかー
curves > duplicate srface curves で出来ました。

なるほど
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/3a22d94d-76de-aa71-5b9d-20ec8dcb7b63.png)


ついでになるほどノード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/0c529021-a76c-6f71-4661-6235e3e8ed9f.png)


ん？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/d65670e2-437e-8168-7a4e-893fd2b1abf4.png)

ここアニメーションさせればよくない？



```python
curves = ["curve1","curve2","curve3"]

##出力用srf
outputSrf = cmds.createNode("transform", name = "output_srf")
cmds.createNode("nurbsSurface", name = "output_srfShape", p = outputSrf)

##loftノード作る
loftNode = cmds.createNode("loft")
cmds.connectAttr(loftNode + ".outputSurface",outputSrf + ".create")
cmds.setAttr(loftNode + ".degree",1)
cmds.setAttr(loftNode + ".uniform",1)
cmds.setAttr(loftNode + ".reverseSurfaceNormals",0)
cmds.setAttr(loftNode + ".autoReverse",0)

for i in range(0,len(curves)):
    sourcePlug = curves[i] + ".worldSpace[0]"
    targetPlug = loftNode + ".inputCurve["+str(i)+"]"
    cmds.connectAttr(sourcePlug,targetPlug,f =True)

##出力カーブ生成
outputCurve = cmds.createNode("transform", name = "output_cv")
cmds.createNode("nurbsCurve", name = "output_cvShape", p = outputCurve)

##curveFromSurfaceIso
isoCurve = cmds.createNode("curveFromSurfaceIso")
cmds.setAttr(isoCurve + ".isoparmDirection",1)
cmds.setAttr(isoCurve + ".relativeValue",1)
cmds.setAttr(isoCurve + ".isoparmValue",0)
cmds.connectAttr(loftNode + ".outputSurface",isoCurve + ".inputSurface")
cmds.connectAttr(isoCurve + ".outputCurve", outputCurve + ".create", f=True)

```

わーい　アニメーションできました

https://vimeo.com/manage/videos/888764412