vtkMethodParser.py :  » Game-2D-3D » MayaVi » MayaVi-1.5 » vtkPipeline » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Game 2D 3D » MayaVi 
MayaVi » MayaVi 1.5 » vtkPipeline » vtkMethodParser.py
# $Id: vtkMethodParser.py,v 1.17 2005/07/27 18:37:36 prabhu_r Exp $
#
# This python program/module provides functionality to parse the
# methods of a VTK object and the ability to save and reload the
# current state of a VTK object.
#
# This code is distributed under the conditions of the BSD license.
# See LICENSE.txt for details.
#
# Copyright (c) 2000-2002, Prabhu Ramachandran.
#
# 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.
#
# Author contact information:
#   Prabhu Ramachandran <prabhu_r@users.sf.net>
#   http://www.aero.iitm.ernet.in/~prabhu/

"""  
This python program/module provides functionality to parse the methods
of a VTK object and the ability to save and reload the current state
of a VTK object.

"""

import string, re, sys
import types

try:
    # Shut up deprecation warnings for changes of function signatures
    # to int from float.
    import warnings
    warnings.filterwarnings('ignore', category=DeprecationWarning)
except ImportError:
    pass


# set this to 1 if you want to see debugging messages - very useful if
# you have problems
DEBUG=0

def debug (msg):
    if DEBUG:
        print msg

