File: README.txt

package info (click to toggle)
mayavi2 4.8.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 21,892 kB
  • sloc: python: 49,447; javascript: 32,885; makefile: 129; fortran: 60
file content (942 lines) | stat: -rw-r--r-- 32,364 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
=====================================
An Introduction to Traited VTK (tvtk)
=====================================
:Author: Prabhu Ramachandran
:Contact: prabhu@enthought.com
:Copyright: 2004-2020, Enthought, Inc.

.. contents::


Introduction
============

The tvtk module (also called TVTK) provides a traits_ enabled version
of VTK_.  TVTK objects wrap around VTK objects but additionally
support traits_, and provide a convenient Pythonic API.  TVTK is
implemented mostly in pure Python (except for a small extension
module).  Here is a list of current features.

 * All VTK classes are wrapped.
 * Classes are generated at install time on the installed platform.
 * Support for traits_.
 * Elementary pickle support.
 * Pythonic feel.
 * Handles numpy arrays/Python lists transparently.
 * Support for a pipeline browser, `ivtk` and a high-level `mlab` like
   module.
 * Envisage plugins for a tvtk scene and the pipeline browser.
 * tvtk is free software with a BSD style license.


.. _traits: http://docs.enthought.com/traits
.. _VTK: http://www.vtk.org


Requirements
============

The following is a list of requirements for you to be able to run
tvtk.

 * Python-2.3 or greater.
 * Python should be built with zlib support and must support ZIP file
   imports.
 * VTK-5.x, VTK-4.4 or VTK-4.2.  It is unlikely to work with VTK-3.x.
 * Traits.
 * numpy -- Any recent version should be fine.
 * To use `ivtk.py`, `mlab` you need to have `pyface` installed.
 * To use the plugins you need Envisage installed.


Installation
============

TVTK is meant to be installed as part of the `mayavi` package.
Please visit the installation guide on the Mayavi documentation:

   http://docs.enthought.com/mayavi/mayavi/installation.html

This document only covers building and using TVTK from inside a
checkout of the the mayavi_ repository.  The tvtk module lives
inside `tvtk`.  To build the tvtk module and use them from
inside the `mayavi` sources do the following from the base of the
mayavi source tree (we assume here that this is in
`/home/user/src/lib/mayavi`)::

  $ pwd
  /home/user/src/lib/mayavi
  $ python setup.py build

The code generation will take a bit of time.  On a PentiumIII machine
at 450Mhz, generating the code takes about a minute.  If the code
generation was successful you should see a ZIP file called
`tvtk_classes.zip` in the tvtk directory along with an extension
module.

This completes the installation.  The build can be tested by running
the tests in the `tests/` directory.  This tests the built code::

  $ pwd
  /home/user/src/lib/mayavi
  $ python -m nose.core -v tvtk/tests
  [...]

If the tests run fine, the build is good.  There are other tests in
the `tests` directory that can also be run.

Documentation is available in the 'docs/' directory.  The 'examples/'
directory contains a few simple examples demonstrating tvtk in action.


Basic Usage
===========

An example of how tvtk can be used follows::

    >>> from tvtk.api import tvtk
    >>> cs = tvtk.ConeSource()
    >>> cs.resolution = 36
    >>> m = tvtk.PolyDataMapper()
    >>> m.set_input_data(cs.output)
    >>> a = tvtk.Actor()
    >>> a.mapper = m
    >>> p = a.property
    >>> p.representation = 'w'
    >>> print(p.representation)
    'wireframe'

Or equivalently::

    >>> from tvtk.api import tvtk
    >>> cs = tvtk.ConeSource(resolution=36)
    >>> m = tvtk.PolyDataMapper(input=cs.output)
    >>> p = tvtk.Property(representation='w')
    >>> a = tvtk.Actor(mapper=m, property=p)

Note that the properties of the object can be set during the
instantiation.

To import tvtk please use::

   from tvtk.api import tvtk

While this is perhaps a little inconvenient, note that tvtk provides
access to all the VTK classes.  This is the same way that the `vtk`
package also behaves.

