Back to index

salome-paravis  6.5.0
paravisSM.py
Go to the documentation of this file.
00001 # Copyright (C) 2010-2012  CEA/DEN, EDF R&D
00002 #
00003 # This library is free software; you can redistribute it and/or
00004 # modify it under the terms of the GNU Lesser General Public
00005 # License as published by the Free Software Foundation; either
00006 # version 2.1 of the License.
00007 #
00008 # This library is distributed in the hope that it will be useful,
00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 # Lesser General Public License for more details.
00012 #
00013 # You should have received a copy of the GNU Lesser General Public
00014 # License along with this library; if not, write to the Free Software
00015 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 #
00017 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 #
00019 
00020 r"""servermanager is a module for using paraview server manager in Python.
00021 One can always use the server manager API directly. However, this module
00022 provides an interface easier to use from Python by wrapping several VTK
00023 classes around Python classes.
00024 
00025 Note that, upon load, this module will create several sub-modules: sources,
00026 filters and rendering. These modules can be used to instantiate specific
00027 proxy types. For a list, try "dir(servermanager.sources)"
00028 
00029 A simple example:
00030   from paraview.servermanager import *
00031 
00032   # Creates a new built-in session and makes it the active session.
00033   Connect()
00034 
00035   # Creates a new render view on the active session.
00036   renModule = CreateRenderView()
00037 
00038   # Create a new sphere proxy on the active session and register it
00039   # in the sources group.
00040   sphere = sources.SphereSource(registrationGroup="sources", ThetaResolution=16, PhiResolution=32)
00041 
00042   # Create a representation for the sphere proxy and adds it to the render
00043   # module.
00044   display = CreateRepresentation(sphere, renModule)
00045 
00046   renModule.StillRender()
00047 """
00048 
00049 
00050 
00051 import re, os, new, sys
00052 from paravis import *
00053 
00054 
00055 
00056 def _wrap_property(proxy, smproperty):
00057     """ Internal function.
00058     Given a server manager property and its domains, returns the
00059     appropriate python object.
00060     """
00061     property = None
00062     if smproperty.IsA("vtkSMStringVectorProperty"):
00063         al = smproperty.GetDomain("array_list")
00064         if  al and al.IsA("vtkSMArraySelectionDomain") and \
00065             smproperty.GetRepeatable():
00066             property = ArrayListProperty(proxy, smproperty)
00067         elif al and al.IsA("vtkSMArrayListDomain") and smproperty.GetNumberOfElements() == 5:
00068             property = ArraySelectionProperty(proxy, smproperty)
00069         else:
00070             iter = smproperty.NewDomainIterator()
00071             isFileName = False
00072             while not iter.IsAtEnd():
00073                 # Refer to BUG #9710 to see why optional domains need to be
00074                 # ignored.
00075                 if iter.GetDomain().IsA("vtkSMFileListDomain") and \
00076                   iter.GetDomain().GetIsOptional() == 0 :
00077                     isFileName = True
00078                     break
00079                 iter.Next()
00080             iter.UnRegister(None)
00081             if isFileName:
00082                 property = FileNameProperty(proxy, smproperty)
00083             elif _make_name_valid(smproperty.GetXMLLabel()) == 'ColorArrayName':
00084                 property = ColorArrayProperty(proxy, smproperty)
00085             else:
00086                 property = VectorProperty(proxy, smproperty)
00087     elif smproperty.IsA("vtkSMVectorProperty"):
00088         if smproperty.IsA("vtkSMIntVectorProperty") and \
00089           smproperty.GetDomain("enum"):
00090             property = EnumerationProperty(proxy, smproperty)
00091         else:
00092             property = VectorProperty(proxy, smproperty)
00093     elif smproperty.IsA("vtkSMInputProperty"):
00094         property = InputProperty(proxy, smproperty)
00095     elif smproperty.IsA("vtkSMProxyProperty"):
00096         property = ProxyProperty(proxy, smproperty)
00097     else:
00098         property = Property(proxy, smproperty)
00099     return property
00100 
00101 class Proxy(object):
00102     """Proxy for a server side object. A proxy manages the lifetime of
00103     one or more server manager objects. It also provides an interface
00104     to set and get the properties of the server side objects. These
00105     properties are presented as Python properties. For example,
00106     you can set a property Foo using the following:
00107      proxy.Foo = (1,2)
00108     or
00109      proxy.Foo.SetData((1,2))
00110     or
00111      proxy.Foo[0:2] = (1,2)
00112     For more information, see the documentation of the property which
00113     you can obtain with
00114     help(proxy.Foo).
00115 
00116     This class also provides an iterator which can be used to iterate
00117     over all properties.
00118     eg:
00119       proxy = Proxy(proxy=smproxy)
00120       for property in proxy:
00121           print property
00122 
00123     For advanced users:
00124     This is a python class that wraps a vtkSMProxy.. Makes it easier to
00125     set/get properties.
00126     Instead of:
00127      proxy.GetProperty("Foo").SetElement(0, 1)
00128      proxy.GetProperty("Foo").SetElement(0, 2)
00129     you can do:
00130      proxy.Foo = (1,2)
00131     or
00132      proxy.Foo.SetData((1,2))
00133     or
00134      proxy.Foo[0:2] = (1,2)
00135     Instead of:
00136       proxy.GetProperty("Foo").GetElement(0)
00137     you can do:
00138       proxy.Foo.GetData()[0]
00139     or
00140       proxy.Foo[0]
00141     For proxy properties, you can use append:
00142      proxy.GetProperty("Bar").AddProxy(foo)
00143     you can do:
00144      proxy.Bar.append(foo)
00145     Properties support most of the list API. See VectorProperty and
00146     ProxyProperty documentation for details.
00147 
00148     Please note that some of the methods accessible through the Proxy
00149     class are not listed by help() because the Proxy objects forward
00150     unresolved attributes to the underlying object. To get the full list,
00151     see also dir(proxy.SMProxy). See also the doxygen based documentation
00152     of the vtkSMProxy C++ class.
00153     """
00154 
00155     def __init__(self, **args):
00156         """ Default constructor. It can be used to initialize properties
00157         by passing keyword arguments where the key is the name of the
00158         property. In addition registrationGroup and registrationName (optional)
00159         can be specified (as keyword arguments) to automatically register
00160         the proxy with the proxy manager. """
00161         self.add_attribute('Observed', None)
00162         self.add_attribute('ObserverTag', -1)
00163         self.add_attribute('_Proxy__Properties', {})
00164         self.add_attribute('_Proxy__LastAttrName', None)
00165         self.add_attribute('SMProxy', None)
00166         self.add_attribute('Port', 0)
00167 
00168         if 'port' in args:
00169             self.Port = args['port']
00170             del args['port']
00171 
00172         update = True
00173         if 'no_update' in args:
00174             if args['no_update']:
00175                 update = False
00176             del args['no_update']
00177 
00178         if 'proxy' in args:
00179             self.InitializeFromProxy(args['proxy'])
00180             del args['proxy']
00181         else:
00182             self.Initialize(None, update)
00183         if 'registrationGroup' in args:
00184             registrationGroup = args['registrationGroup']
00185             del args['registrationGroup']
00186             registrationName = self.SMProxy.GetGlobalIDAsString()
00187             if 'registrationName' in args:
00188                 registrationName = args['registrationName']
00189                 del args['registrationName']
00190             pxm = ProxyManager()
00191             pxm.RegisterProxy(registrationGroup, registrationName, self.SMProxy)
00192         if update:
00193             self.UpdateVTKObjects()
00194         for key in args.keys():
00195             setattr(self, key, args[key])
00196         # Visit all properties so that they are created
00197         for prop in self:
00198             pass
00199 
00200     def __setattr__(self, name, value):
00201         try:
00202             setter = getattr(self.__class__, name)
00203             setter = setter.__set__
00204         except AttributeError:
00205             if not hasattr(self, name):
00206                 raise AttributeError("Attribute %s does not exist. " % name +
00207                   " This class does not allow addition of new attributes to avoid " +
00208                   "mistakes due to typos. Use add_attribute() if you really want " +
00209                   "to add this attribute.")
00210             self.__dict__[name] = value
00211         else:
00212             setter(self, value)
00213 
00214     def add_attribute(self, name, value):
00215         self.__dict__[name] = value
00216 
00217     def __del__(self):
00218         """Destructor. Cleans up all observers as well as remove
00219         the proxy from the _pyproxies dictionary"""
00220         # Make sure that we remove observers we added
00221         if self.Observed:
00222             observed = self.Observed
00223             tag = self.ObserverTag
00224             self.Observed = None
00225             self.ObserverTag = -1
00226             observed.RemoveObserver(tag)
00227         if self.SMProxy and (self.SMProxy, self.Port) in _pyproxies:
00228             del _pyproxies[(self.SMProxy, self.Port)]
00229 
00230     def InitializeFromProxy(self, aProxy, update=True):
00231         """Constructor. Assigns proxy to self.SMProxy, updates the server
00232         object as well as register the proxy in _pyproxies dictionary."""
00233         import weakref
00234         self.SMProxy = aProxy
00235         if update:
00236             self.SMProxy.UpdateVTKObjects()
00237         _pyproxies[(self.SMProxy, self.Port)] = weakref.ref(self)
00238 
00239     def Initialize(self):
00240         "Overridden by the subclass created automatically"
00241         pass
00242 
00243     def __eq__(self, other):
00244         "Returns true if the underlying SMProxies are the same."
00245         if isinstance(other, Proxy):
00246             try:
00247                 if self.Port != other.Port:
00248                     return False
00249             except:
00250                 pass
00251             ## VSV using IsSame instead ==
00252             return self.SMProxy.IsSame(other.SMProxy)
00253         return self.SMProxy.IsSame(other)
00254 
00255     def __ne__(self, other):
00256         "Returns false if the underlying SMProxies are the same."
00257         return not self.__eq__(other)
00258 
00259     def __iter__(self):
00260         "Creates an iterator for the properties."
00261         return PropertyIterator(self)
00262 
00263     def SetPropertyWithName(self, pname, arg):
00264         """Generic method for setting the value of a property."""
00265         prop = self.GetProperty(pname)
00266         if prop is None:
00267             raise RuntimeError, "Property %s does not exist. Please check the property name for typos." % pname
00268         prop.SetData(arg)
00269 
00270     def GetPropertyValue(self, name):
00271         """Returns a scalar for properties with 1 elements, the property
00272         itself for vectors."""
00273         p = self.GetProperty(name)
00274         if isinstance(p, VectorProperty):
00275             if p.GetNumberOfElements() == 1 and not p.GetRepeatable():
00276                 if p.SMProperty.IsA("vtkSMStringVectorProperty") or not p.GetArgumentIsArray():
00277                     return p[0]
00278         elif isinstance(p, InputProperty):
00279             if not p.GetMultipleInput():
00280                 if len(p) > 0:
00281                     return p[0]
00282                 else:
00283                     return None
00284         elif isinstance(p, ProxyProperty):
00285             if not p.GetRepeatable():
00286                 if len(p) > 0:
00287                     return p[0]
00288                 else:
00289                     return None
00290         return p
00291 
00292     def GetProperty(self, name):
00293         """Given a property name, returns the property object."""
00294         if name in self.__Properties and self.__Properties[name]():
00295             return self.__Properties[name]()
00296         smproperty = self.SMProxy.GetProperty(name)
00297         # Maybe they are looking by the label. Try to match that.
00298         if not smproperty:
00299             iter = PropertyIterator(self)
00300             for prop in iter:
00301                 if name == _make_name_valid(iter.PropertyLabel):
00302                     smproperty = prop.SMProperty
00303                     break
00304         if smproperty:
00305             property = _wrap_property(self, smproperty)
00306             if property is not None:
00307                 import weakref
00308                 self.__Properties[name] = weakref.ref(property)
00309             return property
00310         return None
00311 
00312     def ListProperties(self):
00313         """Returns a list of all property names on this proxy."""
00314         property_list = []
00315         iter = self.__iter__()
00316         for property in iter:
00317             name = _make_name_valid(iter.PropertyLabel)
00318             if name:
00319                 property_list.append(name)
00320         return property_list
00321 
00322     def __ConvertArgumentsAndCall(self, *args):
00323         """ Internal function.
00324         Used to call a function on SMProxy. Converts input and
00325         output values as appropriate.
00326         """
00327         newArgs = []
00328         for arg in args:
00329             if issubclass(type(arg), Proxy) or isinstance(arg, Proxy):
00330                 newArgs.append(arg.SMProxy)
00331             else:
00332                 newArgs.append(arg)
00333         func = getattr(self.SMProxy, self.__LastAttrName)
00334         retVal = func(*newArgs)
00335         if type(retVal) is type(self.SMProxy) and retVal.IsA("vtkSMProxy"):
00336             return _getPyProxy(retVal)
00337         elif type(retVal) is type(self.SMProxy) and retVal.IsA("vtkSMProperty"):
00338             return _wrap_property(self, retVal)
00339         else:
00340             return retVal
00341 
00342     def __GetActiveCamera(self):
00343         """ This method handles GetActiveCamera specially. It adds
00344         an observer to the camera such that everytime it is modified
00345         the render view updated"""
00346         import weakref
00347         c = self.SMProxy.GetActiveCamera()
00348         # VSV: Observers are not supported
00349 ##         if not c.HasObserver("ModifiedEvent"):
00350 ##             self.ObserverTag =c.AddObserver("ModifiedEvent", _makeUpdateCameraMethod(weakref.ref(self)))
00351 ##             self.Observed = c
00352         return c
00353 
00354     def __getattr__(self, name):
00355         """With the exception of a few overloaded methods,
00356         returns the SMProxy method"""
00357         if not self.SMProxy:
00358             raise AttributeError("class %s has no attribute %s" % ("None", name))
00359             return None
00360         # Handle GetActiveCamera specially.
00361         if name == "GetActiveCamera" and \
00362            hasattr(self.SMProxy, "GetActiveCamera"):
00363             return self.__GetActiveCamera
00364         if name == "SaveDefinition" and hasattr(self.SMProxy, "SaveDefinition"):
00365             return self.__SaveDefinition
00366         # If not a property, see if SMProxy has the method
00367         try:
00368             proxyAttr = getattr(self.SMProxy, name)
00369             self.__LastAttrName = name
00370             return self.__ConvertArgumentsAndCall
00371         except:
00372             pass
00373         return getattr(self.SMProxy, name)
00374 
00375 class SourceProxy(Proxy):
00376     """Proxy for a source object. This class adds a few methods to Proxy
00377     that are specific to sources. It also provides access to the output
00378     ports. Output ports can be accessed by name or index:
00379     > op = source[0]
00380     or
00381     > op = source['some name'].
00382     """
00383     def UpdatePipeline(self, time=None):
00384         """This method updates the server-side VTK pipeline and the associated
00385         data information. Make sure to update a source to validate the output
00386         meta-data."""
00387         if time != None:
00388             self.SMProxy.UpdatePipeline(time)
00389         else:
00390             self.SMProxy.UpdatePipeline()
00391         # This is here to cause a receive
00392         # on the client side so that progress works properly.
00393         if ActiveConnection and ActiveConnection.IsRemote():
00394             self.SMProxy.GetDataInformation()
00395 
00396     def FileNameChanged(self):
00397         "Called when the filename of a source proxy is changed."
00398         self.UpdatePipelineInformation()
00399 
00400     def UpdatePipelineInformation(self):
00401         """This method updates the meta-data of the server-side VTK pipeline and
00402         the associated information properties"""
00403         self.SMProxy.UpdatePipelineInformation()
00404 
00405     def GetDataInformation(self, idx=None):
00406         """This method returns a DataInformation wrapper around a
00407         vtkPVDataInformation"""
00408         if idx == None:
00409             idx = self.Port
00410         if self.SMProxy:
00411             return DataInformation( \
00412                 self.SMProxy.GetDataInformation(idx), \
00413                 self.SMProxy, idx)
00414 
00415     def __getitem__(self, idx):
00416         """Given a slice, int or string, returns the corresponding
00417         output port"""
00418         if isinstance(idx, slice):
00419             indices = idx.indices(self.SMProxy.GetNumberOfOutputPorts())
00420             retVal = []
00421             for i in range(*indices):
00422                 retVal.append(OutputPort(self, i))
00423             return retVal
00424         elif isinstance(idx, int):
00425             if idx >= self.SMProxy.GetNumberOfOutputPorts() or idx < 0:
00426                 raise IndexError
00427             return OutputPort(self, idx)
00428         else:
00429             return OutputPort(self, self.SMProxy.GetOutputPortIndex(idx))
00430 
00431     def GetPointDataInformation(self):
00432         """Returns the associated point data information."""
00433         self.UpdatePipeline()
00434         return FieldDataInformation(self.SMProxy, self.Port, "PointData")
00435 
00436     def GetCellDataInformation(self):
00437         """Returns the associated cell data information."""
00438         self.UpdatePipeline()
00439         return FieldDataInformation(self.SMProxy, self.Port, "CellData")
00440 
00441     def GetFieldDataInformation(self):
00442         """Returns the associated cell data information."""
00443         self.UpdatePipeline()
00444         return FieldDataInformation(self.SMProxy, self.Port, "FieldData")
00445 
00446     PointData = property(GetPointDataInformation, None, None, "Returns point data information")
00447     CellData = property(GetCellDataInformation, None, None, "Returns cell data information")
00448     FieldData = property(GetFieldDataInformation, None, None, "Returns field data information")
00449 
00450 
00451 class ExodusIIReaderProxy(SourceProxy):
00452     """Special class to define convenience functions for array
00453     selection."""
00454 
00455     def FileNameChanged(self):
00456         "Called when the filename changes. Selects all variables."
00457         SourceProxy.FileNameChanged(self)
00458         self.SelectAllVariables()
00459 
00460     def SelectAllVariables(self):
00461         "Select all available variables for reading."
00462         for prop in ('PointVariables', 'EdgeVariables', 'FaceVariables',
00463                      'ElementVariables', 'GlobalVariables'):
00464             f = getattr(self, prop)
00465             f.SelectAll()
00466 
00467     def DeselectAllVariables(self):
00468         "Deselects all variables."
00469         for prop in ('PointVariables', 'EdgeVariables', 'FaceVariables',
00470                      'ElementVariables', 'GlobalVariables'):
00471             f = getattr(self, prop)
00472             f.DeselectAll()
00473 
00474 class ViewLayoutProxy(Proxy):
00475     """Special class to define convenience methods for View Layout"""
00476 
00477     def SplitViewHorizontal(self, view, fraction=0.5):
00478         """Split the cell containing the specified view horizontally.
00479         If no fraction is specified, the frame is split into equal parts.
00480         On success returns a positve number that identifying the new cell
00481         location that can be used to assign view to, or split further.
00482         Return -1 on failure."""
00483         location = self.GetViewLocation(view)
00484         if location == -1:
00485             raise RuntimeError, "View is not present in this layout."
00486         if fraction < 0.0 or fraction > 1.0:
00487             raise RuntimeError, "'fraction' must be in the range [0.0, 1.0]"
00488         return self.SMProxy.SplitHorizontal(location, fraction)
00489 
00490     def SplitViewVertical(self, view=None, fraction=0.5):
00491         """Split the cell containing the specified view horizontally.
00492         If no view is specified, active view is used.
00493         If no fraction is specified, the frame is split into equal parts.
00494         On success returns a positve number that identifying the new cell
00495         location that can be used to assign view to, or split further.
00496         Return -1 on failure."""
00497         location = self.GetViewLocation(view)
00498         if location == -1:
00499             raise RuntimeError, "View is not present in this layout."
00500         if fraction < 0.0 or fraction > 1.0:
00501             raise RuntimeError, "'fraction' must be in the range [0.0, 1.0]"
00502         return self.SMProxy.SplitVertical(location, fraction)
00503 
00504     def AssignView(self, location, view):
00505         """Assign a view at a particular location. Note that the view's position may
00506         be changed by subsequent Split() calls. Returns true on success."""
00507         viewproxy = None
00508         if isinstance(view, Proxy):
00509             view = view.SMProxy
00510         return self.SMProxy.AssignView(location, view)
00511 
00512     def GetViewLocation(self, view):
00513         if isinstance(view, Proxy):
00514             view = view.SMProxy
00515         return self.SMProxy.GetViewLocation(view)
00516 
00517 class Property(object):
00518     """Generic property object that provides access to one of the properties of
00519     a server object. This class does not allow setting/getting any values but
00520     provides an interface to update a property using __call__. This can be used
00521     for command properties that correspond to function calls without arguments.
00522     For example,
00523     > proxy.Foo()
00524     would push a Foo property which may cause the proxy to call a Foo method
00525     on the actual VTK object.
00526 
00527     For advanced users:
00528     Python wrapper around a vtkSMProperty with a simple interface.
00529     In addition to all method provided by vtkSMProperty (obtained by
00530     forwarding unknown attributes requests to the underlying SMProxy),
00531     Property and sub-class provide a list API.
00532 
00533     Please note that some of the methods accessible through the Property
00534     class are not listed by help() because the Property objects forward
00535     unresolved attributes to the underlying object. To get the full list,
00536     see also dir(proxy.SMProperty). See also the doxygen based documentation
00537     of the vtkSMProperty C++ class.
00538     """
00539     def __init__(self, proxy, smproperty):
00540         """Default constructor. Stores a reference to the proxy."""
00541         import weakref
00542         self.SMProperty = smproperty
00543         self.Proxy = proxy
00544 
00545     def __repr__(self):
00546         """Returns a string representation containing property name
00547         and value"""
00548         if not type(self) is Property:
00549             if self.GetData() is not None:
00550                 repr = self.GetData().__repr__()
00551             else:
00552                 repr = "None"
00553         else:
00554             repr = "Property name= "
00555             name = self.Proxy.GetPropertyName(self.SMProperty)
00556             if name:
00557                 repr += name
00558             else:
00559                 repr += "Unknown"
00560 
00561         return repr
00562 
00563     def __call__(self):
00564         """Forces a property update using InvokeCommand."""
00565         if type(self) is Property:
00566             self.Proxy.SMProxy.InvokeCommand(self._FindPropertyName())
00567         else:
00568             raise RuntimeError, "Cannot invoke this property"
00569 
00570     def _FindPropertyName(self):
00571         "Returns the name of this property."
00572         return self.Proxy.GetPropertyName(self.SMProperty)
00573 
00574     def _UpdateProperty(self):
00575         "Pushes the value of this property to the server."
00576         # For now, we are updating all properties. This is due to an
00577         # issue with the representations. Their VTK objects are not
00578         # created until Input is set therefore, updating a property
00579         # has no effect. Updating all properties everytime one is
00580         # updated has the effect of pushing values set before Input
00581         # when Input is updated.
00582         # self.Proxy.SMProxy.UpdateProperty(self._FindPropertyName())
00583         self.Proxy.SMProxy.UpdateVTKObjects()
00584 
00585     def __getattr__(self, name):
00586         "Unknown attribute requests get forwarded to SMProperty."
00587         return getattr(self.SMProperty, name)
00588 
00589     Name = property(_FindPropertyName, None, None,
00590            "Returns the name for the property")
00591 
00592 class GenericIterator(object):
00593     """Iterator for container type objects"""
00594 
00595     def __init__(self, obj):
00596         self.Object = obj
00597         self.index = 0
00598 
00599     def __iter__(self):
00600         return self
00601 
00602     def next(self):
00603         if self.index >= len(self.Object):
00604             raise StopIteration
00605 
00606         idx = self.index
00607         self.index += 1
00608         return self.Object[idx]
00609 
00610 class VectorProperty(Property):
00611     """A VectorProperty provides access to one or more values. You can use
00612     a slice to get one or more property values:
00613     > val = property[2]
00614     or
00615     > vals = property[0:5:2]
00616     You can use a slice to set one or more property values:
00617     > property[2] = val
00618     or
00619     > property[1:3] = (1,2)
00620     """
00621     def ConvertValue(self, value):
00622         return value
00623 
00624     def __len__(self):
00625         """Returns the number of elements."""
00626         return self.SMProperty.GetNumberOfElements()
00627 
00628     def __iter__(self):
00629         """Implementation of the sequence API"""
00630         return GenericIterator(self)
00631 
00632     def __setitem__(self, idx, value):
00633         """Given a list or tuple of values, sets a slice of values [min, max)"""
00634         if isinstance(idx, slice):
00635             indices = idx.indices(len(self))
00636             for i, j in zip(range(*indices), value):
00637                 self.SMProperty.SetElement(i, self.ConvertValue(j))
00638             self._UpdateProperty()
00639         elif idx >= len(self) or idx < 0:
00640             raise IndexError
00641         else:
00642             self.SMProperty.SetElement(idx, self.ConvertValue(value))
00643             self._UpdateProperty()
00644 
00645     def GetElement(self, index):
00646         return self.SMProperty.GetElement(index)
00647 
00648     def __getitem__(self, idx):
00649         """Returns the range [min, max) of elements. Raises an IndexError
00650         exception if an argument is out of bounds."""
00651         ls = len(self)
00652         if isinstance(idx, slice):
00653             indices = idx.indices(ls)
00654             retVal = []
00655             for i in range(*indices):
00656                retVal.append(self.GetElement(i))
00657             return retVal
00658         elif idx >= ls:
00659             raise IndexError
00660         elif idx < 0:
00661             idx = ls + idx
00662             if idx < 0:
00663                 raise IndexError
00664 
00665         return self.GetElement(idx)
00666 
00667     def GetData(self):
00668         "Returns all elements as either a list or a single value."
00669         property = self.SMProperty
00670         if property.GetRepeatable() or \
00671            property.GetNumberOfElements() > 1:
00672             return self[0:len(self)]
00673         elif property.GetNumberOfElements() == 1:
00674             return self.GetElement(0)
00675 
00676     def SetData(self, values):
00677         """Allows setting of all values at once. Requires a single value or
00678         a iterable object."""
00679         if not hasattr(values, "__iter__"):
00680             values = (values,)
00681         if not self.GetRepeatable() and len(values) != self.GetNumberOfElements():
00682             raise RuntimeError("This property requires %d values." % self.GetNumberOfElements())
00683         if self.GetRepeatable():
00684             # Clean up first
00685             self.SMProperty.SetNumberOfElements(0)
00686         idx = 0
00687         for val in values:
00688             self.SMProperty.SetElement(idx, self.ConvertValue(val))
00689             idx += 1
00690         self._UpdateProperty()
00691 
00692     def Clear(self):
00693         "Removes all elements."
00694         self.SMProperty().SetNumberOfElements(0)
00695         self._UpdateProperty()
00696 
00697 class ColorArrayProperty(VectorProperty):
00698     """This subclass of VectorProperty handles setting of the array to
00699     color by. It handles attribute type as well as well array name."""
00700 
00701     def GetAvailable(self):
00702         """Returns the list of available arrays as (attribute type, array name
00703         tuples."""
00704         arrays = []
00705         for a in self.Proxy.Input.PointData:
00706             arrays.append(('POINT_DATA', a.GetName()))
00707         for a in self.Proxy.Input.CellData:
00708             arrays.append(('CELL_DATA', a.GetName()))
00709         return arrays
00710 
00711     def SetData(self, value):
00712         """Overwritten to enable setting attribute type (the ColorAttributeType
00713         property and the array name. The argument should be the array name
00714         (in which case the first appropriate attribute type is picked) or
00715         a tuple of attribute type and array name."""
00716         if isinstance(value, tuple) and len(value) == 2:
00717             att = value[0]
00718             arr = value[1]
00719         elif isinstance(value, str):
00720             att = None
00721             arr = value
00722         else:
00723             raise ValueError("Expected a tuple of 2 values or a string.")
00724 
00725         if not arr:
00726             self.SMProperty.SetElement(0, '')
00727             self._UpdateProperty()
00728             return
00729 
00730         found = False
00731         for a in self.Available:
00732             if a[1] == arr and (not att or att == a[0]):
00733                 att = a[0]
00734                 found = True
00735                 break
00736 
00737         if  not found:
00738             pvoptions = vtkProcessModule.GetProcessModule().GetOptions()
00739             # if this process is from a parallel batch run in symmetric mpi mode
00740             # then we may not have any points or cells on some processes in which
00741             # case we'll probably be missing the point and cell data too.  the
00742             # check below makes sure that we avoid this situation.
00743             if pvoptions.GetProcessType() != 0x40 or pvoptions.GetSymmetricMPIMode() == False \
00744                     or len(self.Available) != 0:
00745                 raise ValueError("Could not locate array %s in the input." % arr)
00746 
00747         catt = self.Proxy.GetProperty("ColorAttributeType")
00748         if att != None:
00749             catt.SetData(att)
00750         self.SMProperty.SetElement(0, arr)
00751         self._UpdateProperty()
00752 
00753     Available = property(GetAvailable, None, None, \
00754         "This read-only property returns the list of arrays that can be colored by.")
00755 
00756 
00757 class EnumerationProperty(VectorProperty):
00758     """Subclass of VectorProperty that is applicable for enumeration type
00759     properties."""
00760 
00761     def GetElement(self, index):
00762         """Returns the text for the given element if available. Returns
00763         the numerical values otherwise."""
00764         val = self.SMProperty.GetElement(index)
00765         domain = self.SMProperty.GetDomain("enum")
00766         for i in range(domain.GetNumberOfEntries()):
00767             if domain.GetEntryValue(i) == val:
00768                 return domain.GetEntryText(i)
00769         return val
00770 
00771     def ConvertValue(self, value):
00772         """Converts value to type suitable for vtSMProperty::SetElement()"""
00773         if type(value) == str:
00774             domain = self.SMProperty.GetDomain("enum")
00775             if domain.HasEntryText(value):
00776                 return domain.GetEntryValueForText(value)
00777             else:
00778                 raise ValueError("%s is not a valid value." % value)
00779         return VectorProperty.ConvertValue(self, value)
00780 
00781     def GetAvailable(self):
00782         "Returns the list of available values for the property."
00783         retVal = []
00784         domain = self.SMProperty.GetDomain("enum")
00785         for i in range(domain.GetNumberOfEntries()):
00786             retVal.append(domain.GetEntryText(i))
00787         return retVal
00788 
00789     Available = property(GetAvailable, None, None, \
00790         "This read-only property contains the list of values that can be applied to this property.")
00791 
00792 
00793 class FileNameProperty(VectorProperty):
00794     """Property to set/get one or more file names.
00795     This property updates the pipeline information everytime its value changes.
00796     This is used to keep the array lists up to date."""
00797 
00798     def _UpdateProperty(self):
00799         "Pushes the value of this property to the server."
00800         VectorProperty._UpdateProperty(self)
00801         self.Proxy.FileNameChanged()
00802 
00803 class ArraySelectionProperty(VectorProperty):
00804     "Property to select an array to be processed by a filter."
00805 
00806     def GetAssociation(self):
00807         val = self.GetElement(3)
00808         if val == "":
00809             return None
00810         for key, value in ASSOCIATIONS.iteritems():
00811             if value == int(val):
00812                 return key
00813 
00814         return None
00815 
00816     def GetArrayName(self):
00817         return self.GetElement(4)
00818 
00819     def __len__(self):
00820         """Returns the number of elements."""
00821         return 2
00822 
00823     def __setitem__(self, idx, value):
00824         raise RuntimeError, "This property cannot be accessed using __setitem__"
00825 
00826     def __getitem__(self, idx):
00827         """Returns attribute type for index 0, array name for index 1"""
00828         if isinstance(idx, slice):
00829             indices = idx.indices(len(self))
00830             retVal = []
00831             for i in range(*indices):
00832                 if i >= 2 or i < 0:
00833                     raise IndexError
00834                 if i == 0:
00835                     retVal.append(self.GetAssociation())
00836                 else:
00837                     retVal.append(self.GetArrayName())
00838             return retVal
00839         elif idx >= 2 or idx < 0:
00840             raise IndexError
00841 
00842         if i == 0:
00843             return self.GetAssociation()
00844         else:
00845             return self.GetArrayName()
00846 
00847     def SetData(self, values):
00848         """Allows setting of all values at once. Requires a single value,
00849         a tuple or list."""
00850         if not isinstance(values, tuple) and \
00851            not isinstance(values, list):
00852             values = (values,)
00853         if len(values) == 1:
00854             self.SMProperty.SetElement(4, values[0])
00855         elif len(values) == 2:
00856             if isinstance(values[0], str):
00857                 val = str(ASSOCIATIONS[values[0]])
00858             else:
00859                 # In case user didn't specify valid association,
00860                 # just pick POINTS.
00861                 val = str(ASSOCIATIONS['POINTS'])
00862             self.SMProperty.SetElement(3,  str(val))
00863             self.SMProperty.SetElement(4, values[1])
00864         else:
00865             raise RuntimeError, "Expected 1 or 2 values."
00866         self._UpdateProperty()
00867 
00868     def UpdateDefault(self):
00869         "Helper method to set default values."
00870         if self.SMProperty.GetNumberOfElements() != 5:
00871             return
00872         if self.GetElement(4) != '' or \
00873             self.GetElement(3) != '':
00874             return
00875 
00876         for i in range(0,3):
00877             if self.GetElement(i) == '':
00878                 self.SMProperty.SetElement(i, '0')
00879         al = self.SMProperty.GetDomain("array_list")
00880         al.Update(self.SMProperty)
00881         al.SetDefaultValues(self.SMProperty)
00882 
00883 class ArrayListProperty(VectorProperty):
00884     """This property provides a simpler interface for selecting arrays.
00885     Simply assign a list of arrays that should be loaded by the reader.
00886     Use the Available property to get a list of available arrays."""
00887 
00888     def __init__(self, proxy, smproperty):
00889         VectorProperty.__init__(self, proxy, smproperty)
00890         self.__arrays = []
00891 
00892     def GetAvailable(self):
00893         "Returns the list of available arrays"
00894         dm = self.GetDomain("array_list")
00895         retVal = []
00896         for i in range(dm.GetNumberOfStrings()):
00897             retVal.append(dm.GetString(i))
00898         return retVal
00899 
00900     Available = property(GetAvailable, None, None, \
00901         "This read-only property contains the list of items that can be read by a reader.")
00902 
00903     def SelectAll(self):
00904         "Selects all arrays."
00905         self.SetData(self.Available)
00906 
00907     def DeselectAll(self):
00908         "Deselects all arrays."
00909         self.SetData([])
00910 
00911     def __iter__(self):
00912         """Implementation of the sequence API"""
00913         return GenericIterator(self)
00914 
00915     def __len__(self):
00916         """Returns the number of elements."""
00917         return len(self.GetData())
00918 
00919     def __setitem__(self, idx, value):
00920       """Given a list or tuple of values, sets a slice of values [min, max)"""
00921       self.GetData()
00922       if isinstance(idx, slice):
00923           indices = idx.indices(len(self))
00924           for i, j in zip(range(*indices), value):
00925               self.__arrays[i] = j
00926           self.SetData(self.__arrays)
00927       elif idx >= len(self) or idx < 0:
00928           raise IndexError
00929       else:
00930           self.__arrays[idx] = self.ConvertValue(value)
00931           self.SetData(self.__arrays)
00932 
00933     def __getitem__(self, idx):
00934       """Returns the range [min, max) of elements. Raises an IndexError
00935       exception if an argument is out of bounds."""
00936       self.GetData()
00937       if isinstance(idx, slice):
00938           indices = idx.indices(len(self))
00939           retVal = []
00940           for i in range(*indices):
00941               retVal.append(self.__arrays[i])
00942           return retVal
00943       elif idx >= len(self) or idx < 0:
00944           raise IndexError
00945       return self.__arrays[idx]
00946 
00947     def SetData(self, values):
00948         """Allows setting of all values at once. Requires a single value,
00949         a tuple or list."""
00950         # Clean up first
00951         iup = self.SMProperty.GetImmediateUpdate()
00952         self.SMProperty.SetImmediateUpdate(False)
00953         # Clean up first
00954         self.SMProperty.SetNumberOfElements(0)
00955         if not isinstance(values, tuple) and \
00956            not isinstance(values, list):
00957             values = (values,)
00958         fullvalues = []
00959         for i in range(len(values)):
00960             val = self.ConvertValue(values[i])
00961             fullvalues.append(val)
00962             fullvalues.append('1')
00963         for array in self.Available:
00964             if not values.__contains__(array):
00965                 fullvalues.append(array)
00966                 fullvalues.append('0')
00967         i = 0
00968         for value in fullvalues:
00969             self.SMProperty.SetElement(i, value)
00970             i += 1
00971 
00972         self._UpdateProperty()
00973         self.SMProperty.SetImmediateUpdate(iup)
00974 
00975     def GetData(self):
00976         "Returns all elements as a list."
00977         property = self.SMProperty
00978         nElems = property.GetNumberOfElements()
00979         if nElems%2 != 0:
00980             raise ValueError, "The SMProperty with XML label '%s' has a size that is not a multiple of 2." % property.GetXMLLabel()
00981         self.__arrays = []
00982         for i in range(0, nElems, 2):
00983             if self.GetElement(i+1) != '0':
00984                 self.__arrays.append(self.GetElement(i))
00985         return list(self.__arrays)
00986 
00987 class ProxyProperty(Property):
00988     """A ProxyProperty provides access to one or more proxies. You can use
00989     a slice to get one or more property values:
00990     > proxy = property[2]
00991     or
00992     > proxies = property[0:5:2]
00993     You can use a slice to set one or more property values:
00994     > property[2] = proxy
00995     or
00996     > property[1:3] = (proxy1, proxy2)
00997     You can also append and delete:
00998     > property.append(proxy)
00999     and
01000     > del property[1:2]
01001 
01002     You can also remove all elements with Clear().
01003 
01004     Note that some properties expect only 1 proxy and will complain if
01005     you set the number of values to be something else.
01006     """
01007     def __init__(self, proxy, smproperty):
01008         """Default constructor.  Stores a reference to the proxy.  Also looks
01009         at domains to find valid values."""
01010         Property.__init__(self, proxy, smproperty)
01011         # Check to see if there is a proxy list domain and, if so,
01012         # initialize ourself. (Should this go in ProxyProperty?)
01013         listdomain = self.GetDomain('proxy_list')
01014         if listdomain:
01015             if listdomain.GetClassName() != 'vtkSMProxyListDomain':
01016                 raise ValueError, "Found a 'proxy_list' domain on an InputProperty that is not a ProxyListDomain."
01017             pm = ProxyManager()
01018             group = "pq_helper_proxies." + proxy.GetGlobalIDAsString()
01019             if listdomain.GetNumberOfProxies() == 0:
01020                 for i in xrange(listdomain.GetNumberOfProxyTypes()):
01021                     igroup = listdomain.GetProxyGroup(i)
01022                     name = listdomain.GetProxyName(i)
01023                     iproxy = CreateProxy(igroup, name)
01024                     listdomain.AddProxy(iproxy)
01025                     pm.RegisterProxy(group, proxy.GetPropertyName(smproperty), iproxy)
01026                 listdomain.SetDefaultValues(self.SMProperty)
01027 
01028     def GetAvailable(self):
01029         """If this proxy has a list domain, then this function returns the
01030         strings you can use to select from the domain.  If there is no such
01031         list domain, the returned list is empty."""
01032         listdomain = self.GetDomain('proxy_list')
01033         retval = []
01034         if listdomain:
01035             for i in xrange(listdomain.GetNumberOfProxies()):
01036                 proxy = listdomain.GetProxy(i)
01037                 retval.append(proxy.GetXMLLabel())
01038         return retval
01039 
01040     Available = property(GetAvailable, None, None,
01041                          """This read only property is a list of strings you can
01042                          use to select from the list domain.  If there is no
01043                          such list domain, the array is empty.""")
01044 
01045     def __iter__(self):
01046         """Implementation of the sequence API"""
01047         return GenericIterator(self)
01048 
01049     def __len__(self):
01050         """Returns the number of elements."""
01051         return self.SMProperty.GetNumberOfProxies()
01052 
01053     def remove(self, proxy):
01054         """Removes the first occurence of the proxy from the property."""
01055         self.SMProperty.RemoveProxy(proxy.SMProxy)
01056         self._UpdateProperty()
01057         
01058     def __setitem__(self, idx, value):
01059       """Given a list or tuple of values, sets a slice of values [min, max)"""
01060       if isinstance(idx, slice):
01061         indices = idx.indices(len(self))
01062         for i, j in zip(range(*indices), value):
01063           self.SMProperty.SetProxy(i, j.SMProxy)
01064         self._UpdateProperty()
01065       elif idx >= len(self) or idx < 0:
01066         raise IndexError
01067       else:
01068         self.SMProperty.SetProxy(idx, value.SMProxy)
01069         self._UpdateProperty()
01070 
01071     def __delitem__(self,idx):
01072       """Removes the element idx"""
01073       if isinstance(idx, slice):
01074         indices = idx.indices(len(self))
01075         # Collect the elements to delete to a new list first.
01076         # Otherwise indices are screwed up during the actual
01077         # remove loop.
01078         toremove = []
01079         for i in range(*indices):
01080           toremove.append(self[i])
01081         for i in toremove:
01082           self.SMProperty.RemoveProxy(i.SMProxy)
01083         self._UpdateProperty()
01084       elif idx >= len(self) or idx < 0:
01085         raise IndexError
01086       else:
01087         self.SMProperty.RemoveProxy(self[idx].SMProxy)
01088         self._UpdateProperty()
01089 
01090     def __getitem__(self, idx):
01091       """Returns the range [min, max) of elements. Raises an IndexError
01092       exception if an argument is out of bounds."""
01093       if isinstance(idx, slice):
01094         indices = idx.indices(len(self))
01095         retVal = []
01096         for i in range(*indices):
01097           retVal.append(_getPyProxy(self.SMProperty.GetProxy(i)))
01098         return retVal
01099       elif idx >= len(self) or idx < 0:
01100         raise IndexError
01101       return _getPyProxy(self.SMProperty.GetProxy(idx))
01102 
01103     def __getattr__(self, name):
01104         "Unknown attribute requests get forwarded to SMProperty."
01105         return getattr(self.SMProperty, name)
01106 
01107     def index(self, proxy):
01108         idx = 0
01109         for px in self:
01110             ## VSV: ==
01111             if proxy.IsSame(px):
01112                 return idx
01113             idx += 1
01114         raise ValueError("proxy is not in the list.")
01115 
01116     def append(self, proxy):
01117         "Appends the given proxy to the property values."
01118         self.SMProperty.AddProxy(proxy.SMProxy)
01119         self._UpdateProperty()
01120 
01121     def GetData(self):
01122         "Returns all elements as either a list or a single value."
01123         property = self.SMProperty
01124         if property.GetRepeatable() or property.GetNumberOfProxies() > 1:
01125             return self[0:len(self)]
01126         else:
01127             if property.GetNumberOfProxies() > 0:
01128                 return _getPyProxy(property.GetProxy(0))
01129         return None
01130 
01131     def SetData(self, values):
01132         """Allows setting of all values at once. Requires a single value,
01133         a tuple or list."""
01134         if isinstance(values, str):
01135             position = -1
01136             try:
01137                 position = self.Available.index(values)
01138             except:
01139                 raise ValueError, values + " is not a valid object in the domain."
01140             values = self.GetDomain('proxy_list').GetProxy(position)
01141         if not isinstance(values, tuple) and \
01142            not isinstance(values, list):
01143             values = (values,)
01144         self.SMProperty.RemoveAllProxies()
01145         for value in values:
01146             if isinstance(value, Proxy):
01147                 value_proxy = value.SMProxy
01148             else:
01149                 value_proxy = value
01150             self.SMProperty.AddProxy(value_proxy)
01151         self._UpdateProperty()
01152 
01153     def Clear(self):
01154         "Removes all elements."
01155         self.SMProperty.RemoveAllProxies()
01156         self._UpdateProperty()
01157 
01158 class InputProperty(ProxyProperty):
01159     """An InputProperty allows making pipeline connections. You can set either
01160     a source proxy or an OutputProperty to an input property:
01161 
01162     > property[0] = proxy
01163     or
01164     > property[0] = OuputPort(proxy, 1)
01165 
01166     > property.append(proxy)
01167     or
01168     > property.append(OutputPort(proxy, 0))
01169     """
01170     def __setitem__(self, idx, value):
01171       """Given a list or tuple of values, sets a slice of values [min, max)"""
01172       if isinstance(idx, slice):
01173         indices = idx.indices(len(self))
01174         for i, j in zip(range(*indices), value):
01175           op = value[i-min]
01176           self.SMProperty.SetInputConnection(i, op.SMProxy, op.Port)
01177         self._UpdateProperty()
01178       elif idx >= len(self) or idx < 0:
01179         raise IndexError
01180       else:
01181         self.SMProperty.SetInputConnection(idx, value.SMProxy, value.Port)
01182         self._UpdateProperty()
01183 
01184     def __getitem__(self, idx):
01185       """Returns the range [min, max) of elements. Raises an IndexError
01186       exception if an argument is out of bounds."""
01187       if isinstance(idx, slice):
01188         indices = idx.indices(len(self))
01189         retVal = []
01190         for i in range(*indices):
01191             port = None
01192             if self.SMProperty.GetProxy(i):
01193                 port = OutputPort(_getPyProxy(self.SMProperty.GetProxy(i)),\
01194                                   self.SMProperty.GetOutputPortForConnection(i))
01195             retVal.append(port)
01196         return retVal
01197       elif idx >= len(self) or idx < 0:
01198         raise IndexError
01199       return OutputPort(_getPyProxy(self.SMProperty.GetProxy(idx)),\
01200                         self.SMProperty.GetOutputPortForConnection(idx))
01201 
01202     def append(self, value):
01203         """Appends the given proxy to the property values.
01204         Accepts Proxy or OutputPort objects."""
01205         self.SMProperty.AddInputConnection(value.SMProxy, value.Port)
01206         self._UpdateProperty()
01207 
01208     def GetData(self):
01209         """Returns all elements as either a list of OutputPort objects or
01210         a single OutputPort object."""
01211         property = self.SMProperty
01212         if property.GetRepeatable() or property.GetNumberOfProxies() > 1:
01213             return self[0:len(self)]
01214         else:
01215             if property.GetNumberOfProxies() > 0:
01216                 return OutputPort(_getPyProxy(property.GetProxy(0)),\
01217                                   self.SMProperty.GetOutputPortForConnection(0))
01218         return None
01219 
01220     def SetData(self, values):
01221         """Allows setting of all values at once. Requires a single value,
01222         a tuple or list. Accepts Proxy or OutputPort objects."""
01223         if isinstance(values, str):
01224             ProxyProperty.SetData(self, values)
01225             return
01226         if not isinstance(values, tuple) and \
01227            not isinstance(values, list):
01228             values = (values,)
01229         self.SMProperty.RemoveAllProxies()
01230         for value in values:
01231             if value:
01232                 self.SMProperty.AddInputConnection(value.SMProxy, value.Port)
01233         self._UpdateProperty()
01234 
01235     def _UpdateProperty(self):
01236         "Pushes the value of this property to the server."
01237         ProxyProperty._UpdateProperty(self)
01238         iter = PropertyIterator(self.Proxy)
01239         for prop in iter:
01240             if isinstance(prop, ArraySelectionProperty):
01241                 prop.UpdateDefault()
01242 
01243 
01244 class DataInformation(object):
01245     """DataInformation is a contained for meta-data associated with an
01246     output data.
01247 
01248     DataInformation is a python wrapper around a vtkPVDataInformation.
01249     In addition to proving all methods of a vtkPVDataInformation, it provides
01250     a few convenience methods.
01251 
01252     Please note that some of the methods accessible through the DataInformation
01253     class are not listed by help() because the DataInformation objects forward
01254     unresolved attributes to the underlying object. To get the full list,
01255     see also dir(proxy.DataInformation).
01256     See also the doxygen based documentation of the vtkPVDataInformation C++
01257     class.
01258     """
01259     def __init__(self, dataInformation, proxy, idx):
01260         """Default constructor. Requires a vtkPVDataInformation, a source proxy
01261         and an output port id."""
01262         self.DataInformation = dataInformation
01263         self.Proxy = proxy
01264         self.Idx = idx
01265 
01266     def Update(self):
01267         """****Deprecated**** There is no reason anymore to use this method
01268         explicitly, it is called automatically when one gets any value from the
01269         data information object.
01270         Update the data information if necessary. Note that this
01271         does not cause execution of the underlying object. In certain
01272         cases, you may have to call UpdatePipeline() on the proxy."""
01273         if self.Proxy:
01274             self.Proxy.GetDataInformation(self.Idx)
01275 
01276     def GetDataSetType(self):
01277         """Returns the dataset type as defined in vtkDataObjectTypes."""
01278         self.Update()
01279         if not self.DataInformation:
01280             raise RuntimeError, "No data information is available"
01281         if self.DataInformation.GetCompositeDataSetType() > -1:
01282             return self.DataInformation.GetCompositeDataSetType()
01283         return self.DataInformation.GetDataSetType()
01284 
01285     def GetDataSetTypeAsString(self):
01286         """Returns the dataset type as a user-friendly string. This is
01287         not the same as the enumaration used by VTK"""
01288         return vtk.vtkDataObjectTypes.GetClassNameFromTypeId(self.GetDataSetType())
01289 
01290     def __getattr__(self, name):
01291         """Forwards unknown attribute requests to the underlying
01292         vtkPVInformation."""
01293         if not self.DataInformation:
01294             raise AttributeError("class has no attribute %s" % name)
01295             return None
01296         self.Update()
01297         return getattr(self.DataInformation, name)
01298 
01299 class ArrayInformation(object):
01300     """Meta-information associated with an array. Use the Name
01301     attribute to get the array name.
01302 
01303     Please note that some of the methods accessible through the ArrayInformation
01304     class are not listed by help() because the ArrayInformation objects forward
01305     unresolved attributes to the underlying object.
01306     See the doxygen based documentation of the vtkPVArrayInformation C++
01307     class for a full list.
01308     """
01309     def __init__(self, proxy, field, name):
01310         self.Proxy = proxy
01311         self.FieldData = field
01312         self.Name = name
01313 
01314     def __getattr__(self, name):
01315         """Forward unknown methods to vtkPVArrayInformation"""
01316         array = self.FieldData.GetFieldData().GetArrayInformation(self.Name)
01317         if not array: return None
01318         return getattr(array, name)
01319 
01320     def __repr__(self):
01321         """Returns a user-friendly representation string."""
01322         return "Array: " + self.Name
01323 
01324     def GetRange(self, component=0):
01325         """Given a component, returns its value range as a tuple of 2 values."""
01326         array = self.FieldData.GetFieldData().GetArrayInformation(self.Name)
01327         range = array.GetComponentRange(component)
01328         return (range[0], range[1])
01329 
01330 class FieldDataInformationIterator(object):
01331     """Iterator for FieldDataInformation"""
01332 
01333     def __init__(self, info, items=False):
01334         self.FieldDataInformation = info
01335         self.index = 0
01336         self.items = items
01337 
01338     def __iter__(self):
01339         return self
01340 
01341     def next(self):
01342         if self.index >= self.FieldDataInformation.GetNumberOfArrays():
01343             raise StopIteration
01344 
01345         self.index += 1
01346         ai = self.FieldDataInformation[self.index-1]
01347         if self.items:
01348             return (ai.GetName(), ai)
01349         else:
01350             return ai
01351 
01352 
01353 class FieldDataInformation(object):
01354     """Meta-data for a field of an output object (point data, cell data etc...).
01355     Provides easy access to the arrays using the slice interface:
01356     > narrays = len(field_info)
01357     > for i in range(narrays):
01358     >   array_info = field_info[i]
01359 
01360     Full slice interface is supported:
01361     > arrays = field_info[0:5:3]
01362     where arrays is a list.
01363 
01364     Array access by name is also possible:
01365     > array_info = field_info['Temperature']
01366 
01367     The number of arrays can also be accessed using the NumberOfArrays
01368     property.
01369     """
01370     def __init__(self, proxy, idx, field):
01371         self.Proxy = proxy
01372         self.OutputPort = idx
01373         self.FieldData = field
01374 
01375     def GetFieldData(self):
01376         """Convenience method to get the underlying
01377         vtkPVDataSetAttributesInformation"""
01378         return getattr(self.Proxy.GetDataInformation(self.OutputPort), "Get%sInformation" % self.FieldData)()
01379 
01380     def GetNumberOfArrays(self):
01381         """Returns the number of arrays."""
01382         self.Proxy.UpdatePipeline()
01383         return self.GetFieldData().GetNumberOfArrays()
01384 
01385     def GetArray(self, idx):
01386         """Given an index or a string, returns an array information.
01387         Raises IndexError if the index is out of bounds."""
01388         self.Proxy.UpdatePipeline()
01389         if not self.GetFieldData().GetArrayInformation(idx):
01390             return None
01391         if isinstance(idx, str):
01392             return ArrayInformation(self.Proxy, self, idx)
01393         elif idx >= len(self) or idx < 0:
01394             raise IndexError
01395         return ArrayInformation(self.Proxy, self, self.GetFieldData().GetArrayInformation(idx).GetName())
01396 
01397     def __len__(self):
01398         """Returns the number of arrays."""
01399         return self.GetNumberOfArrays()
01400 
01401     def __getitem__(self, idx):
01402         """Implements the [] operator. Accepts an array name."""
01403         if isinstance(idx, slice):
01404             indices = idx.indices(self.GetNumberOfArrays())
01405             retVal = []
01406             for i in range(*indices):
01407                 retVal.append(self.GetArray(i))
01408             return retVal
01409         return self.GetArray(idx)
01410 
01411     def keys(self):
01412         """Implementation of the dictionary API"""
01413         kys = []
01414         narrays = self.GetNumberOfArrays()
01415         for i in range(narrays):
01416             kys.append(self.GetArray(i).GetName())
01417         return kys
01418 
01419     def values(self):
01420         """Implementation of the dictionary API"""
01421         vals = []
01422         narrays = self.GetNumberOfArrays()
01423         for i in range(narrays):
01424             vals.append(self.GetArray(i))
01425         return vals
01426 
01427     def iteritems(self):
01428         """Implementation of the dictionary API"""
01429         return FieldDataInformationIterator(self, True)
01430 
01431     def items(self):
01432         """Implementation of the dictionary API"""
01433         itms = []
01434         narrays = self.GetNumberOfArrays()
01435         for i in range(narrays):
01436             ai = self.GetArray(i)
01437             itms.append((ai.GetName(), ai))
01438         return itms
01439 
01440     def has_key(self, key):
01441         """Implementation of the dictionary API"""
01442         if self.GetArray(key):
01443             return True
01444         return False
01445 
01446     def __iter__(self):
01447         """Implementation of the dictionary API"""
01448         return FieldDataInformationIterator(self)
01449 
01450     def __getattr__(self, name):
01451         """Forwards unknown attributes to the underlying
01452         vtkPVDataSetAttributesInformation"""
01453         array = self.GetArray(name)
01454         if array: return array
01455         raise AttributeError("class has no attribute %s" % name)
01456         return None
01457 
01458     NumberOfArrays = property(GetNumberOfArrays, None, None, "Returns the number of arrays.")
01459 
01460 def OutputPort(proxy, outputPort=0):
01461     if not Proxy:
01462         return None
01463     if isinstance(outputPort, str):
01464         outputPort = proxy.GetOutputPortIndex(outputPort)
01465     if outputPort >= proxy.GetNumberOfOutputPorts():
01466         return None
01467     if proxy.Port == outputPort:
01468         return proxy
01469     newinstance = _getPyProxy(proxy.SMProxy, outputPort)
01470     newinstance.Port = outputPort
01471     newinstance._Proxy__Properties = proxy._Proxy__Properties
01472     return newinstance
01473 
01474 class ProxyManager(object):
01475     """When running scripts from the python shell in the ParaView application,
01476     registering proxies with the proxy manager is the only mechanism to
01477     notify the graphical user interface (GUI) that a proxy
01478     exists. Therefore, unless a proxy is registered, it will not show up in
01479     the user interface. Also, the proxy manager is the only way to get
01480     access to proxies created using the GUI. Proxies created using the GUI
01481     are automatically registered under an appropriate group (sources,
01482     filters, representations and views). To get access to these objects,
01483     you can use proxyManager.GetProxy(group, name). The name is the same
01484     as the name shown in the pipeline browser.
01485 
01486     This class is a python wrapper for vtkSMProxyManager. Note that the
01487     underlying vtkSMProxyManager is a singleton. All instances of this
01488     class will refer to the same object. In addition to all methods provided by
01489     vtkSMProxyManager (all unknown attribute requests are forwarded
01490     to the vtkSMProxyManager), this class provides several convenience
01491     methods.
01492 
01493     Please note that some of the methods accessible through the ProxyManager
01494     class are not listed by help() because the ProxyManager objects forwards
01495     unresolved attributes to the underlying object. To get the full list,
01496     see also dir(proxy.SMProxyManager). See also the doxygen based documentation
01497     of the vtkSMProxyManager C++ class.
01498     """
01499 
01500     def __init__(self, session=None):
01501         """Constructor. Assigned self.SMProxyManager to
01502         vtkSMProxyManager.GetProxyManager()."""
01503         global ActiveConnection
01504         if not session:
01505             session = ActiveConnection.Session
01506         self.SMProxyManager = session.GetSessionProxyManager()
01507 
01508     def RegisterProxy(self, group, name, aProxy):
01509         """Registers a proxy (either SMProxy or proxy) with the
01510         server manager"""
01511         if isinstance(aProxy, Proxy):
01512             self.SMProxyManager.RegisterProxy(group, name, aProxy.SMProxy)
01513         else:
01514             self.SMProxyManager.RegisterProxy(group, name, aProxy)
01515 
01516     def NewProxy(self, group, name):
01517         """Creates a new proxy of given group and name and returns an SMProxy.
01518         Note that this is a server manager object. You should normally create
01519         proxies using the class objects. For example:
01520         obj = servermanager.sources.SphereSource()"""
01521         if not self.SMProxyManager:
01522             return None
01523         aProxy = self.SMProxyManager.NewProxy(group, name, "NULL")
01524         if not aProxy:
01525             return None
01526         aProxy.UnRegister(None)
01527         return aProxy
01528 
01529     def GetProxy(self, group, name):
01530         """Returns a Proxy registered under a group and name"""
01531         if not self.SMProxyManager:
01532             return None
01533         aProxy = self.SMProxyManager.GetProxy(group, name)
01534         if not aProxy:
01535             return None
01536         return _getPyProxy(aProxy)
01537 
01538     def GetPrototypeProxy(self, group, name):
01539         """Returns a prototype proxy given a group and name. This is an
01540         SMProxy. This is a low-level method. You should not normally
01541         have to call it."""
01542         if not self.SMProxyManager:
01543             return None
01544         aProxy = self.SMProxyManager.GetPrototypeProxy(group, name)
01545         if not aProxy:
01546             return None
01547         return aProxy
01548 
01549     def GetProxiesInGroup(self, groupname):
01550         """Returns a map of proxies in a particular group."""
01551         proxies = {}
01552         iter = self.NewGroupIterator(groupname)
01553         for aProxy in iter:
01554             proxies[(iter.GetKey(), aProxy.GetGlobalIDAsString())] = aProxy
01555         return proxies
01556 
01557     def UnRegisterProxy(self, groupname, proxyname, aProxy):
01558         """Unregisters a proxy."""
01559         if not self.SMProxyManager:
01560             return
01561         if aProxy != None and isinstance(aProxy,Proxy):
01562             aProxy = aProxy.SMProxy
01563         if aProxy:
01564             self.SMProxyManager.UnRegisterProxy(groupname, proxyname, aProxy)
01565 
01566     def GetProxies(self, groupname, proxyname):
01567         """Returns all proxies registered under the given group with the
01568         given name. Note that it is possible to register more than one
01569         proxy with the same name in the same group. Because the proxies
01570         are different, there is no conflict. Use this method instead of
01571         GetProxy() if you know that there are more than one proxy registered
01572         with this name."""
01573         if not self.SMProxyManager:
01574             return []
01575         collection = vtk.vtkCollection()
01576         result = []
01577         self.SMProxyManager.GetProxies(groupname, proxyname, collection)
01578         for i in range(0, collection.GetNumberOfItems()):
01579             aProxy = _getPyProxy(collection.GetItemAsObject(i))
01580             if aProxy:
01581                 result.append(aProxy)
01582 
01583         return result
01584 
01585     def __iter__(self):
01586         """Returns a new ProxyIterator."""
01587         iter = ProxyIterator()
01588         iter.Begin()
01589         return iter
01590 
01591     def NewGroupIterator(self, group_name):
01592         """Returns a ProxyIterator for a group. The resulting object
01593         can be used to traverse the proxies that are in the given
01594         group."""
01595         iter = self.__iter__()
01596         iter.SetModeToOneGroup()
01597         iter.Begin(group_name)
01598         return iter
01599 
01600     def NewDefinitionIterator(self, groupname=None):
01601         """Returns an iterator that can be used to iterate over
01602            all groups and types of proxies that the proxy manager
01603            can create."""
01604         iter = None
01605         if groupname != None:
01606             iter = ProxyDefinitionIterator(self.GetProxyDefinitionManager().NewSingleGroupIterator(groupname,0))
01607         else:
01608             iter = ProxyDefinitionIterator(self.GetProxyDefinitionManager().NewIterator(0))
01609 
01610         return iter
01611 
01612     def __ConvertArgumentsAndCall(self, *args):
01613       newArgs = []
01614       for arg in args:
01615           if issubclass(type(arg), Proxy) or isinstance(arg, Proxy):
01616               newArgs.append(arg.SMProxy)
01617           else:
01618               newArgs.append(arg)
01619       func = getattr(self.SMProxyManager, self.__LastAttrName)
01620       retVal = func(*newArgs)
01621       if type(retVal) is type(self.SMProxyManager) and retVal.IsA("vtkSMProxy"):
01622           return _getPyProxy(retVal)
01623       else:
01624           return retVal
01625 
01626     def __getattr__(self, name):
01627         """Returns attribute from the ProxyManager"""
01628         try:
01629             pmAttr = getattr(self.SMProxyManager, name)
01630             self.__LastAttrName = name
01631             return self.__ConvertArgumentsAndCall
01632         except:
01633             pass
01634         return getattr(self.SMProxyManager, name)
01635 
01636     def LoadState(self, filename, loader = None):
01637         self.SMProxyManager.LoadXMLState(filename, loader)
01638 
01639     def SaveState(self, filename):
01640         self.SMProxyManager.SaveXMLState(filename)
01641 
01642 class PropertyIterator(object):
01643     """Wrapper for a vtkSMPropertyIterator class to satisfy
01644        the python iterator protocol. Note that the list of
01645        properties can also be obtained from the class object's
01646        dictionary.
01647        See the doxygen documentation for vtkSMPropertyIterator C++
01648        class for details.
01649        """
01650 
01651     def __init__(self, aProxy):
01652         self.SMIterator = aProxy.NewPropertyIterator()
01653         if self.SMIterator:
01654             self.SMIterator.UnRegister(None)
01655             self.SMIterator.Begin()
01656         self.Key = None
01657         self.PropertyLabel = None
01658         self.Proxy = aProxy
01659 
01660     def __iter__(self):
01661         return self
01662 
01663     def next(self):
01664         if not self.SMIterator:
01665             raise StopIteration
01666 
01667         if self.SMIterator.IsAtEnd():
01668             self.Key = None
01669             raise StopIteration
01670         self.Key = self.SMIterator.GetKey()
01671         self.PropertyLabel = self.SMIterator.GetPropertyLabel()
01672         self.SMIterator.Next()
01673         return self.Proxy.GetProperty(self.Key)
01674 
01675     def GetProxy(self):
01676         """Returns the proxy for the property last returned by the call to
01677         'next()'"""
01678         return self.Proxy
01679 
01680     def GetKey(self):
01681         """Returns the key for the property last returned by the call to
01682         'next()' """
01683         return self.Key
01684 
01685     def GetProperty(self):
01686         """Returns the property last returned by the call to 'next()' """
01687         return self.Proxy.GetProperty(self.Key)
01688 
01689     def __getattr__(self, name):
01690         """returns attributes from the vtkSMPropertyIterator."""
01691         return getattr(self.SMIterator, name)
01692 
01693 class ProxyDefinitionIterator(object):
01694     """Wrapper for a vtkPVProxyDefinitionIterator class to satisfy
01695        the python iterator protocol.
01696        See the doxygen documentation of the vtkPVProxyDefinitionIterator
01697        C++ class for more information."""
01698     def __init__(self, iter):
01699         self.SMIterator = iter
01700         if self.SMIterator:
01701             self.SMIterator.UnRegister(None)
01702             self.SMIterator.InitTraversal()
01703         self.Group = None
01704         self.Key = None
01705 
01706     def __iter__(self):
01707         return self
01708 
01709     def next(self):
01710         if self.SMIterator.IsDoneWithTraversal():
01711             self.Group = None
01712             self.Key = None
01713             raise StopIteration
01714         self.Group = self.SMIterator.GetGroupName()
01715         self.Key = self.SMIterator.GetProxyName()
01716         self.SMIterator.GoToNextItem()
01717         return {"group": self.Group, "key":self.Key }
01718 
01719     def GetProxyName(self):
01720         """Returns the key for the proxy definition last returned by the call
01721         to 'next()' """
01722         return self.Key
01723 
01724     def GetGroup(self):
01725         """Returns the group for the proxy definition last returned by the
01726         call to 'next()' """
01727         return self.Group
01728 
01729     def __getattr__(self, name):
01730         """returns attributes from the vtkPVProxyDefinitionIterator."""
01731         return getattr(self.SMIterator, name)
01732 
01733 
01734 class ProxyIterator(object):
01735     """Wrapper for a vtkSMProxyIterator class to satisfy the
01736      python iterator protocol.
01737      See the doxygen documentation of vtkSMProxyIterator C++ class for
01738      more information.
01739      """
01740     def __init__(self):
01741         self.SMIterator = vtkSMProxyIterator()
01742         self.SMIterator.SetSession(ActiveConnection.Session)
01743         self.SMIterator.Begin()
01744         self.AProxy = None
01745         self.Group = None
01746         self.Key = None
01747 
01748     def __iter__(self):
01749         return self
01750 
01751     def next(self):
01752         if self.SMIterator.IsAtEnd():
01753             self.AProxy = None
01754             self.Group = None
01755             self.Key = None
01756             raise StopIteration
01757             return None
01758         self.AProxy = _getPyProxy(self.SMIterator.GetProxy())
01759         self.Group = self.SMIterator.GetGroup()
01760         self.Key = self.SMIterator.GetKey()
01761         self.SMIterator.Next()
01762         return self.AProxy
01763 
01764     def GetProxy(self):
01765         """Returns the proxy last returned by the call to 'next()'"""
01766         return self.AProxy
01767 
01768     def GetKey(self):
01769         """Returns the key for the proxy last returned by the call to
01770         'next()' """
01771         return self.Key
01772 
01773     def GetGroup(self):
01774         """Returns the group for the proxy last returned by the call to
01775         'next()' """
01776         return self.Group
01777 
01778     def __getattr__(self, name):
01779         """returns attributes from the vtkSMProxyIterator."""
01780         return getattr(self.SMIterator, name)
01781 
01782 # Caution: Observers must be global methods otherwise we run into memory
01783 #          leak when the interpreter get reset from the C++ layer.
01784 def _update_definitions(caller, event):
01785     updateModules(ActiveConnection.Modules)
01786 
01787 class Connection(object):
01788     """
01789       This is a python representation for a session/connection.
01790     """
01791     def __init__(self, connectionId, session):
01792         """Default constructor. Creates a Connection with the given
01793         ID, all other data members initialized to None."""
01794         global MultiServerConnections
01795         global ActiveConnection
01796         self.ID = connectionId
01797         self.Session = session
01798         self.Modules = PVModule()
01799         self.Alive = True
01800         self.DefinitionObserverTag = 0
01801         self.CustomDefinitionObserverTag = 0
01802         if MultiServerConnections == None and ActiveConnection:
01803             raise RuntimeError, "Concurrent connections not supported!"
01804         if MultiServerConnections != None and not self in MultiServerConnections:
01805            MultiServerConnections.append(self)
01806         ActiveConnection = self
01807         __InitAfterConnect__(self)
01808         __exposeActiveModules__()
01809 
01810     def __eq__(self, other):
01811         "Returns true if the connection ids are the same."
01812         return (self.ID == other.ID)
01813 
01814     def __repr__(self):
01815         """User friendly string representation"""
01816         return "Connection (%s) [%d]" % (self.Session.GetURI(), self.ID)
01817 
01818     def GetURI(self):
01819         """Get URI of the connection"""
01820         return self.Session.GetURI()
01821 
01822     def IsRemote(self):
01823         """Returns True if the connection to a remote server, False if
01824         it is local (built-in)"""
01825         if self.Session.IsA("vtkSMSessionClient"):
01826             return True
01827         return False
01828 
01829     def GetNumberOfDataPartitions(self):
01830         """Returns the number of partitions on the data server for this
01831            connection"""
01832         return self.Session.GetServerInformation().GetNumberOfProcesses()
01833 
01834     def AttachDefinitionUpdater(self):
01835         """Attach observer to automatically update modules when needed."""
01836         # VTN: Observers are not supported
01837         # ProxyDefinitionsUpdated = 2000
01838 ##        self.DefinitionObserverTag = self.Session.GetProxyDefinitionManager().AddObserver(2000, _update_definitions)
01839         # CompoundProxyDefinitionsUpdated = 2001
01840 ##        self.CustomDefinitionObserverTag = self.Session.GetProxyDefinitionManager().AddObserver(2001, _update_definitions)
01841         pass
01842 
01843     def close(self):
01844         if self.DefinitionObserverTag:
01845             self.Session.GetProxyDefinitionManager().RemoveObserver(self.DefinitionObserverTag)
01846             self.Session.GetProxyDefinitionManager().RemoveObserver(self.CustomDefinitionObserverTag)
01847         self.Session = None
01848         self.Modules = None
01849         self.Alive = False
01850 
01851     def __del__(self):
01852         if self.Alive:
01853            self.close()
01854 
01855 def SaveState(filename):
01856     """Given a state filename, saves the state of objects registered
01857     with the proxy manager."""
01858     pm = ProxyManager()
01859     pm.SaveState(filename)
01860 
01861 def LoadState(filename, connection=None):
01862     """Given a state filename and an optional connection, loads the server
01863     manager state."""
01864     if not connection:
01865         connection = ActiveConnection
01866     if not connection:
01867         raise RuntimeError, "Cannot load state without a connection"
01868     pm = ProxyManager()
01869     pm.LoadState(filename, None)
01870     views = GetRenderViews()
01871     for view in views:
01872         # Make sure that the client window size matches the
01873         # ViewSize property. In paraview, the GUI takes care
01874         # of this.
01875         if view.GetClassName() == "vtkSMIceTDesktopRenderViewProxy":
01876             view.GetRenderWindow().SetSize(view.ViewSize[0], \
01877                                            view.ViewSize[1])
01878 
01879 def InitFromGUI():
01880     """
01881     Method used to initialize the Python Shell from the ParaView GUI.
01882     """
01883     global fromGUI, ActiveConnection
01884     if not fromGUI:
01885        print "from paraview.simple import *"
01886     fromGUI = True
01887     # ToggleProgressPrinting() ### FIXME COLLABORATION
01888     enableMultiServer(vtkProcessModule.GetProcessModule().GetMultipleSessionsSupport())
01889     iter = vtkProcessModule.GetProcessModule().NewSessionIterator();
01890     iter.InitTraversal()
01891     ActiveConnection = None
01892     activeSession = vtkSMProxyManager.GetProxyManager().GetActiveSession()
01893     tmpActiveConnection = None
01894     while not iter.IsDoneWithTraversal():
01895        c = Connection(iter.GetCurrentSessionId(), iter.GetCurrentSession())
01896        if c.Session == activeSession:
01897           tmpActiveConnection = c
01898        iter.GoToNextItem()
01899     iter.UnRegister(None)
01900     if tmpActiveConnection:
01901        ActiveConnection = tmpActiveConnection
01902 
01903 def Connect(ds_host=None, ds_port=11111, rs_host=None, rs_port=22221):
01904     """
01905     Use this function call to create a new session. On success,
01906     it returns a vtkSMSession object that abstracts the connection.
01907     Otherwise, it returns None.
01908     There are several ways in which this function can be called:
01909     * When called with no arguments, it creates a new session
01910      to the built-in server on the client itself.
01911     * When called with ds_host and ds_port arguments, it
01912       attempts to connect to a server(data and render server on the same server)
01913       on the indicated host:port.
01914     * When called with ds_host, ds_port, rs_host, rs_port, it
01915       creates a new connection to the data server on ds_host:ds_port and to the
01916       render server on rs_host: rs_port.
01917     """
01918     global fromGUI
01919     if fromGUI:
01920         raise RuntimeError, "Cannot create a session through python. Use the GUI to setup the connection."
01921     if ds_host == None:
01922         session = vtkSMSession()
01923     elif rs_host == None:
01924         session = vtkSMSessionClient()
01925         session.Connect("cs://%s:%d" % (ds_host, ds_port))
01926     else:
01927         session = vtkSMSessionClient()
01928         session.Connect("cdsrs://%s:%d/%s:%d" % (ds_host, ds_port, rs_host, rs_port))
01929     id = vtkProcessModule.GetProcessModule().RegisterSession(session)
01930     connection = Connection(id, session)
01931     return connection
01932 
01933 def ReverseConnect(port=11111):
01934     """
01935     Use this function call to create a new session. On success,
01936     it returns a Session object that abstracts the connection.
01937     Otherwise, it returns None.
01938     In reverse connection mode, the client waits for a connection
01939     from the server (client has to be started first). The server
01940     then connects to the client (run pvserver with -rc and -ch
01941     option).
01942     The optional port specified the port to listen to.
01943     """
01944     global fromGUI
01945     if fromGUI:
01946         raise RuntimeError, "Cannot create a connection through python. Use the GUI to setup the connection."
01947     session = vtkSMSessionClient()
01948     session.Connect("csrc://hostname:" + port)
01949     id = vtkProcessModule.GetProcessModule().RegisterSession(session)
01950     connection = Connection(id, session)
01951     return connection
01952 
01953 def Disconnect(session=None):
01954     """Disconnects the connection. Make sure to clear the proxy manager
01955     first."""
01956     global ActiveConnection
01957     global MultiServerConnections
01958     global fromGUI
01959     if fromGUI:
01960         raise RuntimeError, "Cannot disconnect through python. Use the GUI to disconnect."
01961     if ActiveConnection and (not session or session == ActiveConnection.Session):
01962         session = ActiveConnection.Session
01963         if MultiServerConnections:
01964            MultiServerConnections.remove(ActiveConnection)
01965            ActiveConnection.close()
01966            ActiveConnection = None
01967            switchActiveConnection()
01968         else:
01969            ActiveConnection.close()
01970            ActiveConnection = None
01971     elif MultiServerConnections:
01972         for connection in MultiServerConnections:
01973           if connection.Session == session:
01974             connection.close()
01975             MultiServerConnections.remove(connection)
01976     if session:
01977       vtkProcessModule.GetProcessModule().UnRegisterSession(session)
01978     return
01979 
01980 def CreateProxy(xml_group, xml_name, session=None):
01981     """Creates a proxy. If session is set, the proxy's session is
01982     set accordingly. If session is None, the current Session is used, if
01983     present. You should not have to use method normally. Instantiate the
01984     appropriate class from the appropriate module, for example:
01985     sph = servermanager.sources.SphereSource()"""
01986     global ActiveConnection
01987     if not session:
01988         session = ActiveConnection.Session
01989     if not session:
01990         raise RuntimeError, "Cannot create objects without a session."
01991     pxm = ProxyManager(session)
01992     return pxm.NewProxy(xml_group, xml_name)
01993 
01994 def GetRenderView(connection=None):
01995     """Return the render view in use.  If more than one render view is in
01996     use, return the first one."""
01997 
01998     render_module = None
01999     for aProxy in ProxyManager():
02000         if aProxy.IsA("vtkSMRenderViewProxy"):
02001             render_module = aProxy
02002             break
02003     return render_module
02004 
02005 def GetRenderViews(connection=None):
02006     """Returns the set of all render views."""
02007     render_modules = []
02008     for aProxy in ProxyManager():
02009         if aProxy.IsA("vtkSMRenderViewProxy"):
02010             render_modules.append(aProxy)
02011     return render_modules
02012 
02013 def GetContextViews(connection=None):
02014     """Returns the set of all context views."""
02015     context_modules = []
02016     for aProxy in ProxyManager():
02017         if aProxy.IsA("vtkSMContextViewProxy"):
02018             context_modules.append(aProxy)
02019     return context_modules
02020 
02021 def CreateRenderView(session=None, **extraArgs):
02022     """Creates a render window on the particular session. If session
02023     is not specified, then the active session is used, if available.
02024 
02025     This method can also be used to initialize properties by passing
02026     keyword arguments where the key is the name of the property. In addition
02027     registrationGroup and registrationName (optional) can be specified (as
02028     keyword arguments) to automatically register the proxy with the proxy
02029     manager."""
02030     return _create_view("RenderView", session, **extraArgs)
02031 
02032 def _create_view(view_xml_name, session=None, **extraArgs):
02033     """Creates a view on the particular session. If session
02034     is not specified, then the active session is used, if available.
02035     This method can also be used to initialize properties by passing
02036     keyword arguments where the key is the name of the property."""
02037     if not session:
02038         session = ActiveConnection.Session
02039     if not session:
02040         raise RuntimeError, "Cannot create view without session."
02041     pxm = ProxyManager()
02042     view_module = None
02043     if view_xml_name:
02044         view_module = CreateProxy("views", view_xml_name, session)
02045     if not view_module:
02046         return None
02047     extraArgs['proxy'] = view_module
02048     python_proxy_name = _make_name_valid(view_module.GetXMLName())
02049     proxy = rendering.__dict__[python_proxy_name](**extraArgs)
02050     return proxy
02051 
02052 def GetRepresentation(aProxy, view):
02053     for rep in view.Representations:
02054         #VSV: ==
02055         try: isRep = rep.Input.IsSame(aProxy)
02056         except: isRep = False
02057         if isRep: return rep
02058     return None
02059 
02060 def CreateRepresentation(aProxy, view, **extraArgs):
02061     """Creates a representation for the proxy and adds it to the render
02062     module.
02063 
02064     This method can also be used to initialize properties by passing
02065     keyword arguments where the key is the name of the property.In addition
02066     registrationGroup and registrationName (optional) can be specified (as
02067     keyword arguments) to automatically register the proxy with the proxy
02068     manager.
02069 
02070     This method tries to create the best possible representation for the given
02071     proxy in the given view. Additionally, the user can specify proxyName
02072     (optional) to create a representation of a particular type."""
02073 
02074     global rendering
02075     if not aProxy:
02076         raise RuntimeError, "proxy argument cannot be None."
02077     if not view:
02078         raise RuntimeError, "view argument cannot be None."
02079     if "proxyName" in extraArgs:
02080       display = CreateProxy("representations", extraArgs['proxyName'], None)
02081       del extraArgs['proxyName']
02082     else:
02083       display = view.SMProxy.CreateDefaultRepresentation(aProxy.SMProxy, 0)
02084       if display:
02085         display.UnRegister(None)
02086     if not display:
02087         return None
02088     extraArgs['proxy'] = display
02089     proxy = rendering.__dict__[display.GetXMLName()](**extraArgs)
02090     proxy.Input = aProxy
02091     proxy.UpdateVTKObjects()
02092     view.Representations.append(proxy)
02093     return proxy
02094 
02095 class _ModuleLoader(object):
02096     def find_module(self, fullname, path=None):
02097         if vtkPVPythonModule.HasModule(fullname):
02098             return self
02099         else:
02100             return None
02101     def load_module(self, fullname):
02102         import imp
02103         moduleInfo = vtkPVPythonModule.GetModule(fullname)
02104         if not moduleInfo:
02105             raise ImportError
02106         module = sys.modules.setdefault(fullname, imp.new_module(fullname))
02107         module.__file__ = "<%s>" % moduleInfo.GetFullName()
02108         module.__loader__ = self
02109         if moduleInfo.GetIsPackage:
02110             module.__path__ = moduleInfo.GetFullName()
02111         code = compile(moduleInfo.GetSource(), module.__file__, 'exec')
02112         exec code in module.__dict__
02113         return module
02114 
02115 def LoadXML(xmlstring):
02116     """DEPRECATED. Given a server manager XML as a string, parse and process it."""
02117     raise RuntimeError, "Deprecated. Use LoadPlugin(...) instead."
02118 
02119 
02120 def LoadPlugin(filename,  remote=True, connection=None):
02121     """ Given a filename and a session (optional, otherwise uses
02122     ActiveConnection), loads a plugin. It then updates the sources,
02123     filters and rendering modules."""
02124 
02125     if not connection:
02126         connection = ActiveConnection
02127     if not connection:
02128         raise RuntimeError, "Cannot load a plugin without a connection."
02129     plm = vtkSMProxyManager.GetProxyManager().GetPluginManager()
02130 
02131     if remote:
02132         status = plm.LoadRemotePlugin(filename, connection.Session)
02133     else:
02134         status = plm.LoadLocalPlugin(filename)
02135 
02136     # shouldn't the extension check happend before attempting to load the plugin?
02137     if not status:
02138         raise RuntimeError, "Problem loading plugin %s" % (filename)
02139     else:
02140         # we should never have to call this. The modules should update automatically.
02141         updateModules(connection.Modules)
02142 
02143 
02144 def Fetch(input, arg1=None, arg2=None, idx=0):
02145     """
02146     A convenience method that moves data from the server to the client,
02147     optionally performing some operation on the data as it moves.
02148     The input argument is the name of the (proxy for a) source or filter
02149     whose output is needed on the client.
02150 
02151     You can use Fetch to do three things:
02152 
02153     If arg1 is None (the default) then all of the data is brought to the client.
02154     In parallel runs an appropriate append Filter merges the
02155     data on each processor into one data object. The filter chosen will be
02156     vtkAppendPolyData for vtkPolyData, vtkAppendRectilinearGrid for
02157     vtkRectilinearGrid, vtkMultiBlockDataGroupFilter for vtkCompositeData,
02158     and vtkAppendFilter for anything else.
02159 
02160     If arg1 is an integer then one particular processor's output is brought to
02161     the client. In serial runs the arg is ignored. If you have a filter that
02162     computes results in parallel and brings them to the root node, then set
02163     arg to be 0.
02164 
02165     If arg1 and arg2 are a algorithms, for example vtkMinMax, the algorithm
02166     will be applied to the data to obtain some result. Here arg1 will be
02167     applied pre-gather and arg2 will be applied post-gather. In parallel
02168     runs the algorithm will be run on each processor to make intermediate
02169     results and then again on the root processor over all of the
02170     intermediate results to create a global result.
02171 
02172     Optional argument idx is used to specify the output port number to fetch the
02173     data from. Default is port 0.
02174     """
02175 
02176     import types
02177 
02178     reducer = filters.ReductionFilter(Input=OutputPort(input,idx))
02179 
02180     #create the pipeline that reduces and transmits the data
02181     if arg1 == None:
02182         cdinfo = input.GetDataInformation(idx).GetCompositeDataInformation()
02183         if cdinfo.GetDataIsComposite():
02184             print "use composite data append"
02185             reducer.PostGatherHelperName = "vtkMultiBlockDataGroupFilter"
02186 
02187         elif input.GetDataInformation(idx).GetDataClassName() == "vtkPolyData":
02188             print "use append poly data filter"
02189             reducer.PostGatherHelperName = "vtkAppendPolyData"
02190 
02191         elif input.GetDataInformation(idx).GetDataClassName() == "vtkRectilinearGrid":
02192             print "use append rectilinear grid filter"
02193             reducer.PostGatherHelperName = "vtkAppendRectilinearGrid"
02194 
02195         elif input.GetDataInformation(idx).IsA("vtkDataSet"):
02196             print "use unstructured append filter"
02197             reducer.PostGatherHelperName = "vtkAppendFilter"
02198 
02199     elif type(arg1) is types.IntType:
02200         reducer.PassThrough = arg1
02201 
02202     else:
02203         reducer.PreGatherHelper = arg1
02204         reducer.PostGatherHelper = arg2
02205 
02206     # reduce
02207     reducer.UpdatePipeline()
02208     dataInfo = reducer.GetDataInformation(0)
02209     dataType = dataInfo.GetDataSetType()
02210     if dataInfo.GetCompositeDataSetType() > 0:
02211       dataType = dataInfo.GetCompositeDataSetType()
02212 
02213     fetcher = filters.ClientServerMoveData(Input=reducer)
02214     fetcher.OutputDataType = dataType
02215     fetcher.WholeExtent = dataInfo.GetExtent()[:]
02216     #fetch
02217     fetcher.UpdatePipeline()
02218 
02219     op = fetcher.GetClientSideObject().GetOutputDataObject(0)
02220     opc = op.NewInstance()
02221     opc.ShallowCopy(op)
02222     opc.UnRegister(None)
02223     return opc
02224 
02225 def AnimateReader(reader, view, filename=None):
02226     """This is a utility function that, given a reader and a view
02227     animates over all time steps of the reader. If the optional
02228     filename is provided, a movie is created (type depends on the
02229     extension of the filename."""
02230     if not reader:
02231         raise RuntimeError, "No reader was specified, cannot animate."
02232     if not view:
02233         raise RuntimeError, "No view was specified, cannot animate."
02234     # Create an animation scene
02235     scene = animation.AnimationScene()
02236 
02237     # We need to have the reader and the view registered with
02238     # the time keeper. This is how the scene gets its time values.
02239     try:
02240         tk = ProxyManager().GetProxiesInGroup("timekeeper").values()[0]
02241         scene.TimeKeeper = tk
02242     except IndexError:
02243         tk = misc.TimeKeeper()
02244         scene.TimeKeeper = tk
02245 
02246     if not reader in tk.TimeSources:
02247         tk.TimeSources.append(reader)
02248     if not view in tk.Views:
02249         tk.Views.append(view)
02250 
02251 
02252     # with 1 view
02253     scene.ViewModules = [view]
02254     # Update the reader to get the time information
02255     reader.UpdatePipelineInformation()
02256     # Animate from 1st time step to last
02257     scene.StartTime = reader.TimestepValues.GetData()[0]
02258     scene.EndTime = reader.TimestepValues.GetData()[-1]
02259 
02260     # Each frame will correspond to a time step
02261     scene.PlayMode = 2 #Snap To Timesteps
02262 
02263     # Create a special animation cue for time.
02264     cue = animation.TimeAnimationCue()
02265     cue.AnimatedProxy = view
02266     cue.AnimatedPropertyName = "ViewTime"
02267     scene.Cues = [cue]
02268 
02269     if filename:
02270         writer = vtkSMAnimationSceneImageWriter()
02271         writer.SetFileName(filename)
02272         writer.SetFrameRate(1)
02273         writer.SetAnimationScene(scene.SMProxy)
02274 
02275         # Now save the animation.
02276         if not writer.Save():
02277             raise RuntimeError, "Saving of animation failed!"
02278     else:
02279         scene.Play()
02280     return scene
02281 
02282 def GetProgressPrintingIsEnabled():
02283     return progressObserverTag is not None
02284 
02285 def SetProgressPrintingEnabled(value):
02286     """Is not supported because of not supported observers"""
02287     pass
02288 
02289 def ToggleProgressPrinting():
02290     """Turn on/off printing of progress.  See SetProgressPrintingEnabled."""
02291     SetProgressPrintingEnabled(not GetProgressPrintingIsEnabled())
02292 
02293 def Finalize():
02294     """Although not required, this can be called at exit to cleanup."""
02295     global progressObserverTag
02296     # Make sure to remove the observer
02297     if progressObserverTag:
02298         ToggleProgressPrinting()
02299     vtkInitializationHelper.Finalize()
02300 
02301 # Internal methods
02302 
02303 def _getPyProxy(smproxy, outputPort=0):
02304     """Returns a python wrapper for a server manager proxy. This method
02305     first checks if there is already such an object by looking in the
02306     _pyproxies group and returns it if found. Otherwise, it creates a
02307     new one. Proxies register themselves in _pyproxies upon creation."""
02308     if not smproxy:
02309         return None
02310     if (smproxy, outputPort) in _pyproxies:
02311         return _pyproxies[(smproxy, outputPort)]()
02312 
02313     xmlName = smproxy.GetXMLName()
02314     if smproxy.GetXMLLabel():
02315         xmlName = smproxy.GetXMLLabel()
02316     classForProxy = _findClassForProxy(_make_name_valid(xmlName), smproxy.GetXMLGroup())
02317     if classForProxy:
02318         retVal = classForProxy(proxy=smproxy, port=outputPort)
02319     else:
02320         retVal = Proxy(proxy=smproxy, port=outputPort)
02321     return retVal
02322 
02323 def _makeUpdateCameraMethod(rv):
02324     """ This internal method is used to create observer methods """
02325     if not hasattr(rv(), "BlockUpdateCamera"):
02326         rv().add_attribute("BlockUpdateCamera", False)
02327     def UpdateCamera(obj, string):
02328         if not rv().BlockUpdateCamera:
02329           # used to avoid some nasty recursion that occurs when interacting in
02330           # the GUI.
02331           rv().BlockUpdateCamera = True
02332           rv().SynchronizeCameraProperties()
02333           rv().BlockUpdateCamera = False
02334     return UpdateCamera
02335 
02336 def _createInitialize(group, name):
02337     """Internal method to create an Initialize() method for the sub-classes
02338     of Proxy"""
02339     pgroup = group
02340     pname = name
02341     def aInitialize(self, connection=None, update=True):
02342         if not connection:
02343             connection = ActiveConnection
02344         if not connection:
02345             raise RuntimeError,\
02346                   'Cannot create a proxy without a session.'
02347         if not connection.Session.GetProxyDefinitionManager().HasDefinition(pgroup, pname):
02348             error_msg = "The connection does not provide any definition for %s." % pname
02349             raise RuntimeError, error_msg
02350         self.InitializeFromProxy(\
02351             CreateProxy(pgroup, pname, connection.Session), update)
02352     return aInitialize
02353 
02354 def _createGetProperty(pName):
02355     """Internal method to create a GetXXX() method where XXX == pName."""
02356     propName = pName
02357     def getProperty(self):
02358         return self.GetPropertyValue(propName)
02359     return getProperty
02360 
02361 def _createSetProperty(pName):
02362     """Internal method to create a SetXXX() method where XXX == pName."""
02363     propName = pName
02364     def setProperty(self, value):
02365         return self.SetPropertyWithName(propName, value)
02366     return setProperty
02367 
02368 def _findClassForProxy(xmlName, xmlGroup):
02369     """Given the xmlName for a proxy, returns a Proxy class. Note
02370     that if there are duplicates, the first one is returned."""
02371     global sources, filters, writers, rendering, animation, implicit_functions,\
02372            piecewise_functions, extended_sources, misc
02373     if not xmlName:
02374         return None
02375     if xmlGroup == "sources":
02376         return sources.__dict__[xmlName]
02377     elif xmlGroup == "filters":
02378         return filters.__dict__[xmlName]
02379     elif xmlGroup == "implicit_functions":
02380         return implicit_functions.__dict__[xmlName]
02381     elif xmlGroup == "piecewise_functions":
02382         return piecewise_functions.__dict__[xmlName]
02383     elif xmlGroup == "writers":
02384         return writers.__dict__[xmlName]
02385     elif xmlGroup == "extended_sources":
02386         return extended_sources.__dict__[xmlName]
02387     elif xmlName in rendering.__dict__:
02388         return rendering.__dict__[xmlName]
02389     elif xmlName in animation.__dict__:
02390         return animation.__dict__[xmlName]
02391     elif xmlName in misc.__dict__:
02392         return misc.__dict__[xmlName]
02393     else:
02394         return None
02395 
02396 def _printProgress(caller, event):
02397     """The default event handler for progress. Prints algorithm
02398     name and 1 '.' per 10% progress."""
02399     global currentAlgorithm, currentProgress
02400 
02401     pm = vtkProcessModule.GetProcessModule()
02402     progress = pm.GetLastProgress() / 10
02403     # If we got a 100% as the first thing, ignore
02404     # This is to get around the fact that some vtk
02405     # algorithms report 100% more than once (which is
02406     # a bug)
02407     if not currentAlgorithm and progress == 10:
02408         return
02409     alg = pm.GetLastProgressName()
02410     if alg != currentAlgorithm and alg:
02411         if currentAlgorithm:
02412             while currentProgress <= 10:
02413                 import sys
02414                 sys.stdout.write(".")
02415                 currentProgress += 1
02416             print "]"
02417             currentProgress = 0
02418         print alg, ": [ ",
02419         currentAlgorithm = alg
02420     while currentProgress <= progress:
02421         import sys
02422         sys.stdout.write(".")
02423         #sys.stdout.write("%d " % pm.GetLastProgress())
02424         currentProgress += 1
02425     if progress == 10:
02426         print "]"
02427         currentAlgorithm = None
02428         currentProgress = 0
02429 
02430 def updateModules(m):
02431     """Called when a plugin is loaded, this method updates
02432     the proxy class object in all known modules."""
02433 
02434     createModule("sources", m.sources)
02435     createModule("filters", m.filters)
02436     createModule("writers", m.writers)
02437     createModule("representations", m.rendering)
02438     createModule("views", m.rendering)
02439     createModule("lookup_tables", m.rendering)
02440     createModule("textures", m.rendering)
02441     createModule('cameramanipulators', m.rendering)
02442     createModule("animation", m.animation)
02443     createModule("misc", m.misc)
02444     createModule('animation_keyframes', m.animation)
02445     createModule('implicit_functions', m.implicit_functions)
02446     createModule('piecewise_functions', m.piecewise_functions)
02447     createModule("extended_sources", m.extended_sources)
02448     createModule("incremental_point_locators", m.misc)
02449 
02450 def _createModules(m):
02451     """Called when the module is loaded, this creates sub-
02452     modules for all know proxy groups."""
02453 
02454     m.sources = createModule('sources')
02455     m.filters = createModule('filters')
02456     m.writers = createModule('writers')
02457     m.rendering = createModule('representations')
02458     createModule('views', m.rendering)
02459     createModule("lookup_tables", m.rendering)
02460     createModule("textures", m.rendering)
02461     createModule('cameramanipulators', m.rendering)
02462     m.animation = createModule('animation')
02463     createModule('animation_keyframes', m.animation)
02464     m.implicit_functions = createModule('implicit_functions')
02465     m.piecewise_functions = createModule('piecewise_functions')
02466     m.extended_sources = createModule("extended_sources")
02467     m.misc = createModule("misc")
02468     createModule("incremental_point_locators", m.misc)
02469 
02470 class PVModule(object):
02471     pass
02472 
02473 def _make_name_valid(name):
02474     """Make a string into a valid Python variable name."""
02475     if not name:
02476         return None
02477     import string
02478     valid_chars = "_%s%s" % (string.ascii_letters, string.digits)
02479     name = str().join([c for c in name if c in valid_chars])
02480     if not name[0].isalpha():
02481         name = 'a' + name
02482     return name
02483 
02484 def createModule(groupName, mdl=None):
02485     """Populates a module with proxy classes defined in the given group.
02486     If mdl is not specified, it also creates the module"""
02487     global ActiveConnection
02488 
02489     if not ActiveConnection:
02490       raise RuntimeError, "Please connect to a server using \"Connect\""
02491 
02492     pxm = ProxyManager()
02493     # Use prototypes to find all proxy types.
02494     pxm.InstantiateGroupPrototypes(groupName)
02495 
02496     debug = False
02497     if not mdl:
02498         debug = True
02499         mdl = PVModule()
02500     definitionIter = pxm.NewDefinitionIterator(groupName)
02501     for i in definitionIter:
02502         proxyName = i['key']
02503         proto = pxm.GetPrototypeProxy(groupName, proxyName)
02504         if not proto:
02505            print "Error while loading %s/%s %s"%(groupName, i['group'], proxyName)
02506            continue
02507         pname = proxyName
02508         if proto.GetXMLLabel():
02509             pname = proto.GetXMLLabel()
02510         pname = _make_name_valid(pname)
02511         if not pname:
02512             continue
02513         if pname in mdl.__dict__:
02514             if debug:
02515                 print "Warning: %s is being overwritten. This may point to an issue in the ParaView configuration files" % pname
02516         cdict = {}
02517         # Create an Initialize() method for this sub-class.
02518         cdict['Initialize'] = _createInitialize(groupName, proxyName)
02519         iter = PropertyIterator(proto)
02520         # Add all properties as python properties.
02521         for prop in iter:
02522             propName = iter.GetKey()
02523             if (prop.GetInformationOnly() and propName != "TimestepValues" ) \
02524                    or prop.GetIsInternal():
02525                 continue
02526             names = [propName]
02527             names = [iter.PropertyLabel]
02528                 
02529             propDoc = None
02530             if prop.GetDocumentation():
02531                 propDoc = prop.GetDocumentation().GetDescription()
02532             for name in names:
02533                 name = _make_name_valid(name)
02534                 if name:
02535                     cdict[name] = property(_createGetProperty(propName),
02536                                            _createSetProperty(propName),
02537                                            None,
02538                                            propDoc)
02539         # Add the documentation as the class __doc__
02540         if proto.GetDocumentation() and \
02541            proto.GetDocumentation().GetDescription():
02542             doc = proto.GetDocumentation().GetDescription()
02543         else:
02544             doc = Proxy.__doc__
02545         cdict['__doc__'] = doc
02546         # Create the new type
02547         if proto.GetXMLName() == "ExodusIIReader":
02548             superclasses = (ExodusIIReaderProxy,)
02549         elif proto.IsA("vtkSMSourceProxy"):
02550             superclasses = (SourceProxy,)
02551         elif proto.IsA("vtkSMViewLayoutProxy"):
02552             superclasses = (ViewLayoutProxy,)
02553         else:
02554             superclasses = (Proxy,)
02555 
02556         cobj = type(pname, superclasses, cdict)
02557         # Add it to the modules dictionary
02558         mdl.__dict__[pname] = cobj
02559     return mdl
02560 
02561 
02562 def __determineGroup(proxy):
02563     """Internal method"""
02564     if not proxy:
02565         return None
02566     xmlgroup = proxy.GetXMLGroup()
02567     xmlname = proxy.GetXMLName()
02568     if xmlgroup == "sources":
02569         if xmlname in ["BlockSelectionSource",
02570                        "FrustumSelectionSource",
02571                        "GlobalIDSelectionSource",
02572                        "PedigreeIDSelectionSource",
02573                        "IDSelectionSource",
02574                        "CompositeDataIDSelectionSource",
02575                        "HierarchicalDataIDSelectionSource",
02576                        "ThresholdSelectionSource",
02577                        "LocationSelectionSource"]:
02578             return "selection_sources"
02579         return "sources"
02580     elif xmlgroup == "filters":
02581         return "sources"
02582     elif xmlgroup == "representations":
02583         if xmlname == "ScalarBarWidgetRepresentation":
02584             return "scalar_bars"
02585         return "representations"
02586     elif xmlgroup == "animation_keyframes":
02587         return "animation"
02588     return xmlgroup
02589 
02590 __nameCounter = {}
02591 def __determineName(proxy, group):
02592     global __nameCounter
02593     name = _make_name_valid(proxy.GetXMLLabel())
02594     if not name:
02595         return None
02596     if not __nameCounter.has_key(name):
02597         __nameCounter[name] = 1
02598         val = 1
02599     else:
02600         __nameCounter[name] += 1
02601         val = __nameCounter[name]
02602     return "%s%d" % (name, val)
02603 
02604 def __getName(proxy, group):
02605     pxm = ProxyManager(proxy.GetSession())
02606     if isinstance(proxy, Proxy):
02607         proxy = proxy.SMProxy
02608     return pxm.GetProxyName(group, proxy)
02609 
02610 class MissingRegistrationInformation(Exception):
02611     """Exception for missing registration information. Raised when a name or group 
02612     is not specified or when a group cannot be deduced."""
02613     pass
02614 
02615 class MissingProxy(Exception):
02616     """Exception fired when the requested proxy is missing."""
02617     pass
02618     
02619 def Register(proxy, **extraArgs):
02620     """Registers a proxy with the proxy manager. If no 'registrationGroup' is
02621     specified, then the group is inferred from the type of the proxy.
02622     'registrationName' may be specified to register with a particular name
02623     otherwise a default name will be created."""
02624     # TODO: handle duplicate registration
02625     if "registrationGroup" in extraArgs:
02626         registrationGroup = extraArgs["registrationGroup"]
02627     else:
02628         registrationGroup = __determineGroup(proxy)
02629 
02630     if "registrationName" in extraArgs:
02631         registrationName = extraArgs["registrationName"]
02632     else:
02633         registrationName = __determineName(proxy, registrationGroup)
02634     if registrationGroup and registrationName:
02635         pxm = ProxyManager()
02636         pxm.RegisterProxy(registrationGroup, registrationName, proxy)
02637     else:
02638         raise MissingRegistrationInformation, "Registration error %s %s." % (registrationGroup, registrationName)
02639     return (registrationGroup, registrationName)
02640 
02641 def UnRegister(proxy, **extraArgs):
02642     """UnRegisters proxies registered using Register()."""
02643     if "registrationGroup" in extraArgs:
02644         registrationGroup = extraArgs["registrationGroup"]
02645     else:
02646         registrationGroup = __determineGroup(proxy)
02647 
02648     if "registrationName" in extraArgs:
02649         registrationName = extraArgs["registrationName"]
02650     else:
02651         registrationName = __getName(proxy, registrationGroup)
02652 
02653     if registrationGroup and registrationName:
02654         pxm = ProxyManager()
02655         pxm.UnRegisterProxy(registrationGroup, registrationName, proxy)
02656     else:
02657         raise RuntimeError, "UnRegistration error."
02658     return (registrationGroup, registrationName)
02659 
02660 def demo1():
02661     """This simple demonstration creates a sphere, renders it and delivers
02662     it to the client using Fetch. It returns a tuple of (data, render
02663     view)"""
02664     if not ActiveConnection:
02665         Connect()
02666     ss = sources.Sphere(Radius=2, ThetaResolution=32)
02667     shr = filters.Shrink(Input=OutputPort(ss,0))
02668     cs = sources.Cone()
02669     app = filters.AppendDatasets()
02670     app.Input = [shr, cs]
02671     rv = CreateRenderView()
02672     rep = CreateRepresentation(app, rv)
02673     rv.ResetCamera()
02674     rv.StillRender()
02675     data = Fetch(ss)
02676 
02677     return (data, rv)
02678 
02679 def demo2(fname="/Users/berk/Work/ParaViewData/Data/disk_out_ref.ex2"):
02680     """This method demonstrates the user of a reader, representation and
02681     view. It also demonstrates how meta-data can be obtained using proxies.
02682     Make sure to pass the full path to an exodus file. Also note that certain
02683     parameters are hard-coded for disk_out_ref.ex2 which can be found
02684     in ParaViewData. This method returns the render view."""
02685     if not ActiveConnection:
02686         Connect()
02687     # Create the exodus reader and specify a file name
02688     reader = sources.ExodusIIReader(FileName=fname)
02689     # Get the list of point arrays.
02690     arraySelection = reader.PointVariables
02691     print arraySelection.Available
02692     # Select all arrays
02693     arraySelection.SetData(arraySelection.Available)
02694 
02695     # Next create a default render view appropriate for the session type.
02696     rv = CreateRenderView()
02697     # Create the matching representation
02698     rep = CreateRepresentation(reader, rv)
02699     rep.Representation = 1 # Wireframe
02700     # Black background is not pretty
02701     rv.Background = [0.4, 0.4, 0.6]
02702     rv.StillRender()
02703     # Reset the camera to include the whole thing
02704     rv.ResetCamera()
02705     rv.StillRender()
02706     # Change the elevation of the camera. See VTK documentation of vtkCamera
02707     # for camera parameters.
02708     c = rv.GetActiveCamera()
02709     c.Elevation(45)
02710     rv.StillRender()
02711     # Now that the reader execute, let's get some information about it's
02712     # output.
02713     pdi = reader[0].PointData
02714     # This prints a list of all read point data arrays as well as their
02715     # value ranges.
02716     print 'Number of point arrays:', len(pdi)
02717     for i in range(len(pdi)):
02718         ai = pdi[i]
02719         print "----------------"
02720         print "Array:", i, ai.Name, ":"
02721         numComps = ai.GetNumberOfComponents()
02722         print "Number of components:", numComps
02723         for j in range(numComps):
02724             print "Range:", ai.GetRange(j)
02725     # White is boring. Let's color the geometry using a variable.
02726     # First create a lookup table. This object controls how scalar
02727     # values are mapped to colors. See VTK documentation for
02728     # details.
02729     lt = rendering.PVLookupTable()
02730     # Assign it to the representation
02731     rep.LookupTable = lt
02732     # Color by point array called Pres
02733     rep.ColorAttributeType = 0 # point data
02734     rep.ColorArrayName = "Pres"
02735     # Add to RGB points. These are tuples of 4 values. First one is
02736     # the scalar values, the other 3 the RGB values. This list has
02737     # 2 points: Pres: 0.00678, color: blue, Pres: 0.0288, color: red
02738     lt.RGBPoints = [0.00678, 0, 0, 1, 0.0288, 1, 0, 0]
02739     lt.ColorSpace = 1 # HSV
02740     rv.StillRender()
02741     return rv
02742 
02743 def demo3():
02744     """This method demonstrates the use of servermanager with numpy as
02745     well as pylab for plotting. It creates an artificial data sources,
02746     probes it with a line, delivers the result to the client using Fetch
02747     and plots it using pylab. This demo requires numpy and pylab installed.
02748     It returns a tuple of (data, render view)."""
02749     import paraview.numpy_support
02750     import pylab
02751 
02752     if not ActiveConnection:
02753         Connect()
02754     # Create a synthetic data source
02755     source = sources.Wavelet()
02756     # Let's get some information about the data. First, for the
02757     # source to execute
02758     source.UpdatePipeline()
02759 
02760     di = source.GetDataInformation()
02761     print "Data type:", di.GetPrettyDataTypeString()
02762     print "Extent:", di.GetExtent()
02763     print "Array name:", \
02764           source[0].PointData[0].Name
02765 
02766     rv = CreateRenderView()
02767 
02768     rep1 = CreateRepresentation(source, rv)
02769     rep1.Representation = 3 # outline
02770 
02771     # Let's apply a contour filter
02772     cf = filters.Contour(Input=source, ContourValues=[200])
02773 
02774     # Select the array to contour by
02775     #cf.SelectInputScalars = 'RTData'
02776 
02777     rep2 = CreateRepresentation(cf, rv)
02778 
02779     rv.Background = (0.4, 0.4, 0.6)
02780     # Reset the camera to include the whole thing
02781     rv.StillRender()
02782     rv.ResetCamera()
02783     rv.StillRender()
02784 
02785     # Now, let's probe the data
02786     probe = filters.ResampleWithDataset(Input=source)
02787     # with a line
02788     line = sources.Line(Resolution=60)
02789     # that spans the dataset
02790     bounds = di.GetBounds()
02791     print "Bounds: ", bounds
02792     line.Point1 = bounds[0:6:2]
02793     line.Point2 = bounds[1:6:2]
02794 
02795     probe.Source = line
02796 
02797     # Render with the line
02798     rep3 = CreateRepresentation(line, rv)
02799     rv.StillRender()
02800 
02801     # Now deliver it to the client. Remember, this is for small data.
02802     data = Fetch(probe)
02803     # Convert it to a numpy array
02804     data = paraview.numpy_support.vtk_to_numpy(
02805       data.GetPointData().GetArray("RTData"))
02806     # Plot it using matplotlib
02807     pylab.plot(data)
02808     pylab.show()
02809 
02810     return (data, rv, probe)
02811 
02812 def demo4(fname="/Users/berk/Work/ParaViewData/Data/can.ex2"):
02813     """This method demonstrates the user of AnimateReader for
02814     creating animations."""
02815     if not ActiveConnection:
02816         Connect()
02817     reader = sources.ExodusIIReader(FileName=fname)
02818     view = CreateRenderView()
02819     repr = CreateRepresentation(reader, view)
02820     view.StillRender()
02821     view.ResetCamera()
02822     view.StillRender()
02823     c = view.GetActiveCamera()
02824     c.Elevation(95)
02825     return AnimateReader(reader, view)
02826 
02827 
02828 def demo5():
02829     """ Simple sphere animation"""
02830     if not ActiveConnection:
02831         Connect()
02832     sphere = sources.Sphere()
02833     view = CreateRenderView()
02834     repr = CreateRepresentation(sphere, view)
02835 
02836     view.StillRender()
02837     view.ResetCamera()
02838     view.StillRender()
02839 
02840     # Create an animation scene
02841     scene = animation.AnimationScene()
02842     # Add 1 view
02843     scene.ViewModules = [view]
02844 
02845     # Create a cue to animate the StartTheta property
02846     cue = animation.KeyFrameAnimationCue()
02847     cue.AnimatedProxy = sphere
02848     cue.AnimatedPropertyName = "StartTheta"
02849     # Add it to the scene's cues
02850     scene.Cues = [cue]
02851 
02852     # Create 2 keyframes for the StartTheta track
02853     keyf0 = animation.CompositeKeyFrame()
02854     keyf0.Type = 2 # Set keyframe interpolation type to Ramp.
02855     # At time = 0, value = 0
02856     keyf0.KeyTime = 0
02857     keyf0.KeyValues= [0]
02858 
02859     keyf1 = animation.CompositeKeyFrame()
02860     # At time = 1.0, value = 200
02861     keyf1.KeyTime = 1.0
02862     keyf1.KeyValues= [200]
02863 
02864     # Add keyframes.
02865     cue.KeyFrames = [keyf0, keyf1]
02866 
02867     scene.Play()
02868     return scene
02869 
02870 ASSOCIATIONS = { 'POINTS' : 0, 'CELLS' : 1, 'VERTICES' : 4, 'EDGES' : 5, 'ROWS' : 6}
02871 
02872 # Users can set the active connection which will be used by API
02873 # to create proxies etc when no connection argument is passed.
02874 # Connect() automatically sets this if it is not already set.
02875 ActiveConnection = None
02876 
02877 # Fields for multi-server support
02878 MultiServerConnections = None
02879 
02880 # API for multi-server support
02881 def enableMultiServer(multiServer=True):
02882   """This method enable the current servermanager to support several
02883   connections. Once we enable the multi-server support, the user can create
02884   as many connection as he want and switch from one to another in order to
02885   create and manage proxy."""
02886   global MultiServerConnections, ActiveConnection
02887   if not multiServer and MultiServerConnections:
02888       raise RuntimeError, "Once we enable Multi-Server support we can not get back"
02889   MultiServerConnections = []
02890   if ActiveConnection:
02891     MultiServerConnections.append(ActiveConnection)
02892 
02893 def switchActiveConnection(newActiveConnection=None):
02894   """Switch active connection to be the provided one or if none just pick the
02895   other one"""
02896   global MultiServerConnections, ActiveConnection
02897   if MultiServerConnections == None:
02898     raise RuntimeError, "enableMultiServer() must be called before"
02899 
02900   # Manage the case when no connection is provided
02901   if newActiveConnection:
02902     ActiveConnection = newActiveConnection
02903     __exposeActiveModules__()
02904     # Update active session for ParaView
02905     if vtkSMProxyManager.GetProxyManager().GetActiveSession() != ActiveConnection.Session:
02906        vtkSMProxyManager.GetProxyManager().SetActiveSession(ActiveConnection.Session)
02907     return ActiveConnection
02908   else:
02909     for connection in MultiServerConnections:
02910       if connection != ActiveConnection:
02911          ActiveConnection = connection
02912          __exposeActiveModules__()
02913          # Update active session for ParaView
02914          if vtkSMProxyManager.GetProxyManager().GetActiveSession() != ActiveConnection.Session:
02915             vtkSMProxyManager.GetProxyManager().SetActiveSession(ActiveConnection.Session)
02916          return ActiveConnection
02917   return None
02918 
02919 # Needs to be called when paraview module is loaded from python instead
02920 # of pvpython, pvbatch or GUI.
02921 if not vtkProcessModule.GetProcessModule():
02922 #    pvoptions = None Not applicable for SALOME Python console
02923 #    if paraview.options.batch:
02924 #      pvoptions = vtkPVOptions();
02925 #      pvoptions.SetProcessType(0x40)
02926 #      if paraview.options.symmetric:
02927 #        pvoptions.SetSymmetricMPIMode(True)
02928     vtkInitializationHelper.Initialize(sys.executable,
02929         vtkProcessModule.PROCESS_CLIENT, pvoptions)
02930 
02931 # Initialize progress printing. Can be turned off by calling
02932 # ToggleProgressPrinting() again.
02933 progressObserverTag = None
02934 currentAlgorithm = False
02935 currentProgress = 0
02936 fromGUI = False
02937 ToggleProgressPrinting()
02938 
02939 _pyproxies = {}
02940 
02941 # Create needed sub-modules
02942 # We can no longer create modules, unless we have connected to a server.
02943 # _createModules()
02944 
02945 # Set up our custom importer (if possible)
02946 loader = _ModuleLoader()
02947 sys.meta_path.append(loader)
02948 
02949 def __InitAfterConnect__(connection):
02950     """
02951     This function is called everytime after a server connection is made.
02952     Since the ProxyManager and all proxy definitions are changed every time a
02953     new connection is made, we re-create all the modules
02954     """
02955     _createModules(connection.Modules)
02956     ## VSV fromFilter is alwais False for SALOME because it can't be changed from ParaView code
02957     #if not paraview.fromFilter:
02958         # fromFilter is set when this module is imported from the programmable
02959         # filter
02960 #    global _defUpdater
02961 #    _defUpdater = __DefinitionUpdater()
02962     connection.AttachDefinitionUpdater()
02963     pass
02964 
02965 def __exposeActiveModules__():
02966     """Update servermanager submodules to point to the current
02967     ActiveConnection.Modules.*"""
02968     # Expose all active module to the current servermanager module
02969     if ActiveConnection:
02970        for m in [mName for mName in dir(ActiveConnection.Modules) if mName[0] != '_' ]:
02971           exec "global %s;%s = ActiveConnection.Modules.%s" % (m,m,m)
02972 
02973 # Definitions for working in SALOME GUI mode
02974 #aParams = myParavis.GetConnectionParameters()
02975 #ActiveConnection = Connect()
02976 ##Connection(aParams[0])
02977 #ActiveConnection.SetHost(aParams[1], aParams[2], aParams[3], aParams[4], aParams[5])
02978 #ToggleProgressPrinting()
02979 #fromGUI = True
02980 
02981 InitFromGUI()
02982 
02983 if hasattr(sys, "ps1"):
02984     # session is interactive.
02985     print vtkSMProxyManager.GetParaViewSourceVersion();
02986 
02987 def GetConnectionFromId(id):
02988    for connection in MultiServerConnections:
02989       if connection.ID == id:
02990          return connection
02991    return None
02992 
02993 def GetConnectionFromSession(session):
02994    for connection in MultiServerConnections:
02995       if connection.Session == session:
02996          return connection
02997    return None
02998 
02999 def GetConnectionAt(index):
03000    return MultiServerConnections[index]
03001 
03002 def GetNumberOfConnections():
03003    return len(MultiServerConnections)