Salome HOME
Merge from V6_main 01/04/2013
[modules/paravis.git] / src / PV_SWIG / pvsimple.py
1 # Copyright (C) 2010-2013  CEA/DEN, EDF R&D
2 #
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License.
7 #
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 # Lesser General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19
20 r"""simple is a module for using paraview server manager in Python. It 
21 provides a simple convenience layer to functionality provided by the
22 C++ classes wrapped to Python as well as the servermanager module.
23
24 A simple example:
25   from paraview.simple import *
26
27   # Create a new sphere proxy on the active connection and register it
28   # in the sources group.
29   sphere = Sphere(ThetaResolution=16, PhiResolution=32)
30
31   # Apply a shrink filter
32   shrink = Shrink(sphere)
33   
34   # Turn the visiblity of the shrink object on.
35   Show(shrink)
36   
37   # Render the scene
38   Render()
39 """
40
41 import paravisSM
42
43 servermanager = paravisSM
44
45 def enableMultiServer():
46     servermanager.enableMultiServer()
47
48 def switchActiveConnection(newActiveConnection=None, ns=None):
49     if not ns:
50        ns = globals()
51     _remove_functions(ns)
52     servermanager.switchActiveConnection(newActiveConnection)
53     _add_functions(ns)
54
55 def Disconnect(ns=None, force=True):
56     if servermanager.ActiveConnection and (force or servermanager.MultiServerConnections == None):
57        if ns:
58           _remove_functions(ns)
59        _remove_functions(globals())
60        if not servermanager.fromGUI:
61           servermanager.ProxyManager().DisableStateUpdateNotification()
62           servermanager.ProxyManager().UnRegisterProxies()
63        active_objects.view = None
64        active_objects.source = None
65        servermanager.Disconnect()
66        if not servermanager.fromGUI:
67           import gc
68           gc.collect()
69
70 def Connect(ds_host=None, ds_port=11111, rs_host=None, rs_port=11111):
71     """Creates a connection to a server. Example usage:
72     > Connect("amber") # Connect to a single server at default port
73     > Connect("amber", 12345) # Connect to a single server at port 12345
74     > Connect("amber", 11111, "vis_cluster", 11111) # connect to data server, render server pair"""
75     Disconnect(globals(), False)
76     connection = servermanager.Connect(ds_host, ds_port, rs_host, rs_port)
77     _add_functions(globals())
78
79     servermanager.ProxyManager().DisableStateUpdateNotification()
80     servermanager.ProxyManager().UpdateFromRemote()
81     tk = servermanager.ProxyManager().GetProxy("timekeeper", "TimeKeeper")
82     if not tk:
83        try:
84            tk = servermanager.misc.TimeKeeper()
85            servermanager.ProxyManager().RegisterProxy("timekeeper", "TimeKeeper", tk)
86        except AttributeError:
87            print "Error: Could not create TimeKeeper"
88
89     scene = servermanager.ProxyManager().GetProxy("animation", "AnimationScene")
90     if not scene:
91        try:
92            scene = AnimationScene()
93            scene.TimeKeeper = tk
94        except NameError:
95            print "Error: Could not create AnimationScene"
96
97     servermanager.ProxyManager().EnableStateUpdateNotification()
98     servermanager.ProxyManager().TriggerStateUpdate()
99
100     return connection
101
102 def ReverseConnect(port=11111):
103     """Create a reverse connection to a server.  Listens on port and waits for
104     an incoming connection from the server."""
105     Disconnect(globals(), False)
106     connection = servermanager.ReverseConnect(port)
107     _add_functions(globals())
108
109     servermanager.ProxyManager().DisableStateUpdateNotification()
110     servermanager.ProxyManager().UpdateFromRemote()
111     tk = servermanager.ProxyManager().GetProxy("timekeeper", "TimeKeeper")
112     if not tk:
113        tk = servermanager.misc.TimeKeeper()
114        servermanager.ProxyManager().RegisterProxy("timekeeper", "TimeKeeper", tk)
115
116     scene = servermanager.ProxyManager().GetProxy("animation", "AnimationScene")
117     if not scene:
118        scene = AnimationScene()
119        scene.TimeKeeper = tk
120
121     servermanager.ProxyManager().EnableStateUpdateNotification()
122     servermanager.ProxyManager().TriggerStateUpdate()
123
124     return connection
125
126 def _create_view(view_xml_name):
127     "Creates and returns a 3D render view."
128     view = servermanager._create_view(view_xml_name)
129     servermanager.ProxyManager().RegisterProxy("views", \
130       "my_view%d" % _funcs_internals.view_counter, view)
131     active_objects.view = view
132     _funcs_internals.view_counter += 1
133
134     tk = servermanager.ProxyManager().GetProxiesInGroup("timekeeper").values()[0]
135     views = tk.Views
136     if not view in views:
137         views.append(view)
138     try:
139         scene = GetAnimationScene()
140         if not view in scene.ViewModules:
141             scene.ViewModules.append(view)
142     except servermanager.MissingProxy:
143         pass
144     return view
145
146 def CreateRenderView():
147     return _create_view("RenderView")
148
149 def CreateXYPlotView():
150     return _create_view("XYChartView")
151
152 def CreateBarChartView():
153     return _create_view("XYBarChartView")
154
155 def CreateComparativeRenderView():
156     return _create_view("ComparativeRenderView")
157
158 def CreateComparativeXYPlotView():
159     return _create_view("ComparativeXYPlotView")
160  
161 def CreateComparativeBarChartView():
162     return _create_view("ComparativeBarChartView")
163
164 def CreateParallelCoordinatesChartView():
165     return _create_view("ParallelCoordinatesChartView")
166
167 def Create2DRenderView():
168     return _create_view("2DRenderView")
169
170 def OpenDataFile(filename, **extraArgs):
171     """Creates a reader to read the give file, if possible.
172        This uses extension matching to determine the best reader possible.
173        If a reader cannot be identified, then this returns None."""
174     session = servermanager.ActiveConnection.Session
175     reader_factor = servermanager.vtkSMProxyManager.GetProxyManager().GetReaderFactory()
176     if reader_factor.GetNumberOfRegisteredPrototypes() == 0:
177       reader_factor.RegisterPrototypes(session, "sources")
178     first_file = filename
179     if type(filename) == list:
180         first_file = filename[0]
181     if not reader_factor.TestFileReadability(first_file, session):
182         msg = "File not readable: %s " % first_file
183         raise RuntimeError, msg
184     if not reader_factor.CanReadFile(first_file, session):
185         msg = "File not readable. No reader found for '%s' " % first_file
186         raise RuntimeError, msg
187     prototype = servermanager.ProxyManager().GetPrototypeProxy(
188       reader_factor.GetReaderGroup(), reader_factor.GetReaderName())
189     xml_name = paraview.make_name_valid(prototype.GetXMLLabel())
190     reader_func = _create_func(xml_name, servermanager.sources)
191     if prototype.GetProperty("FileNames"):
192       reader = reader_func(FileNames=filename, **extraArgs)
193     else :
194       reader = reader_func(FileName=filename, **extraArgs)
195     return reader
196
197 def CreateWriter(filename, proxy=None, **extraArgs):
198     """Creates a writer that can write the data produced by the source proxy in
199        the given file format (identified by the extension). If no source is
200        provided, then the active source is used. This doesn't actually write the
201        data, it simply creates the writer and returns it."""
202     if not filename:
203        raise RuntimeError, "filename must be specified"
204     session = servermanager.ActiveConnection.Session
205     writer_factory = servermanager.vtkSMProxyManager.GetProxyManager().GetWriterFactory()
206     if writer_factory.GetNumberOfRegisteredPrototypes() == 0:
207         writer_factory.RegisterPrototypes(session, "writers")
208     if not proxy:
209         proxy = GetActiveSource()
210     if not proxy:
211         raise RuntimeError, "Could not locate source to write"
212     writer_proxy = writer_factory.CreateWriter(filename, proxy.SMProxy, proxy.Port)
213     return servermanager._getPyProxy(writer_proxy)
214
215 def GetRenderView():
216     """Returns the active view if there is one. Else creates and returns a new view."""
217     view = active_objects.view
218     if not view:
219         # it's possible that there's no active view, but a render view exists.
220         # If so, locate that and return it (before trying to create a new one).
221         view = servermanager.GetRenderView()
222     if not view:
223         view = CreateRenderView()
224     return view
225
226 def GetRenderViews():
227     """Returns all render views as a list."""
228     return servermanager.GetRenderViews()
229
230 def GetRepresentation(proxy=None, view=None):
231     """Given a pipeline object and view, returns the corresponding representation object.
232     If pipeline object and view are not specified, active objects are used."""
233     if not view:
234         view = active_objects.view
235     if not proxy:
236         proxy = active_objects.source
237     rep = servermanager.GetRepresentation(proxy, view)
238     if not rep:
239         rep = servermanager.CreateRepresentation(proxy, view)
240         servermanager.ProxyManager().RegisterProxy("representations", \
241           "my_representation%d" % _funcs_internals.rep_counter, rep)
242         _funcs_internals.rep_counter += 1
243     return rep
244     
245 def GetDisplayProperties(proxy=None, view=None):
246     """Given a pipeline object and view, returns the corresponding representation object.
247     If pipeline object and/or view are not specified, active objects are used."""
248     return GetRepresentation(proxy, view)
249     
250 def Show(proxy=None, view=None, **params):
251     """Turns the visibility of a given pipeline object on in the given view.
252     If pipeline object and/or view are not specified, active objects are used."""
253     if proxy == None:
254         proxy = GetActiveSource()
255     if proxy == None:
256         raise RuntimeError, "Show() needs a proxy argument or that an active source is set."
257     if not view and not active_objects.view:
258         CreateRenderView()
259     rep = GetDisplayProperties(proxy, view)
260     if rep == None:
261         raise RuntimeError, "Could not create a representation object for proxy %s" % proxy.GetXMLLabel()
262     for param in params.keys():
263         setattr(rep, param, params[param])
264     rep.Visibility = 1
265     return rep
266
267 def Hide(proxy=None, view=None):
268     """Turns the visibility of a given pipeline object off in the given view.
269     If pipeline object and/or view are not specified, active objects are used."""
270     rep = GetDisplayProperties(proxy, view)
271     rep.Visibility = 0
272
273 def Render(view=None):
274     """Renders the given view (default value is active view)"""
275     if not view:
276         view = active_objects.view
277     view.StillRender()
278     if _funcs_internals.first_render:
279         # Not all views have a ResetCamera method
280         try:
281             view.ResetCamera()
282             view.StillRender()
283         except AttributeError: pass
284         _funcs_internals.first_render = False
285     return view
286         
287 def ResetCamera(view=None):
288     """Resets the settings of the camera to preserver orientation but include
289     the whole scene. If an argument is not provided, the active view is
290     used."""
291     if not view:
292         view = active_objects.view
293     if hasattr(view, "ResetCamera"):
294         view.ResetCamera()
295     if hasattr(view, "ResetDisplay"):
296         view.ResetDisplay()
297     Render(view)
298
299 def _DisableFirstRenderCameraReset():
300     """Disable the first render camera reset.  Normally a ResetCamera is called
301     automatically when Render is called for the first time after importing
302     this module."""
303     _funcs_internals.first_render = False
304
305 def SetProperties(proxy=None, **params):
306     """Sets one or more properties of the given pipeline object. If an argument
307     is not provided, the active source is used. Pass a list of property_name=value
308     pairs to this function to set property values. For example:
309      SetProperties(Center=[1, 2, 3], Radius=3.5)
310     """
311     if not proxy:
312         proxy = active_objects.source
313     for param in params.keys():
314         if not hasattr(proxy, param):
315             raise AttributeError("object has no property %s" % param)
316         setattr(proxy, param, params[param])
317
318 def GetProperty(*arguments, **keywords):
319     """Get one property of the given pipeline object. If keywords are used,
320        you can set the proxy and the name of the property that you want to get
321        like in the following example :
322             GetProperty({proxy=sphere, name="Radius"})
323        If it's arguments that are used, then you have two case:
324          - if only one argument is used that argument will be
325            the property name.
326          - if two arguments are used then the first one will be
327            the proxy and the second one the property name.
328        Several example are given below:
329            GetProperty({name="Radius"})
330            GetProperty({proxy=sphereProxy, name="Radius"})
331            GetProperty( sphereProxy, "Radius" )
332            GetProperty( "Radius" )
333     """
334     name = None
335     proxy = None
336     for key in keywords:
337         if key == "name":
338             name = keywords[key]
339         if key == "proxy":
340             proxy = keywords[key]
341     if len(arguments) == 1 :
342         name = arguments[0]
343     if len(arguments) == 2 :
344         proxy = arguments[0]
345         name  = arguments[1]
346     if not name:
347         raise RuntimeError, "Expecting at least a property name as input. Otherwise keyword could be used to set 'proxy' and property 'name'"
348     if not proxy:
349         proxy = active_objects.source
350     return proxy.GetProperty(name)
351
352 def SetDisplayProperties(proxy=None, view=None, **params):
353     """Sets one or more display properties of the given pipeline object. If an argument
354     is not provided, the active source is used. Pass a list of property_name=value
355     pairs to this function to set property values. For example:
356      SetProperties(Color=[1, 0, 0], LineWidth=2)
357     """
358     rep = GetDisplayProperties(proxy, view)
359     SetProperties(rep, **params)
360
361 def SetViewProperties(view=None, **params):
362     """Sets one or more properties of the given view. If an argument
363     is not provided, the active view is used. Pass a list of property_name=value
364     pairs to this function to set property values. For example:
365      SetProperties(Background=[1, 0, 0], UseImmediateMode=0)
366     """
367     if not view:
368         view = active_objects.view
369     SetProperties(view, **params)
370
371 def RenameSource(newName, proxy=None):
372     """Renames the given source.  If the given proxy is not registered
373     in the sources group this method will have no effect.  If no source is
374     provided, the active source is used."""
375     if not proxy:
376         proxy = active_objects.source
377     pxm = servermanager.ProxyManager()
378     oldName = pxm.GetProxyName("sources", proxy)
379     if oldName:
380       pxm.RegisterProxy("sources", newName, proxy)
381       pxm.UnRegisterProxy("sources", oldName, proxy)
382
383 def FindSource(name):
384     return servermanager.ProxyManager().GetProxy("sources", name)
385
386 def GetSources():
387     """Given the name of a source, return its Python object."""
388     return servermanager.ProxyManager().GetProxiesInGroup("sources")
389
390 def GetRepresentations():
391     """Returns all representations (display properties)."""
392     return servermanager.ProxyManager().GetProxiesInGroup("representations")
393
394 def UpdatePipeline(time=None, proxy=None):
395     """Updates (executes) the given pipeline object for the given time as
396     necessary (i.e. if it did not already execute). If no source is provided,
397     the active source is used instead."""
398     if not proxy:
399         proxy = active_objects.source
400     if time:
401         proxy.UpdatePipeline(time)
402     else:
403         proxy.UpdatePipeline()
404
405 def Delete(proxy=None):
406     """Deletes the given pipeline object or the active source if no argument
407     is specified."""
408     if not proxy:
409         proxy = active_objects.source
410     # Unregister any helper proxies stored by a vtkSMProxyListDomain
411     for prop in proxy:
412         listdomain = prop.GetDomain('proxy_list')
413         if listdomain:
414             if listdomain.GetClassName() != 'vtkSMProxyListDomain':
415                 continue
416             group = "pq_helper_proxies." + proxy.GetGlobalIDAsString()
417             for i in xrange(listdomain.GetNumberOfProxies()):
418                 pm = servermanager.ProxyManager()
419                 iproxy = listdomain.GetProxy(i)
420                 name = pm.GetProxyName(group, iproxy)
421                 if iproxy and name:
422                     pm.UnRegisterProxy(group, name, iproxy)
423                     
424     # Remove source/view from time keeper
425     tk = servermanager.ProxyManager().GetProxiesInGroup("timekeeper").values()[0]
426     if isinstance(proxy, servermanager.SourceProxy):
427         try:
428             idx = tk.TimeSources.index(proxy)
429             del tk.TimeSources[idx]
430         except ValueError:
431             pass
432     else:
433         try:
434             idx = tk.Views.index(proxy)
435             del tk.Views[idx]
436         except ValueError:
437             pass
438     servermanager.UnRegister(proxy)
439     
440     # If this is a representation, remove it from all views.
441     if proxy.SMProxy.IsA("vtkSMRepresentationProxy") or \
442         proxy.SMProxy.IsA("vtkSMNewWidgetRepresentationProxy"):
443         for view in GetRenderViews():
444             view.Representations.remove(proxy)
445     # If this is a source, remove the representation iff it has no consumers
446     # Also change the active source if necessary
447     elif proxy.SMProxy.IsA("vtkSMSourceProxy"):
448         sources = servermanager.ProxyManager().GetProxiesInGroup("sources")
449         for i in range(proxy.GetNumberOfConsumers()):
450             if proxy.GetConsumerProxy(i) in sources:
451                 raise RuntimeError("Source has consumers. It cannot be deleted " +
452                   "until all consumers are deleted.")
453         #VSV:==
454         if proxy.IsSame(GetActiveSource()):
455             if hasattr(proxy, "Input") and proxy.Input:
456                 if isinstance(proxy.Input, servermanager.Proxy):
457                     SetActiveSource(proxy.Input)
458                 else:
459                     SetActiveSource(proxy.Input[0])
460             else: SetActiveSource(None)
461         for rep in GetRepresentations().values():
462             #VSV:==
463             if rep.Input.IsSame(proxy):
464                 Delete(rep)
465     # Change the active view if necessary
466     elif proxy.SMProxy.IsA("vtkSMRenderViewProxy"):
467         ##VSV:==
468         if proxy.IsSame(GetActiveView()):
469             if len(GetRenderViews()) > 0:
470                 SetActiveView(GetRenderViews()[0])
471             else:
472                 SetActiveView(None)
473
474 def CreateLookupTable(**params):
475     """Create and return a lookup table.  Optionally, parameters can be given
476     to assign to the lookup table.
477     """
478     lt = servermanager.rendering.PVLookupTable()
479     servermanager.Register(lt)
480     SetProperties(lt, **params)
481     return lt
482
483 def CreatePiecewiseFunction(**params):
484     """Create and return a piecewise function.  Optionally, parameters can be
485     given to assign to the piecewise function.
486     """
487     pfunc = servermanager.piecewise_functions.PiecewiseFunction()
488     servermanager.Register(pfunc)
489     SetProperties(pfunc, **params)
490     return pfunc
491
492 def GetLookupTableForArray(arrayname, num_components, **params):
493     """Used to get an existing lookuptable for a array or to create one if none
494     exists. Keyword arguments can be passed in to initialize the LUT if a new
495     one is created."""
496     proxyName = "%d.%s.PVLookupTable" % (int(num_components), arrayname)
497     lut = servermanager.ProxyManager().GetProxy("lookup_tables", proxyName)
498     if lut:
499         return lut
500     # No LUT exists for this array, create a new one.
501     # TODO: Change this to go a LookupTableManager that is shared with the GUI,
502     # so that the GUI and python end up create same type of LUTs. For now,
503     # python will create a Blue-Red LUT, unless overridden by params.
504     lut = servermanager.rendering.PVLookupTable(
505             ColorSpace="HSV", RGBPoints=[0, 0, 0, 1, 1, 1, 0, 0])
506     SetProperties(lut, **params)
507     servermanager.Register(lut, registrationName=proxyName)
508     return lut
509
510 def CreateScalarBar(**params):
511     """Create and return a scalar bar widget.  The returned widget may
512     be added to a render view by appending it to the view's representations
513     The widget must have a valid lookup table before it is added to a view.
514     It is possible to pass the lookup table (and other properties) as arguments
515     to this method:
516     
517     lt = MakeBlueToRedLt(3.5, 7.5)
518     bar = CreateScalarBar(LookupTable=lt, Title="Velocity")
519     GetRenderView().Representations.append(bar)
520     
521     By default the returned widget is selectable and resizable.
522     """
523     sb = servermanager.rendering.ScalarBarWidgetRepresentation()
524     servermanager.Register(sb)
525     sb.Selectable = 1
526     sb.Resizable = 1
527     sb.Enabled = 1
528     sb.Title = "Scalars"
529     SetProperties(sb, **params)
530     return sb
531
532 # TODO: Change this to take the array name and number of components. Register 
533 # the lt under the name ncomp.array_name
534 def MakeBlueToRedLT(min, max):
535     # Define RGB points. These are tuples of 4 values. First one is
536     # the scalar values, the other 3 the RGB values. 
537     rgbPoints = [min, 0, 0, 1, max, 1, 0, 0]
538     return CreateLookupTable(RGBPoints=rgbPoints, ColorSpace="HSV")
539     
540 def _find_writer(filename):
541     """Internal function."""
542     extension = None
543     parts = filename.split('.')
544     if len(parts) > 1:
545         extension = parts[-1]
546     else:
547         raise RuntimeError, "Filename has no extension, please specify a write"
548         
549     if extension == 'png':
550         return 'vtkPNGWriter'
551     elif extension == 'bmp':
552         return 'vtkBMPWriter'
553     elif extension == 'ppm':
554         return 'vtkPNMWriter'
555     elif extension == 'tif' or extension == 'tiff':
556         return 'vtkTIFFWriter'
557     elif extension == 'jpg' or extension == 'jpeg':
558         return 'vtkJPEGWriter'
559     else:
560         raise RuntimeError, "Cannot infer filetype from extension:", extension
561
562 def AddCameraLink(viewProxy, viewProxyOther, linkName):
563     """Create a camera link between two view proxies.  A name must be given
564     so that the link can be referred to by name.  If a link with the given
565     name already exists it will be removed first."""
566     if not viewProxyOther: viewProxyOther = GetActiveView()
567     link = servermanager.vtkSMCameraLink()
568     link.AddLinkedProxy(viewProxy.SMProxy, 1)
569     link.AddLinkedProxy(viewProxyOther.SMProxy, 2)
570     link.AddLinkedProxy(viewProxyOther.SMProxy, 1)
571     link.AddLinkedProxy(viewProxy.SMProxy, 2)
572     RemoveCameraLink(linkName)
573     servermanager.ProxyManager().RegisterLink(linkName, link)
574
575 def RemoveCameraLink(linkName):
576     """Remove a camera link with the given name."""
577     servermanager.ProxyManager().UnRegisterLink(linkName)
578
579 def WriteImage(filename, view=None, **params):
580     """Saves the given view (or the active one if none is given) as an
581     image. Optionally, you can specify the writer and the magnification
582     using the Writer and Magnification named arguments. For example:
583      WriteImage("foo.mypng", aview, Writer=vtkPNGWriter, Magnification=2)
584     If no writer is provided, the type is determined from the file extension.
585     Currently supported extensions are png, bmp, ppm, tif, tiff, jpg and jpeg.
586     The writer is a VTK class that is capable of writing images.
587     Magnification is used to determine the size of the written image. The size
588     is obtained by multiplying the size of the view with the magnification.
589     Rendering may be done using tiling to obtain the correct size without
590     resizing the view."""
591     if not view:
592         view = active_objects.view
593     writer = None
594     if params.has_key('Writer'):
595         writer = params['Writer']
596     mag = 1
597     if params.has_key('Magnification'):
598         mag = int(params['Magnification'])
599     if not writer:
600         writer = _find_writer(filename)
601     view.WriteImage(filename, writer, mag)
602
603 def AnimateReader(reader=None, view=None, filename=None):
604     """This is a utility function that, given a reader and a view
605     animates over all time steps of the reader. If the optional
606     filename is provided, a movie is created (type depends on the
607     extension of the filename."""
608     if not reader:
609         reader = active_objects.source
610     if not view:
611         view = active_objects.view
612         
613     return servermanager.AnimateReader(reader, view, filename)
614
615
616 def _create_func(key, module):
617     """Internal function."""
618
619     def CreateObject(*input, **params):
620         """This function creates a new proxy. For pipeline objects that accept inputs,
621         all non-keyword arguments are assumed to be inputs. All keyword arguments are
622         assumed to be property,value pairs and are passed to the new proxy."""
623
624         # Instantiate the actual object from the given module.
625         px = module.__dict__[key]()
626
627         # Make sure non-keyword arguments are valid
628         for inp in input:
629             if inp != None and not isinstance(inp, servermanager.Proxy):
630                 if px.GetProperty("Input") != None:
631                     raise RuntimeError, "Expecting a proxy as input."
632                 else:
633                     raise RuntimeError, "This function does not accept non-keyword arguments."
634
635         # Assign inputs
636         if px.GetProperty("Input") != None:
637             if len(input) > 0:
638                 px.Input = input
639             else:
640                 # If no input is specified, try the active pipeline object
641                 if px.GetProperty("Input").GetRepeatable() and active_objects.get_selected_sources():
642                     px.Input = active_objects.get_selected_sources()
643                 elif active_objects.source:
644                     px.Input = active_objects.source
645         else:
646             if len(input) > 0:
647                 raise RuntimeError, "This function does not expect an input."
648
649         registrationName = None
650         for nameParam in ['registrationName', 'guiName']:
651           if nameParam in params:
652               registrationName = params[nameParam]
653               del params[nameParam]
654
655         # Pass all the named arguments as property,value pairs
656         for param in params.keys():
657             setattr(px, param, params[param])
658
659         try:
660             # Register the proxy with the proxy manager.
661             if registrationName:
662                 group, name = servermanager.Register(px, registrationName=registrationName)
663             else:
664                 group, name = servermanager.Register(px)
665
666
667             # Register pipeline objects with the time keeper. This is used to extract time values
668             # from sources. NOTE: This should really be in the servermanager controller layer.
669             if group == "sources":
670                 has_tk = True
671                 try:
672                     tk = servermanager.ProxyManager().GetProxiesInGroup("timekeeper").values()[0]
673                 except IndexError:
674                     has_tk = False
675                 if has_tk:
676                     sources = tk.TimeSources
677                     if not px in sources:
678                         sources.append(px)
679
680                 active_objects.source = px
681         except servermanager.MissingRegistrationInformation:
682             pass
683
684         return px
685
686     return CreateObject
687
688 def _create_doc(new, old):
689     """Internal function."""
690     import string
691     res = ""
692     for doc in (new, old):
693         ts = []
694         strpd = doc.split('\n')
695         for s in strpd:
696             ts.append(s.lstrip())
697         res += string.join(ts)
698         res += '\n'
699     return res
700     
701 def _func_name_valid(name):
702     """Internal function."""
703     valid = True
704     for c in name:
705         if c == '(' or c ==')':
706             valid = False
707             break
708     return valid
709
710 def _add_functions(g):
711     activeModule = servermanager.ActiveConnection.Modules
712     for m in [activeModule.filters, activeModule.sources,
713               activeModule.writers, activeModule.animation]:
714         dt = m.__dict__
715         for key in dt.keys():
716             cl = dt[key]
717             if not isinstance(cl, str):
718                 if not key in g and _func_name_valid(key):
719                     g[key] = _create_func(key, m)
720                     exec "g[key].__doc__ = _create_doc(m.%s.__doc__, g[key].__doc__)" % key
721
722 def _remove_functions(g):
723     list = []
724     if servermanager.ActiveConnection:
725        list = [m for m in dir(servermanager.ActiveConnection.Modules) if m[0] != '_']
726
727     for m in list:
728         dt = servermanager.ActiveConnection.Modules.__dict__[m].__dict__
729         for key in dt.keys():
730             cl = dt[key]
731             if not isinstance(cl, str) and g.has_key(key):
732                 g.pop(key)
733                 #print "remove %s function" % key
734
735 def GetActiveView():
736     """Returns the active view."""
737     return active_objects.view
738     
739 def SetActiveView(view):
740     """Sets the active view."""
741     active_objects.view = view
742     
743 def GetActiveSource():
744     """Returns the active source."""
745     return active_objects.source
746     
747 def SetActiveSource(source):
748     """Sets the active source."""
749     active_objects.source = source
750     
751 def GetActiveCamera():
752     """Returns the active camera for the active view. The returned object
753     is an instance of vtkCamera."""
754     return GetActiveView().GetActiveCamera()
755
756 def GetAnimationScene():
757     """Returns the application-wide animation scene. ParaView has only one
758     global animation scene. This method provides access to that. Users are
759     free to create additional animation scenes directly, but those scenes
760     won't be shown in the ParaView GUI."""
761     animation_proxies = servermanager.ProxyManager().GetProxiesInGroup("animation")
762     scene = None
763     for aProxy in animation_proxies.values():
764         if aProxy.GetXMLName() == "AnimationScene":
765             scene = aProxy
766             break
767     if not scene:
768         raise servermanager.MissingProxy, "Could not locate global AnimationScene."
769     return scene
770
771 def WriteAnimation(filename, **params):
772     """Writes the current animation as a file. Optionally one can specify
773     arguments that qualify the saved animation files as keyword arguments.
774     Accepted options are as follows:
775     * Magnification (integer) : set the maginification factor for the saved
776       animation.
777     * Quality (0 [worst] or 1 or 2 [best]) : set the quality of the generated
778       movie (if applicable).
779     * Subsampling (integer) : setting whether the movie encoder should use
780       subsampling of the chrome planes or not, if applicable. Since the human
781       eye is more sensitive to brightness than color variations, subsampling
782       can be useful to reduce the bitrate. Default value is 0.
783     * BackgroundColor (3-tuple of doubles) : set the RGB background color to
784       use to fill empty spaces in the image.
785     * FrameRate (double): set the frame rate (if applicable)."""
786     scene = GetAnimationScene()
787     # ensures that the TimeKeeper track is created.
788     GetTimeTrack()
789     iw = servermanager.vtkSMAnimationSceneImageWriter()
790     iw.SetAnimationScene(scene.SMProxy)
791     iw.SetFileName(filename)
792     if params.has_key("Magnification"):
793         iw.SetMagnification(int(params["Magnification"]))
794     if params.has_key("Quality"):
795         iw.SetQuality(int(params["Quality"]))
796     if params.has_key("Subsampling"):
797         iw.SetSubsampling(int(params["Subsampling"]))
798     if params.has_key("BackgroundColor"):
799         iw.SetBackgroundColor(params["BackgroundColor"])
800     if params.has_key("FrameRate"):
801         iw.SetFrameRate(float(params["FrameRate"]))
802     iw.Save()
803
804 def _GetRepresentationAnimationHelper(sourceproxy):
805     """Internal method that returns the representation animation helper for a
806        source proxy. It creates a new one if none exists."""
807     # ascertain that proxy is a source proxy
808     if not sourceproxy in GetSources().values():
809         return None
810     for proxy in servermanager.ProxyManager():
811         if proxy.GetXMLName() == "RepresentationAnimationHelper" and\
812            proxy.GetProperty("Source").IsProxyAdded(sourceproxy.SMProxy):
813              return proxy
814     # create a new helper
815     proxy = servermanager.misc.RepresentationAnimationHelper(
816       Source=sourceproxy)
817     servermanager.ProxyManager().RegisterProxy(
818       "pq_helper_proxies.%s" % sourceproxy.GetGlobalIDAsString(),
819       "RepresentationAnimationHelper", proxy)
820     return proxy
821
822 def GetAnimationTrack(propertyname_or_property, index=None, proxy=None):
823     """Returns an animation cue for the property. If one doesn't exist then a
824     new one will be created.
825     Typical usage:
826         track = GetAnimationTrack("Center", 0, sphere) or
827         track = GetAnimationTrack(sphere.GetProperty("Radius")) or
828
829         # this returns the track to animate visibility of the active source in
830         # all views.
831         track = GetAnimationTrack("Visibility")
832
833      For animating properties on implicit planes etc., use the following
834      signatures:
835         track = GetAnimationTrack(slice.SliceType.GetProperty("Origin"), 0) or
836         track = GetAnimationTrack("Origin", 0, slice.SliceType)
837
838     """
839     if not proxy:
840         proxy = GetActiveSource()
841     if not isinstance(proxy, servermanager.Proxy):
842         raise TypeError, "proxy must be a servermanager.Proxy instance"
843     if isinstance(propertyname_or_property, str):
844         propertyname = propertyname_or_property
845     elif isinstance(propertyname_or_property, servermanager.Property):
846         prop = propertyname_or_property
847         propertyname = prop.Name
848         proxy = prop.Proxy
849     else:
850         raise TypeError, "propertyname_or_property must be a string or servermanager.Property"
851
852     # To handle the case where the property is actually a "display" property, in
853     # which case we are actually animating the "RepresentationAnimationHelper"
854     # associated with the source.
855     if propertyname in ["Visibility", "Opacity"]:
856         proxy = _GetRepresentationAnimationHelper(proxy)
857     if not proxy or not proxy.GetProperty(propertyname):
858         raise AttributeError, "Failed to locate property %s" % propertyname
859
860     scene = GetAnimationScene()
861     for cue in scene.Cues:
862         try:
863             if cue.AnimatedProxy.IsSame(proxy) and\
864                cue.AnimatedPropertyName == propertyname:
865                 if index == None or index.IsSame(cue.AnimatedElement): ##index == cue.AnimatedElement:
866                     return cue
867         except AttributeError:
868             pass
869
870     # matching animation track wasn't found, create a new one.
871     cue = KeyFrameAnimationCue()
872     cue.AnimatedProxy = proxy
873     cue.AnimatedPropertyName = propertyname
874     if index != None:
875         cue.AnimatedElement = index
876     scene.Cues.append(cue)
877     return cue
878
879 def GetCameraTrack(view=None):
880     """Returns the camera animation track for the given view. If no view is
881     specified, active view will be used. If no exisiting camera animation track
882     is found, a new one will be created."""
883     if not view:
884         view = GetActiveView()
885     if not view:
886         raise ValueError, "No view specified"
887     scene = GetAnimationScene()
888     for cue in scene.Cues:
889         if cue.AnimatedProxy.IsSame(view) and\
890            cue.GetXMLName() == "CameraAnimationCue":
891             return cue
892     # no cue was found, create a new one.
893     cue = CameraAnimationCue()
894     cue.AnimatedProxy = view
895     scene.Cues.append(cue)
896     return cue
897
898 def GetTimeTrack():
899     """Returns the animation track used to control the time requested from all
900     readers/filters during playback.
901     This is the "TimeKeeper - Time" track shown in ParaView's 'Animation View'.
902     If none exists, a new one will be created."""
903     scene = GetAnimationScene()
904     tk = scene.TimeKeeper
905     for cue in scene.Cues:
906         if cue.GetXMLName() == "TimeAnimationCue" and cue.AnimatedProxy.IsSame(tk)\
907             and cue.AnimatedPropertyName == "Time":
908             return cue
909     # no cue was found, create a new one.
910     cue = TimeAnimationCue()
911     cue.AnimatedProxy = tk
912     cue.AnimatedPropertyName = "Time"
913     scene.Cues.append(cue)
914     return cue
915
916 def LoadXML(xmlstring, ns=None):
917     """Given a server manager XML as a string, parse and process it.
918     If you loaded the simple module with from paraview.simple import *,
919     make sure to pass globals() as the second arguments:
920     LoadXML(xmlstring, globals())
921     Otherwise, the new functions will not appear in the global namespace."""
922     if not ns:
923         ns = globals()
924     servermanager.LoadXML(xmlstring)
925     _add_functions(ns)
926
927 def LoadPlugin(filename, remote=True, ns=None):
928     """Loads a ParaView plugin and updates this module with new constructors
929     if any. The remote argument (default to True) is to specify whether 
930     the plugin will be loaded on client (remote=False) or on server (remote=True).
931     If you loaded the simple module with from paraview.simple import *,
932     make sure to pass globals() as an argument:
933     LoadPlugin("myplugin", False, globals()), to load on client;
934     LoadPlugin("myplugin", True, globals()), to load on server; 
935     LoadPlugin("myplugin", ns=globals()), to load on server.
936     Otherwise, the new functions will not appear in the global namespace."""
937     
938     if not ns:
939         ns = globals()
940     servermanager.LoadPlugin(filename, remote)
941     _add_functions(ns)
942
943 def LoadDistributedPlugin(pluginname, remote=True, ns=None):
944     """Loads a plugin that's distributed with the executable. This uses the
945     information known about plugins distributed with ParaView to locate the
946     shared library for the plugin to load. Raises a RuntimeError if the plugin
947     was not found."""
948     if not servermanager.ActiveConnection:
949         raise RuntimeError, "Cannot load a plugin without a session."
950     plm = servermanager.vtkSMProxyManager.GetProxyManager().GetPluginManager()
951     if remote:
952         session = servermanager.ActiveConnection.Session
953         info = plm.GetRemoteInformation(session)
954     else:
955         info = plm.GetLocalInformation()
956     for cc in range(0, info.GetNumberOfPlugins()):
957         if info.GetPluginName(cc) == pluginname:
958             return LoadPlugin(info.GetPluginFileName(cc), remote, ns)
959     raise RuntimeError, "Plugin '%s' not found" % pluginname
960
961 def GetLayouts():
962     """Returns the layout proxies on the active session.
963     Layout proxies are used to place views in a grid."""
964     return servermanager.ProxyManager().GetProxiesInGroup("layouts")
965
966 def GetLayout(view=None):
967     """Return the layout containing the give view, if any.
968     If no view is specified, active view is used.
969     """
970     if not view:
971         view = GetActiveView()
972     if not view:
973         raise RuntimeError, "No active view was found."
974     layouts = GetLayouts()
975     for layout in layouts.values():
976         if layout.GetViewLocation(view) != -1:
977             return layout
978     return None
979
980
981 def SelectCells(query=None, proxy=None):
982     """Select cells satisfying the query. If query is None, then all cells are
983        selected. If proxy is None, then the active source is used."""
984     if not proxy:
985         proxy = GetActiveSource()
986     if not proxy:
987         raise RuntimeError, "No active source was found."
988
989     if not query:
990         # This ends up being true for all cells.
991         query = "id >= 0"
992
993     # Note, selSource is not registered with the proxy manager.
994     selSource = servermanager.sources.SelectionQuerySource()
995     selSource.FieldType = "CELL"
996     selSource.QueryString = str(query)
997     proxy.SMProxy.SetSelectionInput(proxy.Port, selSource.SMProxy, 0)
998     return selSource
999
1000 def ClearSelection(proxy=None):
1001     """Clears the selection on the active source."""
1002     if not proxy:
1003         proxy = GetActiveSource()
1004     if not proxy:
1005         raise RuntimeError, "No active source was found."
1006     proxy.SMProxy.SetSelectionInput(proxy.Port, None, 0)
1007
1008 class ActiveObjects(object):
1009     """This class manages the active objects (source and view). The active
1010     objects are shared between Python and the user interface. This class
1011     is for internal use. Use the Set/Get methods for setting and getting
1012     active objects."""
1013     def __get_selection_model(self, name, session=None):
1014         "Internal method."
1015         if session and not servermanager.ActiveConnection.Session.IsSame(session):
1016             raise RuntimeError, "Try to set an active object with invalid active connection."
1017         pxm = servermanager.ProxyManager(session)
1018         model = pxm.GetSelectionModel(name)
1019         if not model:
1020             model = servermanager.vtkSMProxySelectionModel()
1021             pxm.RegisterSelectionModel(name, model)
1022         return model
1023
1024     def set_view(self, view):
1025         "Sets the active view."
1026         active_view_model = self.__get_selection_model("ActiveView")
1027         if view:
1028             active_view_model = self.__get_selection_model("ActiveView", view.GetSession())
1029             active_view_model.SetCurrentProxy(view.SMProxy, 0)
1030         else:
1031             active_view_model = self.__get_selection_model("ActiveView")
1032             active_view_model.SetCurrentProxy(None, 0)
1033
1034     def get_view(self):
1035         "Returns the active view."
1036         return servermanager._getPyProxy(
1037             self.__get_selection_model("ActiveView").GetCurrentProxy())
1038
1039     def set_source(self, source):
1040         "Sets the active source."
1041         active_sources_model = self.__get_selection_model("ActiveSources")
1042         if source:
1043             # 3 == CLEAR_AND_SELECT
1044             active_sources_model = self.__get_selection_model("ActiveSources", source.GetSession())
1045             active_sources_model.SetCurrentProxy(source.SMProxy, 3)
1046         else:
1047             active_sources_model = self.__get_selection_model("ActiveSources")
1048             active_sources_model.SetCurrentProxy(None, 3)
1049
1050     def __convert_proxy(self, px):
1051         "Internal method."
1052         if not px:
1053             return None
1054         if px.IsA("vtkSMSourceProxy"):
1055             return servermanager._getPyProxy(px)
1056         else:
1057             return servermanager.OutputPort(
1058               servermanager._getPyProxy(px.GetSourceProxy()),
1059               px.GetPortIndex())
1060         
1061     def get_source(self):
1062         "Returns the active source."
1063         return self.__convert_proxy(
1064           self.__get_selection_model("ActiveSources").GetCurrentProxy())
1065
1066     def get_selected_sources(self):
1067         "Returns the set of sources selected in the pipeline browser."
1068         model = self.__get_selection_model("ActiveSources")
1069         proxies = []
1070         for i in xrange(model.GetNumberOfSelectedProxies()):
1071             proxies.append(self.__convert_proxy(model.GetSelectedProxy(i)))
1072         return proxies
1073
1074     view = property(get_view, set_view)
1075     source = property(get_source, set_source)
1076
1077 class _funcs_internals:
1078     """Internal class."""
1079     first_render = True
1080     view_counter = 0
1081     rep_counter = 0
1082
1083 def demo1():
1084     """Simple demo that create the following pipeline
1085     sphere - shrink - \
1086                        - append
1087     cone            - /
1088     """
1089     # Create a sphere of radius = 2, theta res. = 32
1090     # This object becomes the active source.
1091     ss = Sphere(Radius=2, ThetaResolution=32)
1092     # Apply the shrink filter. The Input property is optional. If Input
1093     # is not specified, the filter is applied to the active source.
1094     shr = Shrink(Input=ss)
1095     # Create a cone source.
1096     cs = Cone()
1097     # Append cone and shrink
1098     app = AppendDatasets()
1099     app.Input = [shr, cs]
1100     # Show the output of the append filter. The argument is optional
1101     # as the app filter is now the active object.
1102     Show(app)
1103     # Render the default view.
1104     Render()
1105
1106 def demo2(fname="/Users/berk/Work/ParaView/ParaViewData/Data/disk_out_ref.ex2"):
1107     """This demo shows the use of readers, data information and display
1108     properties."""
1109     
1110     # Create the exodus reader and specify a file name
1111     reader = ExodusIIReader(FileName=fname)
1112     # Get the list of point arrays.
1113     avail = reader.PointVariables.Available
1114     print avail
1115     # Select all arrays
1116     reader.PointVariables = avail
1117
1118     # Turn on the visibility of the reader
1119     Show(reader)
1120     # Set representation to wireframe
1121     SetDisplayProperties(Representation = "Wireframe")
1122     # Black background is not pretty
1123     SetViewProperties(Background = [0.4, 0.4, 0.6])
1124     Render()
1125     # Change the elevation of the camera. See VTK documentation of vtkCamera
1126     # for camera parameters.
1127     # NOTE: THIS WILL BE SIMPLER
1128     GetActiveCamera().Elevation(45)
1129     Render()
1130     # Now that the reader executed, let's get some information about it's
1131     # output.
1132     pdi = reader[0].PointData
1133     # This prints a list of all read point data arrays as well as their
1134     # value ranges.
1135     print 'Number of point arrays:', len(pdi)
1136     for i in range(len(pdi)):
1137         ai = pdi[i]
1138         print "----------------"
1139         print "Array:", i, " ", ai.Name, ":"
1140         numComps = ai.GetNumberOfComponents()
1141         print "Number of components:", numComps
1142         for j in range(numComps):
1143             print "Range:", ai.GetRange(j)
1144     # White is boring. Let's color the geometry using a variable.
1145     # First create a lookup table. This object controls how scalar
1146     # values are mapped to colors. See VTK documentation for
1147     # details.
1148     # Map min (0.00678) to blue, max (0.0288) to red
1149     SetDisplayProperties(LookupTable = MakeBlueToRedLT(0.00678, 0.0288))
1150     # Color by point array called Pres
1151     SetDisplayProperties(ColorAttributeType = "POINT_DATA")
1152     SetDisplayProperties(ColorArrayName = "Pres")
1153     Render()
1154
1155 def PrintTrace():
1156     print paravisSM.myParavis.GetTrace()
1157
1158 def SaveTrace(fileName):
1159     paravisSM.myParavis.SaveTrace(fileName)
1160
1161
1162 if not servermanager.ActiveConnection:
1163     Connect()
1164 else:
1165     _add_functions(globals())
1166
1167 def ImportFile(theFileName):
1168     paravisSM.ImportFile(theFileName)
1169
1170 active_objects = ActiveObjects()
1171 active_objects.view = GetRenderView()