If you are familiar with VTK-Python it is clear from the above example
that tvtk "feels" like VTK but is more Pythonic.  The most important
differences are.

  1. tvtk class names are essentially similar to VTK classes except
     there is no annoying 'vtk' at the front.  The only difficulty is
     with classes that start with a digit.  For example
     'vtk3DSImporter' becomes '3DSImporter'.  This is illegal in
     Python and therefore the class name used is 'ThreeDSImporter'.
     So, if the first character is a digit, it is replaced by an
     equivalent non-digit string.  There are very few classes like
     this so this is not a big deal.

  2. tvtk method names are `enthought` style names and not CamelCase.
     That is, if a VTK method is called `AddItem`, the equivalent tvtk
     name is `add_item`.  This is done for the sake of consistency
     with names used in the `enthought` package.

  3. Many VTK methods are replaced by handy properties.  In the above
     example, we used `m.input = cs.output` and `p.representation =
     'w'` instead of what would have been `m.SetInput(cs.GetOutput())`
     and `p.SetRepresentationToWireframe()` etc.  Some of these
     properties are really traits_.

  4. Unlike VTK objects, one can set the properties of a tvtk object
     when the object is initialized by passing the properties (traits)
     of the object as keyword arguments at the time of class
     instantiation.  For example `cs = tvtk.ConeSource(radius=0.1,
     height=0.5)`.

If you are used to VTK, this might take a little getting used to.
However, these changes are consistent across all of tvtk.  If they
aren't, its a bug.  Please let me know if you see inconsistencies.

If the underlying VTK object returns another VTK object, this is
suitably wrapped as a tvtk object.  Similarly, all relevant parameters
for a tvtk method should be tvtk objects, these are transparently
converted to VTK objects.


Advanced Usage
==============

There are several important new features that tvtk provides in
addition to the above.  A tvtk object basically wraps around a
VTK-Python object and provides a trait enabled API for the VTK object.
Before we discuss these new features it is important to understand the
notion of what we mean by the "basic state" or "state" of a tvtk
object.  This is defined and subsequently the new features are
discussed in some detail.


.. _state:

Definition of the "basic state" of a tvtk object
------------------------------------------------

In tvtk the set of all properties of the VTK object that are
represented as traits and have for their value a simple Python type
(int/float/string) or a special value (like a tuple specifying color)
define the state.

In terms of the implementation of tvtk, any property of a VTK object
that can be set by using methods having the form `<Property>On` or
`<Property>Off`, `Set<Property>To<Value>` and `Set/Get<Property>`
(where the return type is an int/float/string/tuple) are represented
as traits.  These properties are said to represent the "basic state"
of the tvtk object.

Note that the complete state of the underlying C++ object is
impossible to represent in the Python world since this usually
involves various pointers to other C++ objects.

It is also important to consider that the identity of objects
is preserved according to the VTK behavior. For example, in the
following code, the default object created by the VTK implementation of
`GetLines()` is the same for any vtkPolyData::

  >>> data1 = vtk.vtkPolyData()
  >>> data2 = vtk.vtkPolyData()
  >>> data1.GetLines()
  (vtkCellArray)0x103b52e30
  >>> data2.GetLines()
  (vtkCellArray)0x103b52e30

The equivalent tvtk code behaves in the same way::

  >>> data1 = tvtk.PolyData()
  >>> data2 = tvtk.PolyData()
  >>> data1.lines
  <tvtk.tvtk_classes.cell_array.CellArray at 0xe11e570>
  >>> data2.lines
  <tvtk.tvtk_classes.cell_array.CellArray at 0xe11e570>


The wrapped VTK object
-----------------------

The user should not ordinarily know this (or rely on this!) but it
sometimes helps to know how to access the underlying VTK object that
the tvtk object has wrapped.  The recommended way to do this is by
using the `to_vtk` function.  For example::

  >>> pd = tvtk.PolyData()
  >>> pd_vtk = tvtk.to_vtk(pd)