class VtkDirMethodParser:
    """ Parses the methods from dir(vtk_obj). """
    def initialize_methods (self, vtk_obj):
        debug ("VtkDirMethodParser:: initialize_methods ()")

        self.methods = dir (vtk_obj)[:]
        # stores the <blah>On methods
        self.toggle_meths = []
        # stores the Set<blah>To<blah> methods
        self.state_meths = []
        # stores the methods that have a Get<blah> and Set<blah>
        # only the <blah> is stored
        self.get_set_meths = []
        # pure get methods
        self.get_meths = []
        self.state_patn = re.compile ("To[A-Z0-9]")

        # Removing the Get/SetReferenceCount method
        try:
            self.methods.index ('GetReferenceCount')
        except ValueError:
            pass
        else:
            self.methods.remove ('GetReferenceCount')
            if 'SetReferenceCount' in self.methods:
                self.methods.remove ('SetReferenceCount')
            # The ReferenceCount is merely displayed
            self.get_meths.append ('GetReferenceCount')
        try:
            self.methods.index ('GetGlobalWarningDisplay')
        except ValueError:
            pass
        else:
            for m in ('GetGlobalWarningDisplay', 'SetGlobalWarningDisplay',
                      'GlobalWarningDisplayOff','GlobalWarningDisplayOn'):
                self.methods.remove (m)

        # testing if this version of vtk has David Gobbi's cool
        # stuff.
        try:
            junk = vtk_obj.__class__
        except AttributeError:
            pass
        else:
            # Bug in vtkRenderWindows:(
            if re.match ("vtk\w*RenderWindow", vtk_obj.GetClassName ()):
                for method in self.methods[:]:
                    if string.find (method, "StereoCapableWindow") > -1:
                        self.methods.remove (method)
                    elif string.find (method, "Position") > -1:
                        self.methods.remove (method)
            # Infinite loop bug.in older VTK versions
            if re.match ("vtk\w*Reader", vtk_obj.GetClassName ()):
                for method in self.methods[:]:
                    if re.match ("GetNumberOf\w*InFile", method):
                        self.methods.remove (method)
            # no need to check other bugs.
            return

        done = 0            
        # Bug in vtkRenderWindows:(
        if re.match ("vtk\w*RenderWindow", vtk_obj.GetClassName ()):
            for method in self.methods[:]:
                if string.find (method, "FileName") > -1:
                    self.methods.remove (method)
                    done = done +1
                elif string.find (method, "StereoCapableWindow") > -1:
                    self.methods.remove (method)
                    done = done +1
                elif string.find (method, "Position") > -1:
                    self.methods.remove (method)
                    done = done + 1
                elif string.find (method, "EventPending") > -1:
                    self.methods.remove (method)
                    done = done + 1                 
                elif done == 7:
                    break

        # Severe bug - causes segfault in older VTK releases
        if re.match ("vtk\w*Reader", vtk_obj.GetClassName ()):
            #self.methods = []
            for method in self.methods[:]:
                if string.find (method, "Name") > -1:
                    self.methods.remove (method)
                elif string.find (method, "InputString") > -1:
                    self.methods.remove (method)
                # Infinite loop bug.
                elif re.match ("GetNumberOf\w*InFile", method):
                    self.methods.remove (method)

    def parse_methods (self, vtk_obj):
        self.initialize_methods (vtk_obj)
        
        debug ("VtkDirMethodParser:: parse_methods() : initialized methods")
        
        for method in self.methods[:]:
            if string.find (method[:3], "Set") >= 0 and \
                 self.state_patn.search (method) is not None :
                try:
                    eval ("vtk_obj.Get%s"%method[3:])
                except AttributeError:
                    self.state_meths.append (method)
                    self.methods.remove (method)
            # finding all the On/Off toggle methods
            elif string.find (method[-2:], "On") >= 0:
                try:
                    self.methods.index ("%sOff"%method[:-2])
                except ValueError:
                    pass
                else:
                    self.toggle_meths.append (method)
                    self.methods.remove (method)
                    self.methods.remove ("%sOff"%method[:-2])
            # finding the Get/Set methods.
            elif string.find (method[:3], "Get") == 0:
                set_m = "Set"+method[3:]
                try: 
                    self.methods.index (set_m) 
                except ValueError:
                    pass
                else:
                    self.get_set_meths.append (method[3:])
                    self.methods.remove (method)
                    self.methods.remove (set_m)

        self.clean_up_methods (vtk_obj)

    def clean_up_methods (self, vtk_obj):
        self.clean_get_set (vtk_obj)
        self.clean_state_methods (vtk_obj)
        self.clean_get_methods (vtk_obj)

    def clean_get_set (self, vtk_obj):
        debug ("VtkDirMethodParser:: clean_get_set()")
        # cleaning up the Get/Set methods by removing the toggle funcs.
        for method in self.toggle_meths:
            try:
                self.get_set_meths.remove (method[:-2])
            except ValueError:
                pass

        # cleaning them up by removing any methods that are responsible for
        # other vtkObjects
        for method in self.get_set_meths[:]:
            try:
                eval ("vtk_obj.Get%s ().GetClassName ()"%method)
            except (TypeError, AttributeError):
                pass
            else:
                self.get_set_meths.remove (method)
                continue
            try:
                val = eval ("vtk_obj.Get%s ()"%method)
            except (TypeError, AttributeError):
                self.get_set_meths.remove (method)
            else:
                if val is None:
                    self.get_set_meths.remove (method)
        
    def clean_state_methods (self, vtk_obj):
        debug ("VtkDirMethodParser:: clean_state_methods()")
        # Getting the remaining pure GetMethods 
        for method in self.methods[:]:
            if string.find (method[:3], "Get") == 0:
                self.get_meths.append (method)
                self.methods.remove (method)

        # These aren't state methods.
        ignore = ['SetUpdateExtentToWholeExtent', 'SetInputArrayToProcess']
        for method in self.state_meths[:]:
            if method in ignore:
                self.methods.append(method)
                self.state_meths.remove(method)

        # Grouping similar state methods
        if len (self.state_meths) != 0:
            tmp = self.state_meths[:]
            self.state_meths = []
            state_group = [tmp[0]]
            end = self.state_patn.search (tmp[0]).start ()
            # stores the method type common to all similar methods
            m = tmp[0][3:end] 
            for i in range (1, len (tmp)):
                if string.find (tmp[i], m) >= 0:
                    state_group.append (tmp[i])
                else:
                    self.state_meths.append (state_group)
                    state_group = [tmp[i]]      
                    end = self.state_patn.search (tmp[i]).start ()
                    m = tmp[i][3:end]
                try: # remove the corresponding set method in get_set
                    val = self.get_set_meths.index (m)
                except ValueError: 
                    pass
                else:
                    del self.get_set_meths[val]
                    #self.get_meths.append ("Get"+m)
                clamp_m = "Get" + m + "MinValue"
                try: # remove the GetNameMax/MinValue in get_meths
                    val = self.get_meths.index (clamp_m)
                except ValueError:
                    pass
                else:
                    del self.get_meths[val]
                    val = self.get_meths.index ("Get" + m + "MaxValue")
                    del self.get_meths[val]

            if len (state_group) > 0:
                self.state_meths.append (state_group)

    def clean_get_methods (self, vtk_obj):
        debug ("VtkDirMethodParser:: clean_get_methods()")
        for method in self.get_meths[:]:
            #print method
            try:
                res = eval ("vtk_obj.%s ()"%method)
            except (TypeError, AttributeError):
                self.get_meths.remove (method)
                continue
            else:
                try:
                    eval ("vtk_obj.%s ().GetClassName ()"%method)
                except AttributeError:
                    pass
                else:
                    self.get_meths.remove (method)
                    continue
            if string.find (method[-8:], "MaxValue") > -1:
                self.get_meths.remove( method)
            elif string.find (method[-8:], "MinValue") > -1:
                self.get_meths.remove( method)
                
        self.get_meths.sort ()

    def toggle_methods (self):
        return self.toggle_meths

    def state_methods (self):
        return self.state_meths

    def get_set_methods (self):
        return self.get_set_meths

    def get_methods (self):
        return self.get_meths


