mayaのカメラをなんとかしたい１  ~postScaleをFLengthに変換~

mayaのカメラにある postScaleは、レンズの数値そのままで画角を広げられるので
余白出しとかの時にとても重宝しています。

が、
他のソフトへカメラを渡す場合、mayaの固有機能であるpostScaleは渡せないのでこまったなー
となりました。

んじゃぁ postScale で調整後の画角のFocalLengthを算出してしまおうと

考える
--

そもそもpostScaleはどこに掛かるのか・・・

filmGate表示で確認してみると

postScale 1.0
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/6bc1114e-80ef-df99-f893-a6df166ce16b.png)

postScale 0.8
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/2b0546a5-cbec-5d47-699b-1122eb305524.png)

外からnearClipを表示させてみて確認してみると
postScale 1.0
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/53e7527f-d760-a4a0-894d-d8616e6665bf.png)

postScale 0.8
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/f116d988-c557-a4cb-7ea2-d9db62db9fd4.png)


実際に filmGateサイズを変えてるわけではなく画像として拡縮してる感じですね。

広げてるのに0.8とは？と思いますが、1.0/0.8 = 1.25 とかその辺かなぁ
（filmApertureを0.8してる感じだろうか？）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/24c2330d-9362-5138-962a-ac6738a323b5.png)

今のfilmGateのサイズを求めて、postScaleの逆数掛けて、そこからFocalLengthを求められそうな気はします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/986f47d3-2bd9-2b65-be37-0ef19ea437b0.png)


検証
--

とりあえず、filmGateのサイズを求め方を調べてみます。
アトリビュートには見当たらないので、とりあえずAPI眺めますか。

ん～　具体的にコレというのが見当たりませんね・・・

うん、面倒ですが　filmAperture　から算出してしまいます。

なので、

- filmAperture と FocalLength と nearClipPlaneから　filmGateサイズを算出
- filmGateにpostScale値の逆数を掛ける
- scale後のfilmGateから　FocalLengthを算出

ん～　なんか無駄な事やってる気もしますが、とりあえずこれでやってみます。

実装
--

```python
import maya.cmds as cmds
import maya.api.OpenMaya as om

def getDagNode(target):    
    try:
        sellist = om.MGlobal.getSelectionListByName(target)
        return sellist.getDagPath(0)
    except:
        return None
        
def convertPostScaleToFLength(source):
    sourceCamDAG = getDagNode(source)
    sourceCamFn = om.MFnCamera(sourceCamDAG)
    
    horizontalFilmAperture = sourceCamFn.horizontalFilmAperture
    verticalFilmAperture = sourceCamFn.verticalFilmAperture            
    nearClippingPlane  = sourceCamFn.nearClippingPlane 
    FLength = sourceCamFn.focalLength 
    
    postScale = sourceCamFn.postScale
    invPostScale = 1.0 / postScale    
        
    filmGateH = horizontalFilmAperture * (nearClippingPlane / FLength)
    filmGateV = verticalFilmAperture * (nearClippingPlane / FLength)        
    scaledHsize = filmGateH * invPostScale
    scaledVsize = filmGateV * invPostScale
        
    FLengthNew =  (horizontalFilmAperture * nearClippingPlane)/scaledHsize        

    cmds.setAttr(source  + ".focalLength",FLengthNew)
    cmds.setAttr(source  + ".postScale",1.0)

    
```

ではこんなカメラで試してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/279b6483-93ca-31f8-5a45-4ae99932a97f.png)

```python
convertPostScaleToFLength("persp1")
```

実行時にカメラの画角が一切動いてませんが、数値は変化したので成功したようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/a399ec37-1718-f035-f113-df4dd47e53c9.png)

filmGateでやってるので、fitResolutionGateがVでもHでも問題なさそうです。

が、これよくよく考えてみたら
filmAperture 固定となるんで、　FocalLength * (1.0/postScale) でいいんじゃね？　という疑問がわいたところでおしまいにします。