Source code for simphony_mayavi.core.cell_collection

from collections import MutableSequence

import numpy
from tvtk.api import tvtk


# FIXME This is a good candidate class for mayavi.


[docs]class CellCollection(MutableSequence): """ A mutable sequence of cells wrapping a tvtk.CellArray. """ def __init__(self, cell_array=None): """ Constructor Parameters ---------- cell_array : tvtk.CellArray The tvtk object to wrap. Default value is an empty tvtk.CellArray. """ if cell_array is None: cell_array = tvtk.CellArray() self._cell_array = cell_array
[docs] def __len__(self): """ The number of contained cells. """ # Need to use the vtk implementation due to issue # https://github.com/enthought/mayavi/issues/178 vtk_object = tvtk.to_vtk(self._cell_array) return vtk_object.GetNumberOfCells()
[docs] def __getitem__(self, index): """ Return the connectivity list for the cell at ``index``. """ location = self._cell_location(index) points = tvtk.IdList() self._cell_array.get_cell(location, points) return tuple(points)
[docs] def __setitem__(self, index, value): """ Update the connectivity list for cell at ``index``. .. note:: If the size of the connectivity list changes a slower path creating temporary arrays is used. """ cells = self._cell_array location = self._cell_location(index) start = location + 1 data = cells.data npoints = int(data[location]) if npoints == len(value): for i, j in enumerate(value): data[start + i] = j else: length = len(self) array = cells.to_array() left, _, right = numpy.split( array, [location, start + npoints]) new_cell = numpy.array([len(value)] + value, left.dtype) array = numpy.r_[left, new_cell, right] cells.set_cells(length, array)
[docs] def __delitem__(self, index): """ Remove cell at ``index``. .. note:: This operation will need to create temporary arrays in order to keep the data info consistent. """ location = self._cell_location(index) cells = self._cell_array new_length = len(self) - 1 start = location + 1 npoints = int(cells.data[location]) array = cells.to_array() left, _, right = numpy.split( array, [location, start + npoints]) array = numpy.r_[left, right] cells.set_cells(new_length, array)
[docs] def insert(self, index, value): """ Insert cell at ``index``. .. note:: This operation needs to use a slower path based on temporary array when index < sequence length. """ length = len(self) cells = self._cell_array if index >= length: cells.insert_next_cell(value) else: location = self._cell_location(index) new_length = length + 1 array = cells.to_array() left, right = numpy.split( array, (location,)) new_cell = numpy.array([len(value)] + value, left.dtype) array = numpy.r_[left, new_cell, right] cells.set_cells(new_length, array)
# Private methods ###################################################### def _cell_location(self, index): length = len(self) if 0 <= index < length: data = self._cell_array.data location = 0 for _ in range(index): location += int(data[location]) + 1 else: raise IndexError("Index {} out of range".format(index)) return location