The inverse process of creating a tvtk object from a VTK object is to
use the `to_tvtk` function like so::

  >>> pd1 = tvtk.to_tvtk(pd_vtk)
  >>> print(pd1 == pd)
  True

Notice that `pd1 == pd`.  TVTK maintains an internal cache of existing
tvtk objects and when the `to_tvtk` method is given a VTK object it
returns the cached object for the particular VTK object.  This is
particularly useful in situations like this::

  >>> cs = tvtk.ConeSource()
  >>> o = cs.output
  >>> m = tvtk.PolyDataMapper()
  >>> m.input = o
  >>> # ...
  >>> print(m.input == o)
  True

It must be noted that if a tvtk object's goes out of scope in Python,
it is garbage collected.  However, its underlying VTK object may still
exist inside the VTK pipeline.  When one accesses this object, a new
tvtk wrapper object is created.  The following illustrates this::

  >>> cs = tvtk.ConeSource()
  >>> o = cs.output
  >>> m = tvtk.PolyDataMapper()
  >>> m.input_connection = cs.output_port
  >>> print(id(o))
  126526931186080
  >>> print(id(m.input))
  126526931186080
  >>> del o
  >>> print(id(m.input))
  126526931186080

Thus, after `o` is garbage collected `m.input` no longer refers to the
original tvtk object the old one is cached and returned.  


tvtk and traits
---------------

All tvtk objects are derived from `traits.HasStrictTraits`.  As
discussed above, all the basic state related methods are represented
as traits in tvtk.  This is why we are able to do::

    >>> p = a.property
    >>> p.representation = 'w'
    >>> print(p.representation)
    'wireframe'
    >>> # OR do this:
    >>> p = tvtk.Property(opacity=0.5, color=(1,0,0), representation='w')

Also note that it is possible to set many properties of a tvtk object
in one go using the `set` method.  For example::

    >>> p = tvtk.Property()
    >>> p.trait_set(opacity=0.5, color=(1,0,0), representation='w')

Any tvtk object will automatically provide the basic functionality of
a traited class.  Thus, one can also pop up a standard GUI editor for
any tvtk object trivially.  For example if one is using `pycrust` or
is using `gui_thread` (this module should be available if SciPy_ is
installed) or `ipython -wthread` one could easily do this::

    >>> p = tvtk.Property()
    >>> p.edit_traits()
    >>> # OR
    >>> p.configure_traits() # This should work even without gui_thread

A GUI editor should pop-up at this point.  Note, that changes made to
the trait will automagically be propagated to the underlying VTK
object.  Most importantly, the reverse is also true.  That is, if some
other object changes the basic state of the wrapped VTK object, then
the trait will be automagically updated.  For example::

    >>> p = tvtk.Property()
    >>> print(p.representation)
    'surface'
    >>> p_vtk = tvtk.to_tvtk(p)
    >>> p_vtk.SetRepresentationToWireframe()
    >>> print(p.representation)
    'wireframe'

This also means that if you change properties of the object on the
interpreter and at the same time are using a GUI editor, if the object
changes, the GUI editor will update automatically.

It is important to note that tvtk objects have strict traits.  It is
therefore an error to set an attribute that is not already defined in
the class.  This is illustrated in the following example::

  >>> cs = tvtk.ConeSource()
  >>> cs.foo = 1
  Traceback (most recent call last):
    File "<stdin>", line 1, in ?
  TraitError: Cannot set the undefined 'foo' attribute of a 'ConeSource' object.



.. _SciPy: http://www.scipy.org


Sub-classing tvtk classes
-------------------------

You may subclass tvtk classes but please keep in mind the following:

 1. All tvtk classes derive from `HasStrictTraits`.

 2. You must make sure to call the super class's __init__ correctly.

 3. If you have to override the __del__ method, you *must* make sure
    you call the super class's __del__ method.



Pickling tvtk objects
---------------------

