[Paraview] StateLoader, second attempt

Robert Maynard RobertJMaynard at gmail.com
Tue Sep 4 16:58:40 EDT 2007


The previous version of the state loader script I released previously was
designed around the old python wrappings. With the new and improved
servermanager wrappings released, I decided to update the script to handle
the better way of doing things. The biggest improvement was the total
removal of all eval commands from the script, which makes me allot happier.

Even if you don't really need the script, it should provide a decent
overview of the numerous new commands, and style of the servermanager
wrappings.

#!/usr/bin/env python

from paraview.servermanager import *
import cPickle as pickle

class State:
  '''Allows the user to save states, which is all the display properties for
each Pipeline object and camera. After saving
  states you can than load them back up, reverting all the object and camera
properties to what they where
  on saving. The set of views can also be saved to a file by using pickle so
that you can build up multiple viewStates
  and than display them at a latter time

  Currently Supports:
    saving a state by calling
      addView(statename) statename can be numeric / string

    Loading a state:
      loadView(statename) will load the respective state. If nothing changes
      click on the render window of paraview, that should fix the render
display.

    Extra Commands:
      deleteView(name), will delete the view
      deleteAllViews, will clear the view list
      renameView(oldName, newName), renames the view currently called
oldName, to newName
      containsView(name), Will tell you if the name is already being used by
a view
      listViews(), Will list all the names of the views currently made
      debugView(name), Will dump the properties of the view, for testing

    Pickle Saving all States:
      saveState(filepath+filename) will pickle all the states so that you
can load them up at a different time

      loadState(filepath+filename) will unpickle all the states so that you
can run previously generated states

    Bug:
      Currently items added after a view is stored are not turned off/on
when loading view that do not effect
      that item. This may or may not be helpfull to you


  '''
  def __init__(self):
    #storage for a list of view objects
    self.view = list()
    self.proxies  = {1:'representations',2:'sources', 3:'views'}

  def loadState(self,file):
    '''loads a pickle view file, the passed in value needs
    to be a string that is the path to the pickled view'''
    #loads a State file
    try:
      #open an ascii pickle file
      self.view = pickle.load(open(file))
    except IOError:
      print "file not found"

  def saveState(self,file):
    '''save the current view collection as a ascii pickle'''
    pickle.dump(self.view,open(file,'w'))

  def deleteView(self,name):
    '''deletes the first occurance of a name from the view list'''
    for item in self.view:
      if (item.name == name):
        del item
        return True
    return False

  def deleteAllViews(self):
    '''deletes all views from the list'''
    del self.view
    self.view = list()

  def renameView(self,oldName, newName):
    '''rename a view with a new name'''
    for item in self.view:
      if (item.name == oldName):
        item.name = newName
        return True
    return False

  def containsView(self,name):
    '''checks to see if a view with the name already exists'''
    return (name in self.view)

  def debugView(self, name):
    '''debug print the view'''
    for item in self.view:
      print item.items
      print " ------- "

  def listViews(self):
    '''lists all the views sorted by name'''
    viewNames = list()
    for item in self.view:
      if ( (item.name in viewNames)==False):
        viewNames.append(item.name)
    #collect all the views and than sort them
    viewNames.sort()
    #display all the names
    for name in viewNames:
      print name

  def loadView(self,name):
    '''loads a select view that has already be saved.
       ex: state.loadView(1)'''
    for v in self.view:
      if (v.name == name):
        self.__load(v.proxy, v.items)

  def addView(self,name):
    '''adds the current state of all items in paraview + cameras as a view.
    loading this view will restore all the saved items to the current state
    ex: state.addView(1)'''
    for key in self.proxies.keys():
      newView = view(name, key, self.__getProperties(key))
      self.view.append(newView)

  def __load(self, proxyKey, items):
    #load the current view object
    proxy = self.__getProxiesInGroup(self.proxies[proxyKey])

    #reconstruct all the properties.
    if (proxyKey == 1):
      sources = self.__buildSourceNames(proxy)
      for sourceName,disp in zip(sources,proxy):
        for i in items:
          if (i[0] == sourceName):
            self.__reconstructDisplay(proxy, disp,
i[1])
    else:
      for name in proxy:
        for i in items:
          if (i[0] == name):
            self.__reconstructDisplay(proxy, name, i[1])
            if (proxyKey == 3):
              proxy[name].StillRender()

  def __reconstructDisplay(self,proxy, name, propertyList):
    #sets all the properties back to their stored values, by
    #using eval. Hopefully a safer way is found to do this
    for items in propertyList:
      property = items[0]
      value = items[1]
      proxy[name].SetPropertyWithName(property, value)
    proxy[name].UpdateVTKObjects()

  def __getProperties(self, proxyKey):
    #get all the data needed in a view here
    proxy = self.__getProxiesInGroup(self.proxies[proxyKey])
    totalProperties = list()
    if (proxyKey == 1):
      #build a list of source names that correspond to the display objects
      #so that load order wont effect display assocation
      sourceNames = self.__buildSourceNames(proxy)
      #get all the properties from each display object
      for name,item in zip(sourceNames,proxy):
        totalProperties.append( (name ,self.__getPropertyValues(proxy,item))
)
    else:
      #using the stored name for everything else
      for name in proxy:
        totalProperties.append( (name ,self.__getPropertyValues(proxy,name))
)
    return totalProperties

  def __getPropertyValues(self,proxy, name):
    properties = list()
    for property in proxy[name]:
      name = property.Proxy.GetPropertyName(property.SMProperty)

      try:
        value = property.GetData()
        float(value)
      except (IndexError,TypeError,ValueError,AttributeError,SyntaxError):
        #we can only pickle floats,ints, and strings. So we need a way
        #to make sure we dont save any paraview reference. This would change
        #if the servermanager became
pickleable
        try:
          float(value[0])
        except
(IndexError,TypeError,ValueError,AttributeError,SyntaxError):
          pass
        else:
          properties.append( (name,value) )
      else:
        properties.append( (name,value) )

    return properties

  def __getProxiesInGroup(self,name):
    pxm = servermanager.ProxyManager()
    proxy = pxm.GetProxiesInGroup(name)
    return proxy

  def __buildSourceNames(self, proxy):
    #builds all the source names for each display, by using the
    #dump tool procyLabel method
    sourceNames = list()
    for key in proxy.keys():
      inputValue = proxy[key].Input
      sourceNames.append(self.__proxyLabel(inputValue[0]))
    return sourceNames

  def __proxyLabel( self, outputPort ):
    """Returns the given proxy's PV displayed name. Much thanks from the
DumpTool for
    doing this great function"""
    pxm = servermanager.ProxyManager()
    proxy = outputPort.Proxy
    proxyGroup = pxm.GetProxiesInGroup(self.proxies[2])
    for name in proxyGroup:
      if (proxyGroup[name] == proxy):
        return name
    return None

class view:
  #merely a storage container of view properties
  def __init__(self, name, proxy, items):
    self.proxy = proxy
    self.name = name
    self.items = items

  def __getstate__(self):
    #custom pickle data, so that all the items are stored on
pickling
    pickleDict = dict()
    pickleDict['proxy']=self.proxy
    pickleDict['items']=self.items
    pickleDict['name']=self.name
    return pickleDict

  def __setstate__(self,dict):
    #restore the items and view name when unpickling
    self.proxy = dict['proxy']
    self.items = dict['items']
    self.name = dict['name']
    self.__dict__.update(dict)   # update
attributes
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://public.kitware.com/pipermail/paraview/attachments/20070904/544f22b9/attachment.html


More information about the ParaView mailing list