class VtkMethodParser:

    """ This class finds the methods for a given vtkObject.  It uses
    the output from vtkObject->Print() (or in Python str(vtkObject))
    and output from the VtkDirMethodParser to obtain the methods. """
    
    def parse_methods (self, vtk_obj):
        "Parse for the methods."
        debug ("VtkMethodParser:: parse_methods()")
        self.vtk_warn = -1
        try:
            self.vtk_warn = vtk_obj.GetGlobalWarningDisplay ()
        except AttributeError:
            pass
        else:
            vtk_obj.GlobalWarningDisplayOff ()

        if self._initialize_methods (vtk_obj):
            # if David Gobbi's improvements are in this version of VTK
            # then I need to go no further.
            self._reset_warning_status (vtk_obj)
            return

        for method in self.methods[:]:
            # removing methods that have nothing to the right of the ':'
            if (method[1] == '') or \
               (string.find (method[1], "none") > -1) :
                self.methods.remove (method)
            elif method[0] == "ReferenceCount":
                self.get_meths.append ("Get"+method[0])
                self.methods.remove (method)    

        for method in self.methods:
            # toggle methods are first identified
            if (method[1] == "On") or (method[1] == "Off"):
                # bug in vtkRenderWindow.cxx ver 1.104. so fixing it.
                if re.match ("vtk\w*RenderWindow", vtk_obj.GetClassName ()):
                    if method[0] == "Swapbuffers":
                        method[0] = "SwapBuffers"
                # more bugs
                if re.match ("vtk\w*Renderer", vtk_obj.GetClassName ()):
                    if method[0] == "Two-sidedLighting":
                        method[0] = "TwoSidedLighting"
                try:
                    val = eval ("vtk_obj.Get%s ()"%method[0])
                    if val == 1:
                        eval ("vtk_obj.%sOn ()"%method[0])
                    elif val == 0:
                        eval ("vtk_obj.%sOff ()"%method[0])
                except AttributeError:
                    pass
                else:
                    self.toggle_meths.append (method[0]+"On")           
            else: # see it it is get_set or get or a state method
                found = 0
                # checking if it is a state func.
                # figure out the long names from the dir_state_meths
                for sms in self.dir_state_meths[:]:
                    if string.find (sms[0], method[0]) >= 0:
                        self.state_meths.append (sms)
                        self.dir_state_meths.remove (sms)
                        found = 1
                if found:
                    self.get_meths.append ("Get"+method[0])
                    try:
                        t = eval ("vtk_obj.Get%sAsString ()"%method[0])
                    except AttributeError:
                        pass
                    else:
                        self.get_meths.append ("Get"+method[0]+"AsString")
                else: 
                    # the long name is inherited or it is not a state method
                    try:
                        t = eval ("vtk_obj.Get%s ().GetClassName ()"%
                                  method[0])
                    except AttributeError:
                        pass
                    else:
                        continue        
                    val = 0
                    try:
                        val = eval ("vtk_obj.Get%s ()"%method[0])
                    except (TypeError, AttributeError):
                        pass
                    else:
                        try:
                            f = eval ("vtk_obj.Set%s"%method[0])
                        except AttributeError:
                            self.get_meths.append ("Get"+method[0])
                        else:
                            try:
                                f(val)
                            except TypeError:
                                try:
                                    f(*val)
                                except TypeError:
                                    self.get_meths.append ("Get"+method[0])
                                else:
                                    self.get_set_meths.append (method[0])
                            else:
                                self.get_set_meths.append (method[0])
                        
        self._clean_up_methods (vtk_obj)

    def _get_str_obj (self, vtk_obj):
        debug ("VtkMethodParser:: _get_str_obj()")
        self.methods = str (vtk_obj)
        self.methods = string.split (self.methods, "\n")
        del self.methods[0]

    def _initialize_methods (self, vtk_obj):
        "Do the basic parsing and setting up"
        debug ("VtkMethodParser:: _initialize_methods()")
        dir_p = VtkDirMethodParser ()
        dir_p.parse_methods (vtk_obj)

        # testing if this version of vtk has David Gobbi's cool
        # stuff. If it does then no need to do other things.
        try:
            junk = vtk_obj.__class__
        except AttributeError:
            pass
        else:
            self.toggle_meths = dir_p.toggle_methods ()
            self.state_meths = dir_p.state_methods ()
            self.get_set_meths = dir_p.get_set_methods ()
            self.get_meths = dir_p.get_methods ()
            return 1

        self.dir_toggle_meths = dir_p.toggle_methods ()
        self.dir_state_meths = dir_p.state_methods ()
        self.dir_get_set_meths = dir_p.get_set_methods ()
        self.dir_get_meths = dir_p.get_methods ()

        self._get_str_obj (vtk_obj)
        patn = re.compile ("  \S")
    
        for method in self.methods[:]:
            if not patn.match (method):
                self.methods.remove (method)
    
        for method in self.methods[:]:
            if string.find (method, ":") == -1:
                self.methods.remove (method)

        for i in range (0, len (self.methods)):
            strng = self.methods[i]
            strng = string.replace (strng, " ", "")
            self.methods[i] = string.split (strng, ":")

        done = 0
        if re.match ("vtk\w*RenderWindow", vtk_obj.GetClassName ()):
            for method in self.methods[:]:
                if string.find (method[0], "Position") > -1:
                    self.methods.remove (method)
                    done = done +1
                elif done == 2:
                    break

        self.toggle_meths = []
        self.state_meths = []
        self.get_set_meths = []
        self.get_meths = []    

        return 0

    def _clean_up_methods (self, vtk_obj):
        "Merge dir and str methods.  Finish up."
        debug ("VtkMethodParser:: _clean_up_methods()")
        for meth_list in ((self.dir_toggle_meths, self.toggle_meths),\
                          (self.dir_get_set_meths, self.get_set_meths),\
                          (self.dir_get_meths, self.get_meths)):
            for method in meth_list[0]:
                try:
                    meth_list[1].index (method)
                except ValueError:
                    meth_list[1].append (method)            

        # Remove all get_set methods that are already in toggle_meths
        # This case can happen if the str produces no "On/Off" but
        # dir does and str produces a get_set instead.
        for method in self.toggle_meths:
            try:
                self.get_set_meths.remove (method[:-2])
            except ValueError:
                pass

        self.toggle_meths.sort ()
        self.state_meths.sort ()
        self.get_set_meths.sort ()
        self.get_meths.sort ()
        self._reset_warning_status (vtk_obj)

    def _reset_warning_status (self, vtk_obj):
        debug ("VtkMethodParser:: _reset_warning_status ()")
        if self.vtk_warn > -1:
            vtk_obj.SetGlobalWarningDisplay (self.vtk_warn)
    
    def toggle_methods (self):
        return self.toggle_meths

    def state_methods (self):
        return self.state_meths

    def get_set_methods (self):
        return self.get_set_meths

    def get_methods (self):
        return self.get_meths


