#written by Charlie for Weta Comp dept
#export a Shake Tracker node containing all the points in the selected pointgroup, for the selected sequence
set path [get3DEInstallPath]
source $path/user_data/tcl_archive/veclib.tcl
post3DEInfoRequester "Export 2D tracking curves or 3D backprojected curves of the currently selected points as a Shake Tracker Node.\n\nWritten by Charlie Tait for Weta Comp dept.\n\n(Version 5.1, updated by rs)"
open3DEConsole
proc getBackProjectedPoint2D { pg point fobj frame }\
{
set pg_type [getPGroupType $pg]
set cam [getFobjCamera $fobj]
# Geomery of the Camera
set focal [getCameraFocalLength $cam]
set width [getCameraFBackWidth $cam]
set height [getCameraFBackHeight $cam]
# Lens center offset
set lcx [getCameraLensCenterX $cam]
set lcy [getCameraLensCenterY $cam]
# Field of View size in pixel
set fov_width [getFobjImageWidthFOV $fobj]
set fov_height [getFobjImageHeightFOV $fobj]
set x [getPointCalcPosition3D $pg $point]
set pos [getPGroupPosition3D $pg $fobj $frame]
set rot [getPGroupRotation3D $pg $fobj $frame]
if {$pg_type == "CAMERA"}\
{
# Difference vector from the camera position to the point in 3d
set d [vec3-vec3 $x $pos]
# Calculate the inverse of the camera matrix
set rotinv [mat3trans $rot]
# Reformulate the Difference vector in the coordiante frame of the camera
set dnew [mat3*vec3 $rotinv $d]
# Project this into the z=-1-Plane, that is: x' = x / -z, y' = y' -z (remember: the camera looks into -z direction)
set d2 [vec2/s [list [vget $dnew 0] [vget $dnew 1]] [expr -[vget $dnew 2]]]
# Now we want to express this in pixel respective to the lower left corner of the field of view (dotted line)
# We scale it to metric units, remove the lens center offset, scale it down to dimensionless coordinates,
# so that (0,0) is the lower left corner of the field of view, and (1,1) is the lower upper corner.
set dfovx [expr ([vget $d2 0] * $focal - $lcx) / ($width) + .5]
set dfovy [expr ([vget $d2 1] * $focal - $lcy) / ($height) + .5]
}
# This doesn't work yet:
if {$pg_type == "OBJECT"}\
{
set rotinv [mat3invert $rot]
set d [mat3*vec3 $rotinv $x]
set dnew [vec3+vec3 $d $pos]
set d2 [vec2/s [list [vget $dnew 0] [vget $dnew 1]] [expr -[vget $dnew 2]]]
set dfovx [expr ([vget $d2 0] * $focal - $lcx) / ($width) + .5]
set dfovy [expr ([vget $d2 1] * $focal - $lcy) / ($height) + .5]
}
set pos2d [list $dfovx $dfovy]
return $pos2d
}
set fobj [getSelectedFobj]
if {$fobj==0}\
{
bell
post3DEInfoRequester "Error, there is no sequence selected!"
return
}
set name [getFobjName $fobj]
print3DEConsole "sequence = $fobj ($name)\n"
set pg [getSelectedPGroup]
if {$pg==0}\
{
bell
post3DEInfoRequester "Error, there is no point group selected!"
return
}
set name [getPGroupName $pg]
print3DEConsole "group = $pg ($name)\n"
set count 0;
for {set point [getFirstPoint $pg]} {$point!=0} {set point [getNextPoint $pg $point]}\
{
set selected [getPointSelectionFlag $pg $point]
if {$selected==1} { set count [expr $count+1] }
}
if {$count==0}\
{
bell
post3DEInfoRequester "\n Error: There are no points selected! \n"
return
}
set np $count
print3DEConsole "number of points = $np\n"
set width [getFobjImageWidth $fobj]
print3DEConsole "tracked width = $width\n"
set height [getFobjImageHeight $fobj]
print3DEConsole "tracked height = $height\n"
flush3DEConsole
set filename [post3DEFileRequester "Save Shake Tracker Node..." "*"]
if {$filename==""} { return }
# nothing entered...
set basewidth $width
set baseheight $height
set timeshift 0
set string [post3DEPromptRequester "Please enter: "]
if {$string!=""}\
{
# parse user input...
scan $string "%ld %ld %ld" basewidth baseheight timeshift
}
set file [open $filename w+]
set no_frames [getFobjNoFrames $fobj]
#show intended image size...values in shake Tracker node are not normailsed.
print3DEConsole "basewidth = $basewidth\n"
print3DEConsole "baseheight = $baseheight\n"
#they entered nothing in timeshift field
if {$timeshift==""}\
{
set timeshift 0
}
print3DEConsole "timeshift = $timeshift\n"
set export_tracking_curves [post3DEQuestionRequester "\n Export original 2D tracking curves or 3D backprojected curves? \n" "2D Tracking Curves" "Backprojected Curves"]
print3DEConsole "Writing $np points in pointgroup $pg to $filename\n\n"
flush3DEConsole
#start writing shake script. This is now non-version specific. It'll still work in later versions.....
puts -nonewline $file "// Input nodes\n"
puts -nonewline $file "\n"
#simply a base size black frame as an input to the tracker node.
puts -nonewline $file "Color1 = Color($basewidth, $baseheight, 1, 0, red, red, 1, 0);\n"
puts -nonewline $file "\n"
puts -nonewline $file "// Processing nodes\n"
puts -nonewline $file "\n"
#write the tracker node in its ugly format
puts -nonewline $file "Tracker1 = Tracker(Color1, \"1-$no_frames\", \"1/16\", \"luminance\", 0.75, \n"
puts -nonewline $file " \"use start frame\", 0.5, \"stop\", 1, 1, "
#open point loop
set count 1
for {set point [getFirstPoint $pg]} {$point!=0} {set point [getNextPoint $pg $point]}\
{
#begin this point's X perameters
set selected [getPointSelectionFlag $pg $point]
if {$selected==0} continue;
puts -nonewline $file "\n"
puts -nonewline $file "\"track$count\", "
#puts -nonewline $file "\n\n// Track$point X curve\n"
puts -nonewline $file "Linear(0"
#start frame loop
for {set frame 1} {$frame<=$no_frames} {set frame [expr $frame+1]}\
{
if {$export_tracking_curves} \
{
# original tracking...
set srcxy [getPointPosition2D $pg $point $fobj $frame]
#un-normalize values, based on final image size in shake
set srcx [expr [lindex $srcxy 0]*$basewidth]
set sframe [expr $frame+$timeshift]
#writes X Value at Frame
if {[isPointPos2DValid $pg $point $fobj $frame]==1}\
{
puts -nonewline $file ",$srcx@$sframe"
}
}\
else\
{
# backprojected values...
set srcxy [getBackProjectedPoint2D $pg $point $fobj $frame]
#un-normalize values, based on final image size in shake
set srcx [expr [lindex $srcxy 0]*$basewidth]
set sframe [expr $frame+$timeshift]
#writes X Value at Frame
puts -nonewline $file ",$srcx@$sframe"
}
}
puts -nonewline $file "),"
#begin this point's Y curve
#puts -nonewline $file "\n\n// Track$count Y curve"
puts -nonewline $file "\n"
puts -nonewline $file " Linear(0"
#start frame loop
for {set frame 1} {$frame<=$no_frames} {set frame [expr $frame+1]}\
{
if {$export_tracking_curves} \
{
set srcxy [getPointPosition2D $pg $point $fobj $frame]
#un-normalize values, based on final image size in shake
set srcy [expr [lindex $srcxy 1]*$baseheight]
set sframe [expr $frame+$timeshift]
#writes Y Value at Frame
if {[isPointPos2DValid $pg $point $fobj $frame]==1}\
{
puts -nonewline $file ",$srcy@$sframe"
}
}\
else\
{
set srcxy [getBackProjectedPoint2D $pg $point $fobj $frame]
#un-normalize values, based on final image size in shake
set srcy [expr [lindex $srcxy 1]*$baseheight]
set sframe [expr $frame+$timeshift]
#writes Y Value at Frame
puts -nonewline $file ",$srcy@$sframe"
}
}
puts -nonewline $file "),"
puts -nonewline $file "\n"
puts -nonewline $file " Linear(0,1@1),"
set frame 1
#this defines the (now unimportant) feature and search sizes for the points...again....horribly foratted in shake
#puts -nonewline $file "\n\n// Track$point Feature and search sizes\n"
if {$export_tracking_curves} \
{
set srcxy [getPointPosition2D $pg $point $fobj $frame]
}\
else\
{
set srcxy [getBackProjectedPoint2D $pg $point $fobj $frame]
}
set srcx [expr [lindex $srcxy 0]*$basewidth]
set srcy [expr [lindex $srcxy 1]*$baseheight]
set t1l [expr $srcx-25]
set t1r [expr $srcx+25]
set t1b [expr $srcy-25]
set t1t [expr $srcy+25]
set t1ls [expr $srcx-50]
set t1rs [expr $srcx+50]
set t1bs [expr $srcy-50]
set t1ts [expr $srcy+50]
puts -nonewline $file "$t1l, $t1r, $t1b, $t1t, $t1ls, $t1rs, $t1bs, $t1ts,"
#assign point position to center of tracker window! Yup...Shake is crazy.
#puts -nonewline $file "\n\n// Track$point Center of track window\n"
puts -nonewline $file " track$count\X, track$count\Y, "
#create validity curve (visibility)
#puts -nonewline $file "\n\n// Match Visibility to Enable\n"
puts -nonewline $file " track$count\Enabled,"
#create validity curve (visibility)
#puts -nonewline $file " Linear(0,"
#for {set frame 1} {$frame<=$no_frames} {set frame [expr $frame+1]}\
# {
# set vis [isPointPos2DValid $pg $point $fobj $frame]
# set sframe [expr $frame+$timeshift]
# puts -nonewline $file "$vis@$sframe"
# #if its the last frame, close current curve
# if {$frame==$no_frames}\
# {
# puts -nonewline $file "),"
# }\
# else\
# {
# puts -nonewline $file ","
# }
# }
#create validity curve (enable)
puts -nonewline $file "\n"
#puts -nonewline $file "\n\n//track$point enable curve"
puts -nonewline $file " Linear(0,"
for {set frame 1} {$frame<=$no_frames} {set frame [expr $frame+1]}\
{
if {$export_tracking_curves} \
{
set en [isPointPos2DValid $pg $point $fobj $frame]
}\
else\
{
set en 1
}
set sframe [expr $frame+$timeshift]
puts -nonewline $file "$en@$sframe"
#if its the last frame, close current curve
if {$frame==$no_frames}\
{
if {$count==$np}\
{
puts -nonewline $file ")); "
}\
else\
{
puts -nonewline $file "),"
}\
}\
else\
{
puts -nonewline $file ","
}
}
set count [expr $count+1]
}
post3DEInfoRequester "Data sucessfully written in file \"$filename.\""