tvtk objects support a simple form of pickling.  The state_ of the
tvtk object maybe pickled.  The references to other VTK objects held
by the object are *NOT* picklable.  For example::

    >>> import cPickle
    >>> p = tvtk.Property()
    >>> p.representation = 'w'
    >>> s = cPickle.dumps(p)
    >>> del p
    >>> p = cPickle.load(s)
    >>> print(p.representation)
    'wireframe'

Once again, only the state_ of the object is pickled.  Internal
references are not.  So the construction of the VTK pipeline will not
be pickled.  For example if we pickled the actor from the example
given in the `Basic Usage`_ section, then the `ConeSource`,
`PolyDataMapper` etc. will not be pickled.  Some of the tvtk classes
like `Matrix4x4` also have special code that enables better pickling.

It is also possible to set the state of a live object.  Normally,
`pickle.load` will create a new object.  However, by using
`__setstate__` directly it is possible to just update the state_ of
the object.  For example::

    >>> p = tvtk.Property()
    >>> p.interpolation = 'flat'
    >>> d = p.__getstate__()
    >>> del p
    >>> p = Prop()
    >>> p.__setstate__(d)

Here, after `__setstate__` is called, the object's state alone will be
updated.  No new object is created.


Docstrings
----------

All tvtk methods and traits are documented using the VTK docstrings.
The class names and method names are changed suitably as mentioned in
the `Basic Usage`_ section.  These docstrings are generated
automatically and there might be small mistakes in them.  All methods
of a tvtk object also provide method signature information in the
docstring.


User defined code
-----------------

All the tvtk wrapper classes are generated automatically.  Sometimes
one would like to customize a particular class and use that instead of
the default.  The easiest way to do this would be to copy out the
relevant class from the `tvtk_classes.zip` file, modify it suitably
(without changing the name of the file or class name of course) and
then add this file into the `tvtk/custom` directory.  Any file here
will override the default inside the ZIP file.


Collections
-----------

Any object derived from `Collection` (i.e. `vtkCollection`) will
behave like a proper Python sequence.  Here is an example::

    >>> ac = tvtk.ActorCollection()
    >>> print(len(ac))
    0
    >>> ac.append(tvtk.Actor())
    >>> print(len(ac))
    1
    >>> for i in ac:
    ...    print(i)
    ...
    [...]
    >>> ac[-1] = tvtk.Actor()
    >>> del ac[0]
    >>> print(len(ac))
    0

Currently, only subclasses of `Collection` behave this way.


Array handling
--------------

All the `DataArray` subclasses behave like Pythonic arrays and support
the iteration protocol in addition to `__getitem__`, `__setitem__`,
`__repr__`, `append`, `extend` etc.  Further, it is possible to set
the value of the array using either a numpy array or a Python list
(using the `from_array` method).  One can also get the data stored in
the array into a numpy array (using the `to_array` method).
Similarly, the `Points` and `IdList` classes also support these
features.  The `CellArray` class only provides the `from_array` and
`to_array` methods and does not provide a sequence like protocol.
This is because of the peculiarity of the wrapped `vtkCellArray`
class.

One extremely useful feature is that almost any tvtk method/property
that accepts a `DataArray`, `Points`, `IdList` or `CellArray`
instance, will transparently accept a numpy array or a Python list.
Here is a simple example demonstrating these::

    >>> ########################################
    >>> from tvtk.api import tvtk
    >>> import numpy as np
    >>> data = np.array([[0,0,0,10], [1,0,0,20],
    ...                      [0,1,0,20], [0,0,1,30]], 'f')
    >>> triangles = np.array([[0,1,3], [0,3,2],
    ...                            [1,2,3], [0,2,1]])
    >>> points = data[:,:3]
    >>> temperature = data[:,-1]
    >>> mesh = tvtk.PolyData()
    >>> mesh.points = points
    >>> mesh.polys = triangles
    >>> mesh.point_data.scalars = temperature

    >>> ########################################
    >>> # Array's are Pythonic.
    >>> import operator
    >>> reduce(operator.add, mesh.point_data.scalars, 0.0)
    80.0
    >>> print(mesh.point_data.scalars)
    [10.0, 20.0, 20.0, 30.0]
    >>> print(mesh.points)
    [(0.0, 0.0, 0.0), (1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)]

    >>> ########################################
    >>> # Demo of from_array/to_array
    >>> pts = tvtk.Points()
    >>> pts.from_array(points)
    >>> print(pts.to_array())
    [[ 0.  0.  0.]
     [ 1.  0.  0.]
     [ 0.  1.  0.]
     [ 0.  0.  1.]]