class VtkPicklerException (Exception):
    pass


class VtkPickler:

    """ Enables saving/loading the configuration of VTK objects by
    printing out the methods and the corresponding arguments to a
    file.  While dumping it uses the VtkMethodParser to get the
    methods."""

    def _parse_methods (self, vtk_obj):
        debug ("VtkPickler:: _parse_methods()")
        parser = VtkMethodParser ()
        parser.parse_methods (vtk_obj)
        self.toggle_meths = parser.toggle_methods ()
        self.state_meths = parser.state_methods ()
        self.get_set_meths = parser.get_set_methods ()

    def _shut_off_warnings(self, obj):
        """Turn off VTK deprecation warnings and save the old status
        of the warning flag."""
        self.vtk_warn = -1
        try:
            self.vtk_warn = obj.GetGlobalWarningDisplay ()
        except AttributeError:
            pass
        else:
            obj.GlobalWarningDisplayOff ()

    def _reset_warnings(self, obj):
        """Reset warnings to saved state."""
        if self.vtk_warn > -1:
            obj.SetGlobalWarningDisplay (self.vtk_warn)

    def _write_config(self, out):
        debug ("VtkPickler:: write_config()")
        state_patn = re.compile ("To[A-Z0-9]")
        methods = []
        args = []
        for method in self.toggle_meths:
            func = "Set"+method[:-2]
            val = eval ("self.obj.Get%s ()"%func[3:])
            methods.append ((func, val))
        for method in self.state_meths:
            end = state_patn.search (method[0]).start ()
            func = method[0][:end]
            val = eval ("self.obj.Get%s ()"%func[3:])
            methods.append ((func, val))
        for method in self.get_set_meths:
            func = "Set"+method
            val = eval ("self.obj.Get%s ()"%method)
            methods.append ((func, val))

        if hasattr(out, 'write'):
            out.write (self.obj.GetClassName ()+"\n")
            out.write (str (methods))
            out.write ("\n")
        else:
            d = {}
            d[self.obj.GetClassName()] = dict(methods)
            if hasattr(out, 'update'):
                out.update(d)
            else:
                out = d

    def _write_old_config (self, out):
        debug ("VtkPickler:: write_old_config()")
        state_patn = re.compile ("To[A-Z0-9]")
        methods = []
        args = []
        for method in self.toggle_meths:    
            methods.append ("Set"+method[:-2])
            val = eval ("self.obj.Get%s ()"%method[:-2])
            args.append (val)
        for method in self.state_meths:
            end = state_patn.search (method[0]).start ()
            m = method[0][:end]
            methods.append (m)
            val = eval ("self.obj.Get%s ()"%m[3:])
            args.append (val)
        for method in self.get_set_meths:
            methods.append ("Set"+method)
            val = eval ("self.obj.Get%s ()"%method)
            args.append (val)

        if hasattr(out, 'write'):
            out.write (self.obj.GetClassName ()+"\n")
            out.write (str (methods))
            out.write ("\n")
            out.write (str (args))
            out.write ("\n")
        else:
            d = {}
            d[self.obj.GetClassName()] = dict(map(None, methods, args))
            if hasattr(out, 'update'):
                out.update(d)
            else:
                out = d

    def _load_config (self, input, equiv):
        """Loads the configuration.

        Input args:

           input -- input data either as a file or a dictionary.
           equiv -- is an equivalent name for the object's class.
           Useful to get around names being renamed by VTK folks.
           """
        debug ("VtkPickler:: load_config ()")
        vtk_obj = self.obj
        if hasattr(input, 'readline'):
            c_name = input.readline ()[:-1]
        else:
            c_name = input.keys()[0]

        obj_name = vtk_obj.GetClassName ()
        if (obj_name != c_name) and (c_name != equiv):
            msg = "Error: Object given doesn't match object saved."
            msg = msg + "\nObject given is %s."%vtk_obj.GetClassName () 
            msg = msg + "\nObject saved is %s."%c_name
            msg = msg + "\nNot loading saved configuration!"
            raise VtkPicklerException, msg

        if hasattr(input, 'readline'):
            methods = eval (input.readline ())
            t = type (methods[0]) 
            if t is types.TupleType or t is types.ListType:
                self._load_new_config (methods)
            else:
                self._load_old_config (input, methods)
        else:
            methods = input[c_name].items()
            self._load_new_config (methods)            

    def _load_new_config(self, methods):
        debug ("VtkPickler:: load_new_config ()")
        for method in methods:
            func = method[0]
            arg = method[1]
            if func != 'SetGlobalWarningDisplay':
                self._call_function (func, arg)

    def _load_old_config (self, input, methods):
        debug ("VtkPickler:: load_old_config ()")
        args = eval (input.readline ())
        for i in range (0, len (methods)):
            func = methods[i]
            arg = args[i]
            if func != 'SetGlobalWarningDisplay':
                self._call_function (func, arg)

    def _call_function(self, func, arg):
        debug ("VtkPickler:: _call_function ()")
        try:
            f = eval ("self.obj.%s"%func)
        except AttributeError:
            msg = "Warning: The installed version of VTK does "\
                  "not have the member " + func + \
                  "for the class " + self.obj.GetClassName () + \
                  ".\nIgnoring it.\n"
            debug (msg)
        else:
            try:
                f(arg)
            except TypeError:
                f(*arg)
        
    def dump (self, vtk_obj, output):
        """Dump the configuration for the vtk object into the given
        object (file or dictionary).
        Input args:

           vtk_obj - the VTK object to dump.
           output - The object to dump into (either a file or a dict).
        """
        debug ("VtkPickler:: dump()")
        self.obj = vtk_obj
        self._parse_methods (vtk_obj)

        self._shut_off_warnings(vtk_obj)
        try:
            self._write_config (output)
        finally:
            self._reset_warnings(vtk_obj)

    def load (self, vtk_obj, input, equiv=""):        
        """Load the configuration for the vtk object from the file
        passed.

        Input args:
           vtk_obj - the VTK object
           input - the file from which to load the configuration
           equiv - a hack to allow name changes (arghh) made in VTK.
        """
        
        debug ("VtkPickler:: load()")
        self.obj = vtk_obj

        self._shut_off_warnings(vtk_obj)
        try:
            self._load_config (input, equiv)
        finally:
            self._reset_warnings(vtk_obj)

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.