1############################################################################# 2# Author: # 3# ------ # 4# Anton Kokalj Email: Tone.Kokalj@ijs.si # 5# Department of Physical and Organic Chemistry Phone: x 386 1 477 3523 # 6# Jozef Stefan Institute Fax: x 386 1 477 3811 # 7# Jamova 39, SI-1000 Ljubljana # 8# SLOVENIA # 9# # 10# Source: $XCRYSDEN_TOPDIR/Tcl/scriptingMakeMovie.tcl 11# ------ # 12# Copyright (c) 1996-2003 by Anton Kokalj # 13############################################################################# 14 15 16# ------------------------------------------------------------------------ 17#****c* Scripting/scripting::makeMovie 18# 19# NAME 20# scripting::makeMovie 21# 22# PURPOSE 23 24# This namespace provide the scripting interface for making 25# MPEG/Animated-GIF movies. The scripting::makeMovie namespace 26# interface is kind of state machine. The "init" command initializes 27# the process, and then the movie creation is encapsulated between 28# "begin" and "end" commands. Every movie frame is created within the 29# "begin" and "end" commands with "makeFrame" command. One can create 30# several movies within one scripting file. Make sure the sequence of 31# makeMovie calls will have the following order: 32# 33# init 34# begin 35# makeFrame 36# makeFrame 37# ... 38# end 39# 40# init 41# begin 42# makeFrame 43# makeFrame 44# ... 45# end 46# 47# 48# COMMANDS 49 50# -- scripting::makeMovie::init 51 52# Initializes the movie creation process. It must be called before 53# making movie. One passes several configuration options to init call. 54 55 56# 57# -- scripting::makeMovie::begin 58 59# Marks the begining of movie creation. 60 61# 62# -- scripting::makeMovie::makeFrame 63 64# Makes one movie frame, that is, saves (i.e. prints to file) the 65# content of the currently displayed object. 66 67# 68# -- scripting::makeMovie::end 69 70# Finishes the movie creation and encodes the movie. 71# 72#**** 73# ------------------------------------------------------------------------ 74 75namespace eval scripting::makeMovie { 76 variable movie 77 78 set movie(makeMovie) 0 79 set movie(movieFile) "" 80 set movie(notificationMovie) "" 81} 82 83 84# ------------------------------------------------------------------------ 85#****f* Scripting/scripting::makeMovie::init 86# 87# NAME 88# scripting::makeMovie::init 89# 90# USAGE 91# scripting::makeMovie::init -option value ?-option value? ... 92# 93# PURPOSE 94 95# This proc initializes the movie creation processes. One can pass several 96# configuration options, which determine the technical details of the 97# movie. 98 99# 100# ARGUMENTS 101# args -- various configuration "-option value" pairs 102# 103# OPTIONS 104# ------------------------------------------------------------------------ 105# OPTION ALLOWED-VALUES + DESCRIPTION 106# ------------------------------------------------------------------------ 107# 108# -gif_transp 0|1 --> make oblique|transparent animated-GIF 109# 110# -gif_minimize 0|1 --> don't-minimize|minimize animateg-GIF 111# 112# -gif_global_colormap 0|1 --> don't-use|use global colormap for animated-GIF 113# 114# -movieformat avi|mpeg|gif --> create AVI|MPEG|Animated-GIF 115# 116# -dir tmp|pwd --> put temporary (i.e. frame) files to 117# scratch(tmp) or current working 118# directory(pwd) 119# 120# -frameformat PPM|PNG|JPEG --> format of the frame-files 121# 122# -firstframe positive-integer --> repeat first frame n-times 123# 124# -lastframe positive-integer --> repeat first frame n-times 125# 126# -delay positive-integer --> time dalay between frames 127# in 1/100 sec 128# -loop repeat in movie animation number of times (0=forever) 129# 130# -save_to_file file --> if specified the movie will be saved to file 131# otherwise the filename will be queried 132# 133# 134# RETURN VALUE 135# Undefined. 136# 137# EXAMPLE 138# scripting::makeMovie::init \ 139# -movieformat mpeg \ 140# -dir tmp \ 141# -frameformat PPM \ 142# -firstframe 10 \ 143# -lastframe 10 \ 144# -delay 0 145# 146#**** 147# ------------------------------------------------------------------------ 148 149proc scripting::makeMovie::init {args} { 150 variable movie 151 global gifAnim 152 153 if { $movie(makeMovie) } { 154 error "makeMovie::init called within makeMovie::begin/makeMovie::end, should be called before makeMovie::begin" 155 } 156 157 # load defaults 158 159 set gifAnim(gif_transp) 0 160 set gifAnim(gif_minimize) 0 161 set gifAnim(gif_global_colormap) 0 162 set gifAnim(edit_param) 1 163 set gifAnim(movie_format) mpeg 164 set gifAnim(temp_files_dir) tmp 165 set gifAnim(frame_files_format) PPM 166 set gifAnim(ntime_first_frame) 1 167 set gifAnim(ntime_last_frame) 1 168 set gifAnim(delay) 0 169 set gifAnim(loop) 0 170 171 set movie(movieFile) "" 172 173 set i 0 174 foreach option $args { 175 incr i 176 177 if { $i%2 } { 178 set tag $option 179 } else { 180 switch -glob -- $tag { 181 "-gif_transp" - 182 "-gif_minimize" - 183 "-gif_global_colormap" - 184 "-edit_param" { 185 set tag [string trimleft $tag -] 186 switch $option { 187 1 - on - yes { set gifAnim($tag) 1 } 188 0 - off - no { set gifAnim($tag) 0 } 189 default { 190 ErrorDialog "wrong value $option for $tag option, should be 0 or 1" 191 } 192 } 193 } 194 "-movieformat" { 195 set option [string tolower $option] 196 switch $option { 197 mpeg - gif { set gifAnim(movie_format) $option } 198 avi { set gifAnim(movie_format) mpeg } 199 default { 200 ErrorDialog "wrong value $option for $tag option, should be \"mpeg\" or \"gif\"" 201 } 202 } 203 } 204 205 "-dir" { 206 switch $option { 207 tmp - pwd { set gifAnim(temp_files_dir) $option } 208 default { 209 ErrorDialog "wrong value $option for $tag option, should be \"tmp\" or \"pwd\"" 210 } 211 } 212 } 213 214 "-frameformat" { 215 set option [string toupper $option] 216 switch $option { 217 PPM - PNG - JPEG { set gifAnim(frame_files_format) $option } 218 default { 219 ErrorDialog "wrong value $option for $tag option, should be \"PPM\" or \"JPEG\"" 220 } 221 } 222 } 223 "-ntime_first_frame" - 224 "-firstframe" { 225 if { [nonnegativeInteger $option] } { 226 set gifAnim(ntime_first_frame) $option 227 } else { 228 ErrorDialog "expected integer, but got $option for $tag option" 229 } 230 } 231 "-ntime_last_frame" - 232 "-lastframe" { 233 if { [nonnegativeInteger $option] } { 234 set gifAnim(ntime_last_frame) $option 235 } else { 236 ErrorDialog "expected integer, but got $option for $tag option" 237 } 238 } 239 "-delay" - 240 "-loop" { 241 if { [nonnegativeInteger $option] } { 242 set elem [string trimleft $tag -] 243 set gifAnim($elem) $option 244 } else { 245 ErrorDialog "expected integer, but got $option for $tag option" 246 } 247 } 248 "-save_to_file" { 249 set movie(movieFile) $option 250 } 251 } 252 } 253 } 254 if { $i%2 } { 255 ErrorDialog "scripting::makeMovie::init called with an odd number of arguments !!!" 256 } 257} 258 259 260 261# ------------------------------------------------------------------------ 262#****f* Scripting/scripting::makeMovie::begin 263# 264# NAME 265# scripting::makeMovie::begin 266# 267# USAGE 268# scripting::makeMovie::begin 269# 270# PURPOSE 271# 272# This proc marks the beginning of movie creation. 273# 274# RETURN VALUE 275# Undefined. 276# 277# EXAMPLE 278# scripting::makeMovie::begin 279# 280#**** 281# ------------------------------------------------------------------------ 282 283 284proc scripting::makeMovie::begin {} { 285 variable movie 286 global gifAnim 287 288 set movie(makeMovie) 1 289 290 if { $gifAnim(movie_format) == "mpeg" } { 291 set fmt MPEG 292 } else { 293 set fmt Animated-GIF 294 } 295 set movie(notificationMovie) [DisplayUpdateWidget "Recording" "Recording $fmt movie."] 296 set gifAnim(make_gifAnim) 0 297 gifAnimMake .mesa 298} 299 300 301 302# ------------------------------------------------------------------------ 303#****f* Scripting/scripting::makeMovie::makeFrame 304# 305# NAME 306# scripting::makeMovie::makeFrame 307# 308# USAGE 309# scripting::makeMovie::makeFrame 310# 311# PURPOSE 312 313# This proc makes one movie frame, that is, it flushes (i.e. prints 314# to file) the content of the currently displayed object. 315 316# 317# WARNINGS 318 319# Note that this proc should be called within scripting::makeMovie::begin 320# and scripting::makeMovie::end calls. The scripting::makeMovie::init 321# should be called before "begin; makeFrame; ...; end" sequence. 322 323# 324# RETURN VALUE 325# Undefined. 326# 327# EXAMPLE 328# scripting::makeMovie::makeFrame 329# 330#**** 331# ------------------------------------------------------------------------ 332 333proc scripting::makeMovie::makeFrame {} { 334 variable movie 335 336 if { $movie(makeMovie) } { 337 gifAnimPrintCurrent .mesa 338 } else { 339 error "makeMovie::makeFrame called outside makeMovie::begin/makeMovie::end" 340 } 341} 342 343 344# ------------------------------------------------------------------------ 345#****f* Scripting/scripting::makeMovie::end 346# 347# NAME 348# scripting::makeMovie::end 349# 350# USAGE 351# scripting::makeMovie::end 352# 353# PURPOSE 354# This proc finishes the movie creation and encodes the movie. 355# 356# RETURN VALUE 357# Undefined. 358# 359# EXAMPLE 360# scripting::makeMovie::end 361# 362#**** 363# ------------------------------------------------------------------------ 364 365proc scripting::makeMovie::end {} { 366 variable movie 367 global gifAnim 368 369 if { [winfo exists $movie(notificationMovie)] } { 370 destroy $movie(notificationMovie) 371 } 372 if { $gifAnim(filelist) == "" } { return } 373 374 if { $movie(makeMovie) } { 375 if { $movie(movieFile) == "" } { 376 gifAnimMake .mesa 377 } else { 378 gifAnimMake .mesa {} {} $movie(movieFile) 379 } 380 set movie(makeMovie) 0 381 } else { 382 error "makeMovie::end called before makeMovie::begin" 383 } 384} 385