As can be seen, no `DataArray`, `Points` or `CellArray` instances need
to be created.  Note that Python tuples are *not* converted
implicitly.  The conversion from the passed arrays to the VTK arrays
is handled transparently and very efficiently.  The only exception to
this is the `IdList` class where the conversion is inefficient.
However, the `IdList` class is not used commonly.


The `CellArray` is used to specify the connectivity list for polygonal
data and has some peculiarities.  The `CellArray` needs to be
initialized using the cell connectivity list.  This can be specified
in one of several ways.

    1. A Python list of 1D lists.  Each 1D list can contain one
       cell connectivity list.  This is very slow and is to be
       used only when efficiency is of no consequence.

    2. A 2D numpy array with the cell connectivity list.

    3. A Python list of 2D numpy arrays.  Each numpy array can have a
       different shape.  This makes it easy to generate a cell array
       having cells of different kinds.

This conversion is most efficient if the passed numpy arrays have a
typecode of `tvtk.array_handler.ID_TYPE_CODE`.  Otherwise a
typecast is necessary and this involves an extra copy.  The input data
is *always copied* during the conversion.  Here is an example
illustrating these different approaches::

    >>> a = [[0], [1, 2], [3, 4, 5], [6, 7, 8, 9]]
    >>> cells = tvtk.CellArray()
    >>> cells.from_array(a)
    >>> a = np.array([[0,1,2], [3,4,5], [6,7,8]], int)
    >>> cells.from_array(a)
    >>> l_a = [a[:,:1], a[:2,:2], a]
    >>> cells.from_array(a)


An alternative way to use an arbitrary connectivity list having
different numbers of points per cell is to use the following
approach::

    >>> ids = np.array([3, 0,1,3,
    ...                 3, 0,3,2,
    ...                 3, 1,2,3,
    ...                 3, 0,2,1])
    >>> # The list is of form [npts,p0,p1,...p(npts-1), ...]
    >>> n_cell = 4
    >>> cells = tvtk.CellArray()
    >>> cells.set_cells(n_cell, ids)
    >>> print(cells.data)
    [3.0, ..., 1.0], length = 16

This is done very efficiently and does not copy the input data.  More
details on this are provided in the next sub-section.


Also note that `DataArray` objects can still be passed to these
methods as before.  For example we could have just as easily done
this::

    >>> points = tvtk.Points()
    >>> points.from_array(data[:,:3])
    >>> temperature = tvtk.FloatArray()
    >>> temperature.from_array(data[:,-1])
    >>> cells = tvtk.CellArray()
    >>> cells.set_cells(n_cell, ids)
    >>> mesh = tvtk.PolyData()
    >>> mesh.points = points
    >>> mesh.polys = cells
    >>> mesh.point_data.scalars = temperature


Important considerations
~~~~~~~~~~~~~~~~~~~~~~~~

To clarify the ensuing discussion we make a distinction between two
different forms of array handling.

  a. Explicit conversion -- These happen when the user is creating a
     tvtk array object and initializes this from a numpy array or
     Python list.  Like so::

        >>> f = tvtk.FloatArray()
        >>> a = np.array([1,2,3], int)
        >>> f.from_array(a)

  b. Implicit conversion -- These happen when the user passes an array
     or list to a tvtk method that expects a `DataArray`, `Points`,
     `IdList` or `CellArray` instance.


