これとは逆に、 特定の部分の解像度を割り出したいなーという場面も。
全体が 960*540 だとして、この赤い部分の解像度はいくつ?
トリミング用のフレームを設置して、そこから大判と同じ方法で解像度を算出。
そのあと解像度を変更し、フレームがresolutionGateに一致するようにカメラを調整。
ここまでやってみます。
トリミング用のプレートはこんな感じで。
plateCtrl で位置を、plateでスケールを調整する感じです。
import maya.cmds as cmds
import maya.api.OpenMaya as om2
def getResGateSize(cameraName,resolutionW,resolutionH):
sourceCamDAG = om2.MGlobal.getSelectionListByName(cameraName).getDagPath(0)
sourceCamFn = om2.MFnCamera(sourceCamDAG)
if cmds.getAttr(cameraName + ".filmFit") == 1:
deviceAspectRatio = resolutionH / resolutionW
sourceResH = sourceCamFn.horizontalFilmAperture * deviceAspectRatio
sourceResW = sourceCamFn.horizontalFilmAperture
elif cmds.getAttr(cameraName + ".filmFit") == 2:
deviceAspectRatio = resolutionW / resolutionH
sourceResH = sourceCamFn.verticalFilmAperture
sourceResW = sourceCamFn.verticalFilmAperture * deviceAspectRatio
return sourceResW*25.4,sourceResH*25.4
def addCameraProxyPos(cameraName):
camProxy = cameraName + "_proxy"
if cmds.objExists(camProxy) == False:
cmds.createNode("transform",name = camProxy)
cmds.parentConstraint(cameraName,camProxy)
return camProxy
def addNearClipPos(cameraName):
camProxy = addCameraProxyPos(cameraName)
nearClipPoint = cameraName + "_nearClipPos"
if cmds.objExists(nearClipPoint) == False:
nearClipPoint = cmds.createNode("transform",name = nearClipPoint)
cmds.parent(nearClipPoint,camProxy,r = True)
rev = cmds.createNode("floatMath")
cmds.setAttr(rev + ".operation",2)
cmds.setAttr(rev + ".floatB",-1)
cmds.connectAttr(cameraName + ".nearClipPlane",rev+".floatA" )
cmds.connectAttr(rev + ".outFloat",nearClipPoint+".tz" )
return nearClipPoint
def addTrimFrame(cameraName,defaultResolution):
resolutionW = defaultResolution[0]
resolutionH = defaultResolution[1]
sourceResW,sourceResH = getResGateSize(cameraName,resolutionW,resolutionH)
nearClipPoint = addNearClipPos(cameraName)
scaleSpace = cmds.createNode("joint",name = cameraName + "_scaleSpace")
planeCtrl = cmds.createNode("joint",name = cameraName + "_planeCtrl")
cmds.setAttr(scaleSpace + ".drawStyle",2)
cmds.setAttr(planeCtrl + ".drawStyle",2)
cmds.parent(planeCtrl,scaleSpace,a=True)
cmds.parent(scaleSpace,nearClipPoint,r=True)
resGatePlane = cmds.polyPlane(axis = [0,0,1],sx = 1,sy = 1,ch =False,name = cameraName + "_resGateplane")[0]
cmds.setAttr(resGatePlane + ".template",1)
cmds.parent(resGatePlane,planeCtrl,r=True)
lengthRatio = cmds.createNode("floatMath")
cmds.connectAttr(cameraName + ".nearClipPlane",lengthRatio + ".floatA")
cmds.connectAttr(cameraName + ".focalLength",lengthRatio + ".floatB")
cmds.setAttr(lengthRatio + ".operation",3)
outRezGateW = cmds.createNode("floatMath")
outRezGateH = cmds.createNode("floatMath")
cmds.setAttr(outRezGateW + ".operation",2)
cmds.setAttr(outRezGateH + ".operation",2)
cmds.connectAttr(lengthRatio + ".outFloat",outRezGateW + ".floatA")
cmds.connectAttr(lengthRatio + ".outFloat",outRezGateH + ".floatA")
cmds.setAttr(outRezGateW + ".floatB",sourceResW)
cmds.setAttr(outRezGateH + ".floatB",sourceResH)
cmds.connectAttr(outRezGateW + ".outFloat",scaleSpace + ".sx")
cmds.connectAttr(outRezGateH + ".outFloat",scaleSpace + ".sy")
cmds.connectAttr(outRezGateW + ".outFloat",planeCtrl + ".sx")
cmds.connectAttr(outRezGateH + ".outFloat",planeCtrl + ".sy")
cmds.setAttr(planeCtrl + ".tz",l = True)
cmds.setAttr(planeCtrl + ".r",l = True)
cmds.setAttr(planeCtrl + ".s",l = True)
cmds.setAttr(resGatePlane + ".t",l = True)
cmds.setAttr(resGatePlane + ".r",l = True)
cmds.setAttr(resGatePlane + ".sz",l = True)
return resGatePlane,lengthRatio,planeCtrl,scaleSpace
select = cmds.ls(sl =True)
target = select[0]
defaultResolution = [cmds.getAttr("defaultResolution.width"),cmds.getAttr("defaultResolution.height") ]
addTrimFrame(target,defaultResolution)
設置した板の情報を取得して、
resolutionGateとの比率をだして 解像度を算出します。
import maya.cmds as cmds
import maya.api.OpenMaya as om2
import math
def getPosition(target):
nodeType = cmds.nodeType(target)
if nodeType == "joint" or nodeType == "transform" or nodeType == "ikHandle" or nodeType == "place3dTexture":
# return cmds.xform(target , q =True , ws = True, t =True)
return cmds.xform(target , q =True , ws = True, rotatePivot =True)
elif nodeType == "mesh" or nodeType == "nurbsCurve" or nodeType == "nurbsSurface" or nodeType == "lattice":
return cmds.xform(target , q =True , ws = True, t =True)
def getResGateSize(cameraName,resolutionW,resolutionH):
sourceCamDAG = om2.MGlobal.getSelectionListByName(cameraName).getDagPath(0)
sourceCamFn = om2.MFnCamera(sourceCamDAG)
if cmds.getAttr(cameraName + ".filmFit") == 1:
deviceAspectRatio = resolutionH / resolutionW
sourceResH = sourceCamFn.horizontalFilmAperture * deviceAspectRatio
sourceResW = sourceCamFn.horizontalFilmAperture
elif cmds.getAttr(cameraName + ".filmFit") == 2:
deviceAspectRatio = resolutionW / resolutionH
sourceResH = sourceCamFn.verticalFilmAperture
sourceResW = sourceCamFn.verticalFilmAperture * deviceAspectRatio
return sourceResW*25.4,sourceResH*25.4
def getTrimResolution(cameraName,parentSpace,planeIndex=[2,3,0,1]):
nearClipPlane = cmds.getAttr(cameraName + ".nearClipPlane")
focalLength = cmds.getAttr(cameraName + ".focalLength")
ratio = nearClipPlane / focalLength
pointA = getPosition(planeName +".vtx["+str(planeIndex[0])+"]")#left-top
pointB = getPosition(planeName +".vtx["+str(planeIndex[1])+"]")#right-top
pointC = getPosition(planeName +".vtx["+str(planeIndex[2])+"]")#left-bot
pointD = getPosition(planeName +".vtx["+str(planeIndex[3])+"]")#right-bot
vectorA = om2.MVector(pointA)
vectorB = om2.MVector(pointB)
vectorC = om2.MVector(pointC)
vectorD = om2.MVector(pointD)
resolutionW = cmds.getAttr("defaultResolution.width")
resolutionH = cmds.getAttr("defaultResolution.height")
resGateW,resGateH = getResGateSize(cameraName,resolutionW,resolutionH)
width = (vectorB - vectorA).length()
height = (vectorC - vectorA).length()
ratioW = width / (resGateW*ratio)
ratioH = height / (resGateH*ratio)
trimedResolution = [resolutionW * ratioW, resolutionH * ratioH]
if trimedResolution[0] % 8 != 0:
trimedResolution[0] = trimedResolution[0] + (8 - trimedResolution[0] % 8)
if trimedResolution[1] % 8 != 0:
trimedResolution[1] = trimedResolution[1] + (8 - trimedResolution[1] % 8)
return trimedResolution
##-----------------------------------------------------------------------------------------------------------
cameraName = "persp1"
parentSpace = "persp1_nearClipPos"
planeName = "persp1_resGateplane"
planeIndex = [2,3,0,1] ##left-top/right-top/left-bot/right-bot
trimedResolution = getTrimResolution(cameraName,parentSpace,planeIndex=[2,3,0,1])
# Result: [176.0, 352.0]
合ってそうなきはしますね
つづけて、カメラの filmOffsetとpostScaleで切り抜きフレームにresolutionGateが合うようにします。
import maya.cmds as cmds
import maya.api.OpenMaya as om2
import math
def getPosition(target):
nodeType = cmds.nodeType(target)
if nodeType == "joint" or nodeType == "transform" or nodeType == "ikHandle" or nodeType == "place3dTexture":
# return cmds.xform(target , q =True , ws = True, t =True)
return cmds.xform(target , q =True , ws = True, rotatePivot =True)
elif nodeType == "mesh" or nodeType == "nurbsCurve" or nodeType == "nurbsSurface" or nodeType == "lattice":
return cmds.xform(target , q =True , ws = True, t =True)
def getResGateSize(cameraName,resolutionW,resolutionH):
sourceCamDAG = om2.MGlobal.getSelectionListByName(cameraName).getDagPath(0)
sourceCamFn = om2.MFnCamera(sourceCamDAG)
if cmds.getAttr(cameraName + ".filmFit") == 1:
deviceAspectRatio = resolutionH / resolutionW
sourceResH = sourceCamFn.horizontalFilmAperture * deviceAspectRatio
sourceResW = sourceCamFn.horizontalFilmAperture
elif cmds.getAttr(cameraName + ".filmFit") == 2:
deviceAspectRatio = resolutionW / resolutionH
sourceResH = sourceCamFn.verticalFilmAperture
sourceResW = sourceCamFn.verticalFilmAperture * deviceAspectRatio
return sourceResW*25.4,sourceResH*25.4
def getTrimResolution(cameraName,parentSpace,planeIndex=[2,3,0,1]):
nearClipPlane = cmds.getAttr(cameraName + ".nearClipPlane")
focalLength = cmds.getAttr(cameraName + ".focalLength")
ratio = nearClipPlane / focalLength
pointA = getPosition(planeName +".vtx["+str(planeIndex[0])+"]")#left-top
pointB = getPosition(planeName +".vtx["+str(planeIndex[1])+"]")#right-top
pointC = getPosition(planeName +".vtx["+str(planeIndex[2])+"]")#left-bot
pointD = getPosition(planeName +".vtx["+str(planeIndex[3])+"]")#right-bot
vectorA = om2.MVector(pointA)
vectorB = om2.MVector(pointB)
vectorC = om2.MVector(pointC)
vectorD = om2.MVector(pointD)
resolutionW = cmds.getAttr("defaultResolution.width")
resolutionH = cmds.getAttr("defaultResolution.height")
resGateW,resGateH = getResGateSize(cameraName,resolutionW,resolutionH)
width = (vectorB - vectorA).length()
height = (vectorC - vectorA).length()
ratioW = width / (resGateW*ratio)
ratioH = height / (resGateH*ratio)
trimedResolution = [resolutionW * ratioW, resolutionH * ratioH]
if trimedResolution[0] % 8 != 0:
trimedResolution[0] = trimedResolution[0] + (8 - trimedResolution[0] % 8)
if trimedResolution[1] % 8 != 0:
trimedResolution[1] = trimedResolution[1] + (8 - trimedResolution[1] % 8)
return trimedResolution
def adjustFrame(cameraName,planeName,parentSpace,resolutionW,resolutionH,planeIndex):
nearClipPlane = cmds.getAttr(cameraName + ".nearClipPlane")
focalLength = cmds.getAttr(cameraName + ".focalLength")
resGateW,resGateH = getResGateSize(cameraName,resolutionW,resolutionH)
ratio = nearClipPlane / focalLength
##filmOffset
matrixP = om2.MMatrix(cmds.getAttr(parentSpace+".worldInverseMatrix[0]"))
matrixA = om2.MMatrix(cmds.getAttr(planeName+".worldMatrix[0]"))
localPositionA = om2.MTransformationMatrix(matrixA*matrixP).translation(om2.MSpace.kWorld)
offsetX = ((localPositionA[0]/(resGateW*ratio))*resGateW) / 25.4
offsetY = ((localPositionA[1]/(resGateH*ratio))*resGateH) / 25.4
curOffsetX = cmds.getAttr(cameraName + ".horizontalFilmOffset")
curOffsetY = cmds.getAttr(cameraName + ".verticalFilmOffset")
cmds.setAttr(cameraName + ".horizontalFilmOffset",curOffsetX + offsetX)
cmds.setAttr(cameraName + ".verticalFilmOffset",curOffsetY + offsetY)
##postScale
pointA = getPosition(planeName +".vtx["+str(planeIndex[0])+"]")#left-top
pointB = getPosition(planeName +".vtx["+str(planeIndex[1])+"]")#right-top
width = (om2.MVector(pointB) - om2.MVector(pointA)).length()
ratioW = width / (resGateW*ratio)
curPostScale = cmds.getAttr(cameraName + ".postScale")
cmds.setAttr(cameraName + ".postScale",curPostScale*(1.0/ratioW))
##---------------------------------------------------------------------------------------------
cameraName = "persp1"
parentSpace = "persp1_nearClipPos"
planeName = "persp1_resGateplane"
planeIndex = [2,3,0,1] ##left-top/right-top/left-bot/right-bot
trimedResolution = getTrimResolution(cameraName,parentSpace,planeIndex=[2,3,0,1])
cmds.setAttr("defaultResolution.width",trimedResolution[0])
cmds.setAttr("defaultResolution.height",trimedResolution[1])
cmds.setAttr("defaultResolution.deviceAspectRatio", trimedResolution[0] / trimedResolution[1])
adjustFrame(cameraName,planeName,parentSpace,trimedResolution[0],trimedResolution[1],planeIndex)





