Files
ThirdParty-6/ParaView-5.0.1/Plugins/pvblot/pvblot.py

303 lines
11 KiB
Python

r"""
An interpreter that provides blot-like syntax and functionality. To run
the interpreter simply call the start function.
"""
#==============================================================================
#
# Program: ParaView
# Module: pvblot.py
#
# Copyright (c) Kitware, Inc.
# All rights reserved.
# See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even
# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the above copyright notice for more information.
#
#==============================================================================
#-------------------------------------------------------------------------
# Copyright 2009 Sandia Corporation.
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
# the U.S. Government retains certain rights in this software.
#-------------------------------------------------------------------------
import cmd
import inspect
import blotish
import blot_common
import traceback
import sys
class _PVBlotInterp(cmd.Cmd):
"""pvblot - A blot-like interpreter using ParaView as a back end.
The pvblot interpreter reads commands in a manner similar to the SEACAS
blot command and performs visualization using the ParaView framework.
The images you get from pvblot will often provide more information than
those generated by the original blot tool. Comments begin with "$" and
continue to the end of the line. Commands are case insensitive and can
be abbreviated with any unique prefix. Keep in mind that there are
some differences in the blot commands and those offered here. There
are also many blot commands that are not replicated here.
"""
prompt = "BLOT> "
_blotish_commands = {}
def __init__(self, completekey='tab', stdin=None, stdout=None):
cmd.Cmd.__init__(self, completekey, stdin, stdout)
for funcname, func in blotish.__dict__.iteritems():
if funcname[0] == '_' or not inspect.isfunction(func): continue
if not func.__doc__ or not len(func.__doc__):
raise blotish.BlotishError("Method %s is undocumented." % funcname)
self._blotish_commands[funcname] = func
# Insert dummy commands for help.
self._blotish_commands['exit'] = _PVBlotInterp.do_exit
self._error_flag = False
def get_unique_command(self, command_name):
"""Given a command name, returns the function that implements it.
The command name should be in all lower case. The command name
need only cover the first part of the command uniquely. If no
command is found, or more than one command is found, raises a
BlotishError."""
valid_commands = []
for existing_command in self._blotish_commands.keys():
if existing_command.startswith(command_name):
valid_commands.append(existing_command)
if not valid_commands:
# If no command was found, maybe the command name is a variable name
func = blotish._find_variable_command(command_name)
if func is not None:
return func
else:
raise blotish.BlotishError("No such command '%s'" % command_name)
if len(valid_commands) > 1:
raise blotish.BlotishError(
"Command not found. Possible commands: %s" % str(", ").join(valid_commands))
return self._blotish_commands[valid_commands[0]]
def remove_comments_from_line(self, line):
"""Searches a command string for the comment character. If found,
removes the comment character and everything following it to create
a new command string. Returns the new command string converted to
lowercase."""
comment_start = line.find('$')
if (comment_start >= 0):
line = line[:comment_start]
return line.lower()
def precmd(self, command):
"""This method is called to preprocess a command input."""
return self.remove_comments_from_line(command)
def do_help(self, command_name):
"""The given argument is a string representing a command name. The
string may be empty. Prints documentation for the command name if given
else prints a list of available command names."""
if not command_name:
print _PVBlotInterp.__doc__
print "The following commands are supported:"
print " ",
blotish_commands = self._blotish_commands.keys()
blotish_commands.sort()
for c in blotish_commands:
print c,
print
print
print "For more information on any command, try help <command>."
return
try:
command = self.get_unique_command(command_name)
print command.__doc__
except blotish.BlotishError, err:
blot_common.print_blot_error(err)
def do_exit(self, args):
"Exit the blot interpreter."
return True
def do_eof(self, line):
"""Print a blank line and return True to signal we are ready to exit."""
print ""
return True
def handle_exception(self, exception):
"""Print a formatted error message if the exception is a BlotishError
else print a traceback. Does not cause the interpreter to quit."""
self._error_flag = True
if exception.__class__ is blotish.BlotishError:
blot_common.print_blot_error(exception)
else:
traceback.print_exc(file=sys.stdout)
def handle_async_input(self, s):
"""Takes an input string. If there is an object waiting for asynchronous
input that uses the string then return true, if an exception is thrown then
it prints the exception and possibly a traceback and returns true. If the
input is not used at all then return false."""
ret = True
try: ret = blotish._handle_input(s)
except Exception, err:
self.handle_exception(err)
# Update the prompt, some commands cause the prompt to change
self.prompt = blotish._get_prompt()
return ret
def emptyline(self):
"""If an object is waiting for asynchronous input pass it the empty string"""
self.handle_async_input("")
def default(self, s):
"""This method is called to handle all blotish commands."""
# First see if the asynchronous IO helper eats the string
if self.handle_async_input(s):
return False
# Split the string into tokens. Treat the first token as the command
# name, look for a blotish command and call it with the remaining tokens.
args = s.split()
try:
command = self.get_unique_command(args[0])
command(*args[1:])
except Exception, err:
self.handle_exception(err)
# Update the prompt, some commands cause the prompt to change
self.prompt = blotish._get_prompt()
def initialize(filename=None):
"""Initialize the pvblot interpreter for non-interactive use.
Normally you just call start and it takes care of reading and executing
commands. However, in situation where you are not reading from stdin and
stdout, you may need some other controlling mechanism to call methods
one at a time. In that case, use the initialize, execute, and finalize
functions.
"""
# Turn off progress printing while running
import paraview.servermanager
global wasProgressPrinting
wasProgressPrinting = paraview.servermanager.GetProgressPrintingIsEnabled()
paraview.servermanager.SetProgressPrintingEnabled(False)
blotish._init_blotish(filename)
global interpreter
interpreter = _PVBlotInterp()
def execute(command):
"""Run a command in the interpreter.
Normally you just call start and it takes care of reading and executing
commands. However, in situation where you are not reading from stdin and
stdout, you may need some other controlling mechanism to call methods
one at a time. In that case, use the initialize, execute, and finalize
functions.
This function returns a true value if the exit command is given.
"""
global interpreter
command = interpreter.precmd(command)
stop = interpreter.onecmd(command)
stop = interpreter.postcmd(stop, command)
return stop
def finalize():
"""Clean up the interpreter.
Normally you just call start and it takes care of reading and executing
commands. However, in situation where you are not reading from stdin and
stdout, you may need some other controlling mechanism to call methods
one at a time. In that case, use the initialize, execute, and finalize
functions.
"""
global interpreter
del interpreter
blotish._cleanup()
# Set the progress printing state to whatever it was before
import paraview.servermanager
global wasProgressPrinting
paraview.servermanager.SetProgressPrintingEnabled(wasProgressPrinting)
def execute_file(filename):
"""Executes each command in the file. If an exit command is executed
this method will stop execution and return True. This method returns
False after all commands have been executed. If a command causes an
error then execution stops but this method will still return False.
This can only be called after calling initialize()"""
try:
f = open(filename, 'r')
except IOError, err:
print "Could not open file", filename
return
blotish._set_interactive(False)
exit_flag = False
for line in f:
line = line.rstrip()
exit_flag = execute(line)
if exit_flag: break
if interpreter._error_flag: break
blotish._set_interactive(True)
return exit_flag
def start(data_file, script_file=None):
"""Start the pvblot interpreter."""
# Try to start up the interpreter
try:
initialize(data_file)
except blotish.BlotishError, err:
blot_common.print_blot_error(err)
return
# Maybe run a script
exit_flag = False
if script_file:
exit_flag = execute_file(script_file)
# Start the interpreter unless the script called exit
if not exit_flag:
global interpreter
interpreter.cmdloop()
# Cleanup
finalize()
def main():
"""
Call start() after parsing sys.argv for arguments:
[-input script_file] data_file
"""
data_file = None
script_file = None
if sys.argv and len(sys.argv) > 1:
if sys.argv[1] == "-input":
try: script_file = sys.argv[2]
except IndexError:
print "You need to specify a blot script for the -input option."
return
try: data_file = sys.argv[3]
except IndexError:
print "You need to specify a data filename."
return
else: data_file = sys.argv[1]
start(data_file, script_file)
#If we are running this source file directly, start it up.
if __name__ == '__main__':
main()