There are a few issues to keep in mind when using tvtk's array
handling features.  When possible, tvtk uses a view of the passed
numpy array and does not make a copy of the data stored in it.  This
means that changes to the VTK data array or to the numpy array are
visible in the other.  For example::

   >>> f = tvtk.FloatArray()
   >>> a = np.array([1,2,3], 'f')
   >>> f.from_array(a)
   >>> a[0] = 10.0
   >>> print(f)
   [10.0, 2.0, 3.0]
   >>> f[0] = -1.0
   >>> print(a)
   [-1.  2.  3.]

It is important to note that it is perfectly safe to delete the
reference to the numpy array since this array is actually cached safely
to eliminate nasty problems.  This memory is freed when the VTK array is
garbage collected.  Saving a reference to the numpy array also ensures
that the numpy array cannot be resized (this could have disastrous
effects).

However, there are exceptions to this behaviour of using "views" of
the numpy array.  The `DataArray` class and its subclasses and the
`Points` class only make copies of the given data in the following
situations.

    1. A Python list is given as the data.

    2. A non-contiguous numpy array is given.

    3. The method requiring the conversion of the array to a VTK array
       expects a `vtkBitArray` instance.

    4. The types of the expected VTK array and the passed numpy
       array are not equivalent to each other.  For example if the
       array passed has typecode 'i' but the tvtk method expects a
       `FloatArray`.


The cases 3 and 4 occur very rarely in implicit conversions because
most methods accept `DataArray` instances rather than specific
subclasses.  However, these cases are likely to occur in explicit
conversions.

`CellArray` *always* makes a copy of the data on assignment.  For
example::

    >>> ca = tvtk.CellArray()
    >>> triangles = np.array([[0,1,3], [0,3,2],
    ...                       [1,2,3], [0,2,1]])
    >>> ca.from_array(triangles)

This always makes a copy.  However, if one uses the `set_cells` method
a copy is made in the same circumstances as specified above for
`DataArray` and `Points` classes.  If no copy is made, the cell data
is a "view" of the numpy array.  Thus, the following example does
not make a copy::

    >>> ids = np.array([3, 0,1,3,
    ...                 3, 0,3,2,
    ...                 3, 1,2,3,
    ...                 3, 0,2,1], int)
    >>> ca.set_cells(4, ids)


Changing the values of the ids or changing the number of cells is
*not* recommended and will lead to undefined behaviour.  It should
also be noted that it is best to pass cell connectivity data in arrays
having typecode `tvtk.array_handler.ID_TYPE_CODE` (this is
actually computed dynamically depending on your VTK build and
platform).

The `IdList` also *always* makes a copy of the data passed to it.


Another issue to keep in mind is that VTK's data arrays always
re-allocate memory if they are resized.  This is illustrated in the
following example::

   >>> d = tvtk.DoubleArray()
   >>> a = np.array([1,2,3], 'd')
   >>> d.from_array(a)
   >>> a[0] = 10
   >>> d.append(4.0)
   >>> a[0] = 1
   >>> print(a)
   [ 1.   2.   3.]
   >>> print(d)
   [10.0, 2.0, 3.0, 4.0]
   >>> # Notice that d[0] == 10.0

In this case, `a` is not resized but `d` is.  Here, `d` actually makes
a copy of `a` and any further changes to `d` or `a` will not be
reflected in the other.  This case also illustrates a small problem.
`d` will hold a reference to `a` internally even though it uses none
of `a`'s memory.  Fortunately, when `d` is garbage collected the
memory occupied by `a` will be freed.  Thus the problem is not serious
but probably worth keeping in mind.


Summary of issues
~~~~~~~~~~~~~~~~~

To summarize the considerations of the previous sub-section, the
following are to be noted.

  1. Most often `DataArray` and `Points` objects do not make copies of
     the numpy data.  The exceptions are listed above.  This means
     changes to either the tvtk object or the array are reflected in
     the other.

  2. It is safe to delete references to the array object converted.
     You cannot resize the numpy array though.

  3. `CellArray` always copies data on assignment.  However, when
     using `set_cells`, the behaviour is similar to what happens for
     `DataArray` objects.  Note that it is not advisable to change the
     connectivity ids and number of cells when this is done.  Also
     note that for the `CellArray` it is best to pass data in the form
     of numpy arrays having a typecode of
     `tvtk.array_handler.ID_TYPE_CODE`).  Otherwise one
     incurs an extra copy due to a typecast.

  4. `IdList` always makes a copy of the data.  This class is very
     rarely used.

  5. tvtk array objects *always* copy the data when resized.  This
     could lead to increased memory usage in some circumstances.
     However, this is *not* a memory leak.


