Group {
name Brookes_ImagePlane

knobChanged "def add_input(group, prefix):\n with group:\n if nuke.toNode(prefix) is None:\n input = nuke.nodes.Input()\n input.setName(prefix)\n noop_input = nuke.toNode(prefix+'_input')\n noop_input.setInput(0, input)\n input.setXYpos(noop_input.xpos(), noop_input.ypos()-50)\n\ndef remove_input(group, prefix):\n with group:\n node = nuke.toNode(prefix)\n if node:\n nuke.delete(node)\n\ngroup = nuke.thisNode()\nknobName = nuke.thisKnob().name()\n\nif knobName == 'use_ref_cam':\n if group['use_ref_cam'].getValue():\n add_input(group, 'ref_cam')\n else:\n remove_input(group, 'ref_cam')"

selected true

addUserKnob {20 Brookes_ImagePlane}
addUserKnob {26 title l "" +STARTLINE T "<b>Brookes ImagePlane</b>"}
addUserKnob {26 author l "" +STARTLINE T "<font color="#888" size="2">Brookes</font>"}
addUserKnob {26 ""}

addUserKnob {7 distance t "Distance from camera" R 0.0001 100}
distance 10

addUserKnob {3 ref_frame l "Reference frame"}
ref_frame 1001

addUserKnob {6 use_ref_cam l "Use reference camera" t "Useful when transferring the ImagePlane between shots with different cameras." -STARTLINE}

addUserKnob {26 ""}

addUserKnob {41 format l "Output format" T Card3D1.format}

addUserKnob {14 max_overscan l "Max overscan" R 0 100}
max_overscan 300

addUserKnob {41 filter T Card3D1.filter}
addUserKnob {41 clamp -STARTLINE T Card3D1.clamp}
addUserKnob {41 black_outside l "Black outside" -STARTLINE T Card3D1.black_outside}
addUserKnob {41 motionblur T Card3D1.motionblur}
addUserKnob {41 shutter l "Shutter" T Card3D1.shutter}
addUserKnob {41 shutteroffset l "Shutter offset" T Card3D1.shutteroffset}
addUserKnob {41 shuttercustomoffset l "" -STARTLINE T Card3D1.shuttercustomoffset}
}

Axis2 {
inputs 0
useMatrix true
matrix {
{{parent.Cam1.world_matrix(ref_frame)} {parent.Cam1.world_matrix(ref_frame)} {parent.Cam1.world_matrix(ref_frame)} {parent.Cam1.world_matrix(ref_frame)}}
{{parent.Cam1.world_matrix(ref_frame)} {parent.Cam1.world_matrix(ref_frame)} {parent.Cam1.world_matrix(ref_frame)} {parent.Cam1.world_matrix(ref_frame)}}
{{parent.Cam1.world_matrix(ref_frame)} {parent.Cam1.world_matrix(ref_frame)} {parent.Cam1.world_matrix(ref_frame)} {parent.Cam1.world_matrix(ref_frame)}}
{{parent.Cam1.world_matrix(ref_frame)} {parent.Cam1.world_matrix(ref_frame)} {parent.Cam1.world_matrix(ref_frame)} {parent.Cam1.world_matrix(ref_frame)}}
}
name Axis1
xpos -90
ypos 291
}

Input {
inputs 0
name cam
xpos -328
ypos 77
number 1
}

Dot {
name Dot2
xpos -294
ypos 130
}

set N30dbd400 [stack 0]

Dot {
name Dot1
xpos -294
ypos 398
}

Input {
inputs 0
name Input
xpos 1
ypos 77
}

Card3D {
inputs 3
xform_order RST
translate {
{"Cam1.win_translate.u(ref_frame) uniform_scale / 2"}
{"Cam1.win_translate.v(ref_frame) uniform_scale / 2"}
{-parent.distance}
}
rotate {0 0 {-Cam1.winroll(ref_frame)}}
scaling {
{Cam1.win_scale.u(ref_frame)}
{Cam1.win_scale.v(ref_frame)}
1
}
uniform_scale {"Cam1.projection_mode == 0 ? distance * Cam1.haperture(ref_frame) / Cam1.focal(ref_frame) : Cam1.haperture(ref_frame) / Cam1.focal(ref_frame)"}
motionblur 10
shutteroffset centred
name Card3D1
xpos 1
ypos 395
}

Crop {
box {
{"min(max(bbox.x, -max_overscan.w), width+max_overscan.w)"}
{"min(max(bbox.y, -max_overscan.h), height+max_overscan.h)"}
{"max(min(bbox.r, width+max_overscan.w), -max_overscan.w)"}
{"max(min(bbox.t, height+max_overscan.h), -max_overscan.h)"}
}
crop false
name Crop1
xpos 1
ypos 440
}

Output {
name Output1
xpos 1
ypos 498
}

NoOp {
inputs 0
name ref_cam_input
xpos -166
ypos 125
}

push $N30dbd400

Switch {
inputs 2
which {{use_ref_cam}}
name Switch1
xpos -234
ypos 188
}

Camera {
projection_mode {"[expression [value the_cam]projection_mode([value the_frame])]"}
focal {"[expression [value the_cam]focal([value the_frame])]"}
haperture {"[expression [value the_cam]haperture([value the_frame])]"}
vaperture {"[expression [value the_cam]vaperture([value the_frame])]"}
near {"[expression [value the_cam]near([value the_frame])]"}
far {"[expression [value the_cam]far([value the_frame])]"}
win_translate {
{"[expression [value the_cam]win_translate.u([value the_frame])]"}
{"[expression [value the_cam]win_translate.v([value the_frame])]"}
}
win_scale {
{"[expression [value the_cam]win_scale.u([value the_frame])]"}
{"[expression [value the_cam]win_scale.v([value the_frame])]"}
}
winroll {"[expression [value the_cam]winroll([value the_frame])]"}
focal_point {"[expression [value the_cam]focal_point([value the_frame])]"}
fstop {"[expression [value the_cam]fstop([value the_frame])]"}
name Cam1

help "Brookes ImagePlane camera helper.\n\nCam1 reads the projection properties from the connected upstream camera and provides them to the ImagePlane."

onCreate "n = nuke.thisNode()\nfor k in ["projection_mode","focal","haperture","vaperture","near","far","win_translate","win_scale","winroll","focal_point","fstop"]:\n n[k].setFlag(0x0000000010000000)"

xpos -224
ypos 291

addUserKnob {20 Cam1 l Defaults}

addUserKnob {43 the_cam +INVISIBLE}
the_cam "[
set starting_point "this.input0"
set default "this.d_"

if {[exists $starting_point]} {
set x [node $starting_point]
} {
return $default
}

set finished 0

while {$finished != 1} {

while \{\[class \$x] != \"Camera4\" && \[class \$x] != \"Camera3\" && \[class \$x] != \"Camera2\" && \[class \$x] != \"Camera\" && \[class \$x] != \"Input\" && \$x != \[topnode \$x]\} \{

    set x \[node \$x.input0]

\}

if \{\[class \$x]==\"Camera4\"||\[class \$x]==\"Camera3\"||\[class \$x]==\"Camera2\"||\[class \$x]==\"Camera\"\} \{

    set x \[append x \".\"]

    return \$x

\} \{

    if \{\[class \$x]==\"Input\"\} \{

        set inp \"\$x.parent.input\"

        set inputNum \[value \$x.number]

        set inp \[append inp \$inputNum]

        if \{\[exists \$inp]\} \{

            set x \[node \$inp]

        \} \{

            set finished 1

        \}

    \} \{

        set finished 1

    \}

\}

}

return $default
]"

addUserKnob {43 the_frame +INVISIBLE}
the_frame "[
set the_camera [string trimright [value the_cam] .]

if {[exists $the_camera]} {
return [value $the_camera.frame]
} {
return [frame]
}
]"

addUserKnob {4 d_projection_mode l Projection M {perspective orthographic uv spherical ""}}

addUserKnob {7 d_focal l "Focal length" R 0 100}
d_focal 50

addUserKnob {7 d_haperture l "Horizontal aperture" R 0 50}
d_haperture 24.576

addUserKnob {7 d_vaperture l "Vertical aperture" R 0 50}
d_vaperture 18.672

addUserKnob {7 d_near l Near R 0 10}
d_near 0.1

addUserKnob {7 d_far l Far R 0 10000}
d_far 10000

addUserKnob {30 d_win_translate l "Window translate"}

addUserKnob {30 d_win_scale l "Window scale"}
d_win_scale {1 1}

addUserKnob {7 d_winroll l "Window roll" R 0 45}

addUserKnob {7 d_focal_point l "Focal distance" R 0 10}
d_focal_point 2

addUserKnob {7 d_fstop l Fstop R 0 30}
d_fstop 16

addUserKnob {26 version l " " T "<span style="color:#666"><b>Brookes ImagePlane</b> — Cam1</span>"}
}

end_group