Beispiel #1
0
    def __init__(self, array, type_array=None):
        '''

        :param array: Receives a pandas DataFrame, or numpy array or vtkDataArray
        :param type_array: Receives the vtk data type or a numpy array type
        '''
        self._vtk = None
        array = self._convert_list_pandas_to_numpy(array)

        vtk_type = None
        np_type = None
        if isinstance(type_array, int):
            vtk_type = type_array
            np_type = ns.get_vtk_to_numpy_typemap()[type_array]
        elif isinstance(type_array, type):
            vtk_type = ns.get_vtk_array_type(type_array)
            np_type = type_array

        if isinstance(array, np.ndarray):
            if not array.flags.contiguous:
                array = np.ascontiguousarray(array)
            if np_type:
                array = array.astype(np_type)
            self._numpy = array
            self._vtk = ns.numpy_to_vtk(self._numpy, array_type=vtk_type)
            self._vtk._np = array
        elif isinstance(array, vtk.vtkDataArray):
            if type_array is None or array.GetDataType() == vtk_type:
                self._vtk = array
                self._numpy = ns.vtk_to_numpy(array)
            else:
                if type_array is None:
                    np_type = np.double
                    vtk_type = vtk.VTK_DOUBLE
                np_array = ns.vtk_to_numpy(array).astype(np_type)
                self._vtk = ns.create_vtk_array(vtk_type)
                self._vtk.SetName(array.GetName())
                self.numpy_to_vtk(np_array)
        else:
            raise ValueError(
                'Expected a Numpy array, but received a: {}'.format(
                    type(array)))
        self._vtk.AddObserver(vtk.vtkCommand.ModifiedEvent, self._update_numpy)
Beispiel #2
0
def numpy_to_vtk(num_array, deep=0, array_type=None):
    """Converts a contiguous real numpy Array to a VTK array object.

    This function only works for real arrays that are contiguous.
    Complex arrays are NOT handled.  It also works for multi-component
    arrays.  However, only 1, and 2 dimensional arrays are supported.
    This function is very efficient, so large arrays should not be a
    problem.

    If the second argument is set to 1, the array is deep-copied from
    from numpy. This is not as efficient as the default behavior
    (shallow copy) and uses more memory but detaches the two arrays
    such that the numpy array can be released.

    WARNING: You must maintain a reference to the passed numpy array, if
    the numpy data is gc'd and VTK will point to garbage which will in
    the best case give you a segfault.

    Parameters
    ----------
    - num_array :  a contiguous 1D or 2D, real numpy array.

    Notes
    -----
    This was pulled from VTK and modified to eliminate numpy 1.14 warnings.
    VTK uses a BSD license, so it's OK to do  that.
    """
    z = np.asarray(num_array)
    if not z.flags.contiguous:
        z = np.ascontiguousarray(z)

    shape = z.shape
    assert z.flags.contiguous, 'Only contiguous arrays are supported.'
    assert len(shape) < 3, \
           "Only arrays of dimensionality 2 or lower are allowed!"
    assert not np.issubdtype(z.dtype, np.complexfloating), \
           "Complex numpy arrays cannot be converted to vtk arrays."\
           "Use real() or imag() to get a component of the array before"\
           " passing it to vtk."

    # First create an array of the right type by using the typecode.
    if array_type:
        vtk_typecode = array_type
    else:
        vtk_typecode = get_vtk_array_type(z.dtype)
    result_array = create_vtk_array(vtk_typecode)

    # Fixup shape in case its empty or scalar.
    try:
        test_var = shape[0]
    except:
        shape = (0, )

    # Find the shape and set number of components.
    if len(shape) == 1:
        result_array.SetNumberOfComponents(1)
    else:
        result_array.SetNumberOfComponents(shape[1])

    result_array.SetNumberOfTuples(shape[0])

    # Ravel the array appropriately.
    arr_dtype = get_numpy_array_type(vtk_typecode)
    if np.issubdtype(z.dtype, arr_dtype) or \
       z.dtype == np.dtype(arr_dtype):
        z_flat = np.ravel(z)
    else:
        z_flat = np.ravel(z).astype(arr_dtype)
        # z_flat is now a standalone object with no references from the caller.
        # As such, it will drop out of this scope and cause memory issues if we
        # do not deep copy its data.
        deep = 1

    # Point the VTK array to the numpy data.  The last argument (1)
    # tells the array not to deallocate.
    result_array.SetVoidArray(z_flat, len(z_flat), 1)
    if deep:
        copy = result_array.NewInstance()
        copy.DeepCopy(result_array)
        result_array = copy
    else:
        result_array._numpy_reference = z
    return result_array