The upshot of these features is that array conversion can be extremely
efficient in terms of speed and memory considerations.


Other utility modules
=====================

The `tvtk` package ships with several other utility modules.  These
are briefly described in the following sections.

Miscellaneous
--------------

If you need to write out VTK data files given a TVTK dataset.  The
``tvtk.api.write_data`` function should be useful.  For example::

    >>> from tvtk.api import tvtk, write_data
    >>> pd = tvtk.PolyData()
    >>> # ...
    >>> write_data(pd, 'file_name')

This will write out an XML file with basename ``file_name``.  If one specifies
a ``.vtk`` extension, like say::

    >>> write_data(pd, 'file_name.vtk')

It will write out an old-style ASCII file.  See the docstring for more details.

VTK-Python defines several handy colors and these are made available in TVTK.
For example::

    >>> from tvtk.api import colors
    >>> colors.alice_blue
    (0.9412, 0.9725, 1.0)

This allows you to refer to color by name easily.

`pipeline.browser`
------------------

The `PipelineBrowser` class presents the view of the VTK pipeline as a
tree.  Double-clicking any node will let you edit the properties of
the object with a trait sheet editor.  The `TreeEditor` from the
traits package is used to represent the view.  This pipeline browser
is similar to but more sophisticated than MayaVi_'s (1.x) pipeline
browser.  The browser will most often automatically update itself as
you change the VTK pipeline.  When it does not you can right click on
any node and click refresh.

The algorithm to generate the objects in the tree can be changed.  The
user may subclass `TreeGenerator` and use that instead.  Please read
the code and docstrings for more details on the implementation.

.. _MayaVi: http://mayavi.sf.net


`tools.ivtk`
------------

A utility module that makes VTK/TVTK easier to use from the Python
interpreter.  The module uses the `tvtk.scene` module to
provide a wxPython widget.  ivtk basically provides this scene along
with an optional Python interpreter (via PyCrust) and an optional
pipeline browser view.

For a stand-alone application one may simply run the module.  To use
this under IPython_ (with -wthread) use the `viewer()` helper
function.  For example::

    >>> from tvtk.tools import ivtk
    >>> from tvtk.api import tvtk
    >>> # Create your actor ...
    >>> a = tvtk.Actor()
    >>> # Now create the viewer.
    >>> v = ivtk.viewer()
    >>> v.scene.add_actors(a)  # or v.scene.add_actor(a)


ivtk provides several useful classes that you may use from either
PyFace or wxPython -- `IVTK`, `IVTKWithCrust`, `IVTKWithBrowser` and
`IVTKWithCrustAndBrowser`.  Again read the code and docstrings to
learn more.  An example using ivtk is also available in
`examples/ivtk_example.py`.

.. _IPython: http://ipython.scipy.org


`tools.mlab`
------------

A module that provides Matlab-like 3d visualization functionality.
The general idea is shamelessly stolen from the `high-level API`_
provided by Octaviz_. Some of the test cases and demos are also
translated from there!

.. _Octaviz: http://octaviz.sourceforge.net/
.. _high-level API: http://octaviz.sourceforge.net/index.php?page=manpagesq

The implementation provided here is object oriented and each
visualization capability is implemented as a class that has traits.
So each of these may be configured.  Each visualization class derives
(ultimately) from MLabBase which is responsible for adding/removing
its actors into the render window.  The classes all require that the
RenderWindow be a `tvtk.scene.Scene` instance (this constraint
can be relaxed if necessary later on).

This module offers the following broad class of functionality:

`Figure`
  This basically manages all of the objects rendered.  Just like
  figure in any Matlab like environment.  A convenience function
  called `figure` may be used to create a nice Figure instance.

