maya latticeのdivを幅維持したまま増やしたい

latticeの格子の幅を調整したわいいけど、もう少し全体を大きくしたい。
けれどもlatticeのスケールを変えると、格子の幅を再度調整し直し。
面倒なので、同じ幅の格子を追加できるようなスクリプトを書いてしまおう。

設計
-

順序としては
- 全体の幅を取得
- 格子1個あたりの幅を取得
- 格子n個分の幅を全体幅に追加し、スケール値を算出
- latticeに格子n個追加

こんな感じでしょうか。

全体の幅を取得
-

latticeの縦・横・奥行の各長さを取りたい。
バウンディングボックスでも取れるが、latticeのコントロールポイントは規則正しく並んでいるので

一番最初　lattice.pt[0][0][0] と　
一番最後  lattice.pt[-1][-1][-1] の

コントロールポイント位置を取得してやってみる。

一番最後のindexを取るためにまず各方向のdivisionsを取得
 
    divS = cmds.getAttr(lattice + ".sDivisions")
    divT = cmds.getAttr(lattice + ".tDivisions")
    divU = cmds.getAttr(lattice + ".uDivisions")

これを使って、最初と最後のコントロールポイントの位置を取得する。

    minPoint = cmds.xform(lattice + ".pt[0][0][0]",q =True,ws =True,t =True)
    maxPoint = cmds.xform(lattice + ".pt["+str(divS-1)+"]["+str(divT-1)+"]["+str(divU-1)+"]",q =True,ws =True,t =True)


格子1個あたりの幅を取得
-

格子1つあたりの幅を取得するには、軸方向の長さを軸の格子数 -1 で割ればいい。
各軸の長さは、1つ前で求めた最大・最小位置から算出。

    lengthS = (maxPoint[0] - minPoint[0])/(divS-1)
    lengthT = (maxPoint[1] - minPoint[1])/(divT-1)
    lengthU = (maxPoint[2] - minPoint[2])/(divU-1)


格子n個分の幅を全体幅に追加し、スケール値を算出
-

格子+n個分の幅かな

追加格子数を

    addDiv = [1,1,1]

として、追加後の格子数を算出

    newDivS = divS + addDiv[0]
    newDivT = divT + addDiv[1]
    newDivU = divU + addDiv[2]

ただし、addDiv の値がマイナスだった場合　追加後の格子数が2以下にならないようにしなければならない。

    if newDivS < 2:
        newDivS = 2    
    if newDivT < 2:
        newDivT = 2
    if newDivU < 2:
        newDivU = 2

その上で、各軸の追加後のスケール値を算出

    scaleS = (lengthS * (newDivS-1))/ (maxPoint[0] - minPoint[0])
    scaleT = (lengthT * (newDivT-1))/ (maxPoint[1] - minPoint[1])
    scaleU = (lengthU * (newDivU-1))/ (maxPoint[2] - minPoint[2])

スケール値は相対値なので、現在のスケール値に対して乗算する

    cmds.setAttr(lattice + ".sx", cmds.getAttr(lattice + ".sx") * scaleS)
    cmds.setAttr(lattice + ".sy", cmds.getAttr(lattice + ".sy") * scaleT)
    cmds.setAttr(lattice + ".sz", cmds.getAttr(lattice + ".sz") * scaleU)

この時 baseShapeも同じくスケールさせないと大変なことになるので、
ffdを経由してコネクションからbaseShapeを取得し、同一のスケールにする

    ffd = cmds.listConnections(lattice + ".latticeOutput", d =True)[0]
    baseShape = cmds.listConnections(ffd + ".baseLatticeMatrix", d =False, s =True)[0]

    cmds.setAttr(baseShape + ".sx", cmds.getAttr(lattice + ".sx"))
    cmds.setAttr(baseShape + ".sy", cmds.getAttr(lattice + ".sy"))
    cmds.setAttr(baseShape + ".sz", cmds.getAttr(lattice + ".sz"))    

まとめる
-
以上をまとめるとこんな感じ

```python
import maya.cmds as cmds

def addFFDDiv(lattice,addDiv):
    divS = cmds.getAttr(lattice + ".sDivisions")
    divT = cmds.getAttr(lattice + ".tDivisions")
    divU = cmds.getAttr(lattice + ".uDivisions")

    minPoint = cmds.xform(lattice + ".pt[0][0][0]",q =True,ws =True,t =True)
    maxPoint = cmds.xform(lattice + ".pt["+str(divS-1)+"]["+str(divT-1)+"]["+str(divU-1)+"]",q =True,ws =True,t =True)

    lengthS = (maxPoint[0] - minPoint[0])/(divS-1)
    lengthT = (maxPoint[1] - minPoint[1])/(divT-1)
    lengthU = (maxPoint[2] - minPoint[2])/(divU-1)

    newDivS = divS + addDiv[0]
    newDivT = divT + addDiv[1]
    newDivU = divU + addDiv[2]

    if newDivS < 2:
        newDivS = 2
    
    if newDivT < 2:
        newDivT = 2

    if newDivU < 2:
        newDivU = 2

    scaleS = (lengthS * (newDivS-1))/ (maxPoint[0] - minPoint[0])
    scaleT = (lengthT * (newDivT-1))/ (maxPoint[1] - minPoint[1])
    scaleU = (lengthU * (newDivU-1))/ (maxPoint[2] - minPoint[2])
    
    cmds.setAttr(lattice + ".sx", cmds.getAttr(lattice + ".sx") * scaleS)
    cmds.setAttr(lattice + ".sy", cmds.getAttr(lattice + ".sy") * scaleT)
    cmds.setAttr(lattice + ".sz", cmds.getAttr(lattice + ".sz") * scaleU)
        
    cmds.setAttr(lattice + ".sDivisions",newDivS)
    cmds.setAttr(lattice + ".tDivisions",newDivT)
    cmds.setAttr(lattice + ".uDivisions",newDivU)
    
    ffd = cmds.listConnections(lattice + ".latticeOutput", d =True)[0]
    baseShape = cmds.listConnections(ffd + ".baseLatticeMatrix", d =False, s =True)[0]

    cmds.setAttr(baseShape + ".sx", cmds.getAttr(lattice + ".sx"))
    cmds.setAttr(baseShape + ".sy", cmds.getAttr(lattice + ".sy"))
    cmds.setAttr(baseShape + ".sz", cmds.getAttr(lattice + ".sz"))    
```

実行はこんな感じで。

```
lattice = "ffd2Lattice"
addDiv = [0,1,0]
addFFDDiv(lattice,addDiv)
```

**ただし、コントロールポイントの位置を編集していないlatticeのみ対応。**