`Glyphs`
  This and its subclasses let one place glyphs at points specified as
  inputs.  The subclasses are: `Arrows`, `Cones`, `Cubes`,
  `Cylinders`, `Spheres`, and `Points`.

`Line3`
  Draws lines between the points specified at initialization time.

`Outline`
  Draws an outline for the contained objects.

`Title`
  Draws a title for the entire figure.

`LUTBase`
  Manages a lookup table and a scalar bar (legend) for it.  This is
  subclassed by all classes that need a LUT.

`SurfRegular`
  MayaVi1's `imv.surf` like functionality that plots surfaces given x
  (1D), y(1D) and z (or a callable) arrays.

`SurfRegularC`
  Also plots contour lines.

`TriMesh`
  Given triangle connectivity and points, plots a mesh of them.

`FancyTriMesh`
  Plots the mesh using tubes and spheres so its fancier.

`Mesh`
  Given x, y generated from `numpy.mgrid`, and a z to go with it.
  Along with optional scalars.  This class builds the triangle
  connectivity (assuming that x, y are from `numpy.mgrid`) and builds
  a mesh and shows it.

`FancyMesh`
  Like mesh but shows the mesh using tubes and spheres.

`Surf`
  This generates a surface mesh just like Mesh but renders the mesh as
  a surface.

`Contour3`
  Shows contour for a mesh.

`ImShow`
  Allows one to view large numpy arrays as image data using an image
  actor.  This is just like MayaVi1's `mayavi.tools.imv.viewi`.

To see nice examples of all of these look at the `test_*` functions at
the end of the mlab.py file.  Here is a quick example that uses some
of these test functions::

 >>> from tvtk.tools import mlab
 >>> f = mlab.figure()
 >>> mlab.test_surf(f) # Create a spherical harmonic.
 >>> f.pop() # Remove it.
 >>> mlab.test_molecule(f) # Show a caffeine molecule.
 >>> f.renwin.reset_zoom() # Scale the view.
 >>> f.pop() # Remove this.
 >>> mlab.test_lines(f) # Show pretty lines.
 >>> f.clear() # Remove all the stuff on screen.


Here is the `test_surf` function just to show you how easy it is to
use `mlab`::

 >>> # Create the spherical harmonic.
 >>> from numpy import pi, cos, sin, mgrid
 >>> dphi, dtheta = pi/250.0, pi/250.0
 >>> [phi,theta] = mgrid[0:pi+dphi*1.5:dphi,0:2*pi+dtheta*1.5:dtheta]
 >>> m0, m1, m2, m3, m4, m5, m6, m7 = 4, 3, 2, 3, 6, 2, 6, 4
 >>> r = sin(m0*phi)**m1 + cos(m2*phi)**m3 + sin(m4*theta)**m5 + cos(m6*theta)**m7
 >>> x = r*sin(phi)*cos(theta)
 >>> y = r*cos(phi)
 >>> z = r*sin(phi)*sin(theta)
 >>> # Now show the surface.
 >>> from tvtk.tools import mlab
 >>> fig = mlab.figure()
 >>> s = Surf(x, y, z, z)
 >>> fig.add(s)

As you may notice, this example has also been translated from the
Octaviz_ site.


`plugins`
---------

TVTK ships with two Envisage plugins.  One for a TVTK scene and
another for the pipeline browser.

The `scene` plugin allows one to create a new TVTK scene on the work
area.  Any number of these may be created.  It provides useful menu's
to set the view of the scene (like the ivtk menus).  It also allows
the user to save the view to an image.  The plugin also provides a few
preferences to set the background color of the window etc.

The `browser` plugin places a pipeline browser on the left of the
Envisage window.  This browser is hooked up to listen to scene
additions to the work area.  Each time a scene is added it will show
up as a top-level node in the browser.

These plugins may be used from any Envisage plugin.  To see a fully
functional example of this please look at the `examples/plugin/`
directory.  The example demonstrates how to use the plugins in
Envisage and make an application.